Free lesson · CKAD Prep Program · Module 5: Environment, configuration and security
Scope Service Accounts to Least Privilege
Every pod runs as some service account, and the default one should stay powerless. This lesson mints per-app identities, binds minimal Roles, and audits the result.
11 min reading
Objectives
- Explain what the default service account can do (almost nothing, deliberately)
- Create per-app accounts and bind exactly the needed Roles
- Mount tokens explicitly and say when automount should stay off
- Audit who can do what with auth can-i across subjects
Why this matters
In-cluster clients (CI deployers, operators, app backends calling the API) authenticate as service accounts, and a shared powerful account turns any compromised pod into a cluster-wide incident. Per-app accounts with narrow bindings contain the blast radius to what the app legitimately touches. The exam tests the full loop: account, binding, proof.
Concepts
Service accounts are namespaced identities for non-humans. Each pod runs as exactly one (default when unspecified, which is why specifying matters). Roles plus RoleBindings grant the verbs; kubectl auth can-i --as=system:serviceaccount:<ns>:<name> audits without impersonating. Token projection mounts short-lived, audience-bound tokens; automountServiceAccountToken: false on pods or accounts that never call the API removes credentials from thieves' reach entirely.
The pattern is one account per app, bound to one Role holding its exact verbs, audited after every change. Cluster-wide needs get ClusterRoles bound narrowly (specific namespaces via binding location, never cluster-admin for apps).
Worked example
A deployer that may only restart one Deployment, nothing else:
kubectl create serviceaccount deployer -n demo
kubectl create role restarter -n demo \
--verb=get,list,patch --resource=deployments
kubectl create rolebinding deployer-restart -n demo \
--role=restarter --serviceaccount=demo:deployer
kubectl auth can-i patch deployments -n demo \
--as=system:serviceaccount:demo:deployer
# yes
kubectl auth can-i delete deployments -n demo \
--as=system:serviceaccount:demo:deployer
# no
kubectl auth can-i get pods -n demo \
--as=system:serviceaccount:demo:deployer
# noThree checks, three answers, one narrow identity. Apps that never call the API get automountServiceAccountToken: false and no token at all: least privilege includes absence.
Exam notes
The full subject name is long and exact: a typo'd audit answers about a nonexistent subject, always no, which misleads. Bindings reference accounts by namespace plus name: moving the app without the binding orphans its rights. And image pull secrets are separate from API rights: pulling images needs neither Roles nor tokens.
Quick check
A 4-question self-check. Your answers stay on your device, are never stored or sent. Only a passing score (for example 3 of 4) is saved, and only to unlock lesson progress: at least 3 correct is required before a lesson counts as complete. It never counts toward any certification assessment.
Lesson feedback
No published feedback yet.
Log in and complete the lesson to leave feedback.
Exercise
Create a fictional per-app service account allowed only to read ConfigMaps in its namespace, prove the boundary with three auth can-i checks (one yes, two no), and state where you would disable token automount with why.
Pass criteria
Account plus Role plus binding correct and narrow; three checks with correct expectations; automount answer names the non-API pods with the theft-reduction reason.