Join our Newsletter — 33% off our NHI Course
Home› Guides› Kubernetes Service Account Token Guide: Bound, Short-Lived and…
Guide Cloud & Workload Identity

Kubernetes Service Account Token Guide: Bound, Short-Lived and Least Privilege

PDF for newsletter subscribers · free to read online

← All guides
By Lalit Choda, NHI Mgmt Group Updated 24 October 2026 13 min read
On this page

Every pod in a Kubernetes cluster can receive a service account token by default, and an attacker who gets code execution in that pod inherits whatever that token is allowed to do. Kubernetes has moved from long-lived, Secret-based tokens to short-lived tokens bound to a pod, an audience and an expiry, but many clusters still carry legacy tokens, mount tokens into workloads that never call the API, and bind powerful roles to shared service accounts. This guide covers how service account tokens are issued and validated, the token types and their risks, automounting, audience scoping for external systems, legacy token clean-up, RBAC least privilege, detection and a phased rollout. It is written for platform engineers, cluster administrators and security teams. For the wider set of identities in a cluster (controllers, operators, CI and cloud identities), see the Kubernetes NHI Security Guide.

Key takeaways

  • Bound tokens are the default, not the whole answer. Since v1.22 the kubelet mounts a TokenRequest token that expires and rotates, but its permissions are whatever RBAC grants the service account.
  • Turn off automounting where the API is not used. Setting automountServiceAccountToken: false on the ServiceAccount or Pod removes the credential entirely; the Pod setting wins.
  • Scope every token to an audience. A token for Vault, a cloud provider or a SPIRE server should carry that audience, and receivers must check it, so the token cannot be replayed against the API server or another service.
  • Find and remove Secret-based tokens. Tokens of type kubernetes.io/service-account-token do not expire. Clusters from v1.29 mark unused auto-generated ones invalid after a year, but manually created ones persist until you delete them.
  • Who can create pods can use any service account in the namespace. Pod creation, Secret reads and serviceaccounts/token create rights are token-issuing powers and must be reviewed as such.

How service account tokens work

A ServiceAccount is a namespaced API object that gives a workload an identity. Its token is a JSON Web Token signed by the kube-apiserver, sent in an Authorization: Bearer header. The API server checks the signature, the expiry, whether objects referenced in the claims still exist, the not-before time and the audience. The subject takes the form system:serviceaccount:<namespace>:<name>.

A projected, pod-bound token carries these claims, shown in the Kubernetes documentation's example payload:

  • iss: the first value of --service-account-issuer, for example https://kubernetes.default.svc. The flag can be repeated (v1.22 and later) so an issuer can be changed without disruption: the first value signs, all values are accepted.
  • aud: the requested audiences, or the API server's default audiences (--api-audiences) when none are requested.
  • exp, iat, nbf, jti: validity window and a unique token ID. TokenReview exposes the ID as authentication.kubernetes.io/credential-id (JTI=...), which lets you trace a token through audit logs.
  • kubernetes.io: private claims with the namespace, the ServiceAccount name and UID, and the bound Pod and Node names and UIDs.

When a token is bound to an object, the object's name and UID are stored in those private claims, and deleting the object invalidates the token for the API server. Supported binding targets are Pod, Secret and Node (creating new node-bound tokens is GA from v1.33), with webhook configuration binding in alpha.

Token types compared

TypeHow it is obtainedLifetimeRevocationUse
Projected pod token (default kube-api-access-* volume)The kubelet calls TokenRequest and mounts it at /var/run/secrets/kubernetes.io/serviceaccount/tokenRequested as 3,607 seconds and refreshed by the kubelet before expiry; may be extended (see below)Invalid when the Pod or ServiceAccount is deletedIn-cluster API access
Custom projected tokenserviceAccountToken projected volume with audience, expirationSeconds and pathAs requested, capped by --service-account-max-token-expirationPod deletionVault, cloud federation, SPIRE, other external receivers
TokenRequest via API or kubectl create tokenCaller with create on serviceaccounts/tokenAs requested; options --duration, --audience, --bound-object-kindBound object deletion, or recreating the ServiceAccountShort-lived tokens for jobs, tests and tooling outside pods
Secret-based (legacy) tokenSecret of type kubernetes.io/service-account-token with annotation kubernetes.io/service-account.name; auto-created only before v1.24No expiry, no rotationDelete the SecretAvoid; only where no alternative exists, with a documented owner

Short-lived tokens have a limitation worth knowing: the documentation states there is no central record of issued tokens, so an individual token cannot be revoked. To kill tokens early, delete the bound Pod, or delete and recreate the ServiceAccount, which changes its UID and invalidates every token issued for it.

Extended expiry during migration

To ease the move from non-expiring tokens, --service-account-extend-token-expiration lets the API server issue the default kubelet-requested token with a longer validity than requested, and the example payload in the documentation carries a warnafter claim at the requested lifetime while exp sits a year later. Where extension applies, the extended expiry is the lesser of one year and the configured maximum. Plan to identify workloads that use tokens past warnafter (they do not reread the file), fix their client libraries, and then reduce the extension. Treat the effective lifetime of a stolen default token as potentially much longer than one hour until you have done so.

Automounting and least privilege

Every namespace has a default ServiceAccount, and pods that do not name one use it. Unless automounting is disabled, the kubelet mounts its token whether or not the application ever calls the API, which makes the token a free credential for anyone who compromises the container.

  • Disable by default: set automountServiceAccountToken: false on each namespace's default ServiceAccount and on workload ServiceAccounts that do not need the API. Workloads that need a token opt in at Pod level, which takes precedence.
  • One ServiceAccount per workload: shared accounts merge permissions and blur audit trails. Name them after the workload and record an owner. See the Service Account Inventory Template.
  • Never bind roles to default: any new pod in the namespace would inherit them.
  • Prefer Roles to ClusterRoles: use namespaced RoleBindings with explicit resources and verbs, and avoid wildcards.
  • Enforce with admission: require explicit serviceAccountName and block automount on namespaces that do not need it. See the Kubernetes Admission Control Guide.

RBAC rights that amount to token access

PermissionWhy it matters for tokensMitigation
create on pods or workload controllersThe Kubernetes RBAC good practices note that it implicitly grants the API access of any ServiceAccount in that namespace, since the new pod can name itSeparate namespaces by trust level; restrict which ServiceAccounts pods may use
get or list on SecretsReads every legacy token Secret in scope; a list response includes Secret contentsGrant Secret reads by name only; remove legacy token Secrets
create on serviceaccounts/tokenIssues tokens for existing ServiceAccounts directlyLimit to identity infrastructure (for example a Vault or SPIRE integration)
escalate, bind, impersonateGrant or assume more powerful identities than the holder hasReserve for cluster administrators; alert on use
request-serviceaccounts-token-audience (nodes)With ServiceAccountNodeAudienceRestriction, NodeRestriction limits a kubelet to audiences already referenced by pods on that node; this verb grants moreGrant only for named audiences

Audience-scoped tokens for external systems

Workloads increasingly use their service account token to reach something other than the API server: HashiCorp Vault's Kubernetes auth, cloud IAM federation, a SPIRE server, or an internal service. The default token's audience is the API server, so sending it elsewhere means the receiver could replay it against the cluster. Request a dedicated projected token instead.

  • Projection: add a serviceAccountToken source with audience: vault (or the receiver's identifier) and a short expirationSeconds; the Kubernetes example uses two hours. The kubelet refreshes it, so applications must reread the file.
  • Receiver validation: the documentation recommends the TokenReview API, because it fails immediately once the bound Pod, Secret or Node is deleted. Offline validation through the issuer's OIDC discovery document and JWKS works without calling the cluster but treats the token as valid until expiry even if its bound object is gone. Receivers must always check aud.
  • Cloud federation: Amazon EKS IAM roles for service accounts (IRSA) publishes a public OIDC discovery endpoint per cluster so AWS STS can validate projected tokens through AssumeRoleWithWebIdentity, and AWS documents that the signing key rotates every seven days. Trust policies should pin both the audience and the exact system:serviceaccount:<ns>:<name> subject. See the Workload Identity Federation Guide.
  • SPIFFE: SPIRE's k8s_psat node attestor validates a projected token with audience spire-server through TokenReview and checks it against a ServiceAccount allow list. See the SPIFFE and SPIRE Guide.

Finding and retiring Secret-based tokens

Clusters that predate v1.24, or that were upgraded from such versions, often still hold auto-generated legacy token Secrets, and teams continue to create them manually for CI systems and external tools.

  1. Inventory: list Secrets of type kubernetes.io/service-account-token in every namespace, with the ServiceAccount named in the kubernetes.io/service-account.name annotation and that account's bindings.
  2. Read usage labels: from v1.29 the legacy token cleaner records kubernetes.io/legacy-token-last-used, marks auto-generated Secrets unused for a year (configurable with --legacy-service-account-token-clean-up-period on kube-controller-manager) with kubernetes.io/legacy-token-invalid-since, and deletes them after a further unused period. Manually created Secrets are not covered.
  3. Replace: move each consumer to a projected token, a kubectl create token call with a short duration, or workload identity federation for external systems.
  4. Invalidate, then delete: watch for the audit annotation authentication.k8s.io/legacy-token-invalidated and the invalid_legacy_auto_token_uses_total metric, which show attempts to use invalidated tokens. Removing the invalid-since label temporarily restores a token, which is your rollback.

Token exfiltration and detection

The mounted token file is a predictable target. Remote code execution in a pod, a server-side request forgery that can read local files, an exposed debug endpoint, or a container escape all give an attacker the token at a known path, and Secret-based tokens leak into Git repositories, CI logs and backups like any other credential. In ATT&CK v20 terms this is credential access through T1528 Steal Application Access Token, T1552.001 Credentials In Files and T1552.007 Container API, typically followed by T1613 Container and Resource Discovery, T1609 Container Administration Command and T1550.001 Use Alternate Authentication Material: Application Access Token. The Kubeflow cryptomining attacks of 2020 show the pattern: after reaching exposed dashboards, attackers used the notebook's mounted service account to deploy mining containers.

  • API server audit logs: record requests by ServiceAccount users, including create on serviceaccounts/token, pods, RoleBindings and ClusterRoleBindings, and Secret reads. Use the credential ID to tie a request to a token.
  • Behavioural baselines: alert when a ServiceAccount calls verbs or resources it has never used, especially selfsubjectaccessreviews or selfsubjectrulesreviews (permission discovery), Secret lists or pod creation in other namespaces.
  • Source checks: a pod-bound token used from an address outside the cluster's pod network is a strong exfiltration signal; the bound Pod and Node names in the claims help confirm it.
  • Runtime detection: reads of the token path by processes that are not the application, such as shells or downloaded binaries.
  • Secret scanning: scan repositories and CI logs for Kubernetes JWTs and kubeconfig files. See the Secrets Management Guide.

Metrics that show the programme is working:

  • Percentage of pods with a mounted token that actually call the API (target: close to 100 per cent).
  • Count of Secret-based service account tokens, split into auto-generated and manual (target: zero, with documented exceptions).
  • Number of ServiceAccounts bound to cluster-admin or wildcard roles.
  • Percentage of externally used tokens with a non-default audience.
  • Maximum effective token lifetime in the cluster, after extension.

Phased rollout

  1. Discover: export ServiceAccounts, their bindings, which pods mount tokens, and legacy token Secrets. Use audit logs to establish which ServiceAccounts call the API at all.
  2. Audit-mode policy: deploy admission policies that warn or audit, not deny, on automounted tokens, use of the default ServiceAccount and new token Secrets. Review the findings with workload owners.
  3. Pilot ring: disable automount on default ServiceAccounts in a few non-production namespaces, then on workloads that do not call the API. Test pod start-up, readiness and any operator or sidecar that needs the token.
  4. Least privilege: split shared ServiceAccounts, replace ClusterRoleBindings with namespaced RoleBindings, and remove wildcard verbs.
  5. Audiences and lifetimes: give external integrations their own projected tokens, then lower --service-account-max-token-expiration and disable extension once no client relies on it.
  6. Enforce: switch admission policies from audit to deny, starting with production namespaces that passed the pilot.
  7. Rollback: re-enable automount for a single workload at Pod level, restore a binding from version control, or remove the invalid-since label from a legacy Secret while its consumer is fixed.

Common failure patterns

  • Automount everywhere: web front ends and batch jobs that never call the API carry a usable token, so any remote code execution becomes cluster API access.
  • Powerful roles on shared accounts: a cluster-admin binding on a monitoring or CI ServiceAccount is inherited by every pod that uses it, including ones created by people with only pod creation rights.
  • Manual token Secrets for CI: a non-expiring token pasted into a pipeline variable survives staff changes and repository forks. Use short-lived tokens or federation. See the CI/CD Pipeline Identity Security Guide.
  • Default-audience tokens sent outside the cluster: the receiving service, or anyone who compromises it, can replay the token against the API server.
  • Offline validation without care: receivers that validate only signature and expiry against the JWKS keep accepting tokens for deleted pods until they expire; use TokenReview where revocation matters.
  • Assuming one-hour tokens: with expiry extension still on, a copied default token may stay valid far longer than the 3,607 seconds the kubelet requests.

Framework mapping

FrameworkReferenceRelevance
NIST CSF 2.0PR.AA-01, PR.AA-05Service identities and credentials managed; permissions defined and least privilege
NIST SP 800-53 Rev. 5AC-2, AC-6, IA-5, IA-9, AU-2Account management for ServiceAccounts, least privilege RBAC, authenticator lifetime and rotation, service authentication, audit logging
ISO/IEC 27001:2022 Annex AA.5.17, A.5.18, A.8.2Authentication information, access rights, privileged access rights
MITRE ATT&CK v20T1528, T1552.001, T1552.007, T1550.001, T1613, T1609Token theft and file or API credential access, token reuse, discovery and execution in containers

For how these tokens compare with other machine authentication methods, see the NHI Authentication Guide.

Practitioner checklist

  • Set automountServiceAccountToken: false on every default ServiceAccount and opt in per workload.
  • Give each workload its own ServiceAccount with an owner and namespaced, wildcard-free RoleBindings.
  • Inventory and remove Secrets of type kubernetes.io/service-account-token; document any exception with an owner and review date.
  • Use projected tokens with a specific audience and short expirationSeconds for every external integration.
  • Require receivers to check aud, and to use TokenReview where prompt revocation matters.
  • Restrict pod creation, Secret reads and serviceaccounts/token create rights, and alert on their use.
  • Plan the end of token expiry extension and set --service-account-max-token-expiration.
  • Log ServiceAccount activity in API audit logs and alert on new verbs, permission discovery and off-cluster use.
  • Enforce these rules with admission policies after an audit-mode period.

Standards and references

Related NHI Mgmt Group resources: Kubernetes NHI Security Guide · Kubernetes Security Guide · SPIFFE and SPIRE Guide · Top 10 Kubernetes Security Risks · Workload Identity Federation Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Written and reviewed by Lalit Choda, NHI Mgmt Group. Last updated 24 October 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.