> ## 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.

# Namespaces Should Enforce Pod Security Admission Baseline Or Stricter

### More Info:

Verifies each namespace is labeled with pod-security.kubernetes.io/enforce set to baseline or restricted so the built-in Pod Security Admission controller rejects unsafe pods.

### Risk Level

High

### Address

Security

### Compliance Standards

* Cloudanix Best Practice

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On any machine with kubectl access, list all namespaces and identify those without an enforce label set to baseline or restricted (excluding default system namespaces):
           ```sh theme={null}
           kubectl get ns --show-labels
           ```

        2. For each non-compliant namespace you want at baseline, add or update the enforce label:
           ```sh theme={null}
           kubectl label namespace <NAMESPACE> pod-security.kubernetes.io/enforce=baseline --overwrite
           ```

        3. For each namespace you want at restricted (stricter than baseline), add or update the enforce label:
           ```sh theme={null}
           kubectl label namespace <NAMESPACE> pod-security.kubernetes.io/enforce=restricted --overwrite
           ```

        4. Optionally protect against accidental downgrade by setting the audit and warn levels to match the enforce level (example for restricted):
           ```sh theme={null}
           kubectl label namespace <NAMESPACE> \
             pod-security.kubernetes.io/audit=restricted \
             pod-security.kubernetes.io/warn=restricted \
             --overwrite
           ```

        5. If you manage namespaces via manifests or GitOps, mirror the change by adding a labels block like this to each Namespace manifest you updated, then apply with kubectl apply -f:
           ```yaml theme={null}
           metadata:
             name: <NAMESPACE>
             labels:
               pod-security.kubernetes.io/enforce: baseline
           ```

        6. Verification (on any machine with kubectl access): run the original audit and confirm that all non-system namespaces show enforce=baseline or enforce=restricted and is\_compliant=true:
           ```sh theme={null}
           kubectl get namespaces -o json | jq -r '
             [ .items[]
             | select(.metadata.name as $n | ["kube-system","kube-public","kube-node-lease"] | index($n) | not)
             | .metadata as $m
             | (($m.labels // {}) | to_entries | map("\(.key):\(.value)") | join(",")) as $labels
             | (($m.labels // {})["pod-security.kubernetes.io/enforce"] // "") as $lvl
             | "kind=Namespace name=\($m.name) uid=\($m.uid) apiVersion=v1"
               + (if ($m.creationTimestamp // "") == "" then "" else " created=\($m.creationTimestamp)" end)
               + (if $labels == "" then "" else " labels=\($labels)" end)
               + " enforce=\(if $lvl == "" then "none" else $lvl end)"
               + " is_compliant=\(if ($lvl == "baseline" or $lvl == "restricted") then "true" else "false" end)"
             ] as $rows
             | if ($rows | length) == 0 then "is_compliant=true" else $rows[] end'
           ```
      </Accordion>

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

        1. Identify noncompliant namespaces (excluding system namespaces):

        ```bash theme={null}
        kubectl get namespaces -o json | jq -r '
          .items[]
          | select(.metadata.name as $n | ["kube-system","kube-public","kube-node-lease"] | index($n) | not)
          | select((.metadata.labels["pod-security.kubernetes.io/enforce"] // "") as $lvl | ($lvl != "baseline" and $lvl != "restricted"))
          | .metadata.name'
        ```

        2. Label each noncompliant namespace to enforce `baseline` (example for `dev`, `test`, `prod`—adjust names as needed):

        ```bash theme={null}
        kubectl label namespace dev  pod-security.kubernetes.io/enforce=baseline --overwrite
        kubectl label namespace test pod-security.kubernetes.io/enforce=baseline --overwrite
        kubectl label namespace prod pod-security.kubernetes.io/enforce=baseline --overwrite
        ```

        If you prefer `restricted` for a namespace, use:

        ```bash theme={null}
        kubectl label namespace secure pod-security.kubernetes.io/enforce=restricted --overwrite
        ```

        3. (Optional, declarative) Create or update namespace manifests to include the label, then apply:

        `dev-namespace.yaml`:

        ```yaml theme={null}
        apiVersion: v1
        kind: Namespace
        metadata:
          name: dev
          labels:
            pod-security.kubernetes.io/enforce: baseline
        ```

        Apply:

        ```bash theme={null}
        kubectl apply -f dev-namespace.yaml
        ```

        4. Verification (same as audit, run on any machine with kubectl):

        ```bash theme={null}
        kubectl get namespaces -o json | jq -r '
          [ .items[]
          | select(.metadata.name as $n | ["kube-system","kube-public","kube-node-lease"] | index($n) | not)
          | .metadata as $m
          | (($m.labels // {}) | to_entries | map("\(.key):\(.value)") | join(",")) as $labels
          | (($m.labels // {})["pod-security.kubernetes.io/enforce"] // "") as $lvl
          | "kind=Namespace name=\($m.name) uid=\($m.uid) apiVersion=v1"
            + (if ($m.creationTimestamp // "") == "" then "" else " created=\($m.creationTimestamp)" end)
            + (if $labels == "" then "" else " labels=\($labels)" end)
            + " enforce=\(if $lvl == "" then "none" else $lvl end)"
            + " is_compliant=\(if ($lvl == "baseline" or $lvl == "restricted") then "true" else "false" end)"
          ] as $rows
          | if ($rows | length) == 0 then "is_compliant=true" else $rows[] end'
        ```
      </Accordion>

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

        # This script:
        # - Finds all namespaces except kube-system, kube-public, kube-node-lease
        # - Labels them with pod-security.kubernetes.io/enforce=baseline if they are not already
        #   set to "baseline" or "restricted"
        # - Prints the final enforcement level per namespace
        #
        # Run on: any machine with kubectl access to the cluster
        # Requirements: kubectl, jq in PATH, current context pointing at target cluster

        # Fail fast if required tools are missing
        command -v kubectl >/dev/null 2>&1 || {
          echo "kubectl not found in PATH" >&2
          exit 1
        }
        command -v jq >/dev/null 2>&1 || {
          echo "jq not found in PATH" >&2
          exit 1
        }

        echo "Discovering non-excluded namespaces..."
        mapfile -t NAMESPACES < <(
          kubectl get namespaces -o json \
          | jq -r '.items[]
            | select(.metadata.name as $n
                     | ["kube-system","kube-public","kube-node-lease"] | index($n) | not)
            | .metadata.name'
        )

        if [ "${#NAMESPACES[@]}" -eq 0 ]; then
          echo "No namespaces found to process."
        else
          echo "Namespaces to process: ${NAMESPACES[*]}"
        fi

        # Apply label where needed
        for ns in "${NAMESPACES[@]}"; do
          current_lvl="$(
            kubectl get namespace "$ns" -o json \
            | jq -r '.metadata.labels["pod-security.kubernetes.io/enforce"] // "none"'
          )"

          case "$current_lvl" in
            baseline|restricted)
              echo "Namespace '$ns' already compliant (enforce=$current_lvl), skipping."
              ;;
            *)
              echo "Labeling namespace '$ns' with pod-security.kubernetes.io/enforce=baseline"
              kubectl label namespace "$ns" \
                "pod-security.kubernetes.io/enforce=baseline" \
                --overwrite
              ;;
          esac
        done

        echo
        echo "Verification (should show enforce=baseline or enforce=restricted and is_compliant=true):"
        kubectl get namespaces -o json | jq -r '
          [ .items[]
          | select(.metadata.name as $n | ["kube-system","kube-public","kube-node-lease"] | index($n) | not)
          | .metadata as $m
          | (($m.labels // {}) | to_entries | map("\(.key):\(.value)") | join(",")) as $labels
          | (($m.labels // {})["pod-security.kubernetes.io/enforce"] // "") as $lvl
          | "kind=Namespace name=\($m.name) uid=\($m.uid) apiVersion=v1"
            + (if ($m.creationTimestamp // "") == "" then "" else " created=\($m.creationTimestamp)" end)
            + (if $labels == "" then "" else " labels=\($labels)" end)
            + " enforce=\(if $lvl == "" then "none" else $lvl end)"
            + " is_compliant=\(if ($lvl == "baseline" or $lvl == "restricted") then "true" else "false" end)"
          ] as $rows
          | if ($rows | length) == 0 then "is_compliant=true" else $rows[] end'
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
