compromise the pipeline holding the credential The credential is taken from the system that deploys, not from the cluster.
A stolen session, a rewritten action tag or a poisoned build step yields whatever the pipeline was trusted with.
Precondition. The pipeline holds a cluster credential at all. Workload identity federation removes the standing credential entirely.
Break the chain. Pin build dependencies by digest rather than by tag, keep deploy credentials short-lived, and issue them per pipeline run.
T1 bind a high-privilege ClusterRole into the namespace RBAC's escalation prevention normally refuses a binding that confers rights the caller does not hold.
The bind verb waives that check, so a RoleBinding naming an existing high-privilege ClusterRole succeeds from a low-privilege account.
Break the chain. Never grant bind on clusterroles. Where a deployment identity must create RoleBindings, restrict it with resourceNames to the roles it may reference.
T1 read every Secret in the namespace The new binding grants read across the namespace, which returns every stored credential in it rather than the specific ones the pipeline needed.
Break the chain. Keep pipeline identities to get on named Secrets, and keep operator credentials out of tenant namespaces.
T1 mint a long-lived token for a privileged ServiceAccount The TokenRequest API issues a token for any ServiceAccount in reach, with a lifetime the caller chooses.
Unlike a stolen pod token it is not bound to a pod, so deleting workloads does not revoke it.
tokenRequest for privileged SA
T1
tokenRequest for privileged SA 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. Mint a bound token through the TokenRequest API with an extended lifetime, for example --duration=87600h for ten years. 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. Authenticate as the ServiceAccount with the minted token. T0 when targeting kube-system controller service accounts such as clusterrole-aggregation-controller or kube-controller-manager. 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 ↗ Kubernetes documentation kubernetes.io/docs/reference/kubernetes-api/authentication-resources/token-request-v1/ Break the chain. Keep serviceaccounts/token create off tenant identities, and cap token lifetime with the API server's service-account-max-token-expiration.
T0 add every verb to a ClusterRole already bound to you The escalate verb bypasses privilege-escalation prevention, so rules can be added to a ClusterRole the identity already holds.
No new binding is created, which is why binding audits do not show it.
Break the chain. Never grant escalate. Alert on ClusterRole rule changes that widen an existing binding rather than on new bindings alone.
Sources: kubernetes.io, kubernetes.io