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
- Remediation
Remediation
Manual Steps
-
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.
- On any machine with EKS/IaC access, choose one of:
-
Check if Pod Security Admission (PSA) is already enabled and configured (EKS)
- On any machine with AWS CLI configured, list cluster details:
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:
kubectl get ns --show-labels
- Look for labels like
pod-security.kubernetes.io/enforce=baseline|restrictedon 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.
- On any machine with AWS CLI configured, list cluster details:
-
Check whether Kyverno or Gatekeeper is installed and enforcing
- On any machine with kubectl access, check for Kyverno:
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:
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).
- On any machine with kubectl access, check for Kyverno:
-
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:
kubectl get ns <NAMESPACE> -o jsonpath='{.metadata.labels}'
- For Kyverno/Gatekeeper, inspect representative policies for these topics:
kubectl describe clusterpolicy <NAME> # Kyvernokubectl describe <CONSTRAINT_KIND> <NAME> # Gatekeeper
- If C1–C5 topics are only checked by external scanners/CI and not by admission policies, enforcement is incomplete.
- Using kubectl, review whether current enforcement covers:
-
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=baselineorrestricted(and optionallywarn/audit).
- Ensure namespaces are created and labeled declaratively with:
- 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):
- 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 withoutenforcementAction: dryrun).
- Add or update IaC modules/Helm releases that install the controller into the cluster and define policies/constraints that:
- Roll out in stages (e.g.,
warn/auditfirst, then enforce) to minimize disruption.
- If using PSA via EKS/IaC:
-
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:
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.
- 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:
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.
Automation
#!/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