Skip to main content

Minimize Admission Containers Wishing Share The Host

More Info:​

Do not generally permit containers to be run with the hostPID flag set to true.

Risk Level​

High

Address​

Security

Compliance Standards​

  • APRA CPS 234 (Australia)
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS Critical Security Controls v8
  • CIS GKE
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • Essential 8
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • NIS2 Directive
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • SWIFT Customer Security Controls Framework
  • Sarbanes-Oxley IT General Controls
  • UK NCSC Cyber Assessment Framework

Triage and Remediation​

Remediation​

Manual Steps
  1. List all pods using hostPID

    • Run on: any machine with kubectl access
    kubectl get pods -A -o jsonpath='{range .items[?(@.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
    • Save/record the list of affected pods and their namespaces.
  2. Identify why hostPID is required

    • For each affected pod from step 1, inspect the manifest and labels/annotations:
    # Example for one pod
    kubectl get pod -n <namespace> <pod-name> -o yaml
    • Determine if the pod is part of a DaemonSet, Deployment, Job, or a managed add‑on (CNI, monitoring, security agent, etc.) and document its purpose and owner/team.
  3. Review security justification and alternatives

    • For each pod using hostPID, confirm with the owning team:
      • Explicit functional need (e.g., process-level host monitoring).
      • Whether alternatives exist (node-level agents without hostPID, metrics APIs, or node logs).
    • Classify each use as:
      • Justified exception (operationally required and accepted risk), or
      • Unnecessary (can be removed or redesigned).
  4. Plan and apply manifest corrections where hostPID is unnecessary

    • For each Deployment/DaemonSet/Job/Pod classified as unnecessary:
      • Locate the authoritative manifest (Git repo / Helm chart / Kustomize, not just live object).
      • Edit spec to remove or disable hostPID:
        • Remove the line hostPID: true, or
        • Explicitly set:
          spec:
          hostPID: false
      • Apply the updated manifest:
        kubectl apply -f <path-to-updated-manifest>.yaml
  5. Define and document allowed exceptions

    • For pods where hostPID is justified:
      • Document:
        • Namespace, workload name, reason, owner, approval date.
      • Where possible, scope them to dedicated namespaces and label them (for later policy implementation), for example:
        kubectl label namespace <namespace> hostpid-exception=true --overwrite
  6. Verify the current state matches your decisions

    • Re-run the evidence command:
      kubectl get pods -A -o jsonpath='{range .items[?(@.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
    • Confirm that:
      • All remaining pods with hostPID are documented exceptions.
      • All non-exception workloads no longer appear in the output.
Using kubectl

Using kubectl​

1. List pods using hostPID (current state)​

Run on: any machine with kubectl access.

kubectl get pods -A -o json | jq -r '
.items[]
| . as $pod
| (
.spec.hostPID as $hp
| ( .spec.initContainers[]? + .spec.containers[]? ) as $c
| select($hp == true or $c.securityContext.hostPID == true)
| [
$pod.metadata.namespace,
$pod.metadata.name,
"hostPID=" + ($hp|tostring)
]
| @tsv
)
' | column -t

What indicates a problem:

  • Any line in the output where hostPID=true for regular application pods, especially in non-system namespaces (not kube-system, gke-system, istio-system, etc.), likely needs review.
  • Even in system namespaces, hostPID=true should be justified (e.g., system daemons, node monitoring).

If jq is not available, a simpler (less precise) view:

kubectl get pods -A -o wide --show-labels | grep -i hostpid || echo "No obvious hostPID usage found in basic listing"

2. Inspect a specific pod’s spec for hostPID​

When you see a suspicious pod from step 1, inspect it:

# Example: replace with actual namespace and pod name
kubectl get pod <pod-name> -n <namespace> -o yaml

Review in the output:

  • At pod level:
    • spec.hostPID: true → pod shares host process namespace.
  • At container level (if present in your environment):
    • securityContext.hostPID: true.

This is problematic if:

  • The pod is not a low-level node or system management component, and
  • The application does not clearly require visibility into all host processes.

3. Check for policies that allow hostPID​

Even though the benchmark mentions PodSecurityPolicy (PSP), on GKE you may also be using Pod Security Admission (PSA) or other policy:

a. PodSecurityPolicy (if still present)

kubectl get psp
kubectl get psp -o yaml

In each PSP, look for:

spec:
hostPID: true

Problematic if:

  • A PSP with hostPID: true is bound (via RBAC) to broad subjects (e.g., all service accounts, all namespaces), effectively allowing arbitrary workloads to request hostPID.

b. Pod Security Admission labels on namespaces

kubectl get ns --show-labels

Look at labels like:

  • pod-security.kubernetes.io/enforce=privileged or baseline on general application namespaces.

These labels do not directly show hostPID, but privileged (and sometimes baseline) profiles may allow hostPID depending on policy configuration. Namespaces with less restrictive policies deserve closer review of pods found in step 1.

4. Focus on non-system namespaces​

To narrow to non-system namespaces:

kubectl get pods \
--all-namespaces \
--field-selector=status.phase=Running \
-o json | jq -r '
.items[]
| select(.metadata.namespace | in({"kube-system":true,"gke-system":true,"istio-system":true}) | not)
| select(.spec.hostPID == true)
| [.metadata.namespace, .metadata.name, "hostPID=true"] | @tsv
' | column -t

What indicates a problem:

  • Any non-system application pod with hostPID=true is high-risk and should be explicitly justified or redesigned.

5. Evidence collection for review​

For each suspicious pod, capture spec for documentation / security review:

kubectl get pod <pod-name> -n <namespace> -o yaml > hostpid-<namespace>-<pod-name>.yaml

Share these YAMLs with your security/review team to decide:

  • Whether hostPID is strictly required.
  • Whether an alternative design (e.g., not sharing host PID namespace) is acceptable.

kubectl cannot decide or apply the “correct” fix automatically; the decision to remove or allow hostPID requires human review of each workload’s purpose and risk tolerance.

Automation
#!/usr/bin/env bash
# Check for workloads and policies that allow hostPID=true across the cluster.
# Run on: any machine with kubectl access and current context set.

set -euo pipefail

echo "=== 1) Workloads currently requesting hostPID ==="
echo
echo "# Pods with hostPID=true (including running pods):"
kubectl get pods --all-namespaces -o json \
| jq -r '
.items[]
| select(.spec.hostPID == true)
| [.metadata.namespace, .metadata.name, (.spec.serviceAccountName // "default")]
| @tsv' \
| awk 'BEGIN{print "NAMESPACE\tPOD\tSERVICEACCOUNT"}1'

echo
echo "# PodSpecs in controllers (Deployments/DaemonSets/StatefulSets/Jobs/CronJobs) with hostPID=true:"
for kind in Deployment DaemonSet StatefulSet Job CronJob; do
echo
echo "## $kind objects with hostPID=true:"
kubectl get "$kind" --all-namespaces -o json 2>/dev/null \
| jq -r --arg KIND "$kind" '
.items[]
| select(.spec.template.spec.hostPID == true)
| [.metadata.namespace, .metadata.name, $KIND, (.spec.template.spec.serviceAccountName // "default")]
| @tsv' \
| awk 'BEGIN{print "NAMESPACE\tNAME\tKIND\tSERVICEACCOUNT"}1' || true
done

echo
echo "=== 2) Pod Security Policy (if used) and Pod Security Admission markers ==="
echo
echo "# PSPs that allow hostPID (if PSP is enabled in this cluster):"
if kubectl api-resources | grep -q "^podsecuritypolicies"; then
kubectl get podsecuritypolicies.policy -o json \
| jq -r '
.items[]
| select(.spec.hostPID == true)
| [.metadata.name, (.spec.privileged // false)]
| @tsv' \
| awk 'BEGIN{print "PSP\tPRIVILEGED"}1'
else
echo "PodSecurityPolicy API not available; skipping PSP check."
fi

echo
echo "# Namespaces and their Pod Security Admission labels (if using PSA):"
kubectl get ns --show-labels

echo
echo "=== 3) RBAC ties: which subjects can create hostPID pods via PSP (if PSP present) ==="
if kubectl api-resources | grep -q "^podsecuritypolicies"; then
echo
echo "# ClusterRoleBindings referencing PSPs that allow hostPID:"
# list PSPs with hostPID=true
mapfile -t PSP_HOSTPID < <(kubectl get podsecuritypolicies.policy -o json \
| jq -r '.items[] | select(.spec.hostPID == true) | .metadata.name')

if ((${#PSP_HOSTPID[@]} == 0)); then
echo "No PSPs with hostPID=true found."
else
printf 'PSPs with hostPID=true: %s\n' "${PSP_HOSTPID[@]}"
echo
kubectl get clusterroles,roles -o json \
| jq -r '
.items[]
| select(.rules != null)
| {
kind: .kind,
name: .metadata.name,
rules: (.rules[]? | select(.resources[]? == "podsecuritypolicies") )
}
| select(.rules != null)
| [.kind, .name]
| @tsv' \
| while IFS=$'\t' read -r KIND NAME; do
echo "## $KIND/$NAME"
kubectl describe "$KIND" "$NAME" | sed 's/^/ /'
echo
done
fi
else
echo "PodSecurityPolicy API not available; skipping PSP/RBAC tie analysis."
fi

echo
echo "=== Interpretation guidance ==="
cat <<'EOF'
Rows indicating a potential problem:

1) Workloads
- Any pod or controller listed with hostPID=true is a candidate for review.
- Focus on non-infrastructure namespaces (not kube-system or system add-ons) unless justified.

2) PSP / Policy
- Any PSP with spec.hostPID: true allows creation of hostPID pods for subjects bound to it.
- In PSA (Pod Security Admission) environments, namespaces without restrictive labels
(e.g., 'pod-security.kubernetes.io/enforce=restricted') may allow policies that include hostPID.

3) RBAC ties
- Any ClusterRole/Role that can 'use' a PSP allowing hostPID, and any subjects bound to such roles,
can create hostPID pods. This should be tightly scoped and explicitly justified.

This script does NOT change any configuration. Use it to identify where hostPID is used or allowed,
then manually decide which uses are justified and where to tighten policies or manifests.
EOF

Additional Reading:​