> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Minimize The Admission Of Windows HostProcess Containers

### More Info:

Windows HostProcess containers run with host-level privileges on the node. Restrict their admission in workload namespaces.

### Risk Level

High

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify Windows HostProcess workloads in user namespaces**
           * Run on: any machine with kubectl access
           * Command (lists pods that explicitly request HostProcess):
             ```bash theme={null}
             kubectl get pods --all-namespaces -o json \
               | jq -r '
                 .items[]
                 | select(.spec.securityContext.windowsOptions.hostProcess == true
                          or ([.spec.containers[], (.spec.initContainers // [])[]?
                                | select(.securityContext.windowsOptions.hostProcess == true)] | length) > 0)
                 | [.metadata.namespace, .metadata.name] | @tsv
               '
             ```
           * Repeat, but exclude known infrastructure namespaces (adjust as appropriate for your cluster):
             ```bash theme={null}
             kubectl get pods --all-namespaces -o json \
               | jq -r '
                 .items[]
                 | select(.metadata.namespace as $ns
                          | ($ns | IN("kube-system","kube-public","kube-node-lease","kube-*","azure-*","aws-*","gke-*") | not))
                 | select(.spec.securityContext.windowsOptions.hostProcess == true
                          or ([.spec.containers[], (.spec.initContainers // [])[]?
                                | select(.securityContext.windowsOptions.hostProcess == true)] | length) > 0)
                 | [.metadata.namespace, .metadata.name] | @tsv
               '
             ```

        2. **Decide where HostProcess containers are allowed (policy design)**
           * For each *user* namespace, decide one of:
             * **No HostProcess allowed** (typical for most workloads).
             * **HostProcess allowed only for specific, justified workloads** (e.g., node maintenance agents).
           * Document for each namespace whether HostProcess is: *forbidden*, *tightly controlled*, or *not yet decided*.

        3. **Review and, if needed, create/adjust admission controls (Pod Security or other)**
           * If using built-in Pod Security Admission labels, for each user namespace that should **forbid HostProcess**, label it with at least `baseline` or `restricted` (both disallow HostProcess):
             ```bash theme={null}
             # Example: enforce restricted profile, which disallows Windows HostProcess
             kubectl label namespace <USER_NAMESPACE> \
               pod-security.kubernetes.io/enforce=restricted \
               pod-security.kubernetes.io/enforce-version=latest \
               --overwrite
             ```
           * If you use another admission controller (e.g., Gatekeeper, Kyverno), review existing policies to ensure they *deny* pods with `.securityContext.windowsOptions.hostProcess: true` in any namespace that should not allow them. Use:
             ```bash theme={null}
             kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io -o yaml
             kubectl get constrainttemplates,constraints,clusterpolicies,policies -A -o yaml 2>/dev/null | less
             ```
           * Where HostProcess must be allowed, design *exception* rules (e.g., labels/annotations on specific namespaces or service accounts) and ensure policies only allow HostProcess under those constrained conditions.

        4. **Implement or tighten deny policies for HostProcess in user namespaces**
           * Example Kyverno ClusterPolicy to deny all HostProcess containers except in explicitly allowed namespaces (`windows-hostprocess-allowed=true`):
             ```yaml theme={null}
             apiVersion: kyverno.io/v1
             kind: ClusterPolicy
             metadata:
               name: deny-windows-hostprocess
             spec:
               validationFailureAction: enforce
               background: true
               rules:
               - name: deny-hostprocess
                 match:
                   any:
                   - resources:
                       kinds:
                       - Pod
                 exclude:
                   any:
                   - resources:
                       namespaces:
                       - kube-system
                   - resources:
                       namespaceSelector:
                         matchLabels:
                           windows-hostprocess-allowed: "true"
                 validate:
                   message: "Windows HostProcess containers are not allowed in this namespace."
                   pattern:
                     spec:
                       securityContext:
                         windowsOptions:
                           hostProcess: "false"
                       containers:
                       - (name): "*"
                         securityContext:
                           windowsOptions:
                             hostProcess: "false"
                       =(initContainers):
                       - (name): "*"
                         securityContext:
                           windowsOptions:
                             hostProcess: "false"
             ```
           * Apply (adjust as needed for your own policy engine):
             ```bash theme={null}
             kubectl apply -f deny-windows-hostprocess.yaml
             ```

        5. **Handle existing HostProcess pods in disallowed namespaces**
           * For each pod from step 1 that is in a namespace now marked to forbid HostProcess:
             * Confirm with the owner whether the HostProcess capability is truly required.
             * If not required: update the pod spec / owning controller (Deployment, DaemonSet, Job, etc.) to remove `.securityContext.windowsOptions.hostProcess: true`, then redeploy.
             * If required: either
               * move the workload to a dedicated namespace explicitly marked to allow HostProcess (e.g., label `windows-hostprocess-allowed=true`), and keep strict controls there, or
               * adjust your policy design to formally permit it with documented justification.

        6. **Verify that HostProcess admission is now minimized**
           * Re-run the detection command to confirm there are no HostProcess pods in namespaces where they should be forbidden:
             ```bash theme={null}
             kubectl get pods --all-namespaces -o json \
               | jq -r '
                 .items[]
                 | select(.spec.securityContext.windowsOptions.hostProcess == true
                          or ([.spec.containers[], (.spec.initContainers // [])[]?
                                | select(.securityContext.windowsOptions.hostProcess == true)] | length) > 0)
                 | [.metadata.namespace, .metadata.name] | @tsv
               '
             ```
           * Independently test admission by attempting to create a sample HostProcess pod in a user namespace that should reject it and confirm it fails with a policy error:
             ```bash theme={null}
             cat <<'EOF' | kubectl apply -f -
             apiVersion: v1
             kind: Pod
             metadata:
               name: test-hostprocess-deny
               namespace: <USER_NAMESPACE_THAT_SHOULD_DENY>
             spec:
               os:
                 name: windows
               securityContext:
                 windowsOptions:
                   hostProcess: true
               containers:
               - name: test
                 image: mcr.microsoft.com/windows/nanoserver:ltsc2022
                 command: ["cmd", "/c", "ping -t 127.0.0.1"]
                 securityContext:
                   windowsOptions:
                     hostProcess: true
             EOF
             ```
             Confirm the admission controller rejects this pod creation.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all namespaces that may host user workloads
        #    Run on: any machine with kubectl access
        kubectl get ns

        # 2) For each user-workload namespace, list policies that might control HostProcess:
        #    (ValidatingWebhookConfiguration, MutatingWebhookConfiguration, and constraints)
        kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations,validatingpolicies,validatingadmissionpolicies,clusterrolebindings,rolebindings -A

        # 3) Identify current HostProcess usage in all namespaces
        kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.securityContext.windowsOptions.hostProcess}{"\n"}{end}' \
          | grep -iw "true" || echo "No pods with windowsOptions.hostProcess=true found"

        # 4) Also check container-level windowsOptions on existing pods
        kubectl get pods -A -o json \
          | jq -r '
            .items[]
            | . as $pod
            | ($pod.spec.containers[]?, $pod.spec.initContainers[]?)
            | select(.securityContext.windowsOptions.hostProcess == true)
            | [$pod.metadata.namespace, $pod.metadata.name, .name, "true"]
            | @tsv
          '

        # 5) Inspect a specific namespace for HostProcess-true pods (replace NAMESPACE)
        kubectl get pods -n kube-system -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.securityContext.windowsOptions.hostProcess}{"\n"}{end}' \
          | grep -iw "true" || echo "No HostProcess pods in kube-system"

        # 6) Look for policies that explicitly mention windowsOptions/hostProcess
        kubectl get validatingwebhookconfigurations -o yaml | grep -nE 'windowsOptions|hostProcess' || echo "No hostProcess-related validating webhooks found"
        kubectl get mutatingwebhookconfigurations -o yaml   | grep -nE 'windowsOptions|hostProcess' || echo "No hostProcess-related mutating webhooks found"

        # 7) If using ValidatingAdmissionPolicy (v1), inspect for hostProcess conditions
        kubectl get validatingadmissionpolicies -o yaml | grep -nE 'windowsOptions|hostProcess' || echo "No hostProcess-related ValidatingAdmissionPolicies found"
        ```

        Interpretation (what indicates a problem):

        * Step 3 / 4 / 5 outputs:
          * Any line where the last column is `true` means there is at least one Windows HostProcess container currently running in that namespace. That is *not automatically wrong*, but such pods should be reviewed and justified; user-workload namespaces should generally not contain HostProcess containers unless there is a documented, approved need.

        * Step 2 / 6 / 7 outputs:
          * If there are **no** Validating/Mutating webhooks or ValidatingAdmissionPolicies that reference `windowsOptions` or `hostProcess`, then there is likely **no explicit admission control** restricting Windows HostProcess containers.
          * In user-workload namespaces, “no hostProcess-related policies found” combined with evidence of HostProcess-true pods from steps 3–5 suggests a policy gap that needs human review and a possible policy design.

        Verification after any policy changes:

        ```bash theme={null}
        # Re-check for admitted HostProcess containers
        kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.securityContext.windowsOptions.hostProcess}{"\n"}{end}' \
          | grep -iw "true" || echo "No pods with windowsOptions.hostProcess=true found"

        # Confirm that at least one admission policy references hostProcess
        kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations,validatingadmissionpolicies -A -o yaml \
          | grep -nE 'windowsOptions|hostProcess' || echo "No hostProcess-related admission controls detected"
        ```

        These commands only surface state; a human must decide which namespaces may legitimately allow Windows HostProcess containers and what policy to apply.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Purpose:
        #   Report Windows HostProcess containers across all namespaces for review.
        #   Runs with: any machine with kubectl access and cluster-wide read permissions.

        set -euo pipefail

        echo "Scanning for Windows HostProcess containers in all namespaces..."
        echo

        # 1) List all pods that declare any HostProcess container
        kubectl get pods -A -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                pod: .metadata.name,
                node: (.spec.nodeName // "UNSCHEDULED"),
                os:   (.spec.nodeSelector."kubernetes.io/os"
                       // .spec.nodeSelector."kubernetes.io/arch"
                       // "unknown"),
                containers: (
                  [
                    (.spec.containers[]?        | {name, hp: (.securityContext.windowsOptions.hostProcess // false), type:"container"}),
                    (.spec.initContainers[]?    | {name, hp: (.securityContext.windowsOptions.hostProcess // false), type:"initContainer"}),
                    (.spec.ephemeralContainers[]? | {name, hp: (.securityContext.windowsOptions.hostProcess // false), type:"ephemeralContainer"})
                  ]
                )
              }
            | select([.containers[].hp] | any)
            | [
                .ns,
                .pod,
                .node,
                .os,
                (
                  .containers
                  | map(select(.hp == true) | "\(.type):\(.name)")
                  | join(",")
                )
              ]
            | @tsv
          ' 2>/dev/null \
          | sort -k1,1 -k2,2 \
          | awk 'BEGIN {
              FS="\t";
              printf "%-30s %-40s %-35s %-12s %s\n", "NAMESPACE", "POD", "NODE", "OS", "HOSTPROCESS_CONTAINERS";
              print  "---------------------------------------------------------------------------------------------------------------------------------------";
            }
            {
              printf "%-30s %-40s %-35s %-12s %s\n", $1, $2, $3, $4, $5;
            }'

        echo
        echo "Detail per HostProcess pod (namespace/pod -> container -> spec fragment):"
        echo "---------------------------------------------------------------------------"

        # 2) Show focused spec fragments for each HostProcess container for deeper review
        kubectl get pods -A -o json \
          | jq -r '
            .items[]
            | select(
                [
                  (.spec.containers[]?.securityContext.windowsOptions.hostProcess // false),
                  (.spec.initContainers[]?.securityContext.windowsOptions.hostProcess // false),
                  (.spec.ephemeralContainers[]?.securityContext.windowsOptions.hostProcess // false)
                ] | any
              )
            | "---- " + .metadata.namespace + "/" + .metadata.name,
              (
                [
                  (.spec.containers[]? | select(.securityContext.windowsOptions.hostProcess == true)),
                  (.spec.initContainers[]? | select(.securityContext.windowsOptions.hostProcess == true)),
                  (.spec.ephemeralContainers[]? | select(.securityContext.windowsOptions.hostProcess == true))
                ]
              | .[]
              | "container: " + .name,
                "spec:",
                ( { securityContext: { windowsOptions: .securityContext.windowsOptions } } | tojson ),
                ""
              )
          '

        cat <<'EOF'

        Interpretation / what indicates a problem
        -----------------------------------------
        - Any row in the summary table above indicates a pod that includes at least one
          container with securityContext.windowsOptions.hostProcess = true.
        - These pods should exist only where there is an explicit, justified operational
          requirement (for example, privileged Windows node management DaemonSets).
        - Findings that typically require action:
          * HostProcess containers running in general-purpose application namespaces.
          * HostProcess containers that were not explicitly approved by the security team.
          * Namespaces where you expected policies (e.g., Pod Security Admission,
            Gatekeeper, Kyverno) to deny HostProcess but the table still shows pods.

        Use this report to:
        - Identify namespaces that need admission controls to restrict HostProcess usage.
        - Review each listed pod and decide whether to:
          * Keep it (documented exception) and enforce tight controls; or
          * Replace it with a non-HostProcess design and add/strengthen policies that
            block future HostProcess containers in that namespace.

        There is no safe, deterministic script to auto-fix these workloads: changes
        must be made per-namespace and per-application, based on operational needs.
        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
