Service Accounts
Video: Day 25/40 — Kubernetes Service Account (RBAC Continued) • https://www.youtube.com/watch?v=k2iCq7IlMKM • Duration: ~16 min
Key terms
| Term | Meaning |
|---|---|
| ServiceAccount (SA) | Identity for pods/workloads |
| default SA | Auto-assigned account per namespace |
| Token | Credential mounted into a pod |
| Projected token | Short-lived, audience-bound token |
| automountServiceAccountToken | Toggle for mounting the token |
| RBAC | Binds permissions to a ServiceAccount |
Problem & solution
Pods, controllers, and CI bots also need an identity to call the API, but human user accounts aren't Kubernetes objects and don't fit automated workloads. Service accounts give non-human workloads a managed in-cluster identity.
Solution: Give in-cluster apps a ServiceAccount identity with an auto-mounted token, then grant it permissions through RBAC.
The analogy
Most badges at the port go to people, but the automated cranes and loader robots have to pass through gates too, and you obviously cannot hand a robot a human ID. So the port issues machine badges built specifically for equipment, each carrying a chip the gates can read on the robot's behalf. Kubernetes does the same: a ServiceAccount is the machine badge for a pod or workload, the auto-mounted token is its chip, and the api-server reads that token to authenticate the workload, never treating it as a human user.
Where this fits in the cluster
The same cluster entities appear in every day's notes; the <== marks what this day touches.
Two kinds of accounts
Kubernetes splits identities into user accounts for humans and service accounts for workloads — only the latter is a real cluster object.
USER account -> humans: admins, developers, operators
(certs/OIDC, NOT a Kubernetes object)
SERVICE account -> non-humans: pods, controllers, CI bots, apps
(a real Kubernetes object you can create)
When code inside a pod needs to call the Kubernetes API, it uses a ServiceAccount, not a human user cert.
Default service account
Every namespace has a default SA, and every pod that doesn't name one gets it
mounted automatically.
kubectl get sa # SAs in current namespace
kubectl get sa -A # every namespace has its own 'default'
Create a service account
A ServiceAccount is a namespaced object you create like any other resource.
kubectl create sa build-bot
kubectl get sa build-bot -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-bot
namespace: default
Give it permissions (RBAC, same as users)
A SA is just another subject in a RoleBinding/ClusterRoleBinding.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: build-bot-read
namespace: default
subjects:
- kind: ServiceAccount
name: build-bot
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Verify with impersonation:
kubectl auth can-i list pods \
--as=system:serviceaccount:default:build-bot # -> yes
Use it from a pod
Set serviceAccountName on the pod spec so the container runs as that SA and
gets its token mounted.
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
serviceAccountName: build-bot # <- pod runs as this SA
containers:
- name: app
image: nginx
The token is mounted at:
/var/run/secrets/kubernetes.io/serviceaccount/
token -> JWT bearer token (auto-rotated, projected)
ca.crt -> cluster CA to trust the API server
namespace -> the pod's namespace
Tokens
You can mint a bearer token for a SA on demand, useful for testing API calls or external clients.
kubectl create token build-bot # short-lived token (on demand)
kubectl create token build-bot --duration=1h
Modern Kubernetes uses short-lived, auto-rotated projected tokens instead of the old permanent Secret-based tokens.
End-to-end example: a pod calls the API as its ServiceAccount
The app inside a pod authenticates with its auto-mounted SA token.
End-to-end flow
An in-cluster app authenticates to the API using its mounted ServiceAccount token.
Key takeaways
- User accounts = humans, ServiceAccounts = workloads/bots.
- SAs are real namespaced objects; each namespace has a
defaultSA. - Grant a SA access with the same RBAC (Role/ClusterRole + binding).
- Subject form:
system:serviceaccount:<namespace>:<name>. - Pods authenticate using the projected token mounted into the container.
Checklist
- [ ] Listed default SAs across namespaces
- [ ] Created a
build-botSA and bound it to a Role - [ ] Verified with
--as=system:serviceaccount:default:build-bot - [ ] Ran a pod with
serviceAccountNameand found the mounted token