> ## 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 Containers Sharing The Host IPC Namespace

### More Info:

Sharing the host IPC namespace exposes host inter-process communication to the container. Restrict hostIPC pods 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 pods using `hostIPC` (any machine with kubectl access):
           ```bash theme={null}
           kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.hostIPC==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
           ```

        2. For each affected pod, retrieve its owning controller (Deployment/StatefulSet/DaemonSet/Job) if any (any kubectl machine):
           ```bash theme={null}
           NAMESPACE=example-namespace
           POD=example-pod
           kubectl get pod "$POD" -n "$NAMESPACE" -o jsonpath='{.metadata.ownerReferences}' | jq
           ```
           If there is an ownerReference, plan to edit the controller; otherwise plan to edit the Pod manifest source (e.g., Helm chart, YAML in Git).

        3. Create or update a PodSecurity admission policy to deny `hostIPC` in workload namespaces (any kubectl machine; example for namespace `team-a` using Pod Security Standards via namespace labels):
           ```bash theme={null}
           kubectl label namespace team-a \
             pod-security.kubernetes.io/enforce=restricted \
             pod-security.kubernetes.io/enforce-version=latest \
             --overwrite
           ```
           The `restricted` profile forbids `hostIPC: true` in new or updated pods.

        4. For clusters without Pod Security Admission (or if you prefer Kyverno), create a policy manifest to block `hostIPC` (any kubectl machine). Example Kyverno ClusterPolicy:
           ```bash theme={null}
           cat > deny-hostipc.yaml << 'EOF'
           apiVersion: kyverno.io/v1
           kind: ClusterPolicy
           metadata:
             name: disallow-host-ipc
           spec:
             validationFailureAction: Enforce
             background: true
             rules:
               - name: deny-host-ipc
                 match:
                   any:
                     - resources:
                         kinds:
                           - Pod
                 validate:
                   message: "Using hostIPC is not allowed."
                   pattern:
                     spec:
                       hostIPC: "false"
           EOF

           kubectl apply -f deny-hostipc.yaml
           ```
           Adjust the policy or use your preferred admission controller (e.g., OPA/Gatekeeper) and scope it only to user workload namespaces as per your cluster design.

        5. Remove `hostIPC: true` from workload definitions (any kubectl machine, editing the actual source manifests/Helm values; example for a Deployment):
           ```bash theme={null}
           kubectl get deployment my-app -n team-a -o yaml > /tmp/my-app-deploy.yaml
           sed -i '/hostIPC: true/d' /tmp/my-app-deploy.yaml
           kubectl apply -f /tmp/my-app-deploy.yaml
           ```
           For pods directly created from YAML:
           ```bash theme={null}
           kubectl get pod example-pod -n team-a -o yaml > /tmp/example-pod.yaml
           sed -i '/hostIPC: true/d' /tmp/example-pod.yaml
           kubectl delete pod example-pod -n team-a
           kubectl apply -f /tmp/example-pod.yaml
           ```
           Review with application owners before removing `hostIPC` in case it is functionally required; if truly required, document and tightly scope exceptions in the admission policy.

        6. Verification (any machine with kubectl access):
           ```bash theme={null}
           kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace
           do
             pod_hostipc=$(kubectl get pod "${pod_name}" --namespace "${pod_namespace}" -o jsonpath='{.spec.hostIPC}' 2>/dev/null)
             if [ -z "${pod_hostipc}" ]; then
               pod_hostipc="false"
               echo "***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: true"
             else
               echo "***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: false"
             fi
           done
           ```
           Confirm that no output lines show `is_pod_hostipc: true is_compliant: false` in user workload namespaces.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) Create a baseline PodSecurityPolicy that forbids hostIPC
        #    (only if your cluster still uses PodSecurityPolicy)
        #    Run on: any machine with kubectl access
        cat << 'EOF' | kubectl apply -f -
        apiVersion: policy/v1beta1
        kind: PodSecurityPolicy
        metadata:
          name: restricted-no-hostipc
          annotations:
            seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default'
        spec:
          privileged: false
          hostIPC: false
          hostNetwork: false
          hostPID: false
          hostPorts: []
          runAsUser:
            rule: 'MustRunAsNonRoot'
          seLinux:
            rule: 'RunAsAny'
          fsGroup:
            rule: 'MustRunAs'
            ranges:
              - min: 1
                max: 65535
          supplementalGroups:
            rule: 'MustRunAs'
            ranges:
              - min: 1
                max: 65535
          volumes:
            - 'configMap'
            - 'downwardAPI'
            - 'emptyDir'
            - 'persistentVolumeClaim'
            - 'projected'
            - 'secret'
        EOF
        ```

        ```bash theme={null}
        # 2) Bind the PSP to workload namespaces (example: "apps" and "dev")
        #    Adjust the namespace list as needed.
        #    Run on: any machine with kubectl access

        # Create a ClusterRole that can use the restricted PSP
        cat << 'EOF' | kubectl apply -f -
        apiVersion: rbac.authorization.k8s.io/v1
        kind ClusterRole
        metadata:
          name: use-restricted-no-hostipc-psp
        rules:
          - apiGroups: ['policy']
            resources: ['podsecuritypolicies']
            verbs: ['use']
            resourceNames: ['restricted-no-hostipc']
        EOF
        ```

        ```bash theme={null}
        # Bind the above ClusterRole to all serviceaccounts in a namespace
        # Repeat (or template) for each workload namespace

        # Example for namespace "apps"
        cat << 'EOF' | kubectl apply -f -
        apiVersion: rbac.authorization.k8s.io/v1
        kind: RoleBinding
        metadata:
          name: use-restricted-no-hostipc-psp
          namespace: apps
        roleRef:
          apiGroup: rbac.authorization.k8s.io
          kind: ClusterRole
          name: use-restricted-no-hostipc-psp
        subjects:
          - kind: Group
            name: system:serviceaccounts:apps
            apiGroup: rbac.authorization.k8s.io
        EOF
        ```

        ```bash theme={null}
        # Example for namespace "dev"
        cat << 'EOF' | kubectl apply -f -
        apiVersion: rbac.authorization.k8s.io/v1
        kind: RoleBinding
        metadata:
          name: use-restricted-no-hostipc-psp
          namespace: dev
        roleRef:
          apiGroup: rbac.authorization.k8s.io
          kind: ClusterRole
          name: use-restricted-no-hostipc-psp
        subjects:
          - kind: Group
            name: system:serviceaccounts:dev
            apiGroup: rbac.authorization.k8s.io
        EOF
        ```

        ```bash theme={null}
        # 3) (Alternative / modern clusters) Enforce the Pod Security "restricted" profile,
        #    which also disallows hostIPC, on workload namespaces via Pod Security Admission.
        #    This does not require PSP and is the recommended approach on new clusters.

        # Example for namespace "apps"
        kubectl label namespace apps \
          pod-security.kubernetes.io/enforce=restricted \
          pod-security.kubernetes.io/enforce-version=latest \
          --overwrite

        # Example for namespace "dev"
        kubectl label namespace dev \
          pod-security.kubernetes.io/enforce=restricted \
          pod-security.kubernetes.io/enforce-version=latest \
          --overwrite
        ```

        ```bash theme={null}
        # 4) Remove hostIPC from existing Pod specs that use it (if any).
        #    For each non-system namespace, inspect and patch.

        # List pods currently using hostIPC=true
        kubectl get pods --all-namespaces -o json | \
          jq -r '.items[] | select(.spec.hostIPC==true) | "\(.metadata.namespace) \(.metadata.name)"'

        # For each pod found above, edit its controller (Deployment/StatefulSet/DaemonSet/Job)
        # and remove "hostIPC: true" from the pod spec. Example:

        # Example for Deployment "web" in namespace "apps"
        kubectl -n apps edit deploy web
        # (In the editor, delete the line "hostIPC: true" under spec.template.spec and save.)

        # If it's a bare Pod (no controller), delete and recreate it from a corrected manifest:
        kubectl -n apps delete pod <pod-name>
        # then apply a manifest that omits hostIPC.
        ```

        ```bash theme={null}
        # 5) Verification: confirm that no running pod has spec.hostIPC=true
        #    Run on: any machine with kubectl access
        kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace
        do
          pod_hostipc=$(kubectl get pod "${pod_name}" --namespace "${pod_namespace}" -o jsonpath='{.spec.hostIPC}' 2>/dev/null)
          if [ -z "${pod_hostipc}" ]; then
            pod_hostipc="false"
          fi
          echo "***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: $([ "${pod_hostipc}" = "false" ] && echo true || echo false)"
        done
        ```
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Purpose:
        #   Minimize admission of pods using hostIPC by:
        #     - Creating a baseline "deny-hostipc" Pod Security Policy (for PSP clusters)
        #     - Creating a "restricted-hostipc" Pod Security Policy (or namespace labels)
        #     - Labeling workload namespaces so that hostIPC is disallowed by default
        #
        # Scope:
        #   - Runs from any machine with kubectl access and appropriate RBAC.
        #   - Idempotent and safe to re-run.
        #
        # Notes:
        #   - This check is MANUAL; this script implements one reasonable, restrictive pattern.
        #   - You should review namespaces that are excluded from restriction (system namespaces).
        #   - If your cluster does NOT support PodSecurityPolicy (PSP), the script will fall back
        #     to Kubernetes Pod Security Admission labels (restricted profile) to prevent hostIPC.

        set -euo pipefail

        # -------- Configuration (edit as needed) --------

        # Namespaces to IGNORE (no hostIPC restrictions applied here by this script)
        IGNORED_NAMESPACES=(
          "kube-system"
          "kube-public"
          "kube-node-lease"
          "default"     # remove "default" here if you want to restrict it as well
        )

        # Label key used for workload namespaces to mark them as restricted.
        WORKLOAD_LABEL_KEY="security.k8s.io/hostipc-restricted"
        WORKLOAD_LABEL_VALUE="true"

        # PSP names (if PSP API is present)
        PSP_BASELINE_NAME="baseline-deny-hostipc"
        PSP_RESTRICTED_NAME="restricted-deny-hostipc"

        # -------- Helper functions --------

        ns_in_ignored_list() {
          local ns="$1"
          for ignored in "${IGNORED_NAMESPACES[@]}"; do
            if [[ "$ignored" == "$ns" ]]; then
              return 0
            fi
          done
          return 1
        }

        kubectl_api_exists() {
          local api="$1"
          if kubectl api-versions | grep -q "^${api}"; then
            return 0
          fi
          return 1
        }

        # -------- Detect PSP support and Pod Security Admission --------

        echo "[INFO] Detecting PodSecurityPolicy (PSP) support..."
        PSP_SUPPORTED=false
        if kubectl_api_exists "policy/v1beta1"; then
          if kubectl api-resources | awk '{print $1}' | grep -qx "podsecuritypolicies"; then
            PSP_SUPPORTED=true
            echo "[INFO] PSP is supported by this cluster."
          fi
        fi

        echo "[INFO] Detecting Pod Security Admission support (Pod Security Standards labels)..."
        PSA_SUPPORTED=false
        if kubectl_api_exists "policy/v1"; then
          PSA_SUPPORTED=true
          echo "[INFO] policy/v1 is present; assuming Pod Security Admission is enabled or available."
        fi

        if [[ "$PSP_SUPPORTED" == "false" && "$PSA_SUPPORTED" == "false" ]]; then
          echo "[WARN] Neither PodSecurityPolicy nor Pod Security Admission (PSS labels) could be confirmed."
          echo "[WARN] This script cannot enforce hostIPC restrictions automatically in this cluster."
          echo "[WARN] Please refer to the Manual Steps section for alternative enforcement (e.g., OPA/Gatekeeper or Kyverno)."
          exit 0
        fi

        # -------- PSP-based approach (if available) --------

        if [[ "$PSP_SUPPORTED" == "true" ]]; then
          echo "[INFO] Applying PSP-based hostIPC restrictions."

          # 1. Create or update a baseline PSP that denies hostIPC
          cat <<EOF | kubectl apply -f -
        apiVersion: policy/v1beta1
        kind: PodSecurityPolicy
        metadata:
          name: ${PSP_BASELINE_NAME}
        spec:
          privileged: false
          hostIPC: false
          hostNetwork: false
          hostPID: false
          seLinux:
            rule: RunAsAny
          runAsUser:
            rule: RunAsAny
          fsGroup:
            rule: RunAsAny
          supplementalGroups:
            rule: RunAsAny
          volumes:
          - '*'
        EOF

          # 2. Create or update a stricter PSP for workload namespaces that denies hostIPC
          cat <<EOF | kubectl apply -f -
        apiVersion: policy/v1beta1
        kind: PodSecurityPolicy
        metadata:
          name: ${PSP_RESTRICTED_NAME}
        spec:
          privileged: false
          hostIPC: false
          hostNetwork: false
          hostPID: false
          seLinux:
            rule: RunAsAny
          runAsUser:
            rule: RunAsAny
          fsGroup:
            rule: RunAsAny
          supplementalGroups:
            rule: RunAsAny
          volumes:
          - '*'
        EOF

          echo "[INFO] PSPs ${PSP_BASELINE_NAME} and ${PSP_RESTRICTED_NAME} have been applied."

          # Note:
          #   Binding these PSPs to users/service accounts is cluster-specific RBAC work and is not
          #   deterministically automatable here. You MUST ensure that:
          #     - Workload namespaces / service accounts only have access to PSPs with hostIPC=false.
          #   Use Manual Steps guidance to finalize RBAC bindings.

        fi

        # -------- Pod Security Admission label-based approach --------

        if [[ "$PSA_SUPPORTED" == "true" ]]; then
          echo "[INFO] Applying Pod Security Admission labels to restrict hostIPC in workload namespaces."

          # Retrieve all namespaces except the ignored ones
          ALL_NAMESPACES=$(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
          for ns in $ALL_NAMESPACES; do
            if ns_in_ignored_list "$ns"; then
              echo "[INFO] Skipping ignored namespace: $ns"
              continue
            fi

            echo "[INFO] Labeling namespace $ns for restricted pod security profile and hostIPC restriction."

            # Apply restricted PodSecurity labels (if not already present)
            # These labels ensure that pods cannot use hostIPC or other host namespaces by default.
            kubectl label namespace "$ns" \
              pod-security.kubernetes.io/enforce=restricted \
              pod-security.kubernetes.io/enforce-version=latest \
              --overwrite

            # Additional marker label for tracking that this namespace is intended to disallow hostIPC
            kubectl label namespace "$ns" \
              "${WORKLOAD_LABEL_KEY}=${WORKLOAD_LABEL_VALUE}" \
              --overwrite
          done
        fi

        # -------- Verification --------

        echo "[INFO] Verifying that no running pods use hostIPC=true."

        kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | \
        while read -r pod_name pod_namespace; do
          pod_hostipc=$(kubectl get pod "${pod_name}" --namespace "${pod_namespace}" -o jsonpath='{.spec.hostIPC}' 2>/dev/null || true)
          if [ -z "${pod_hostipc}" ]; then
            pod_hostipc="false"
            echo "***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: true"
          else
            echo "***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: false"
          fi
        done

        echo "[INFO] Verification complete. Review any lines with is_compliant: false."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
