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. On any machine with kubectl access, list all legacy ServiceAccount token Secrets and capture details for review:
  2. Identify which applications still rely on these Secrets by searching for references in Pods, Deployments, and other workload specs:
    Also inspect any custom manifests/IaC (Helm charts, CD configs, etc.) for explicit mounting of these Secrets.
  3. For each workload that currently mounts a ServiceAccount token Secret, decide if you can migrate it to projected ServiceAccount tokens using the EKS-bound token volume instead of a Secret. For Pods you control, plan to:
    • Remove volumes[].secret.secretName and matching volumeMounts that reference the token Secret.
    • Use the automatically mounted ServiceAccount token file at /var/run/secrets/kubernetes.io/serviceaccount/token or add a projected serviceAccountToken volume with audience and expirationSeconds if you need custom settings.
  4. Implement the change for one representative Deployment as a pattern:
    In the editor:
    • Delete any volumes entry that uses secret: with the token Secret’s name.
    • Delete any volumeMounts that mount that volume.
    • (Optional) Add a projected volume, for example:
      and mount it via volumeMounts in the container.
  5. After updating all dependent workloads and confirming they run correctly (check logs and readiness), safely remove unused ServiceAccount token Secrets:
  6. Verify the cluster no longer relies on long-lived ServiceAccount token Secrets, and that remaining ones (if any) are explicitly justified (for example, for legacy or third-party components you cannot yet change):
    Document any remaining Secrets, their owners, and a migration plan to projected tokens where feasible.
What indicates a problem
  • Large numbers of kubernetes.io/service-account-token Secrets that are:
    • Very old (e.g., months/years), and
    • Still mounted into Pods or used by external systems.
  • Workloads or external clients relying on these Secrets instead of using projected ServiceAccount tokens via the TokenRequest API (audience + short expiry).

Problem indicators
  • Type: kubernetes.io/service-account-token.
  • No clear operational rotation process; token appears to be a long‑lived credential used by:
    • CI/CD systems,
    • External scripts/tools,
    • Third‑party integrations, etc.

If many Pods use a ServiceAccount that auto‑generates a long‑lived token Secret and those Pods (or sidecars/agents) read the Secret directly, you likely have a pattern that should be migrated to use projected tokens.
Problem indicators
  • ServiceAccount token Secrets referenced in ConfigMaps, other Secrets, or annotations as static credentials.
  • Evidence the token value has been copied out of the cluster (you’ll usually confirm this via process/doc review, not kubectl).

Problem indicators
  • Sensitive or externally‑integrated workloads not using projected.serviceAccountToken volumes at all, while still having long‑lived SA token Secrets auto‑created.

In the output, look under .spec.volumes:
  • Healthy pattern (what you want to see for security‑sensitive workloads):
  • Problem pattern:
    • Only a default SA token Secret volume (legacy behavior), no projected.serviceAccountToken.
    • Application docs/manifests instruct users to read /var/run/secrets/kubernetes.io/serviceaccount/token as a de‑facto long‑lived credential.