> ## 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 HostPath Volumes

### More Info:

hostPath volumes mount node filesystem paths into containers, enabling access to sensitive host files and escape. Restrict their admission.

### 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 current use of `hostPath` volumes across the cluster**
           * Run on: any machine with kubectl access
           * Command:
             ```bash theme={null}
             kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{range .spec.volumes[?(@.hostPath)]}{"  hostPath: "}{.hostPath.path}{"\n"}{end}{end}' | grep -B1 'hostPath' || echo "No hostPath volumes found"
             ```
           * Review which namespaces and pods are using `hostPath`, and whether they are system components (e.g., in `kube-system`) or user workloads.

        2. **Determine which namespaces require protection (user workloads)**
           * Run on: any machine with kubectl access
           * Command to list namespaces:
             ```bash theme={null}
             kubectl get namespaces
             ```
           * Classify namespaces into:
             * System/control-plane (e.g., `kube-system`, `kube-node-lease`, `kube-public`)
             * Add-on/infra namespaces where `hostPath` may be intentionally required
             * User workload namespaces (targets for strong restriction)

        3. **Design the admission policy for `hostPath` in user namespaces**
           * Decide, per user namespace, whether:
             * `hostPath` should be completely disallowed, or
             * Only specific, narrowly scoped paths are allowed (e.g., a CSI driver)
           * If using an admission controller framework (e.g., ValidatingAdmissionPolicy, Kyverno, Gatekeeper), select the mechanism you will use to enforce `hostPath` restrictions in those namespaces.

        4. **Implement or update policies to restrict `hostPath` in user namespaces**
           * Run on: any machine with kubectl access
           * Example: create a strict `ValidatingAdmissionPolicy` that denies all `hostPath` volumes in selected namespaces (adjust namespaces as needed):
             ```bash theme={null}
             cat << 'EOF' | kubectl apply -f -
             apiVersion: admissionregistration.k8s.io/v1
             kind: ValidatingAdmissionPolicy
             metadata:
               name: deny-hostpath-volumes
             spec:
               failurePolicy: Fail
               matchConstraints:
                 resourceRules:
                   - apiGroups: [""]
                     apiVersions: ["v1"]
                     operations: ["CREATE", "UPDATE"]
                     resources: ["pods"]
               validations:
                 - expression: "!(has(object.spec.volumes) && object.spec.volumes.exists(v, has(v.hostPath)))"
                   message: "hostPath volumes are not allowed in this cluster/namespace."
             ---
             apiVersion: admissionregistration.k8s.io/v1
             kind: ValidatingAdmissionPolicyBinding
             metadata:
               name: deny-hostpath-volumes-binding
             spec:
               policyName: deny-hostpath-volumes
               validationActions: [ "Deny" ]
               matchResources:
                 namespaceSelector:
                   matchExpressions:
                     - key: kubernetes.io/metadata.name
                       operator: In
                       values:
                         - user-namespace-1
                         - user-namespace-2
             EOF
             ```
           * If you must allow specific `hostPath` paths, adjust the `expression` to allow only those paths instead of denying all `hostPath`.

        5. **Test enforcement and handle existing workloads**
           * Run on: any machine with kubectl access
           * Try to deploy a test pod with a `hostPath` volume into a protected namespace and confirm it is rejected:
             ```bash theme={null}
             cat << 'EOF' | kubectl apply -f -
             apiVersion: v1
             kind: Pod
             metadata:
               name: hostpath-test-deny
               namespace: user-namespace-1
             spec:
               containers:
                 - name: test
                   image: busybox
                   command: ["sleep", "3600"]
                   volumeMounts:
                     - name: hp
                       mountPath: /mnt
               volumes:
                 - name: hp
                   hostPath:
                     path: /tmp
             EOF
             ```
           * For existing pods using `hostPath` in user namespaces, review whether they are justified; if not, plan to:
             * Update the workloads to remove `hostPath`, then
             * Redeploy them so that policy is applied on the next create/update.

        6. **Re-verify cluster state after changes**
           * Run on: any machine with kubectl access
           * Confirm no unintended `hostPath` use remains in user namespaces:
             ```bash theme={null}
             kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{range .spec.volumes[?(@.hostPath)]}{"  hostPath: "}{.hostPath.path}{"\n"}{end}{end}' | grep -B1 'hostPath' || echo "No hostPath volumes found"
             ```
           * Confirm the admission policy objects are present and active:
             ```bash theme={null}
             kubectl get validatingadmissionpolicies
             kubectl get validatingadmissionpolicybindings
             ```
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all namespaces that may need policy
        # Run on: any machine with kubectl access
        kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'
        ```

        Look for all namespaces that host user workloads (typically everything except `kube-*`, `kubernetes-dashboard`, `istio-system`, etc., depending on your environment). Those are the ones that must have a restriction policy.

        ***

        ```bash theme={null}
        # 2) Check for Pods currently using hostPath volumes (cluster-wide)
        # Run on: any machine with kubectl access
        kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{range .spec.volumes[*]}{"  volume: "}{.name}{" type: "}{.hostPath.path}{"\n"}{end}{"---\n"}{end}' 2>/dev/null | grep hostPath -B1
        ```

        Problem indication:

        * Any line showing `hostPath.path` (e.g. `/var/run/docker.sock`, `/`, `/var/lib/kubelet`, `/etc`, etc.) is a Pod that mounts the node filesystem.
        * Each such Pod must be manually reviewed for necessity and scope of the hostPath.

        ***

        ```bash theme={null}
        # 3) For a specific namespace, list only Pods with hostPath
        # Replace <namespace>
        kubectl get pod -n <namespace> -o json | \
          jq -r '.items[] | select(.spec.volumes[]? | has("hostPath")) |
                 .metadata.name as $p |
                 .spec.volumes[]? |
                 select(has("hostPath")) |
                 "\($p) \t volume=\(.name) \t path=\(.hostPath.path)"'
        ```

        Problem indication:

        * Any user workload namespace with Pods listed here is using hostPath.
        * Broad or sensitive paths (like `/`, `/var`, `/etc`, `/var/lib`, `/var/run`) are higher risk.

        ***

        ```bash theme={null}
        # 4) Inspect one Pod’s full spec to understand why hostPath is used
        # Replace <namespace> and <pod>
        kubectl get pod -n <namespace> <pod> -o yaml
        ```

        Problem indication:

        * `.spec.volumes[*].hostPath.path` mounted with `hostPath.type: ""` or `Directory` without constraints.
        * Combined with `securityContext.privileged: true`, `allowPrivilegeEscalation: true`, or `runAsUser: 0` indicates high breakout risk.

        ***

        ```bash theme={null}
        # 5) Check for existing admission policies that mention hostPath (PodSecurityPolicies, if present)
        kubectl get podsecuritypolicies.policy -o yaml 2>/dev/null | \
          grep -nE 'hostPath|volumes' -n || echo "No PodSecurityPolicies or no hostPath references found"
        ```

        Problem indication:

        * Absence of PSPs (on clusters that still support them) or PSPs that allow `hostPath` volumes without restriction in namespaces where you found hostPath Pods.

        ***

        ```bash theme={null}
        # 6) Check namespace-level Pod Security admission (if enabled in the cluster)
        # Replace <namespace>
        kubectl get ns <namespace> -o yaml | grep -i 'pod-security'
        ```

        Problem indication:

        * For user namespaces, labels like `pod-security.kubernetes.io/enforce: privileged` (or no labels at all) combined with hostPath usage means there is no baseline/restricted control to constrain such volumes.

        ***

        ```bash theme={null}
        # 7) Check Validating/MutatingWebhookConfigurations for policies handling hostPath
        kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations -o yaml 2>/dev/null | \
          grep -n 'hostPath' -n || echo "No admission webhooks explicitly referencing hostPath found"
        ```

        Problem indication:

        * No admission webhooks addressing `hostPath` in a cluster where you depend on external policy (OPA Gatekeeper, Kyverno, etc.) to restrict such volumes.

        ***

        Use these commands to:

        * Enumerate where hostPath is used.
        * Determine which namespaces run hostPath workloads.
        * Verify whether any admission control mechanism currently restricts hostPath.
          Human review is required to decide which hostPath uses are justified and what policies to apply to each namespace.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Report use of hostPath volumes across all namespaces
        # Run on: any machine with kubectl access and correct KUBECONFIG

        set -euo pipefail

        echo "Scanning all pods for hostPath volume usage..."
        echo

        # 1) High‑level summary: which pods use hostPath and how many
        echo "=== Summary of pods using hostPath volumes ==="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                pod: .metadata.name,
                hostPaths: (
                  [.spec.volumes[]
                    | select(.hostPath != null)
                    | {name, path: .hostPath.path, type: (.hostPath.type // "")}
                  ] // []
                )
              }
            | select(.hostPaths | length > 0)
            | .ns + "\t" + .pod + "\t" + ( (.hostPaths | length) | tostring )
          ' \
          | awk 'BEGIN { print "NAMESPACE\tPOD\tHOSTPATH_VOLUME_COUNT" }1'
        echo

        # 2) Detailed report: each hostPath volume with path/type and pod SA
        echo "=== Detailed hostPath usage (one line per hostPath volume) ==="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | . as $pod
            | ($pod.spec.volumes // [])
            | map(select(.hostPath != null))
            | .[]
            | [
                $pod.metadata.namespace,
                $pod.metadata.name,
                ($pod.spec.serviceAccountName // "default"),
                .name,
                .hostPath.path,
                (.hostPath.type // "")
              ]
            | @tsv
          ' \
          | awk '
            BEGIN {
              OFS="\t";
              print "NAMESPACE","POD","SERVICEACCOUNT","VOLUME_NAME","HOSTPATH_PATH","HOSTPATH_TYPE"
            }
            { print }
          '
        echo

        # 3) Optional: filter out known system namespaces (tune as needed)
        echo "=== Non-system namespaces using hostPath (candidate review targets) ==="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | select(.metadata.namespace
                     | IN("kube-system","kube-public","kube-node-lease") | not)
            | . as $pod
            | ($pod.spec.volumes // [])
            | map(select(.hostPath != null))
            | .[]
            | [
                $pod.metadata.namespace,
                $pod.metadata.name,
                ($pod.spec.serviceAccountName // "default"),
                .name,
                .hostPath.path,
                (.hostPath.type // "")
              ]
            | @tsv
          ' \
          | awk '
            BEGIN {
              OFS="\t";
              print "NAMESPACE","POD","SERVICEACCOUNT","VOLUME_NAME","HOSTPATH_PATH","HOSTPATH_TYPE"
            }
            { print }
          '
        echo "Scan complete."
        ```

        **How to interpret the output**

        * Any line in the summaries indicates a pod that is using a `hostPath` volume.
        * Focus review on:
          * Non‑system namespaces (third section).
          * Sensitive paths (examples: `/`, `/var/run`, `/var/lib/kubelet`, `/etc`, `/var/lib/docker`, `/var/run/docker.sock`, `/run/containerd`, `/var/lib/containerd`, `/host`, `/proc`, `/sys`).
          * Pods running under broadly scoped or shared service accounts.
        * Pods in user/workload namespaces using `hostPath` are candidates for:
          * Refactoring to use PVCs or other volume types.
          * Being constrained by admission policy (e.g., Pod Security / ValidatingAdmissionPolicy / external admission controllers) to prevent or tightly control `hostPath` usage.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
