Most workload identity federation conversations focus on eliminating standing AWS credentials from CI/CD pipelines — replacing IAM user keys with OIDC federation. There's a parallel, less-discussed standing-credential problem living inside Kubernetes clusters themselves: legacy service account tokens that never expire, mounted automatically into every pod unless explicitly disabled.
The Legacy Token Auto-Mount Problem
Prior to Kubernetes 1.24, every service account automatically got a long-lived JWT token stored as a Secret, and that token was auto-mounted into any pod using that service account — whether the pod's workload needed to call the Kubernetes API or not. These tokens had no built-in expiration and remained valid until the associated Secret was manually deleted, which in practice meant most clusters accumulated pods holding API credentials indefinitely, many of which never actually used them.
Kubernetes 1.24 changed the default to bound service account tokens — time-limited, audience-scoped tokens generated via the TokenRequest API rather than stored as static Secrets — but clusters upgraded from earlier versions, or workloads with legacy manifests explicitly referencing the old-style Secret-based tokens, often still carry the long-lived pattern forward without anyone noticing.
Finding What's Actually Exposed
The first step in any elimination effort is inventory, since most teams underestimate how many pods are holding long-lived tokens they don't use:
# Find service accounts still using legacy long-lived Secret-based tokens
kubectl get secrets --all-namespaces \
-o jsonpath='{range .items[?(@.type=="kubernetes.io/service-account-token")]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
# Cross-reference against pods actually mounting a service account token
kubectl get pods --all-namespaces \
-o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.serviceAccountName}{"\n"}{end}'
In most clusters we've assessed, a significant share of pods have automountServiceAccountToken implicitly enabled without their workload ever calling the Kubernetes API — a pure attack-surface cost with zero functional benefit.
The Migration Pattern
- Disable auto-mount by default at the namespace or service-account level (
automountServiceAccountToken: false), forcing an explicit opt-in for workloads that genuinely need API access. - Convert genuinely necessary API access to bound, projected tokens with a defined audience and short TTL, refreshed automatically by the kubelet rather than stored as a static Secret.
- Delete legacy Secret-based tokens for service accounts once confirmed unused, closing the standing-credential window entirely rather than just adding a newer token alongside the old one.
# Projected bound token volume — replaces legacy auto-mounted Secret token
volumes:
- name: api-token
projected:
sources:
- serviceAccountToken:
path: token
expirationSeconds: 3600
audience: api
Extending This to IRSA on EKS
For teams running EKS, this pattern connects directly to IAM Roles for Service Accounts (IRSA), which uses the same bound-token mechanism to let a pod assume an AWS IAM role without any static AWS credential ever touching the pod. Migrating away from legacy long-lived Kubernetes tokens and adopting IRSA (or its successor, EKS Pod Identity) for AWS API access are effectively the same underlying architectural shift applied to two different credential surfaces — Kubernetes API access and AWS API access — and teams doing one migration are usually well-positioned to do the other.
What This Looks Like in an Audit
For SOC 2 or internal security review purposes, the evidence that matters is a cluster-wide inventory showing zero pods with unused, unbounded service account tokens, paired with a policy enforcing automountServiceAccountToken: false as the namespace default. That's a stronger, more verifiable control than a written policy saying tokens "should" be minimized.
This migration pairs naturally with our Kubernetes and containerization capability, and connects directly to the broader standing-credential work covered in eliminating service account passwords.
Talk to us about your credential elimination pilot: 907-841-8407 or contact@rutagon.com.
Talk to us about your credential elimination pilot →
Frequently Asked Questions
Do all Kubernetes clusters have this legacy token problem?
Clusters created on Kubernetes 1.24 or later default to bound tokens, but clusters upgraded from earlier versions, or workloads with older manifests, can still carry legacy Secret-based tokens forward unless explicitly remediated.
How do I know if a pod actually needs Kubernetes API access?
Audit the application code and any client libraries for calls to the Kubernetes API server; workloads that only serve external traffic or call external APIs typically have no legitimate need for a mounted service account token at all.
What's the difference between IRSA and Kubernetes bound service account tokens?
Bound service account tokens are the Kubernetes-native mechanism for authenticating to the Kubernetes API itself; IRSA extends that same bound-token infrastructure to let pods assume AWS IAM roles for AWS API access — related mechanisms, different audiences.
Will disabling auto-mount by default break existing workloads?
It can, for workloads that genuinely rely on the Kubernetes API without explicitly declaring it — which is why the migration should start with an inventory and staged rollout per namespace rather than a blanket cluster-wide change.
Is EKS Pod Identity a replacement for IRSA?
EKS Pod Identity is a newer, simpler mechanism for the same goal — pods assuming IAM roles without static credentials — and is worth evaluating for new workloads, though IRSA remains supported and widely deployed.