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

# Ensure The Cluster Has At Least One Active Policy Control Mechanism

### More Info:

Every namespace with user workloads should be governed by Pod Security Admission or an external policy engine to enforce pod security standards.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify namespaces with user workloads**
           * Run on: any machine with kubectl access
           * Command:
             ```bash theme={null}
             kubectl get namespaces
             kubectl get pods --all-namespaces -o wide
             ```
           * Decide which namespaces contain user applications (exclude clearly system ones like `kube-system`, `kube-public`, `kube-node-lease`, and any cloud-provider/system namespaces your platform uses).

        2. **Check Pod Security Admission labels on those namespaces**
           * Run on: any machine with kubectl access
           * Command (replace `USER_NAMESPACE` with each identified namespace):
             ```bash theme={null}
             kubectl get ns USER_NAMESPACE -o jsonpath='{.metadata.name}{"\t"}{.metadata.labels}{"\n"}'
             ```
           * Review whether labels like `pod-security.kubernetes.io/enforce`, `pod-security.kubernetes.io/warn`, or `pod-security.kubernetes.io/audit` are present and set to an appropriate level (`baseline` or `restricted` for enforce).

        3. **Check for external policy engines (e.g., Gatekeeper, Kyverno) in the cluster**
           * Run on: any machine with kubectl access
           * Commands:
             ```bash theme={null}
             kubectl get pods -A | egrep -i 'gatekeeper|kyverno|opa|policy'
             kubectl get crds | egrep -i 'constrainttemplate|kyverno|policy'
             ```
           * If present, note which engine(s) are installed (e.g., Gatekeeper, Kyverno).

        4. **Verify that policies actually cover the user namespaces**
           * Run on: any machine with kubectl access
           * For Gatekeeper-like engines:
             ```bash theme={null}
             kubectl get k8sallowedrepos.constraints.gatekeeper.sh -A 2>/dev/null || true
             kubectl get constraints -A 2>/dev/null || true
             ```
           * For Kyverno-like engines:
             ```bash theme={null}
             kubectl get clusterpolicy -A 2>/dev/null || true
             kubectl get policy -A 2>/dev/null || true
             ```
           * Inspect sample policies to confirm they apply cluster-wide or explicitly to each user namespace via `spec.match` / `namespaceSelector` (use `kubectl get <kind> <name> -o yaml` as needed).

        5. **Decide and apply remediation where gaps exist**
           * If a user namespace has neither Pod Security Admission labels nor coverage by an external policy engine:
             * Option A (Pod Security Admission):
               ```bash theme={null}
               kubectl label namespace USER_NAMESPACE \
                 pod-security.kubernetes.io/enforce=baseline \
                 pod-security.kubernetes.io/enforce-version=latest \
                 --overwrite
               ```
             * Option B (External policy engine): create or update policies to include that namespace in their `match` rules, then apply them with `kubectl apply -f POLICY_FILE.yaml`.

        6. **Verify that every user namespace is now governed by at least one mechanism**
           * Run on: any machine with kubectl access
           * Commands:
             ```bash theme={null}
             # Re-check namespace labels
             kubectl get ns $(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{" "}{end}') \
               -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels}{"\n"}{end}'

             # Optionally, attempt a clearly non-compliant pod in a user namespace to confirm enforcement
             kubectl run psp-test --image=busybox --restart=Never -n USER_NAMESPACE \
               --overrides='{"spec":{"securityContext":{"runAsUser":0}}}' -- sleep 3600 || true
             kubectl describe pod psp-test -n USER_NAMESPACE || true
             ```
           * Confirm that either PSA labels enforce a profile or the external engine denies or modifies non-compliant pods in each user namespace.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all namespaces and their PSA labels (if any)
        # Run on: any machine with kubectl access
        kubectl get ns -o custom-columns=NAME:.metadata.name, \
        POD-SECURITY-ENFORCE:.metadata.labels.pod-security\.kubernetes\.io/enforce, \
        POD-SECURITY-AUDIT:.metadata.labels.pod-security\.kubernetes\.io/audit, \
        POD-SECURITY-WARN:.metadata.labels.pod-security\.kubernetes\.io/warn

        # 2) Show full labels for specific namespaces that run user workloads
        # Replace <namespace> with the actual namespace name
        kubectl get ns <namespace> -o yaml

        # 3) Check for known external policy engines (by common labels/CRDs)
        # OPA Gatekeeper
        kubectl get pods -A -l app=gatekeeper
        kubectl get constrainttemplates.constraint.gatekeeper.sh 2>/dev/null
        kubectl get constraints --all-namespaces 2>/dev/null

        # Kyverno
        kubectl get pods -A -l app.kubernetes.io/name=kyverno
        kubectl get clusterpolicy,policy -A 2>/dev/null

        # 4) List namespaces that have NO Pod Security Admission labels at all
        kubectl get ns -o json | jq -r '
          .items[]
          | select(.metadata.labels["pod-security.kubernetes.io/enforce"] == null
                   and .metadata.labels["pod-security.kubernetes.io/audit"] == null
                   and .metadata.labels["pod-security.kubernetes.io/warn"] == null)
          | .metadata.name
        '
        ```

        **How to review the output**

        * From command (1):
          * **Problem indication:** Any namespace that:
            * Contains user workloads (e.g., `dev`, `prod`, `staging`, app-specific namespaces), **and**
            * Shows `"<none>"` or empty values in all three columns `POD-SECURITY-ENFORCE`, `POD-SECURITY-AUDIT`, and `POD-SECURITY-WARN`.
          * These namespaces are not covered by Pod Security Admission and require either PSA labels or an external policy engine.

        * From command (2):
          * Inspect `.metadata.labels` for:
            * `pod-security.kubernetes.io/enforce`
            * `pod-security.kubernetes.io/enforce-version`
            * `pod-security.kubernetes.io/audit`
            * `pod-security.kubernetes.io/warn`
          * **Problem indication:** User-workload namespaces without any of these labels, or labels set to a profile that is weaker than your organization’s required standard (e.g., `privileged` where your standard is `baseline` or `restricted`).

        * From command (3):
          * **Problem indication:** No Gatekeeper or Kyverno pods running and no constraints/policies defined, *combined with* user-workload namespaces that also lack PSA labels.
          * In that case, those namespaces have no active policy control mechanism.

        * From command (4):
          * The printed list is all namespaces with no PSA labels.
          * **Problem indication:** Any namespace in this list that you identify as running user workloads and that is also not governed by an external policy engine (from step 3) fails the control and requires a design decision and remediation.
      </Accordion>

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

        # This script must run on any machine with kubectl access and a kubeconfig
        # that can list namespaces and pods cluster‑wide.

        # Namespaces to ignore (system/control-plane)
        IGNORED_NS_REGEX='^(kube-system|kube-public|kube-node-lease|kube-storage-version-migrator|kube-*|tigera-operator|calico-system|cilium-system|gatekeeper-system|opa|istio-system|linkerd|velero|cert-manager)$'

        echo "=== Detecting namespaces with user workloads and checking policy controls ==="
        echo

        # 1. List namespaces that have at least one non-terminated pod (user workloads candidates)
        echo "# Namespaces with running/non-terminated pods (candidate user-workload namespaces):"
        kubectl get pods --all-namespaces --field-selector=status.phase!=Succeeded,status.phase!=Failed -o custom-columns='NAMESPACE:.metadata.namespace' --no-headers \
          | sort -u \
          | grep -Ev "$IGNORED_NS_REGEX" || true
        echo

        # 2. Show pod-security admission labels on those namespaces
        echo "# Pod Security Admission labels on user-workload namespaces:"
        echo "# (psa labels: pod-security.kubernetes.io/enforce, warn, audit + version)"
        kubectl get ns \
          -o custom-columns='NAMESPACE:.metadata.name,ENFORCE:metadata.labels.pod-security\.kubernetes\.io/enforce,ENFORCE_VER:metadata.labels.pod-security\.kubernetes\.io/enforce-version,WARN:metadata.labels.pod-security\.kubernetes\.io/warn,WARN_VER:metadata.labels.pod-security\.kubernetes\.io/warn-version,AUDIT:metadata.labels.pod-security\.kubernetes\.io/audit,AUDIT_VER:metadata.labels.pod-security\.kubernetes\.io/audit-version' \
          --no-headers \
          | grep -Ev "$IGNORED_NS_REGEX" \
          | sort
        echo

        # 3. Highlight user-workload namespaces that appear to lack a PSA enforce level
        echo "# POSSIBLE PROBLEM: user-workload namespaces with no Pod Security 'enforce' label:"
        echo "# (These namespaces have running/non-terminated pods but no enforce label set)"
        user_ns_with_pods=$(
          kubectl get pods --all-namespaces --field-selector=status.phase!=Succeeded,status.phase!=Failed \
            -o custom-columns='NAMESPACE:.metadata.namespace' --no-headers \
            | sort -u \
            | grep -Ev "$IGNORED_NS_REGEX" || true
        )

        if [ -n "$user_ns_with_pods" ]; then
          # Join list into grep pattern
          pattern=$(printf '%s\n' "$user_ns_with_pods" | paste -sd'|' -)

          kubectl get ns \
            -o custom-columns='NAMESPACE:.metadata.name,ENFORCE:metadata.labels.pod-security\.kubernetes\.io/enforce' \
            --no-headers \
            | grep -E "$pattern" \
            | awk '$2=="" {print $1}' \
            | sort -u || true
        else
          echo "# None (no user-workload namespaces with running pods found)."
        fi
        echo

        # 4. OPTIONAL: Look for common external policy engines (Gatekeeper, Kyverno, OPA) by label/namespace
        echo "# Detected external policy engine components (best-effort heuristics):"
        echo "## Gatekeeper:"
        kubectl get pods -A -l gatekeeper.sh/system=yes 2>/dev/null || echo "  (none detected)"
        echo
        echo "## Kyverno:"
        kubectl get pods -A -l app=kyverno 2>/dev/null || echo "  (none detected)"
        echo
        echo "## OPA (gatekeeper-system or opa-related namespaces):"
        kubectl get pods -A -n gatekeeper-system 2>/dev/null || echo "  (no gatekeeper-system namespace)"
        kubectl get ns | grep -Ei 'opa|policy' || true
        echo

        cat <<'EOF'
        INTERPRETING OUTPUT (what indicates a problem):

        1. Candidate user-workload namespaces:
           - Any namespace listed under:
               "# Namespaces with running/non-terminated pods (candidate user-workload namespaces):"
             is considered to host user workloads (and so SHOULD have a policy control mechanism).

        2. Pod Security Admission labels:
           - For these namespaces, check the line under:
               "# Pod Security Admission labels on user-workload namespaces:"
           - If ENFORCE (and ideally ENFORCE_VER) is empty for a user-workload namespace,
             that namespace does NOT have Pod Security Admission enforcement configured.

        3. Problem indicator:
           - The section:
               "# POSSIBLE PROBLEM: user-workload namespaces with no Pod Security 'enforce' label:"
             lists namespaces that:
               * Have running/non-terminated pods (candidate user workloads), AND
               * Do NOT have a pod-security.kubernetes.io/enforce label.
           - Each namespace listed here is a REVIEW REQUIRED condition for this control:
               * Either add/adjust Pod Security Admission labels, OR
               * Confirm that an external policy engine is actively governing that namespace.

        4. External policy engines:
           - The detections under "Detected external policy engine components" are heuristic.
           - Presence alone does NOT prove policies are enforced on every user namespace.
           - For any namespace flagged as a possible problem, you must manually verify
             that your external policy engine has constraints/clusterpolicies that apply
             to that namespace and enforce appropriate pod security standards.

        This script does NOT automatically fix anything. It surfaces namespaces that
        likely need manual review and policy decisions to comply with CIS 5.2.1.
        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
