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 ServiceAccount token Secrets
    • Run on: any machine with kubectl access
    • Command:
    • Review which namespaces and ServiceAccounts still have token Secrets and note any in application namespaces (not just kube-system).
  2. Identify who uses each token Secret and how
    • For a specific Secret, inspect it (do not paste token contents into tickets/logs):
    • Search for references to that Secret name in:
      • Pod specs:
      • Deployments/StatefulSets/DaemonSets/Jobs/CronJobs:
    • Also search your app/IaC repos for the Secret name or service-account-token usage.
  3. Decide whether the workload can switch to projected ServiceAccount tokens
    For each workload that uses a ServiceAccount token Secret:
    • Confirm if it really needs to call the Kubernetes API from inside the pod. If not, plan to remove the token mount entirely.
    • If it does:
      • Check if the code or sidecar can read the token from:
        • The default projected token mount (/var/run/secrets/kubernetes.io/serviceaccount/token), or
        • An explicit projected ServiceAccount token volume with audience and expirationSeconds.
      • If the current configuration is hard‑wiring a Secret volume/volumeMount, plan to migrate it to a projected ServiceAccount token volume.
  4. Reconfigure manifests to stop using long‑lived token Secrets
    • For each affected ServiceAccount:
      • If the only reason it exists is to auto‑provision a legacy token Secret, ensure there are no pods mounting that Secret, then plan to delete the Secret.
    • For each affected workload manifest (e.g., Deployment):
      • Remove explicit secret volume entries and volumeMounts that point at kubernetes.io/service-account-token Secrets.
      • Ensure spec.serviceAccountName is set to the intended ServiceAccount.
      • If the app cannot use the default mount, define a projected token volume similar to:
    • Apply changes:
  5. Remove unused ServiceAccount token Secrets after migration
    • For each previously identified Secret, confirm no pod is mounting it:
    • When you are sure it is unused, delete it:
    • In AKS, new long‑lived ServiceAccount token Secrets should not be auto‑created by recent Kubernetes versions; if you see new ones appear, investigate controllers or tools that may be creating them manually.
  6. Verify that only projected tokens are in use
    • Re-run the review command and confirm that no application namespaces rely on kubernetes.io/service-account-token Secrets:
    • Spot‑check updated pods to ensure they are using projected tokens (either the default mount or your projected volume) and that no secret‑type volumes for ServiceAccount tokens remain.
What to look for (potential problems):
  • Many Secrets of type kubernetes.io/service-account-token in namespaces that host apps using modern SDKs or that already use projected tokens.
  • Namespaces where workloads are short‑lived or highly sensitive but still have multiple legacy token Secrets.
  • ServiceAccounts used by critical apps that also have a corresponding token Secret and no sign of projected token use in the Pods.

What to look for:
  • type: kubernetes.io/service-account-token
  • Very old metadata.creationTimestamp (indicates a long‑lived token).
  • Annotation kubernetes.io/service-account.name pointing to a ServiceAccount still in use.
  • No automated process rotating or deleting these Secrets.

What to look for:
  • Pods that reference Secrets of type kubernetes.io/service-account-token as volumes.
  • These indicate applications may be using long‑lived token Secrets rather than projected tokens.

What to look for (good vs. problematic):
  • Good (preferred):
    • Volumes of type projected with a serviceAccountToken source:
  • Problematic (legacy):
    • Volumes of type secret that reference a ServiceAccount token Secret:
    • Containers reading the token from /var/run/secrets/kubernetes.io/serviceaccount/token directly with no projected token volume.

What to look for:
  • secrets: list containing entries like <serviceaccount-name>-token-xxxxx (indicates classic token Secret exists).
  • Whether Pods using this ServiceAccount (from step 4) mount that Secret directly instead of using a projected serviceAccountToken volume.

What to look for:
  • Very old tokens in application namespaces still attached to active ServiceAccounts.
  • Patterns where every ServiceAccount automatically gets and keeps a token Secret, while Pods are not using projected volumes. This suggests refactoring to TokenRequest/projected tokens is needed.
These kubectl commands only surface current usage; a human must decide per application whether and how to migrate from long‑lived ServiceAccount token Secrets to projected tokens with audience and expiry.