'How to harden k8s cluster with service account

I'm looking to harden my cluster using service accounts. Right now all of the pods are using the default service account. My approach I think would be to create a separate service account for the pods currently in the cluster. The confusions right now for me is understanding what roles/clusterRoles (permissions) do I assign the subjects (i.e service accounts) to for each pod? For some pods, how would I go about identifying if it even needs access to the cluster API?

My cluster contains the following (I removed the IPs for privacy):

kubectl get all
NAME                                                        READY   STATUS    RESTARTS   AGE
pod/nginx-ingress-ingress-nginx-controller   1/1     Running   0          
 
NAME                                                       TYPE           CLUSTER-IP       EXTERNAL-IP       PORT(S)                      AGE
service/kubernetes                                         ClusterIP         <none>                         443/TCP                      123d
service/nginx-ingress-ingress-nginx-controller             LoadBalancer                                      80:31180/TCP,443:31405/TCP   116d
service/nginx-ingress-ingress-nginx-controller-admission   ClusterIP         <none>                          443/TCP                      116d
 
NAME                                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-ingress-ingress-nginx-controller   1/1     1            1           116d
 
NAME                                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-ingress-ingress-nginx-controller                1         1         1       7d19h
 
 
root@osboxes:/home/osboxes# kubectl get all -n <>
NAME                               READY   STATUS    RESTARTS   AGE
pod/mariadb-0               1/1     Running   0          5d19h
pod/web2                    1/1     Running   0          7d17h
 
NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/mariadb   ClusterIP                           <none>        3306/TCP   123d
service/web       ClusterIP                           <none>        80/TCP     116d
 
NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web2          1/1     1            1           7d17h
 
NAME                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/web2-6f8d8bcc76          1         1         1       7d17h
 
NAME                              READY   AGE
statefulset.apps/mariadb          1/1     123d
 
 
kubectl get all -n cert-manager
NAME                                          READY   STATUS    RESTARTS   AGE
pod/cert-manager-6b5c6b786d-cc448             1/1     Running   0          5d19h
pod/cert-manager-cainjector-6bc9d758b-sdb8l   1/1     Running   0          9d
pod/cert-manager-webhook-586d45d5ff-jsh54     1/1     Running   0          9d
 
NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/cert-manager           ClusterIP                     <none>        9402/TCP   12d
service/cert-manager-webhook   ClusterIP                     <none>        443/TCP    12d
 
NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/cert-manager              1/1     1            1           12d
deployment.apps/cert-manager-cainjector   1/1     1            1           12d
deployment.apps/cert-manager-webhook      1/1     1            1           12d
 
NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/cert-manager-6b5c6b786d             1         1         1       7d20h
replicaset.apps/cert-manager-6bbf595697             0         0         0       12d
replicaset.apps/cert-manager-788ff5c97d             0         0         0       7d21h
replicaset.apps/cert-manager-cainjector-6bc9d758b   1         1         1       12d
replicaset.apps/cert-manager-webhook-586d45d5ff     1         1         1       12d


Solution 1:[1]

More than just changing the default service account, you need to follow the NSA/CISA Kubernetes Hardening Guide.

For Pod Security Enforcement:

Enforcing security requirements on Pods can be accomplished natively in Kubernetes through two mechanisms:

  1. A beta1 release feature called Pod Security Admission – Production Kubernetes administrators should adopt Pod Security Admission, as the feature is enabled by default in Kubernetes version 1.23. Pod Security Admission is based around categorizing pods as privileged, baseline, and restricted and provides a more straightforward implementation than PSPs. More information about Pod Security Admission is available in the online documentation2 .
  2. A deprecated feature called Pod Security Policies (PSPs) – Administrators using PSPs while transitioning to Pod Security Admission can use information in Appendix C: Pod Security Policies to enhance their PSPs.

Protecting Pod service account tokens:

By default, Kubernetes automatically provisions a service account when creating a Pod and mounts the account’s secret token within the Pod at runtime. Many containerized applications do not require direct access to the service account as Kubernetes orchestration occurs transparently in the background. If an application is compromised, account tokens in Pods can be gleaned by cyber actors and used to further compromise the cluster. When an application does not need to access the service account directly, Kubernetes administrators should ensure that Pod specifications disable the secret token being mounted. This can be accomplished using the “automountServiceAccountToken: false” directive in the Pod’s YAML specification.

In some cases, containerized applications use provisioned service account tokens to authenticate to external services, such as cloud platforms. In these cases, it can be infeasible to disable the account token. Instead, cluster administrators should ensure that RBAC is implemented to restrict Pod privileges within the cluster.

RBAC:

Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within your organization.

RBAC authorization uses the rbac.authorization.k8s.io API group to drive authorization decisions, allowing you to dynamically configure policies through the Kubernetes API.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Gabriel Robledo Ahumada