Safeguard
Security Guides•

Kubernetes service account tokens: bound, legacy and how to limit them

Pods get a short-lived projected token since v1.22. Older long-lived Secret tokens never expire. How to opt out of mounting and keep roles small.

Safeguard Security Team
3 min read

Every namespace has a default ServiceAccount, and pods that name no account use it. Since Kubernetes v1.22, pods receive a short-lived, automatically rotated token from the TokenRequest API. Before that, tokens were long-lived static Secrets. If a pod does not call the API, turn off automatic mounting.

What a pod gets by default

When a namespace is created, Kubernetes creates a default ServiceAccount in it. A pod with no serviceAccountName gets that account. With RBAC enabled, the docs say this account has no permissions beyond default API discovery rights.

The credentials are mounted into the pod as a projected volume. That token can authenticate to the API server as the account, so whatever RBAC grants that account, code running in the pod can use. A remote code execution bug in your app becomes cluster API access at that level.

Bound tokens versus legacy Secret tokens

The two token types differ in lifetime and exposure.

Legacy tokens were stored in a Secret and, per the authentication hardening guide, cannot have an expiry. They stay valid until the service account is deleted, and anyone who can read Secrets in the namespace can see them. The guide says they were the default before Kubernetes 1.23 and are being replaced.

TokenRequest tokens are short-lived. The guide describes them as good for service authentication, with the advice to keep lifetimes short to limit damage from a compromised token. Check your cluster for old kubernetes.io/service-account-token Secrets and remove those you do not need.

Turn off mounting when the pod does not need it

Most application pods never talk to the Kubernetes API. Set this in the pod spec:

spec:
  serviceAccountName: my-app
  automountServiceAccountToken: false

The docs show this setting stopping credentials from being injected for either the assigned account or the default account. You can also set it on the ServiceAccount itself, which is a sensible default for a namespace.

Give each workload its own account

Create one ServiceAccount per workload and bind a small Role to it. Do not reuse the default account for pods that need API access, because then every pod in the namespace shares those rights. The RBAC good practices page also advises keeping powerful pods off nodes that run untrusted or exposed workloads, using taints, affinity or anti-affinity.

A quick audit

  1. List pods that mount a token but whose code never calls the API.
  2. List ServiceAccounts bound to roles that allow Secret access, pod creation or wildcards.
  3. Find legacy token Secrets.
  4. Confirm no workload relies on the default account for permissions.

For deeper RBAC review see Kubernetes RBAC mistakes that quietly hand out cluster admin.

Quick check

Does the default ServiceAccount have admin rights?

Not by default. With RBAC, it has only API discovery permissions unless someone binds more to it.

How long do bound tokens last?

The fetched pages do not give a default, so check your cluster version and configuration.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.