Skip to main content

More Info:

Advisory: avoid long-lived ServiceAccount token Secrets; use projected (TokenRequest) tokens with an audience and expiry instead.

Risk Level

Informational

Address

Security

Compliance Standards

  • Cloudanix Best Practice

Triage and Remediation

Remediation

Manual Steps

  1. List all legacy ServiceAccount token Secrets
    • Run on: any machine with kubectl access.
    • Identify which namespaces and ServiceAccounts are still using auto-created token Secrets.
  2. Map each token Secret to its ServiceAccount and workloads
    • For a specific Secret (replace SECRET and NAMESPACE):
    • Note the .metadata.annotations["kubernetes.io/service-account.name"].
    • Check which pods use that ServiceAccount:
  3. Identify direct Secret mounting or out-of-cluster use
    • Check if the token Secret is mounted into pods:
    • Review pod and application configuration (manifests, CI/CD, external systems) to see if the Secret name or its token value is referenced for out-of-cluster access (automation scripts, external services).
  4. Decide if each use can be migrated to projected ServiceAccount tokens
    • For in-cluster workloads: plan to replace secret volume mounts with a projected serviceAccountToken volume (TokenRequest) that sets audience and expirationSeconds.
    • For out-of-cluster callers: consider alternatives such as Workload Identity (GKE recommended), or a dedicated authentication method, instead of reusing long-lived cluster ServiceAccount tokens.
  5. Update manifests to stop relying on long-lived token Secrets
    • Edit workloads that mount ServiceAccount token Secrets and replace with a projected token volume. Example pattern (to adapt into the pod spec that used the Secret):
    • Apply the updated manifest from a machine with kubectl access:
  6. Verify no unnecessary ServiceAccount token Secrets remain in active use
    • After pods are updated and restarted, confirm they are not mounting the legacy token Secrets (inspect a sample pod):
    • Re-list legacy token Secrets and decide whether each can be deleted (only after confirming nothing depends on it):
    • Optionally, delete an unused token Secret:
Interpretation:
  • Large numbers of kubernetes.io/service-account-token Secrets, especially in application namespaces, indicate workloads are likely using legacy long-lived tokens instead of projected tokens.
  • Pay special attention to non-system namespaces; kube-system/gke-* may contain some platform-managed tokens.
Interpretation:
  • metadata.annotations["kubernetes.io/service-account.name"] shows which ServiceAccount the token belongs to.
  • Absence of any reference to kubernetes.io/service-account.token-expiration means it is a legacy-style long-lived token.
  • Any external system documented as consuming this Secret directly (for example via CI/CD or off-cluster scripts) is relying on a long-lived token.
Interpretation:
  • Under secrets:, any entries that correspond to kubernetes.io/service-account-token Secrets from step 1 are legacy tokens.
  • Check automountServiceAccountToken:
    • If true or unset, pods using this ServiceAccount will auto-mount a token (legacy on older clusters / manifests).
    • If you intend to use projected tokens only, this typically should be set to false and explicit projected volumes used in Pods.
Interpretation:
  • Any Pod that lists a Secret name that you identified in step 1 (type kubernetes.io/service-account-token) is explicitly mounting a long-lived token Secret.
  • This indicates the workload is not using a projected ServiceAccountToken volume.
Interpretation:
  • Look under spec.volumes:
    • secret: name: <token-secret> → using a long-lived ServiceAccount token Secret.
    • projected: sources: - serviceAccountToken: with audience and expirationSeconds → using a bound/projected token (desired).
  • Under spec.serviceAccountName and spec.automountServiceAccountToken:
    • A Pod relying only on the default automounted token and not using projected.serviceAccountToken is a candidate for migration.
Interpretation:
  • Secrets not referenced by any Pods may be unused legacy tokens that can potentially be phased out.
  • Secrets actively referenced by Pods indicate those workloads must be carefully migrated to use projected ServiceAccount tokens with audience and expiry.