Minimize Admission Of Windows HostProcess Containers
More Info:
Do not generally permit Windows containers to be run with the hostProcess flag set to true
Risk Level
Low
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Discover current usage of HostProcess in the cluster
- Run on: any machine with kubectl access
- Command (find all pods using
hostProcess: true):kubectl get pods -A -o jsonpath='{range .items[?(@.spec.securityContext.windowsOptions.hostProcess==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}' - Command (find all containers using
hostProcess: trueat container level):kubectl get pods -A -o json | jq -r '.items[]| select(.spec.containers[]?.securityContext?.windowsOptions?.hostProcess == trueor .spec.initContainers[]?.securityContext?.windowsOptions?.hostProcess == true)| .metadata.namespace + "\t" + .metadata.name' | sort -u
-
Identify namespaces with user workloads and HostProcess usage
- Run on: any machine with kubectl access
- Command (list namespaces that currently have any HostProcess pod/container):
kubectl get pods -A -o json | jq -r '.items[]| select(.spec.securityContext?.windowsOptions?.hostProcess == trueor (.spec.containers[]? | select(.securityContext?.windowsOptions?.hostProcess == true))or (.spec.initContainers[]? | select(.securityContext?.windowsOptions?.hostProcess == true)))| .metadata.namespace' | sort -u
- Separately, determine which of these namespaces are “user workload” namespaces (vs. system/addon namespaces) according to your cluster’s conventions.
-
Review whether HostProcess is truly required in each affected user namespace
- For each user namespace found in step 2, list workloads and their images:
NAMESPACE=<namespace-name>kubectl get pods -n "$NAMESPACE" -o widekubectl get pods -n "$NAMESPACE" -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
- For each workload using HostProcess (from step 1), review its purpose (docs, owners, code) and decide:
- Is HostProcess strictly needed (e.g., node management/diagnostics agents)?
- Can it be redesigned to run without HostProcess (e.g., normal Windows container, sidecar pattern, or different privilege model)?
- Document which specific deployments/DaemonSets, if any, are permitted to continue using HostProcess.
- For each user namespace found in step 2, list workloads and their images:
-
Define or tighten admission policy per user namespace to restrict HostProcess
- If you use Gatekeeper (OPA) or another admission controller, create or update a policy to deny new pods in target namespaces when any container or pod-level context has
securityContext.windowsOptions.hostProcess: true, with explicit exceptions only for approved workloads from step 3. Example (Gatekeeper ConstraintTemplate/Constraint) must be implemented according to your existing policy framework; apply via manifest:kubectl apply -f <your-admission-policy-manifest>.yaml - If you have no admission policy framework, formally record that gap and plan adoption of a policy mechanism; without an admission controller there is no reliable automatic block on HostProcess.
- If you use Gatekeeper (OPA) or another admission controller, create or update a policy to deny new pods in target namespaces when any container or pod-level context has
-
Remove or reconfigure unauthorized HostProcess workloads
- For any workload in user namespaces where HostProcess is not justified:
- Edit workload to remove HostProcess and redeploy:
In the editor, remove or set toNAMESPACE=<namespace-name>WORKLOAD=<deployment-or-daemonset-name># Example for a Deployment:kubectl -n "$NAMESPACE" edit deployment "$WORKLOAD"
falseany.spec.template.spec.securityContext.windowsOptions.hostProcess, and any container-level.securityContext.windowsOptions.hostProcess. Save and exit to trigger rollout. - If the workload’s function is no longer needed, delete it:
kubectl -n "$NAMESPACE" delete deployment <name># orkubectl -n "$NAMESPACE" delete daemonset <name>
- Edit workload to remove HostProcess and redeploy:
- For any workload in user namespaces where HostProcess is not justified:
-
Verify that HostProcess usage is minimized and policy is effective
- Run on: any machine with kubectl access
- Re-run the evidence commands to confirm no unauthorized HostProcess pods remain:
kubectl get pods -A -o jsonpath='{range .items[?(@.spec.securityContext.windowsOptions.hostProcess==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'kubectl get pods -A -o json | jq -r '.items[]| select(.spec.containers[]?.securityContext?.windowsOptions?.hostProcess == trueor .spec.initContainers[]?.securityContext?.windowsOptions?.hostProcess == true)| .metadata.namespace + "\t" + .metadata.name' | sort -u
- Attempt to create a simple test pod in a protected user namespace with
hostProcess: trueand confirm that the admission policy rejects it (or, if you have no admission controller, explicitly record that no technical enforcement exists and rely on process controls).
Using kubectl
# 1) List all namespaces that might host user workloads
# (run on any machine with kubectl access)
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' \
| grep -Ev '^(kube-system|kube-public|kube-node-lease|default)$'
Output to review:
A list of namespaces where you should evaluate whether Windows HostProcess containers are appropriate. Any namespace that runs multi-tenant or untrusted workloads should be treated as high-risk if HostProcess is allowed.
# 2) Find existing pods using Windows HostProcess in all namespaces
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.securityContext.windowsOptions.hostProcess}{"\n"}{end}' \
| grep -w "true" || echo "No pods with hostProcess=true found"
Problem indication:
Any line printed (not including the "No pods..." message) shows a pod with hostProcess=true. For each such pod, you must decide whether it is strictly necessary and whether it’s placed only in namespaces where this level of privilege is acceptable.
# 3) Inspect deployments/statefulsets/daemonsets that may create HostProcess pods
# Deployments
kubectl get deploy -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.template.spec.securityContext.windowsOptions.hostProcess}{"\n"}{end}' \
| grep -w "true" || echo "No deployments with hostProcess=true found"
# StatefulSets
kubectl get statefulset -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.template.spec.securityContext.windowsOptions.hostProcess}{"\n"}{end}' \
| grep -w "true" || echo "No statefulsets with hostProcess=true found"
# DaemonSets
kubectl get daemonset -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.template.spec.securityContext.windowsOptions.hostProcess}{"\n"}{end}' \
| grep -w "true" || echo "No daemonsets with hostProcess=true found"
Problem indication:
Any workload object listed with hostProcess=true will continuously create HostProcess pods. You must review whether each such workload is necessary and whether its namespace should allow HostProcess at all.
# 4) Check PodSecurity or Pod Security Admission labels on each namespace
kubectl get ns --show-labels
Problem indication:
Look for labels like pod-security.kubernetes.io/enforce, pod-security.kubernetes.io/audit, or pod-security.kubernetes.io/warn.
If namespaces running untrusted or general user workloads have no PodSecurity labels, or are set to a profile that does not restrict HostProcess usage, this is a risk. A human must decide if stricter profiles should be applied.
# 5) Discover any Gatekeeper/PSP-like policies that may already restrict HostProcess
# Gatekeeper (if installed)
kubectl get constrainttemplates.constraints.gatekeeper.sh -A 2>/dev/null || echo "No Gatekeeper constraint templates found (or Gatekeeper not installed)"
kubectl get constraints -A 2>/dev/null || echo "No Gatekeeper constraints found"
# Legacy PodSecurityPolicies (if still present)
kubectl get psp 2>/dev/null || echo "No PodSecurityPolicies found (or API disabled)"
Problem indication:
If no constraints or PSPs are found that mention windowsOptions or hostProcess, then there may be no central policy preventing arbitrary use of Windows HostProcess containers. A human must determine whether additional policy is required.
# 6) Detailed review of a specific namespace (replace with the namespace under review)
kubectl get pods -n NAMESPACE -o yaml | grep -nE 'windowsOptions:|hostProcess:' -n
Problem indication:
Any occurrence of hostProcess: true in a namespace that is intended for regular or multi-tenant workloads is a concern. You must decide whether to redesign these workloads or move them to tightly controlled namespaces.
Verification after changes (policy or workload updates done manually):
# Re-run pod/workload scans to confirm no unexpected HostProcess usage
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.securityContext.windowsOptions.hostProcess}{"\n"}{end}' \
| grep -w "true" || echo "No pods with hostProcess=true found"
kubectl get deploy -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.template.spec.securityContext.windowsOptions.hostProcess}{"\n"}{end}' \
| grep -w "true" || echo "No deployments with hostProcess=true found"
kubectl get statefulset -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.template.spec.securityContext.windowsOptions.hostProcess}{"\n"}{end}' \
| grep -w "true" || echo "No statefulsets with hostProcess=true found"
kubectl get daemonset -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.template.spec.securityContext.windowsOptions.hostProcess}{"\n"}{end}' \
| grep -w "true" || echo "No daemonsets with hostProcess=true found"
If the only remaining hostProcess=true usages are in tightly controlled, explicitly approved namespaces, and admission policies for user-workload namespaces are in place (as manually confirmed), the finding is addressed.
Automation
#!/usr/bin/env bash
# Report Windows HostProcess usage across all namespaces
# Run on: any machine with kubectl access and current context set to the target cluster
set -euo pipefail
echo "Scanning Pods for windowsOptions.hostProcess = true ..."
echo "------------------------------------------------------------------"
kubectl get pods --all-namespaces -o json \
| jq -r '
.items[]
| . as $pod
| (
($pod.spec.containers // []) +
($pod.spec.initContainers // []) +
($pod.spec.ephemeralContainers // [])
)[]
| select(
.securityContext.windowsOptions.hostProcess == true
)
| [
$pod.metadata.namespace,
$pod.metadata.name,
.name,
($pod.spec.nodeName // "N/A"),
($pod.spec.securityContext.windowsOptions.os // "N/A"),
"hostProcess=true"
]
| @tsv' | sort | column -t \
|| echo "No Pods with windowsOptions.hostProcess=true found or error running query."
echo
echo "Scanning PodTemplates (e.g., Deployments, DaemonSets, StatefulSets, Jobs, CronJobs) for hostProcess=true ..."
echo "------------------------------------------------------------------"
kubectl get deploy,ds,sts,job,cronjob --all-namespaces -o json \
| jq -r '
.items[]
| . as $obj
| .spec.template as $tpl
| (
($tpl.spec.containers // []) +
($tpl.spec.initContainers // []) +
($tpl.spec.ephemeralContainers // [])
)[]
| select(
.securityContext.windowsOptions.hostProcess == true
)
| [
$obj.metadata.namespace,
$obj.kind,
$obj.metadata.name,
.name,
($tpl.spec.nodeName // "N/A"),
($tpl.spec.securityContext.windowsOptions.os // "N/A"),
"hostProcess=true"
]
| @tsv' | sort | column -t \
|| echo "No PodTemplates with windowsOptions.hostProcess=true found or error running query."
echo
echo "Summary of namespaces with hostProcess=true workloads ..."
echo "------------------------------------------------------------------"
kubectl get pods --all-namespaces -o json \
| jq -r '
.items[]
| . as $pod
| (
($pod.spec.containers // []) +
($pod.spec.initContainers // []) +
($pod.spec.ephemeralContainers // [])
)[]
| select(
.securityContext.windowsOptions.hostProcess == true
)
| $pod.metadata.namespace
' | sort -u || true
How to interpret the output
- Any line in the first two sections indicates a workload that is running or configured with
securityContext.windowsOptions.hostProcess=true.- Columns are:
NAMESPACE POD/WORKLOAD_NAME CONTAINER_NAME NODE OS hostProcess=true.
- Columns are:
- The final section lists namespaces that currently admit HostProcess workloads; these namespaces need manual review and, if not strictly required, admission policies to restrict
windowsOptions.hostProcess=trueas per the benchmark guidance.