Kubetier
← Permission Reference
T1

create pods

Privileged, hostPID, hostPath, or hostNetwork pods mount / and chroot to the node for full host access.

T0 in kube-system or on a control plane node.

Setting spec.nodeName directly places the pod on any node, bypassing the scheduler's taint checks, since taints are enforced by the scheduler only.

This is still an ordinary pods create request, not the pods/binding subresource that most admission engines never inspect, so admission policy can see and block it.

T0 with following verbs:

The same privileged pod placed on a control plane node

A privileged pod spec decides what the workload can do, and pods/binding decides where it runs.

The taint keeping workloads off the control plane is enforced by the scheduler, so a direct binding ignores it.

T0 with following verbs:

The same privileged pod steered onto a control plane node by a RuntimeClass

A RuntimeClass carries scheduling rules that the pod inherits, so it places the workload where the scheduler would otherwise refuse.

The privileged spec then turns that placement into host access, the same outcome as the pods/binding route.

Contextual upgrade to T0:

Pod is scheduled in kube-system or on a control plane node, exposing node-level and control plane credentials, and admission controls (Pod Security Admission, OPA/Gatekeeper, Kyverno) are absent or configured permissively

API Group
(core)
Scope
namespaced
Audit Level
Request

Escalation Paths

  1. Create a pod with privileged + hostPID or hostPath mounting /

  2. Set spec.nodeName to a specific control plane node to force placement there.

    The NoSchedule taint kubeadm puts on those nodes is a scheduler check only, so a directly bound pod needs no toleration

  3. chroot or nsenter into the host to gain root on the node

  4. Read /etc/kubernetes/pki, steal kubelet cert or SA tokens.

    This is T0 on the control plane

Additional rights needed:

none
K8s docs ↗
  1. Create a pod using hostNetwork, hostPID, hostIPC or hostPath as available

  2. hostNetwork reaches cloud metadata and the API server from the node network namespace.

    hostPID reads host process env vars

  3. hostPath to / reads other pods' SA tokens under /var/lib/kubelet and the cluster CA private key if scheduled on a control plane node

Additional rights needed:

none

Note:

On a control plane node, hostPath to / exposes the cluster CA private key for full cluster compromise.

On worker nodes this is node-level only (T1).

K8s docs ↗
  1. Create a pod targeting a Windows node with spec.securityContext.windowsOptions.hostProcess: true

  2. Container starts as NT AUTHORITY\SYSTEM in the host network and volume namespaces

  3. Windows HostProcess is blocked by both Baseline and Restricted Pod Security Standards.

    Only namespaces enforcing Privileged level or unlabeled namespaces are vulnerable

  4. Full Windows node compromise follows, with lateral move to other workloads or extraction of node credentials

Additional rights needed:

none

Note:

Windows HostProcess containers were introduced as stable in 1.23.

This is by-design for Windows workloads, so no patch applies.

Linux-only clusters are unaffected.

The risk is specific to mixed OS clusters.

K8s docs ↗
  1. The metadata service answers any caller that can reach it, and returns credentials for the node identity rather than for any workload identity

  2. Whether an ordinary pod can reach it is a platform and provisioning property, not a Kubernetes one, so the required pod shape differs per cluster

  3. Where the address is redirected per pod network namespace, as GKE does with GKE_METADATA, a hostNetwork pod runs in the host namespace and reaches the real service

  4. Where nothing intercepts it, which is the AKS default and the eksctl default on EKS, a plain unprivileged pod reaches it with no host access at all

  5. On EKS the barrier is the IMDSv2 hop limit of 1, and it holds only while tokens are required.

    An IMDSv1 GET is not hop limited and returns the credentials anyway

  6. Workload identity does not prevent this.

    It changes which credential the SDK resolves, not which address the pod can reach, and a hostNetwork pod always reaches it

  7. Mounting the host root as root is an independent second route, reading the kubelet credentials and the cloud provider config from disk

  8. The node identity ceiling varies from no cloud permissions at all to full control of the node resource group, so read its role bindings before rating impact

Additional rights needed:

none

Note:

Working as designed rather than a fixable defect.

Whether a plain pod is blocked depends on the platform and on how the node group was set up.

On EKS the control is the hop limit together with required tokens, not either one alone.

K8s docs ↗
K8s docs ↗