how to rotate Kubernetes service account tokens
Explains how to rotate Kubernetes service account tokens so long-lived credentials do not accumulate. Use this when a cluster still uses legacy auto-mounted tokens and you want to move to short-lived, audience-bound tokens. Not for rotating user certificates or cloud IAM roles.
TL;DR
Legacy service account tokens never expire, which makes them a great target. Modern Kubernetes issues short-lived bound tokens automatically when pods request them, and you can rotate what is left by deleting old secrets and restarting pods. The goal is no permanent tokens anywhere in the cluster.
The query
how to rotate Kubernetes service account tokensUse this when
- You found service account tokens that are months or years old in your cluster
- You want to move workloads to time-bound, audience-scoped tokens
- An audit flagged non-expiring credentials in secrets or pod mounts
- You are setting token lifetimes as part of a cluster hardening pass
Not for
- Rotating human user credentials or kubeconfig certs; that is a different flow
- Cloud provider IAM roles; rotate those in the cloud console
- One-off pod restarts; this is about the token lifecycle, not restarts
Steps
- Inventory the long-lived tokens. List service account token secrets and check their age; anything older than your rotation policy is a candidate. Expected output: a list of stale token secrets with their ages.
- Check what each token is used for. Look at which pods and automation mount or reference each secret before touching it. Expected output: every stale token mapped to its consumer, or confirmed unused.
- Migrate consumers to bound tokens where possible. Pods on recent Kubernetes get short-lived tokens via the TokenRequest API automatically; external consumers should use projected volume tokens with an audience and expiry. Expected output: consumers reconfigured to short-lived tokens, old secrets unreferenced.
- Delete the legacy token secrets. Remove the stale secrets from the cluster. Expected output: the secrets are gone from
kubectl get secretsoutput. - Restart affected pods so they pick up new tokens. A rolling restart replaces the mounted credentials. Expected output: pods are running with fresh tokens, apps still authenticate.
- Prevent recurrence. Set policies so new service accounts do not get legacy auto-generated tokens, and put token age in your periodic audit. Expected output: new service accounts come with no long-lived token, and the audit stays clean.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_Wk6etDUugGkQ10lncquNZA