> ## 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 engine to use and scope of enforcement**
           * On any machine with EKS/IaC access, choose one of:
             * Native **Pod Security Admission (PSA)** with EKS (recommended for baseline/restricted pod security).
             * **Kyverno** or **OPA Gatekeeper** for richer policies.
           * Decide: which namespaces must be enforced (prod vs dev), and whether to block non-compliant workloads (fail) or only warn/audit initially.

        2. **Check if Pod Security Admission (PSA) is already enabled and configured (EKS)**
           * On any machine with AWS CLI configured, list cluster details:
             ```bash theme={null}
             aws eks describe-cluster \
               --name <CLUSTER_NAME> \
               --region <AWS_REGION> \
               --query "cluster.{name:name, version:version, logging:logging, tags:tags}"
             ```
           * On any machine with kubectl access, inspect namespaces for PSA labels:
             ```bash theme={null}
             kubectl get ns --show-labels
             ```
           * Look for labels like `pod-security.kubernetes.io/enforce=baseline|restricted` on critical namespaces (e.g., production).
           * If no such labels exist on any namespace you intend to protect, PSA is **not enforcing** workload policy for those namespaces.

        3. **Check whether Kyverno or Gatekeeper is installed and enforcing**
           * On any machine with kubectl access, check for Kyverno:
             ```bash theme={null}
             kubectl get ns kyverno 2>/dev/null || echo "kyverno namespace not found"
             kubectl get deploy -n kyverno 2>/dev/null || echo "no kyverno deployments"
             kubectl get clusterpolicy,policy -A 2>/dev/null || echo "no kyverno policies"
             ```
           * Check for Gatekeeper:
             ```bash theme={null}
             kubectl get ns gatekeeper-system 2>/dev/null || echo "gatekeeper-system namespace not found"
             kubectl get deploy -n gatekeeper-system 2>/dev/null || echo "no gatekeeper deployments"
             kubectl get constrainttemplates.constraints.gatekeeper.sh -A 2>/dev/null || echo "no gatekeeper templates"
             kubectl get constraints.constraints.gatekeeper.sh -A 2>/dev/null || echo "no gatekeeper constraints"
             ```
           * For any policies/constraints found, inspect a few to see if they are **enforce** (blocking) vs **audit** (detect-only).

        4. **Compare current policy coverage against C1–C5 best practices**
           * Using kubectl, review whether current enforcement covers:
             * Pod security (privileged, hostPath, hostNetwork, capabilities, etc.)
             * Resource limits/requests, non-root, image registries, etc.
           * For PSA labels, pick a protected namespace and check:
             ```bash theme={null}
             kubectl get ns <NAMESPACE> -o jsonpath='{.metadata.labels}'
             ```
           * For Kyverno/Gatekeeper, inspect representative policies for these topics:
             ```bash theme={null}
             kubectl describe clusterpolicy <NAME>      # Kyverno
             kubectl describe <CONSTRAINT_KIND> <NAME>  # Gatekeeper
             ```
           * If C1–C5 topics are only checked by external scanners/CI and not by admission policies, enforcement is incomplete.

        5. **Plan and implement enforcement via cloud/IaC configuration**
           * If using **PSA via EKS/IaC**:
             * Update your IaC (e.g., Terraform, CloudFormation, eksctl) to apply appropriate labels to namespaces that must be enforced, for example (Terraform Helm/kubectl provider or eksctl config):
               * Ensure namespaces are created and labeled declaratively with:\
                 `pod-security.kubernetes.io/enforce=baseline` or `restricted` (and optionally `warn`/`audit`).
           * If using **Kyverno or Gatekeeper**:
             * Add or update IaC modules/Helm releases that install the controller into the cluster and define policies/constraints that:
               * Cover C1–C5 best practices.
               * Use enforcing modes (e.g., Kyverno `validationFailureAction: enforce`, Gatekeeper constraints without `enforcementAction: dryrun`).
           * Roll out in stages (e.g., `warn`/`audit` first, then enforce) to minimize disruption.

        6. **Verify that admission enforcement is active**
           * On any machine with kubectl access, attempt to create an intentionally non-compliant pod in an enforced namespace, e.g. for PSA / basic pod security:
             ```bash theme={null}
             kubectl run bad-pod \
               --image=nginx \
               --restart=Never \
               --overrides='{"apiVersion":"v1","kind":"Pod","metadata":{"name":"bad-pod"},"spec":{"hostNetwork":true,"containers":[{"name":"c","image":"nginx","securityContext":{"privileged":true}}]}}' \
               -n <ENFORCED_NAMESPACE>
             ```
           * Confirm that creation is **rejected** with an error from PSA, Kyverno, or Gatekeeper.
           * If the pod is admitted successfully, revisit steps 2–5 and strengthen or correct the admission policy configuration.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot configure or enable admission policy engines on Amazon EKS, because this is managed at the cloud provider / control-plane configuration layer (for example via AWS Console, CLI, or IaC such as Terraform/CloudFormation). To address this finding, follow the guidance in the Manual Steps section for configuring Pod Security Admission or deploying Kyverno / OPA Gatekeeper through your EKS provisioning tooling.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Report admission-policy enforcement state for an Amazon EKS cluster
        # Run on: any machine with kubectl access and correct kubeconfig

        set -euo pipefail

        echo "=== 1) Kubernetes version & EKS cluster info (context) ==="
        kubectl version --short || true
        echo

        echo "=== 2) Pod Security Admission (PSA) namespace labels ==="
        echo "Namespaces with Pod Security Admission labels (pod-security.kubernetes.io/*):"
        kubectl get ns -o custom-columns=NAME:.metadata.name,$(
          printf 'ENFORCING-PROFILE:.metadata.labels.pod-security\\.kubernetes\\.io/enforce,'\
        'ENFORCING-VERSION:.metadata.labels.pod-security\\.kubernetes\\.io/enforce-version,'\
        'AUDIT-PROFILE:.metadata.labels.pod-security\\.kubernetes\\.io/audit,'\
        'WARN-PROFILE:.metadata.labels.pod-security\\.kubernetes\\.io/warn'
        ) | sed 's/,$//'
        echo
        cat <<'EOF'
        INTERPRETATION (PSA):
        - Problem indicators:
          - Many workload namespaces have EMPTY ENFORCING-PROFILE (no enforce label).
          - ENFORCING-PROFILE is set to "privileged" instead of "baseline" or "restricted".
          - Only 'audit' or 'warn' labels are set, but no 'enforce' label.
        - Healthy indicators:
          - All / most workload namespaces have ENFORCING-PROFILE set to "baseline" or "restricted".
        EOF
        echo

        echo "=== 3) Kyverno presence and policy enforcement modes ==="
        echo "- Kyverno core components:"
        kubectl get ns kyverno >/dev/null 2>&1 && {
          kubectl get deploy -n kyverno || true
        } || echo "Kyverno namespace not found; Kyverno is likely not installed."
        echo

        echo "- Kyverno ClusterPolicies (key columns: VALIDATE, BACKGROUND, FAIL-ACTION):"
        kubectl get clusterpolicies.kyverno.io 2>/dev/null \
          -o custom-columns=NAME:.metadata.name,VALIDATE:.spec.validationFailureAction,BACKGROUND:.spec.background \
          || echo "No Kyverno ClusterPolicies found (CRD may be missing or Kyverno not installed)."
        echo

        echo "- Kyverno Policies in all namespaces (for namespace-scoped policies):"
        kubectl get policies.kyverno.io --all-namespaces 2>/dev/null \
          -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name,VALIDATE:.spec.validationFailureAction,BACKGROUND:.spec.background \
          || echo "No Kyverno Policies found."
        echo
        cat <<'EOF'
        INTERPRETATION (Kyverno):
        - Problem indicators:
          - Kyverno not installed (no kyverno namespace, CRDs, or policies).
          - All policies use validationFailureAction=Audit (detect-only) and none use Enforce.
          - Only background=true policies that don't block live admission.
        - Healthy indicators:
          - Kyverno installed and running.
          - Key baseline/restricted workload policies with validationFailureAction=Enforce.
        EOF
        echo

        echo "=== 4) OPA Gatekeeper presence and constraint enforcement ==="
        echo "- Gatekeeper system namespace components:"
        kubectl get ns gatekeeper-system >/dev/null 2>&1 && {
          kubectl get deploy -n gatekeeper-system || true
        } || echo "gatekeeper-system namespace not found; Gatekeeper is likely not installed."
        echo

        echo "- Gatekeeper ConstraintTemplates:"
        kubectl get constrainttemplates.templates.gatekeeper.sh 2>/dev/null \
          -o custom-columns=NAME:.metadata.name,KIND:.spec.crd.spec.names.kind \
          || echo "No ConstraintTemplates found."
        echo

        echo "- Gatekeeper Constraints (all types, across all namespaces):"
        kubectl api-resources --api-group='constraints.gatekeeper.sh' -o name 2>/dev/null | while read -r kind; do
          echo ">> $kind"
          kubectl get "$kind" --all-namespaces -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name,ENFORCEMENT:.spec.enforcementAction 2>/dev/null || echo "  (none)"
          echo
        done
        echo
        cat <<'EOF'
        INTERPRETATION (Gatekeeper):
        - Problem indicators:
          - Gatekeeper not installed (no gatekeeper-system namespace or deployments).
          - No Constraints defined for workload best practices.
          - Constraints exist but use enforcementAction=dryrun only (detect-only).
        - Healthy indicators:
          - Gatekeeper installed and running.
          - Key workload constraints with enforcementAction not set or set to deny/strict (enforcing).
        EOF
        echo

        echo "=== 5) Summary guidance (manual review required) ==="
        cat <<'EOF'
        This script only reports current state.

        For CBP C6.3 you must manually decide:
        - Which admission engine to standardize on (PSA, Kyverno, or Gatekeeper).
        - Which baseline/restricted policies are REQUIRED (must be enforce/deny) vs advisory (audit/warn).
        - Whether all production namespaces are covered by enforce-level policies/constraints.

        Any of these conditions indicate a gap for this control:
        - No PSA enforce labels and no Kyverno/Gatekeeper enforcing policies.
        - Policies/constraints exist only in audit/warn/dryrun mode.
        - Critical namespaces (e.g., app workloads) missing enforcement coverage.
        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
