Minimize Admission Of Containers Sharing The Host Process
More Info:
Sharing the host PID namespace lets a container view and interact with all processes on the node. Enforce policies that restrict admission of hostPID containers.
Risk Level
High
Address
Security
Compliance Standards
- CIS OKE
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Identify all pods using
hostPIDin each workload namespace- Run on: any machine with kubectl access
- Command:
kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}' \| sort
- Record which namespaces and applications currently use
hostPID.
-
Review whether
hostPIDusage is strictly necessary- For each identified pod, inspect its spec and discuss with the owning team whether it truly requires host-level process visibility (e.g., specific debugging/monitoring daemons).
- Command (example for one pod):
kubectl -n <namespace> get pod <pod-name> -o yaml
- Decide: keep
hostPID(documented justification and owner) or plan to remove it from the pod spec.
-
Check for existing admission controls related to
hostPID- Run on: any machine with kubectl access
- If you use PSP (legacy clusters):
kubectl get psp -o yaml | grep -nA5 -B5 hostPID || echo "No PSP hostPID config found"
- If you use Pod Security Admission labels:
kubectl get ns --show-labels | grep pod-security.kubernetes.io
- If you use other admission controllers (e.g., Kyverno, Gatekeeper), list their policies and search for
hostPIDin the policy repo or manifests used to deploy them.
-
Decide and implement a namespace-level policy for future pods
- For each user workload namespace, decide on the stance:
- Disallow hostPID by default, with explicit exceptions via separate namespaces or explicit policy overrides.
- Example Kyverno policy manifest snippet (to be customized and applied if you use Kyverno):
apiVersion: kyverno.io/v1kind: ClusterPolicymetadata:name: disallow-hostpidspec:validationFailureAction: enforcerules:- name: disallow-hostpidmatch:resources:kinds:- Podvalidate:message: "Use of hostPID is not allowed."pattern:spec:hostPID: "false"
- Apply with:
kubectl apply -f disallow-hostpid.yaml
- If you use a different admission mechanism, create/adjust an equivalent rule there.
- For each user workload namespace, decide on the stance:
-
Refactor existing workloads that do not need
hostPID- For pods where
hostPIDis not strictly required, update their manifests (Deployments, StatefulSets, DaemonSets, etc.) to removehostPID: trueor explicitly sethostPID: false. - Example edit for a Deployment:
kubectl -n <namespace> edit deploy <deployment-name>
- In the opened manifest, remove or change:
to either omitspec:template:spec:hostPID: true
hostPIDor set it tofalse. - Save and allow the controller to roll out the updated pods.
- For pods where
-
Verify that
hostPIDusage is minimized and blocked going forward- Re-run the discovery command:
kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}' \| sort
- Confirm that:
- Only explicitly justified system/monitoring pods (if any) still use
hostPID. - Attempting to create a new pod with
hostPID: truein a protected namespace is rejected by your admission policy (test with a small test pod manifest andkubectl apply -f).
- Only explicitly justified system/monitoring pods (if any) still use
- Re-run the discovery command:
Using kubectl
# 1) List all pod security policies (if PSPs are enabled)
# Run on: any machine with kubectl access
kubectl get psp
# Inspect PSP definitions for hostPID allowance
kubectl get psp -o yaml | grep -C5 hostPID
Problem indication:
hostPID: truein a PSP that is referenced by service accounts used for user workloads means those workloads are allowed to request host PID sharing.
# 2) List current namespaces, so you can identify user-workload namespaces
# Run on: any machine with kubectl access
kubectl get ns
Manually identify which namespaces contain user workloads (vs. system/control-plane).
# 3) For each user-workload namespace, list all pods and check for hostPID usage
# Replace <NAMESPACE> with the actual namespace name
# Run on: any machine with kubectl access
kubectl get pods -n <NAMESPACE> -o wide
# Show full pod specs and search for hostPID
kubectl get pods -n <NAMESPACE> -o yaml | grep -C3 hostPID
Problem indication:
- Any pod spec with
hostPID: trueis using the host PID namespace and must be reviewed. - Frequent or unreviewed use of
hostPID: truein user namespaces suggests insufficient admission control.
# 4) Check workload controllers (Deployments, DaemonSets, StatefulSets, Jobs, CronJobs) for hostPID
# Run on: any machine with kubectl access
# Deployments
kubectl get deploy -A -o yaml | grep -C3 hostPID
# DaemonSets
kubectl get ds -A -o yaml | grep -C3 hostPID
# StatefulSets
kubectl get sts -A -o yaml | grep -C3 hostPID
# Jobs
kubectl get jobs -A -o yaml | grep -C3 hostPID
# CronJobs (batch/v1)
kubectl get cronjobs -A -o yaml | grep -C3 hostPID
Problem indication:
- Any controller template containing
hostPID: truewill continuously recreate pods with host PID access, making it harder to enforce restrictions.
# 5) If using Pod Security Admission (PSA), check namespace labels
# Run on: any machine with kubectl access
kubectl get ns --show-labels
Problem indication:
- User-workload namespaces labeled with
pod-security.kubernetes.io/enforceset to a level that permitshostPID: true(e.g., notrestrictedin recent Kubernetes versions) mean host PID usage may not be blocked by default and relies solely on workload authors’ choices.
# 6) If using Gatekeeper/OPA or another admission controller, list constraints
# Example for Gatekeeper (if installed)
# Run on: any machine with kubectl access
kubectl get constrainttemplates
kubectl get constraints --all-namespaces
kubectl get constraints --all-namespaces -o yaml | grep -C5 hostPID
Problem indication:
- Absence of any constraint touching
hostPID, or constraints scoped only to non–user namespaces, means there is no enforced policy to minimize host PID containers.
Verification (after you design and apply your chosen policy):
# Re-check for any pods or controllers still requesting hostPID
kubectl get pods -A -o yaml | grep -C3 hostPID || echo "No pods with hostPID found"
kubectl get deploy,ds,sts,jobs,cronjobs -A -o yaml | grep -C3 hostPID || echo "No controllers with hostPID found"
Automation
#!/usr/bin/env bash
# Report Pods and controllers that request hostPID=true across the cluster.
# Run on: any machine with kubectl access and appropriate RBAC.
set -euo pipefail
echo "=== Checking Pods with hostPID: true ==="
kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.nodeName}{"\n"}{end}' \
| sort || true
echo
echo "=== Checking Deployments with hostPID: true ==="
kubectl get deployments --all-namespaces -o jsonpath='{range .items[?(@.spec.template.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}' \
| sort || true
echo
echo "=== Checking StatefulSets with hostPID: true ==="
kubectl get statefulsets --all-namespaces -o jsonpath='{range .items[?(@.spec.template.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}' \
| sort || true
echo
echo "=== Checking DaemonSets with hostPID: true ==="
kubectl get daemonsets --all-namespaces -o jsonpath='{range .items[?(@.spec.template.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}' \
| sort || true
echo
echo "=== Checking ReplicaSets with hostPID: true (may include controller-owned sets) ==="
kubectl get replicasets --all-namespaces -o jsonpath='{range .items[?(@.spec.template.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}' \
| sort || true
echo
echo "=== Checking CronJobs with hostPID: true ==="
kubectl get cronjobs --all-namespaces -o jsonpath='{range .items[?(@.spec.jobTemplate.spec.template.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}' \
| sort || true
echo
echo "=== Checking Jobs with hostPID: true ==="
kubectl get jobs --all-namespaces -o jsonpath='{range .items[?(@.spec.template.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}' \
| sort || true
echo
echo "=== Summary ==="
echo "Any non-empty list above indicates pods or workload controllers that request hostPID: true."
echo "For each, review whether hostPID is strictly required and, if not, remove hostPID: true from the pod spec."
Explanation of output indicating a problem:
- Any line printed under any of the sections (Pods, Deployments, StatefulSets, DaemonSets, ReplicaSets, CronJobs, Jobs) identifies a workload that is configured with
hostPID: true. - Workloads in user application namespaces with
hostPID: trueare the primary concern for this control and should be reviewed; where not strictly necessary, they should be reconfigured to avoid sharing the host PID namespace and governed by admission policies that prevent such configurations.