hostPath Mounts: The docker.sock Escape Hatch
hostPath Mounts: The docker.sock Escape Hatch sits in the Kubernetes risk register because a small configuration shortcut can widen access, weaken control boundaries, or hide failure conditions. The risk usually starts with helm values for these charts ship with volumes: hostPath: path: /var/run/docker.sock and type: "", meaning no path-type validation runs at admission time. In production, the concern is socket access is functionally root on the node, regardless of the container's own capability set.
The Trap
A hostPath volume that maps /var/run/docker.sock into a pod. This turns up in CI runner charts (GitLab Runner, Jenkins agent), monitoring DaemonSets that shell out to Docker for metadata, and DinD-based build jobs that need to spin sibling containers without paying the nested-daemon tax.
The Default State
Helm values for these charts ship with volumes: hostPath: path: /var/run/docker.sock and type: "", meaning no path-type validation runs at admission time. The container itself often sets privileged: false, so it looks safe on a security scan. Pod Security Admission, if labelled at all, is frequently left at the privileged profile or unlabelled entirely, because teams disabled the old PodSecurityPolicy during the 1.25 migration and never replaced it. Baseline and restricted PSA profiles explicitly forbid hostPath volumes, but nobody enforces that on the namespace where the runner lives.
The Blast Radius
Socket access is functionally root on the node, regardless of the container’s own capability set. Any process that can write to that socket can run docker run -v /:/host --privileged alpine chroot /host, which lands a shell in the host filesystem. From there it reads the kubelet’s client certificate and kubeconfig under /var/lib/kubelet, pulls the cloud instance metadata endpoint at 169.254.169.254 for the node’s IAM role, and harvests every other pod’s projected service account token sitting in /var/lib/kubelet/pods/*/volumes/kubernetes.io~projected. One compromised build job now has cluster-admin-equivalent reach across every namespace scheduled on that node, and because the daemon is shared, it can spin containers on behalf of any workload the node hosts, not just the one that leaked the credential.
The Lead Mechanic Fix
Enforce PSA restricted on any namespace running build or agent workloads: kubectl label ns ci pod-security.kubernetes.io/enforce=restricted --overwrite. Restricted rejects hostPath volumes outright. Back that with an explicit deny for anyone tempted to relax the label, using a Kyverno ClusterPolicy with a validate rule matching spec.volumes[].hostPath.path against /var/run/docker.sock and /var/lib/docker, set to failureAction: Enforce. Replace DinD build steps with kaniko or rootless BuildKit, which build OCI images without a daemon socket at all. Audit existing exposure with kubectl get pods -A -o json | jq '.items[] | select(.spec.volumes[]?.hostPath.path=="/var/run/docker.sock")' and rotate any node that shows a hit, since the kubelet certificate on that node must be treated as burned.