Home › CKAD › Topics › Practice tasks › ServiceAccount Management
CKAD · Application Environment, Configuration and Security

Fix a Pod Running with the Wrong ServiceAccount

In namespace monitoring, Pod metrics-pod is using ServiceAccount wrong-sa and receiving authorization errors. Multiple ServiceAccounts, Roles, and RoleBindings already exist in the namespace:…

Check live lab access → All CKAD tasks

Live lab access

This task description is public. Live practice requires full access unless this is the selected free weekly task. AI Lab Coach is available in single-task labs, including the free weekly task. See this week's free task.

Create an account to continue →

Read this week's free task →

On a phone? Read the task and create your account here, then sign in on a desktop or laptop for the terminal lab. Nothing starts until you choose Start.

The task

Task

In namespace monitoring, Pod metrics-pod is using ServiceAccount wrong-sa and receiving authorization errors.

Multiple ServiceAccounts, Roles, and RoleBindings already exist in the namespace:

Requirements

  1. Identify which ServiceAccount/Role/RoleBinding combination has the correct permissions
  2. Update Pod metrics-pod to use the correct ServiceAccount
  3. Verify the Pod stops showing authorization errors

Hint: Check existing RoleBindings to see which ServiceAccount is bound to which Role.

Original Prepium guide · Written for Kubernetes v1.35 and checked against the official documentation on 6 October 2026. Use a disposable practice cluster.

Find which ServiceAccount really has the access, then move the workload onto it

A Pod talks to the API as exactly one ServiceAccount, the one named in spec.serviceAccountName (or default if nothing was set). What that identity may do is decided only by RoleBindings and ClusterRoleBindings that list it as a subject. So when several accounts and Roles exist side by side, names prove nothing: you follow the bindings. Then you have to change the identity in a way the API actually allows, because that field is fixed once a Pod exists.

Pod.spec.serviceAccountName ──→ ServiceAccount
                                     ▲ subject
RoleBinding ── roleRef ──→ Role ──→ rules (verbs, resources, apiGroups)

1. Build a small maze to practise on

kubectl create namespace prepium-tutorial
kubectl -n prepium-tutorial create serviceaccount ci-runner
kubectl -n prepium-tutorial create serviceaccount config-bot
kubectl -n prepium-tutorial create role cm-reader --verb=get,list --resource=configmaps
kubectl -n prepium-tutorial create role cm-admin --verb=get,list,create,update,delete --resource=configmaps
kubectl -n prepium-tutorial create rolebinding cm-reader-for-bot --role=cm-reader \
  --serviceaccount=prepium-tutorial:config-bot
kubectl -n prepium-tutorial create deployment config-sync --image=nginx:1.27-alpine
kubectl -n prepium-tutorial set serviceaccount deployment config-sync ci-runner

Note that cm-admin exists but nothing binds it. An unbound Role grants nothing to anyone, however promising its name sounds.

2. Read the bindings, not the names

kubectl -n prepium-tutorial get rolebindings -o custom-columns='BINDING:.metadata.name,KIND:.roleRef.kind,ROLE:.roleRef.name,SUBJECTS:.subjects[*].name'
kubectl -n prepium-tutorial describe role cm-reader

The first command prints each binding with the Role it points to and its subjects, so you can draw the chain in one glance. Check roleRef.kind too: a RoleBinding can also reference a ClusterRole, in which case the rules come from that ClusterRole but only apply inside this namespace. Also check the subject's namespace with -o yaml; a subject with the right name in another namespace is a different account.

3. Ask the authorizer, account by account

for sa in ci-runner config-bot default; do
  echo "== $sa"
  kubectl auth can-i list configmaps -n prepium-tutorial \
    --as=system:serviceaccount:prepium-tutorial:$sa
done

In this fresh namespace only config-bot answers yes. This is the evidence you want before touching the workload: the authorizer's own decision, not your reading of YAML. Add --list to see an account's full set of allowed actions in the namespace.

4. Change the identity the way the API allows

Try the tempting shortcut first and read the refusal:

POD=$(kubectl -n prepium-tutorial get pod -l app=config-sync -o name | head -1)
kubectl -n prepium-tutorial patch $POD -p '{"spec":{"serviceAccountName":"config-bot"}}'

The API rejects it: an existing Pod accepts only a short list of in-place changes (container images, tolerations and a few timing fields), and the ServiceAccount is not on it. For a Deployment, change the Pod template instead; the controller rolls out new Pods with the new identity:

kubectl -n prepium-tutorial set serviceaccount deployment config-sync config-bot
kubectl -n prepium-tutorial rollout status deployment/config-sync
kubectl -n prepium-tutorial get pods -l app=config-sync \
  -o custom-columns=POD:.metadata.name,SA:.spec.serviceAccountName

For a bare Pod with no controller, save its manifest, edit serviceAccountName, and recreate it: kubectl replace --force -f pod.yaml deletes the old object and creates the new one in a single command.

Common mistakes

Example checkEvidence
Correct chain identifiedBinding's roleRef and subjects link the chosen account to the needed rules
Account is authorizedkubectl auth can-i ... --as=system:serviceaccount:... prints yes
Workload uses itRunning Pod's spec.serviceAccountName shows the new account
Errors stoppedLogs of the new Pod show no Forbidden responses

Cleanup: kubectl delete namespace prepium-tutorial. References: Configure Service Accounts for Pods, Using RBAC Authorization, Pod update and replacement. Next, try building a Role from a Forbidden error or controlling token automount.

Exam
CKAD
Domain
Application Environment, Configuration and Security
Grading
Programmatic · partial credit

What this tests

Wire up configmaps, secrets, service accounts, RBAC, securityContext, and resource limits. On the CKAD exam, Application Environment, Configuration and Security tasks are graded purely on what you build in the cluster - not multiple choice - so the only way to get faster is to do them on a real cluster against a clock.

Practice it for real

The public description lets you study the task before signing up. Full access includes this live lab; the selected Task of the Week is free with an account. You solve the task in a real terminal, hit validate, and a programmatic checker scores exactly what you got right and wrong (with partial credit). You can open the solution while practising, then retry and use the failed checks to improve your score.

Related CKAD tasks