run a command through the kubelet API The kubelet serves exec on its own port.
Where anonymous authentication is enabled and the port is reachable, the request carries no credential and the API server never sees it, so no RBAC rule applies and no API audit entry is written.
Precondition. The kubelet port is reachable and anonymous authentication is enabled. Both are configuration, not RBAC.
Break the chain. Set anonymous-auth to false on the kubelet, require webhook authorization, and keep the port off any network the workload plane can reach.
The token sits on the container filesystem at a fixed path.
Reading it is a file read, so no grant authorises it and the API server records nothing until the token is used.
Break the chain. Set automountServiceAccountToken to false on workloads that never call the API server.
T1 create a DaemonSet that tolerates every taint A DaemonSet with a blanket toleration schedules one pod onto every node, control plane included, from a single create.
The DaemonSet controller creates the pods, so the caller never needs a pods verb of its own.
daemonSet cluster-wide pod injection
T1
daemonSet cluster-wide pod injection Create a DaemonSet with tolerations using operator Exists so it schedules onto every node, control plane included. create alone is enough. The DaemonSet controller creates the pods, so the caller never needs a pods verb. Put privileged and hostPID in the pod template to reach the host namespaces. Pod Security Admission evaluates each generated pod against its namespace labels, so a baseline or restricted namespace rejects them and the DaemonSet reports failures instead. Where the namespace does not enforce pod security, this is root on every node at once. ↗ Kubernetes documentation kubernetes.io/docs/concepts/workloads/controllers/daemonset/ Break the chain. Enforce the restricted Pod Security Standard so the generated pods are rejected, and keep daemonsets create away from workload identities.
reach the host from the scheduled pod Where the namespace does not enforce pod security, the generated pods run with the host namespaces and mounts they asked for, which is root on every node at once.
Break the chain. Enforce baseline or restricted pod security on every namespace, including the ones operators install into.
T0 harvest every Secret in the cluster A token collected from the node filesystem is used against the API server.
Where it carries cluster-wide read, one request returns every credential in every namespace, and each one is usable until it is rotated.
T0 list secrets
T0
list secrets Full Secret objects come back, not metadata. This includes TLS keys, imagePullSecrets, DB passwords, API keys, kubeconfigs, and any legacy or manually created ServiceAccount token Secrets, cluster-wide. Revoking the grant afterwards does not undo the read, since every credential returned stays valid until it is individually identified and rotated.
↗ Kubernetes documentation kubernetes.io/docs/concepts/configuration/secret/ Cluster-wide secret harvesting
T0
Cluster-wide secret harvesting list or watch secrets cluster-wide, or in kube-system alone, and receive every Secret's data in the response. Auto-created ServiceAccount token Secrets are gone from modern clusters, so what is harvested is whatever was deliberately stored. That is the credential material the cluster actually runs on, including registry pull secrets, database and cloud credentials, TLS private keys, and any long-lived token created on purpose. Revoking the permission afterwards does not undo the exposure. Every credential returned stays valid until it is individually identified and rotated. ↗ Kubernetes documentation kubernetes.io/docs/concepts/configuration/secret/ Break the chain. Keep list and watch on secrets off every identity that does not reconcile the whole cluster, and prefer get on named Secrets.
Sources: unit42.paloaltonetworks.com, www.crowdstrike.com