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

# An Admission Policy Engine Should Enforce Workload Policy

### More Info:

Advisory: an admission controller (Pod Security Admission, Kyverno, or OPA Gatekeeper) should enforce workload best practices at admission time, not only detect them after the fact.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* Cloudanix Best Practice

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Decide which admission policy engine to use (design choice)**
           * If you’re on a recent Kubernetes/managed version that supports it and your needs are basic-to-moderate, prefer **Pod Security Admission (PSA)**.
           * If you need rich, custom policies, consider **Kyverno** or **OPA Gatekeeper**, but ensure your cloud provider supports installing them (via add-ons or your existing IaC).
           * Map which C1–C5 best practices you want enforced (e.g., disallow privileged pods, require resource limits, restrict hostPath, force non‑root, control capabilities).

        2. **Check if any admission policy engine is already enabled (cloud/IaC)**
           * In the **cloud console**, open the cluster details page and look for:
             * A “Pod security” / “Pod security admission” / “Pod security standards” section and note if it is **Enabled** and which level (e.g., baseline/restricted).
             * Any **add‑on** entries for *Kyverno*, *OPA Gatekeeper*, or similar “policy” controllers.
           * In your **IaC (Terraform, Helm, etc.)**, search for definitions referencing PSA, Kyverno, or Gatekeeper:
             * On a machine with access to your IaC repo:
               ```bash theme={null}
               cd /absolute/path/to/your/iac/repository
               grep -RniE 'podSecurity|pod_security|kyverno|gatekeeper|constraintTemplate|ClusterPolicy' .
               ```

        3. **Review whether C1–C5-aligned policies are configured in your chosen tool (cloud/IaC)**
           * For **PSA via provider/IaC**, look at:
             * Cluster‑level settings (e.g., default Pod Security level) in the console or in your IaC resource definitions. Confirm that “baseline” or “restricted” is set to *enforce* (not only *audit* or *warn*).
           * For **Kyverno/Gatekeeper via IaC**, inspect the policy manifests in your repo (found from the grep in step 2) and confirm they:
             * Enforce: no privileged pods, no host networking/paths unless allowed, resource requests/limits, non‑root users, and other C1–C5 items.
             * Are set to enforce (e.g., Kyverno `validationFailureAction: enforce`, Gatekeeper `enforcementAction: deny`).

        4. **Decide and implement the enforcement configuration (cloud/IaC change)**
           * If **no engine is enabled**, update your **cloud provider configuration or IaC** to:
             * Turn on PSA (if available) with an appropriate enforced level on namespaces (e.g., “baseline” or “restricted”), **or**
             * Deploy a supported policy engine add-on (Kyverno/Gatekeeper) and add policies mapped to C1–C5.
           * If an engine is **present but only auditing**, modify its configuration (in the console or IaC) to switch relevant rules/policies from “audit/warn” to **enforce/deny** for the targeted namespaces.
           * Apply the IaC changes using your normal workflow (for example, on your IaC runner machine):
             ```bash theme={null}
             cd /absolute/path/to/your/iac/repository
             # Example for Terraform; replace with your tooling/commands
             terraform plan
             terraform apply
             ```

        5. **Verify that policies are enforced at admission time (cloud/IaC + kubectl evidence)**
           * From any machine with kubectl access, intentionally try to create a pod that violates one of the C1–C5 controls (e.g., privileged container):
             ```bash theme={null}
             cat >/tmp/privileged-pod.yaml << 'EOF'
             apiVersion: v1
             kind: Pod
             metadata:
               name: privileged-test
               namespace: default
             spec:
               containers:
               - name: c
                 image: nginx
                 securityContext:
                   privileged: true
             EOF

             kubectl apply -f /tmp/privileged-pod.yaml
             ```
           * Confirm the request is **rejected** with an admission error message from PSA/Kyverno/Gatekeeper, rather than being created and only reported later.

        6. **Document the decision and scope of enforcement (cloud/IaC)**
           * In your cluster runbook or IaC repository (e.g., `docs/security-policies.md`), record:
             * Which admission policy engine is in use.
             * Which namespaces are covered and at what enforcement level.
             * Which C1–C5 best practices are enforced vs. only audited.
           * This documentation becomes the evidence that this manual control has been reviewed and a conscious enforcement decision has been made.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot configure or enable admission policy engines on a managed control plane; this is done in the cloud provider’s console, CLI, or IaC for the cluster itself. Refer to the Manual Steps section for provider-specific guidance on enabling and configuring Pod Security Admission, Kyverno, or OPA Gatekeeper.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Automation: Assess whether an admission policy engine is enforcing workload policy

        set -euo pipefail

        echo "=== Context ==="
        kubectl config current-context || true
        echo

        echo "=== 1) Pod Security Admission (PSA) configuration ==="
        echo "--- Namespace-level PSA labels (enforce only) ---"
        kubectl get ns -o custom-columns=NAME:.metadata.name,\
        PSA_ENFORCE:.metadata.labels."pod-security\.kubernetes\.io/enforce",\
        PSA_ENFORCE_VERSION:.metadata.labels."pod-security\.kubernetes\.io/enforce-version" \
          --sort-by=.metadata.name

        echo
        echo ">> Review guidance:"
        echo "   - Problem indicators:"
        echo "     * Many application namespaces lack 'pod-security.kubernetes.io/enforce' label."
        echo "     * Enforce level is 'privileged' or very permissive in non-system namespaces."
        echo "   - Healthy indicators:"
        echo "     * Most workload namespaces have 'baseline' or 'restricted' enforce labels,"
        echo "       with an explicit enforce-version."

        echo
        echo "--- Cluster-wide PSA admission configuration (if available) ---"
        # This may be empty on some managed control planes; still useful where supported.
        kubectl get configmap -n kube-system \
          --ignore-not-found \
          | grep -E 'psa|admission|pod-security' || echo "No obvious PSA-related ConfigMaps by simple name match."
        echo
        echo ">> Review guidance:"
        echo "   - Problem indicators:"
        echo "     * No provider-level documentation or config visible for PSA,"
        echo "       AND namespaces also lack enforce labels."
        echo "   - Note: Provider-managed PSA settings may only be visible in the cloud console or IaC."

        echo
        echo "=== 2) Kyverno admission controller ==="
        echo "--- Kyverno components (namespace kyverno) ---"
        kubectl get ns kyverno >/dev/null 2>&1 || {
          echo "Namespace 'kyverno' not found."
          echo ">> Problem indicator: Kyverno not installed in the standard namespace."
        } && {
          kubectl get deploy,ds,po,svc -n kyverno || true
        }

        echo
        echo "--- Kyverno ClusterPolicies (cluster-scoped) ---"
        kubectl get clusterpolicies.kyverno.io 2>/dev/null || echo "No Kyverno ClusterPolicies found."

        echo
        echo "--- Kyverno Namespaced Policies ---"
        for ns in $(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'); do
          kubectl get policies.kyverno.io -n "$ns" 2>/dev/null | sed "s/^/$ns: /" || true
        done

        echo
        echo ">> Review guidance for Kyverno:"
        echo "   - Problem indicators:"
        echo "     * 'kyverno' namespace missing or Kyverno pods not running/Ready."
        echo "     * No ClusterPolicies or Policies defined."
        echo "     * Policies all use 'validationFailureAction: audit' (or default audit)"
        echo "       so violations only log and do NOT block workloads."
        echo "   - Healthy indicators:"
        echo "     * Kyverno controller/webhook pods are Running and Ready."
        echo "     * There are ClusterPolicies/Policies with 'validationFailureAction: enforce'"
        echo "       covering C1–C5-type best practices (securityContext, resources, etc.)."

        echo
        echo "=== 3) OPA Gatekeeper admission controller ==="
        echo "--- Gatekeeper components (namespace gatekeeper-system) ---"
        kubectl get ns gatekeeper-system >/dev/null 2>&1 || {
          echo "Namespace 'gatekeeper-system' not found."
          echo ">> Problem indicator: Gatekeeper not installed in the standard namespace."
        } && {
          kubectl get deploy,ds,po,svc -n gatekeeper-system || true
        }

        echo
        echo "--- Gatekeeper Constraints (enforcing policies) ---"
        kubectl api-resources --api-group='constraints.gatekeeper.sh' -o name 2>/dev/null || \
          echo "No Gatekeeper constraint types registered."

        for ct in $(kubectl api-resources --api-group='constraints.gatekeeper.sh' -o name 2>/dev/null); do
          echo
          echo "Constraint type: $ct"
          kubectl get "$ct" -A 2>/dev/null || echo "  (none)"
        done

        echo
        echo "--- Gatekeeper ConstraintTemplates (registered policy types) ---"
        kubectl get constrainttemplates.templates.gatekeeper.sh 2>/dev/null || echo "No ConstraintTemplates found."

        echo
        echo ">> Review guidance for Gatekeeper:"
        echo "   - Problem indicators:"
        echo "     * 'gatekeeper-system' namespace or pods missing/not Ready."
        echo "     * No ConstraintTemplates and/or no Constraints."
        echo "     * Constraints are only used in 'dryrun' (if configured that way in spec.status),"
        echo "       so violations do not block workloads."
        echo "   - Healthy indicators:"
        echo "     * Gatekeeper controller/webhook pods are Running and Ready."
        echo "     * Constraints exist and are actively enforcing workload best practices."

        echo
        echo "=== 4) General admission webhooks overview ==="
        echo "--- MutatingWebhookConfiguration objects ---"
        kubectl get mutatingwebhookconfigurations.admissionregistration.k8s.io \
          -o wide || echo "No MutatingWebhookConfiguration objects found."

        echo
        echo "--- ValidatingWebhookConfiguration objects ---"
        kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io \
          -o wide || echo "No ValidatingWebhookConfiguration objects found."

        echo
        echo ">> Review guidance for webhooks overall:"
        echo "   - Problem indicators:"
        echo "     * No validating/mutating webhooks associated with security policy engines"
        echo "       (PSA, Kyverno, Gatekeeper, or similar)."
        echo "   - Healthy indicators:"
        echo "     * Webhook configurations referencing Kyverno or Gatekeeper services are present,"
        echo "       and their 'failurePolicy' and 'rules' are set to actually enforce policy."
        echo
        echo "=== Interpretation summary ==="
        echo "Use the sections above to decide:"
        echo " - Whether at least one admission policy engine (PSA, Kyverno, or Gatekeeper)"
        echo "   is installed and its pods are healthy."
        echo " - Whether it has policies/constraints configured in enforcing mode, not just audit/dry-run."
        echo "If no enforcing admission policy engine is present, this control fails and"
        echo "cloud-provider / control-plane configuration should be updated to enable and enforce"
        echo "workload best practices at admission time."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
