Service accounts
Service accounts
Identity for workloads. Every namespace has a default ServiceAccount and
every Pod runs as one.
graph LR
SA[ServiceAccount app] --> P[Pod serviceAccountName: app]
K[kubelet] -->|projected token<br/>1 h, bound to Pod| P
P -->|Authorization: Bearer ...| API[API server]
RB[RoleBinding] --> SA
The kubelet mounts a short-lived, audience-bound JWT into
/var/run/secrets/kubernetes.io/serviceaccount/ (plus CA and namespace) and
refreshes it. The token dies with the Pod. The API sees the Pod as
system:serviceaccount:<ns>:<name>.
apiVersion: v1
kind: ServiceAccount
metadata: { name: app-reader, namespace: dev }
automountServiceAccountToken: false # default for Pods using this SA
---
spec:
serviceAccountName: app-reader
automountServiceAccountToken: true # only where the app needs the API
kubectl create sa app-reader -n dev
kubectl create rolebinding app-reader --clusterrole=view --serviceaccount=dev:app-reader -n dev
kubectl create token app-reader -n dev --duration=10m # for a pipeline or a test
kubectl auth can-i list pods -n dev --as system:serviceaccount:dev:app-reader
Good practice
- One ServiceAccount per application, never grant rights to
default. automountServiceAccountToken: falseunless the app talks to the API - most do not.- No long-lived token Secrets (
kubernetes.io/service-account-token); usekubectl create tokenor projected tokens. - In the cloud, workload identity (Azure Workload Identity, EKS Pod Identity) maps a ServiceAccount to a cloud identity - no cloud keys in Secrets.