Kubetier
← Permission Reference
T1

create serviceaccounts/token

A bound token for any ServiceAccount in scope, minted through the TokenRequest API with no existing Secret and a caller-specified expiry.

Targeting a kube-system controller ServiceAccount is T0.

The caller also chooses the audience.

Where the cluster is federated to a cloud identity provider, the same call mints an assertion that trades for a cloud credential outside the cluster.

Contextual upgrade to T0:

Targeting a kube-system SA such as kube-controller-manager that carries cluster-admin-equivalent permissions

API Group
(core)
Scope
namespaced
Audit Level
RequestResponse

Escalation Paths

  1. Identify a high-privilege ServiceAccount in scope.

    The clusterrole-aggregation-controller SA in kube-system has effective cluster-admin rights and is a prime target.

  2. Mint a bound token through the TokenRequest API with an extended lifetime, for example --duration=87600h for ten years.

  3. The API server honors the request unless --service-account-max-token-expiration is set.

    kubeadm does not set it, so the full 87600h is issued.

    Managed providers commonly do set it.

  4. Authenticate as the ServiceAccount with the minted token.

  5. T0 when targeting kube-system controller service accounts such as clusterrole-aggregation-controller or kube-controller-manager.

  6. The audience is caller specified, so on a cluster federated to a cloud identity provider the same call mints an assertion that exchanges for a cloud credential outside the cluster

Additional rights needed:

none

Note:

The serviceaccounts/token subresource (TokenRequest API) was promoted to stable in 1.22, making this path available without alpha flags.

No patch exists.

Keep token TTLs short and audit all uses of this verb.

K8s docs ↗
  1. An IAM role must already exist whose trust policy names the cluster OIDC provider and conditions on sub system:serviceaccount:<namespace>:<name> plus aud sts.amazonaws.com

  2. The IAM role trusts the cluster OIDC provider and evaluates whatever token claims its trust policy names, most commonly the subject and the audience

  3. Those conditions are policy specific rather than built into IRSA, and the ServiceAccount annotation takes no part in the authorization decision

  4. A pod running under that ServiceAccount, projecting a serviceAccountToken with audience sts.amazonaws.com, receives an assertion STS accepts

  5. AssumeRoleWithWebIdentity is unauthenticated, so the exchange needs no AWS credentials and returns whatever the role itself grants

  6. create serviceaccounts/token mints the same assertion with no pod involved, and the credentials work from outside the cluster

  7. The eks.amazonaws.com/role-arn annotation only drives the pod-identity-webhook, which injects at admission and so never reaches running pods

  8. That annotation is also the discovery path, since it names the role and the ServiceAccount it trusts, and reading it needs only list serviceaccounts

Additional rights needed:

none

Note:

Not a defect and nothing to patch.

The IAM trust policy is the anchor, so an audit that looks only for the eks.amazonaws.com/role-arn annotation misses every variant that bypasses the webhook.

K8s docs ↗
  1. A federated identity credential must already exist on the managed identity, naming the cluster OIDC issuer and system:serviceaccount:<namespace>:<name> as its subject

  2. Entra matches that credential on issuer and subject alone, so the ServiceAccount name is the whole secret and no annotation takes part in the trust decision

  3. A pod running under that ServiceAccount, projecting a serviceAccountToken with audience api://AzureADTokenExchange, receives an assertion Entra accepts

  4. Exchanging the assertion returns an access token for the managed identity, carrying every Azure role assigned to it

  5. create serviceaccounts/token mints the same assertion with no pod involved, and the token it buys is usable from outside the cluster

  6. The pod label azure.workload.identity/use and the ServiceAccount client-id annotation only drive the addon webhook, a convenience for applications rather than the control

Additional rights needed:

none

Note:

Not a defect and nothing to patch.

The federated credential is the trust anchor, so an audit that looks only for the azure.workload.identity annotation misses every variant that does not use the addon webhook.

K8s docs ↗

Included in Built-in Roles

K8s docs ↗

Appears in 1 threat path