> ## 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 ones missing an enforce label or with an incorrect value:
           ```bash theme={null}
           kubectl get ns --show-labels
           ```

        2. For a single non-excluded namespace (example: `my-app`), set the enforce level to `baseline` (or `restricted` if you choose stricter):
           ```bash theme={null}
           kubectl label namespace my-app pod-security.kubernetes.io/enforce=baseline --overwrite
           ```

        3. To label all non-excluded namespaces at once with `baseline`, run:
           ```bash theme={null}
           for ns in $(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' \
             | grep -Ev '^(kube-system|kube-public|kube-node-lease)$'); do
             kubectl label namespace "$ns" pod-security.kubernetes.io/enforce=baseline --overwrite
           done
           ```

        4. If you prefer `restricted` for specific namespaces (example: `prod-app`), override as needed:
           ```bash theme={null}
           kubectl label namespace prod-app pod-security.kubernetes.io/enforce=restricted --overwrite
           ```

        5. (Optional) Review labels on a specific namespace to confirm:
           ```bash theme={null}
           kubectl get ns my-app -o jsonpath='{.metadata.labels}'
           ```

        6. Verification (on any machine with kubectl access):
           ```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="Using kubectl">
        On any machine with kubectl access to the cluster:

        1. Create a manifest to enforce Pod Security Admission (choose `baseline` or `restricted` as appropriate). Example for `baseline`:

        ```bash theme={null}
        cat > enforce-psa-namespaces.yaml << 'EOF'
        apiVersion: v1
        kind: Namespace
        metadata:
          name: default
          labels:
            pod-security.kubernetes.io/enforce: baseline
        ---
        apiVersion: v1
        kind: Namespace
        metadata:
          name: my-apps
          labels:
            pod-security.kubernetes.io/enforce: baseline
        EOF
        ```

        Edit the file to include all target namespaces and the desired level (`baseline` or `restricted`). Do not include `kube-system`, `kube-public`, or `kube-node-lease` unless you have explicitly decided to.

        2. Apply the labels declaratively:

        ```bash theme={null}
        kubectl apply -f enforce-psa-namespaces.yaml
        ```

        If you prefer imperative labeling for a few namespaces, you can run (example for `restricted`):

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

        3. Verification (same logic as the audit):

        ```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

        # PURPOSE:
        #   Ensure every non-system namespace has
        #   pod-security.kubernetes.io/enforce set to at least "baseline"
        #   (leaves "restricted" as-is, does not touch excluded namespaces).
        #
        # REQUIREMENTS:
        #   - Run on any machine with kubectl access and current context set.
        #   - jq must be installed.

        # 1) Identify target namespaces (exclude core system ones)
        echo "[INFO] Discovering namespaces to label..."
        mapfile -t TARGET_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 [ "${#TARGET_NAMESPACES[@]}" -eq 0 ]; then
          echo "[INFO] No non-system namespaces found. Nothing to do."
          exit 0
        fi

        echo "[INFO] Namespaces considered for enforcement:"
        printf '  - %s\n' "${TARGET_NAMESPACES[@]}"

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

          case "$current_level" in
            restricted)
              echo "[SKIP] $ns already at 'restricted' (stricter than baseline)."
              ;;
            baseline)
              echo "[OK]   $ns already enforced at 'baseline'."
              ;;
            "")
              echo "[FIX]  Setting enforce=baseline on namespace: $ns"
              kubectl label namespace "$ns" \
                pod-security.kubernetes.io/enforce=baseline \
                --overwrite
              ;;
            *)
              echo "[INFO] Namespace $ns currently has enforce='$current_level'."
              echo "[INFO] Leaving as-is to avoid downgrading/overriding custom policy."
              ;;
          esac
        done

        # 3) Verification (adapted from audit command)
        echo
        echo "[VERIFY] Current Pod Security Admission enforcement per namespace:"
        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>
