> ## 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 Admission Privileged Containers

### More Info:

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

### Risk Level

Critical

### Address

Security

### Compliance Standards

* APRA CPS 234 (Australia)
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CIS EKS
* 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

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. Identify namespaces that should host only non-privileged workloads (typically all user workload namespaces; exclude system namespaces like `kube-system`, `kube-public`, `kube-node-lease` if needed). On any machine with kubectl access:
           ```bash theme={null}
           kubectl get ns
           ```

        2. For each target namespace, enforce the Restricted Pod Security Admission policy to block privileged containers. Replace `NAMESPACE` with the actual namespace name. On any machine with kubectl access:
           ```bash theme={null}
           kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted
           ```

        3. (Optional but recommended) Configure a cluster-wide warning for less strict baseline violations on all namespaces to help discover workloads that would be affected if you tighten policies further. On any machine with kubectl access:
           ```bash theme={null}
           kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline
           ```

        4. Attempt to create a privileged pod in a Restricted namespace to confirm admission is blocked. On any machine with kubectl access, replace `NAMESPACE` as appropriate:
           ```bash theme={null}
           kubectl run privileged-test \
             --image=busybox \
             --restart=Never \
             --namespace NAMESPACE \
             --overrides='{"apiVersion":"v1","kind":"Pod","metadata":{"name":"privileged-test"}, "spec":{"containers":[{"name":"c","image":"busybox","command":["sh","-c","sleep 3600"],"securityContext":{"privileged":true}}]}}'
           ```
           You should see an admission error indicating the pod is not allowed due to Pod Security restrictions.

        5. Clean up the test pod (if it was created) from the test namespace. On any machine with kubectl access:
           ```bash theme={null}
           kubectl delete pod privileged-test -n NAMESPACE --ignore-not-found
           ```

        6. Verification (cluster-wide): confirm no currently running containers are privileged. On any machine with kubectl access:
           ```bash theme={null}
           kubectl get pods --all-namespaces -o json | \
             jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.privileged == true) then "PRIVILEGED_FOUND" else "NO_PRIVILEGED" end'
           ```
           The output should be:
           ```text theme={null}
           NO_PRIVILEGED
           ```
      </Accordion>

      <Accordion title="Using kubectl">
        On any machine with kubectl access:

        1. Identify namespaces with user workloads (example: `team-a`, `team-b`, `prod-apps`). Adjust the list below to your cluster.

        2. Enforce `restricted` Pod Security Admission (PSA) on those namespaces (blocks privileged pods):

        ```bash theme={null}
        kubectl label --overwrite ns team-a pod-security.kubernetes.io/enforce=restricted
        kubectl label --overwrite ns team-b pod-security.kubernetes.io/enforce=restricted
        kubectl label --overwrite ns prod-apps pod-security.kubernetes.io/enforce=restricted
        ```

        3. (Optional) Set a cluster‑wide warning level so you see PSA warnings everywhere without blocking:

        ```bash theme={null}
        kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline
        ```

        4. Verify labels are in place:

        ```bash theme={null}
        kubectl get ns --show-labels | grep pod-security.kubernetes.io
        ```

        5. Verify no privileged containers remain (same as audit):

        ```bash theme={null}
        kubectl get pods --all-namespaces -o json | \
          jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.privileged == true) then "PRIVILEGED_FOUND" else "NO_PRIVILEGED" end'
        ```
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        set -euo pipefail

        # This script:
        # - Identifies namespaces that currently allow privileged containers
        # - Applies Pod Security Admission labels to minimize privileged containers
        # - Verifies that no privileged containers are admitted
        #
        # Run from: any machine with kubectl access and jq installed.

        # 1) Safety checks
        if ! command -v kubectl >/dev/null 2>&1; then
          echo "kubectl not found in PATH" >&2
          exit 1
        fi

        if ! command -v jq >/dev/null 2>&1; then
          echo "jq not found in PATH" >&2
          exit 1
        fi

        # Ensure we can talk to the cluster
        kubectl cluster-info >/dev/null

        echo "=== Detecting namespaces with privileged containers ==="

        # 2) Detect namespaces that currently have privileged containers
        #    (for operator awareness; labeling is applied broadly below)
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | select(any(.spec.containers[]?; .securityContext?.privileged == true))
            | .metadata.namespace
          ' | sort -u || true

        echo "=== Applying Pod Security Admission labels to restrict privileged containers ==="

        # 3) Enforce 'restricted' PSA level on all namespaces that may host user workloads
        #    Adjust the namespace selector as appropriate for your environment.
        #    Below we:
        #      - enforce=restricted on all namespaces that are NOT in a small system list
        #      - warn=baseline on all namespaces (for visibility)
        #
        #    Edit SYSTEM_NAMESPACES if you need a different set.

        SYSTEM_NAMESPACES=("kube-system" "kube-public" "kube-node-lease" "default")

        # Build a regex of system namespaces for grep -Ev
        SYSTEM_REGEX="$(printf '%s\n' "${SYSTEM_NAMESPACES[@]}" | paste -sd '|' -)"

        # Label all namespaces with warn=baseline (idempotent)
        echo "Labeling all namespaces with pod-security.kubernetes.io/warn=baseline= (idempotent)..."
        kubectl label ns --all pod-security.kubernetes.io/warn=baseline --overwrite

        # Label non-system namespaces with enforce=restricted (idempotent)
        echo "Labeling non-system namespaces with pod-security.kubernetes.io/enforce=restricted (idempotent)..."
        USER_NAMESPACES=$(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' \
          | grep -Ev "^(${SYSTEM_REGEX})$" || true)

        if [ -n "$USER_NAMESPACES" ]; then
          # shellcheck disable=SC2086
          kubectl label ns $USER_NAMESPACES pod-security.kubernetes.io/enforce=restricted --overwrite
        else
          echo "No user namespaces detected to label with enforce=restricted."
        fi

        echo "=== Current PSA labels per namespace ==="
        kubectl get ns --show-labels

        # 4) Verification - ensure no privileged containers are admitted
        echo "=== Verifying no privileged containers are present ==="
        VERIFY_OUTPUT=$(kubectl get pods --all-namespaces -o json | \
          jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.privileged == true)
                 then "PRIVILEGED_FOUND" else "NO_PRIVILEGED" end')

        if [ "$VERIFY_OUTPUT" = "NO_PRIVILEGED" ]; then
          echo "Verification passed: NO_PRIVILEGED"
          exit 0
        else
          echo "Verification failed: PRIVILEGED_FOUND"
          echo "There are still pods running with securityContext.privileged=true."
          echo "Inspect them with:"
          echo "  kubectl get pods --all-namespaces -o json | \\"
          echo "    jq -r ''.items[] | select(any(.spec.containers[]?; .securityContext?.privileged == true)) | .metadata.namespace + \"/\" + .metadata.name'''"
          exit 1
        fi
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://kubernetes.io/docs/concepts/security/pod-security-standards/](https://kubernetes.io/docs/concepts/security/pod-security-standards/)
