> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Lab Solution Service Accounts

> Demonstrates inspecting Kubernetes ServiceAccounts, tokens, and Pod authentication, creating a dedicated service account, generating a token, and updating a Deployment to use the new service account for proper RBAC

In this lab we inspect ServiceAccounts, examine the tokens mounted into Pods, and configure a Deployment so its Pods run with the correct ServiceAccount. This ensures an application (like a web dashboard) can authenticate to the Kubernetes API with the intended RBAC permissions.

***

## 1) How many ServiceAccounts exist in the `default` namespace?

Run:

```bash theme={null}
kubectl get serviceaccounts -n default
```

Example output:

```bash theme={null}
NAME      SECRETS   AGE
default   1         10d
dev       1         2d
```

In this cluster there are two ServiceAccounts in the `default` namespace: `default` and `dev`.

***

## 2) What Secret token is used by the `default` ServiceAccount?

Describe the `default` ServiceAccount:

```bash theme={null}
kubectl describe sa default -n default
```

Look for the `Tokens` section. In this environment the `default` ServiceAccount shows:

```text theme={null}
Tokens: None
```

So the `default` ServiceAccount currently has no token listed (or none is shown).

***

## 3) Inspect the dashboard Deployment — what image does it use?

List Deployments and describe the `web-dashboard` Deployment:

```bash theme={null}
kubectl get deployments -n default
kubectl describe deployment web-dashboard -n default
```

From the Deployment's Pod template under `Containers`, the image is:

```text theme={null}
Image: gcr.io/kodekloud/customimage/my-kubernetes-dashboard
```

This is the container image used by the `web-dashboard` deployment.

***

## 4) When accessing the dashboard UI, an error appears: what does it mean?

When trying to list Pods from the dashboard UI, you may see an error like:

```text theme={null}
pods is forbidden: User "system:serviceaccount:default:default" cannot list resource "pods" in API group "" in the namespace "default"
```

This means the application is authenticating to the API as the `default` ServiceAccount (`system:serviceaccount:default:default`) and that ServiceAccount does not have RBAC permission to list Pods in the `default` namespace. In short: the dashboard is running under a ServiceAccount with insufficient privileges.

***

## 5) Which ServiceAccount is mounted to the dashboard Pod, and where are its credentials located?

Get the Pod name and describe it:

```bash theme={null}
kubectl get pods -n default
kubectl describe pod <web-dashboard-pod-name> -n default
```

In the Pod description, check the `Service Account` field and the `Mounts` section. Example relevant parts:

```text theme={null}
Service Account:  default

Mounts:
  /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-swjvh (ro)
```

So:

* The Pod is using the `default` ServiceAccount.
* The ServiceAccount credentials (token, CA certificate, and namespace file) are projected into the Pod at `/var/run/secrets/kubernetes.io/serviceaccount`.

Also in the `Volumes` section you will often see the projected token details such as:

```text theme={null}
Volumes:
  kube-api-access-swjvh:
    Type: Projected
    TokenExpirationSeconds: 3607
    ConfigMapName: kube-root-ca.crt
    DownwardAPI: true
```

This shows Kubernetes automatically projects the token and related metadata into the Pod.

***

## 6) Create a new ServiceAccount for the dashboard: `dashboard-sa`

Create the ServiceAccount:

```bash theme={null}
kubectl create serviceaccount dashboard-sa -n default
```

Expected output:

```text theme={null}
serviceaccount/dashboard-sa created
```

If the environment includes RBAC manifests, you may find role and rolebinding YAML files in a directory like `/var/rbac/`:

```bash theme={null}
cd /var/rbac
ls
```

Example:

```text theme={null}
dashboard-sa-role-binding.yaml  pod-reader-role.yaml
```

Create a token for the new ServiceAccount (useful for testing by pasting into the dashboard UI):

```bash theme={null}
kubectl create token dashboard-sa -n default
```

Example output (token truncated for brevity):

```text theme={null}
eyJhbGciOiJSUzI1NiIsImtpZCI6InU5U0pK...<snip>...LxkCzj4g
```

<Callout icon="lightbulb" color="#1CB2FE">
  Service account tokens are sensitive credentials. Do not share them, and never commit them into source control.
</Callout>

After pasting this token into the dashboard UI and reloading, the dashboard should be able to list Pods—provided the `dashboard-sa` has the correct RBAC Role or RoleBinding applied in the environment.

<Callout icon="warning" color="#FF6B6B">
  Grant only the minimum permissions required to ServiceAccounts. Avoid binding overly broad roles such as `cluster-admin` unless absolutely necessary.
</Callout>

***

## 7) Configure the `web-dashboard` Deployment to use `dashboard-sa` automatically

Instead of manually pasting a token into the UI, update the Deployment so Pods automatically receive the `dashboard-sa` token. Add `serviceAccountName: dashboard-sa` under `spec.template.spec` in the Deployment manifest.

1. Export the existing Deployment to YAML:

```bash theme={null}
kubectl get deployment web-dashboard -n default -o yaml > dashboard.yaml
```

2. Edit `dashboard.yaml`. Under `spec.template.spec` add the `serviceAccountName` field. Example snippet showing where to add it:

```yaml theme={null}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-dashboard
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      name: web-dashboard
  template:
    metadata:
      labels:
        name: web-dashboard
    spec:
      serviceAccountName: dashboard-sa
      containers:
      - name: web-dashboard
        image: gcr.io/kodekloud/customimage/my-kubernetes-dashboard
        env:
        - name: PYTHONUNBUFFERED
          value: "1"
```

3. Apply the updated Deployment:

```bash theme={null}
kubectl apply -f dashboard.yaml -n default
```

You may see a warning if the Deployment was originally created by a different method, but the update will still be applied.

Verify the Deployment status:

```bash theme={null}
kubectl get deployment web-dashboard -n default
```

Example:

```text theme={null}
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
web-dashboard   1/1     1            1           2m
```

When the new Pod is running, refresh the dashboard UI. Because the Pod now mounts the `dashboard-sa` token automatically at `/var/run/secrets/kubernetes.io/serviceaccount`, the dashboard will authenticate as `system:serviceaccount:default:dashboard-sa` and should be able to list Pods if RBAC permits.

***

## Quick reference — common commands

| Task | Command / Example |
| - | - |
| List ServiceAccounts in `default` | `kubectl get serviceaccounts -n default` |
| Describe a ServiceAccount | `kubectl describe sa default -n default` |
| Get Deployments in `default` | `kubectl get deployments -n default` |
| Describe the dashboard Deployment | `kubectl describe deployment web-dashboard -n default` |
| Describe a Pod | `kubectl describe pod <web-dashboard-pod-name> -n default` |
| Create ServiceAccount | `kubectl create serviceaccount dashboard-sa -n default` |
| Create token for SA | `kubectl create token dashboard-sa -n default` |
| Export Deployment to YAML | `kubectl get deployment web-dashboard -n default -o yaml > dashboard.yaml` |
| Apply updated Deployment | `kubectl apply -f dashboard.yaml -n default` |

***

Summary

* The dashboard was running with the `default` ServiceAccount, which lacked permission to list Pods.
* You created `dashboard-sa`, generated a token to test permissions, and then updated the Deployment to use `serviceAccountName: dashboard-sa`. Future Pods will automatically mount the correct token and use the intended RBAC identity.

Links and references

* [Kubernetes Service Accounts](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/)
* [Kubernetes RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)
* [Kubernetes Secrets and Service Account tokens](https://kubernetes.io/docs/concepts/configuration/secret/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/cka-certification-course-certified-kubernetes-administrator/module/77826599-d456-4cb5-8cbc-b713cc077b45/lesson/4712a5cc-72d4-45f6-be96-5e37102de2d2" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.