Skip to main content

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

Manual Steps
  1. Identify all pods using hostPID in 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.
  2. Review whether hostPID usage 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.
  3. 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 hostPID in the policy repo or manifests used to deploy them.
  4. 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/v1
      kind: ClusterPolicy
      metadata:
      name: disallow-hostpid
      spec:
      validationFailureAction: enforce
      rules:
      - name: disallow-hostpid
      match:
      resources:
      kinds:
      - Pod
      validate:
      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.
  5. Refactor existing workloads that do not need hostPID

    • For pods where hostPID is not strictly required, update their manifests (Deployments, StatefulSets, DaemonSets, etc.) to remove hostPID: true or explicitly set hostPID: false.
    • Example edit for a Deployment:
      kubectl -n <namespace> edit deploy <deployment-name>
    • In the opened manifest, remove or change:
      spec:
      template:
      spec:
      hostPID: true
      to either omit hostPID or set it to false.
    • Save and allow the controller to roll out the updated pods.
  6. Verify that hostPID usage 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: true in a protected namespace is rejected by your admission policy (test with a small test pod manifest and kubectl apply -f).
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: true in 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: true is using the host PID namespace and must be reviewed.
  • Frequent or unreviewed use of hostPID: true in 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: true will 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/enforce set to a level that permits hostPID: true (e.g., not restricted in 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: true are 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.