Skip to main content
security · kubernetes

Secrets of type kubernetes.io/service-account-token

resource types
1
rule IDs covered
3
severity
medium

What does ZopNight detect here?

ZopNight has a rule for Secrets of type `kubernetes.io/service-account-token` in EKS, GKE and AKS clusters, but its discovery currently skips every such Secret, so the rule raises no findings yet. These Secrets hold tokens that never expire or rotate, and since v1.24 Kubernetes has stopped creating them automatically.

Signal and threshold

How ZopNight evaluates Secrets of type kubernetes.io/service-account-token.
Field Value
Rule IDsRC-1754 · RC-1854 · RC-1954
Categorysecurity
Severitymedium
Metricnone — pure configuration read
ThresholdSecret type kubernetes.io/service-account-token
SourceZopNight
Permissions usedlist secrets · list serviceaccounts

Static tokens outlive the reason they were created

A service account token Secret stores a signed credential for a ServiceAccount. The service accounts page marks this method as not recommended: these tokens do not expire and do not rotate, and static long-lived credentials carry risk, especially at scale. Anyone who copies the token from a backup, a CI log or a laptop keeps API access for as long as the Secret exists.

Kubernetes moved away from them in stages. From v1.22, pods get a short-lived, automatically rotating token from the TokenRequest API, mounted as a projected volume. From v1.24 the control plane stopped generating a permanent token Secret for each ServiceAccount by default. You can still create these Secrets by hand, which is why they keep turning up.

Finding token Secrets and their owners

Terminal window
kubectl get secrets -A --field-selector type=kubernetes.io/service-account-token \
-o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name,SA:.metadata.annotations.kubernetes\.io/service-account\.name

The kubernetes.io/legacy-token-last-used label, where present, records the last date the token was used, which helps separate live credentials from leftovers.

Matching on the Secret type

The rule reads the type recorded for each Secret and is written to fire when it is exactly kubernetes.io/service-account-token, whatever the name, age or usage. Today, though, ZopNight’s discovery skips every Secret of that type when it lists Secrets, hand-made ones included, so the rule has nothing to match and raises no findings yet. Until that changes, use the kubectl command above to find these Secrets.

What the check does not cover

Other Secret types, including TLS and registry credentials, are out of scope; Secrets carrying unusually many keys are covered by Secret has excessive keys. Projected tokens mounted into pods are not Secrets and never appear here. The control plane also cleans some tokens up by itself: since v1.30, when the legacy token cleaner became stable, auto-generated legacy tokens unused for a year are labelled kubernetes.io/legacy-token-invalid-since and later purged. That cleaner targets auto-generated tokens, so manually created ones usually remain until you remove them.

Credential risk with no saving

There is no dollar amount. The exposure is a non-expiring API credential whose reach equals every RBAC permission granted to its ServiceAccount.

Replacing the static token

  1. Identify the consumer from the ServiceAccount annotation, the last-used label and your CI or automation configuration.
  2. For workloads in the cluster, rely on the projected token Kubernetes mounts automatically.
  3. For tools outside the cluster, issue a time-bound token with kubectl create token <serviceaccount> --duration 1h, or call the TokenRequest API from the tool.
  4. Once nothing uses the old credential, run kubectl delete secret <name> -n <namespace>.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

472 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

472 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·