Service Accounts
A ServiceAccount is the identity a Pod uses — to call the Kubernetes API, and, through federation, to call cloud services. Where humans authenticate via OIDC, workloads authenticate as ServiceAccounts. It is the workload half of the identity story.
The modern ServiceAccount model is built on short-lived, automatically rotated tokens and federation to cloud IAM, which together end the era of long-lived embedded credentials. Knowing how it works is key to running least-privilege workloads.
Workload Identity, Not Human Identity
A ServiceAccount is a namespaced object that represents a workload. Every Pod runs as one — if you don't specify it, the namespace's default ServiceAccount, which is exactly why the default is dangerous when over-permissioned. RBAC bindings target ServiceAccounts just like users, so a Pod's permissions are whatever its ServiceAccount has been granted.
apiVersion: v1 kind: Pod metadata: name: api spec: serviceAccountName: api-sa automountServiceAccountToken: true containers: - name: api image: my-api:1.0
Bound and Projected Tokens
Originally a ServiceAccount had a long-lived token stored in a Secret — a standing credential that never expired. The modern approach is the projected, bound token: the kubelet requests a short-lived token, scoped (audience-bound) and time-limited, and mounts it into the Pod, rotating it automatically. There is no permanent secret to leak. If a Pod does not need API access at all, set automountServiceAccountToken: false so no token is mounted.
Federation to Cloud IAM
The same ServiceAccount identity can be exchanged for cloud credentials through workload-identity federation — AWS IRSA / EKS Pod Identity, GKE Workload Identity, Azure Workload Identity. The Pod presents its projected token, the cloud trusts the cluster's OIDC issuer, and the Pod receives temporary cloud credentials. No access keys are stored in the Pod, in an image, or in a Secret. This is the right way for a Pod to reach a cloud database or bucket.
Least Privilege for Workloads
The practical guidance is: give each workload its own ServiceAccount with a minimal RBAC role, rather than letting everything share the over-broad default. Disable token automounting where API access isn't needed. And prefer federation over any stored cloud credential. A compromised Pod is then limited to exactly what its ServiceAccount allows — which, done right, is very little.
ServiceAccount — in-cluster identity for workloads; namespaced; uses short-lived projected tokens. The subject of workload RBAC.
User — human identity, defined outside the cluster and federated via OIDC. No in-cluster object.
- Running workloads as the namespace
defaultServiceAccount with broad permissions. - Mounting a ServiceAccount token into Pods that never call the API, expanding the attack surface.
- Relying on legacy long-lived ServiceAccount token Secrets instead of projected bound tokens.
- Storing cloud access keys in a Pod or image instead of using workload-identity federation.
- Sharing one over-permissioned ServiceAccount across many unrelated workloads.
- Give every workload its own ServiceAccount scoped to a minimal RBAC role.
- Use projected, bound, short-lived tokens — the default modern behavior — not stored token Secrets.
- Set
automountServiceAccountToken: falsewhen a Pod needs no API access. - Reach cloud services through workload-identity federation, never embedded keys.
- Treat the
defaultServiceAccount as something to lock down, not to rely on.
Knowledge Check
What identity does a Pod use to call the Kubernetes API?
- Its ServiceAccount — the namespace default if none is specified
- The cluster administrator's client certificate, mounted into the Pod
- A randomly generated User object created fresh for each Pod
- The node's kubelet identity, shared by every Pod on it
What is the advantage of projected, bound ServiceAccount tokens over the legacy ones?
- They are short-lived, audience-scoped, and auto-rotated, so there is no standing credential to leak
- They never expire and are bound to no audience, so Pods are spared the cost of ever refreshing the token
- They are committed to Git alongside the manifest for auditability
- They grant the Pod cluster-admin automatically on first use
What is the recommended way for a Pod to access a cloud bucket or database?
- Workload-identity federation, exchanging the ServiceAccount token for temporary cloud credentials
- Embedding a long-lived cloud access key directly in the container image layers at build time, baked in for every Pod
- Storing the cloud access key in a ConfigMap mounted into the Pod
- Using the node's instance credentials directly from inside the Pod
You got correct