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
-
Identify how the cluster is provisioned (console vs. IaC)
- On any machine with access to your OCI tenancy, determine whether OKE clusters are managed via Terraform/Resource Manager, OCI CLI, or manually in the OCI Console.
- If using Terraform/Resource Manager, locate the codebase that defines your OKE clusters and note any modules related to “gatekeeper”, “kyverno”, or “psa/pod-security”.
-
Check for an admission policy engine deployed to the cluster
- On any machine with
kubectlaccess (this is read-only discovery; remediation will be in console/CLI/IaC):kubectl get pods -A | egrep -i 'gatekeeper|kyverno'kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations \-A -o wide | egrep -i 'gatekeeper|kyverno'kubectl get ns --show-labels | egrep 'pod-security.kubernetes.io/(enforce|audit|warn)' - Interpretation:
- Presence of
gatekeeper-systemorkyvernonamespaces and matching webhook configurations indicates OPA Gatekeeper or Kyverno is installed. pod-security.kubernetes.io/enforcelabels on namespaces indicate Pod Security Admission (PSA) is being used to enforce baseline/restricted policies.
- Presence of
- On any machine with
-
Review current enforcement scope and strength
- Still on a
kubectl-enabled machine, inspect policies to see if they cover the benchmark’s workload best practices (C1–C5) and are set to enforce (not only audit):# Gatekeeper constraints (if present)kubectl get k8sallowedrepos,ksymlinks, -A 2>/dev/nullkubectl get constraints.constraints.gatekeeper.sh -A# Kyverno ClusterPolicies and Policies (if present)kubectl get clusterpolicies -A 2>/dev/nullkubectl get policies -A 2>/dev/null# Pod Security Admission labels (if used)kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{" "}{.metadata.labels}{"\n"}{end}' - Manually compare existing constraints/policies/PSA levels to your required C1–C5 workload controls (e.g., run-as-nonroot, privileged/hostNetwork restrictions, image registry controls, resource limits).
- Still on a
-
Decide on the admission strategy and update configuration via OCI Console/CLI/IaC
- If no enforcement engine exists, or current policies are only auditing/not aligned with C1–C5:
- Choose one primary mechanism for enforcement:
- Enable and standardize Pod Security Admission via namespace labels (for baseline/restricted pods), and/or
- Deploy and manage OPA Gatekeeper or Kyverno using your standard provisioning path (Terraform module, Helm chart invoked by Terraform or OCI DevOps, or manual setup documented in your OKE runbooks).
- Choose one primary mechanism for enforcement:
- Apply changes through your chosen control-plane management surface (Terraform/OCI Resource Manager templates or documented OCI Console procedure). Do not make ad‑hoc kubectl changes if your organization mandates IaC.
- If no enforcement engine exists, or current policies are only auditing/not aligned with C1–C5:
-
Verify enforcement is active (not just audit)
- On a
kubectl-enabled machine, attempt to create a known-bad workload that violates one of your C1–C5 rules (for example, privileged pod without required labels):cat > /tmp/privileged-pod.yaml << 'EOF'apiVersion: v1kind: Podmetadata:name: test-privilegednamespace: defaultspec:containers:- name: cimage: nginxsecurityContext:privileged: trueEOFkubectl apply -f /tmp/privileged-pod.yaml - Confirm that the request is rejected with an error message from PSA, Gatekeeper, or Kyverno, and that it is not merely recorded in audit logs while still allowing creation.
- On a
-
Document and standardize the configuration for future clusters
- In your OCI/OKE provisioning pipeline (Terraform modules, OCI Resource Manager stacks, or standard console build runbooks), add explicit steps/variables to:
- Always deploy and configure the chosen admission controller(s).
- Apply default namespace PSA labels and/or default Gatekeeper/Kyverno policies for C1–C5.
- Keep this documentation with your OKE cluster standard so future clusters automatically enforce workload policy at admission.
- In your OCI/OKE provisioning pipeline (Terraform modules, OCI Resource Manager stacks, or standard console build runbooks), add explicit steps/variables to:
Using kubectl
kubectl cannot configure or enable admission policy engines on Oracle OKE, because this is managed in the OKE control plane via the OCI Console, OCI CLI, or IaC (Terraform/Resource Manager). To plan and implement enforcement with Pod Security Admission, Kyverno, or OPA Gatekeeper, follow the guidance in the Manual Steps section instead.
Automation
#!/usr/bin/env bash
#
# Report admission policy enforcement state for an OKE cluster
# Requirements: kubectl configured with cluster-admin access
set -euo pipefail
echo "=== 1. Check for Pod Security Admission (PSA) enforcement via namespace labels ==="
echo
echo "# Namespaces with Pod Security labels (none may mean PSA not effectively used):"
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.pod-security\.kubernetes\.io/enforce}{"\t"}{.metadata.labels.pod-security\.kubernetes\.io/enforce-version}{"\n"}{end}' \
2>/dev/null | column -t || echo "Failed to list namespaces or PSA labels."
echo
echo "# Namespaces with NO PSA enforce label (these are not covered by Pod Security Admission):"
kubectl get ns -o json | jq -r '
.items[]
| select(.metadata.labels["pod-security.kubernetes.io/enforce"] == null)
| .metadata.name
' 2>/dev/null || echo "jq not available or failed to parse output."
echo
echo "=== 2. Check for Kyverno (workload policy engine) ==="
echo
echo "# Kyverno deployment in kyverno namespace:"
kubectl get deployment -n kyverno kyverno 2>/dev/null || echo "Kyverno deployment not found."
echo
echo "# Kyverno ClusterPolicies (cluster-wide workload policies):"
kubectl get clusterpolicies.kyverno.io 2>/dev/null || echo "No Kyverno ClusterPolicies found or Kyverno CRDs not installed."
echo
echo "# Kyverno Policies (namespaced workload policies):"
kubectl get policies.kyverno.io -A 2>/dev/null || echo "No Kyverno Policies found or Kyverno CRDs not installed."
echo
echo "# Kyverno policies that are not in enforce mode (audit / dryrun only):"
kubectl get clusterpolicies.kyverno.io -o json 2>/dev/null | jq -r '
.items[]
| select(.spec.validationFailureAction != "enforce")
| "\(.metadata.name)\t\(.spec.validationFailureAction)"
' 2>/dev/null || echo "No Kyverno ClusterPolicies in non-enforce mode or Kyverno not present."
echo
echo "=== 3. Check for OPA Gatekeeper (constraint-based enforcement) ==="
echo
echo "# Gatekeeper deployment in gatekeeper-system namespace:"
kubectl get deployment -n gatekeeper-system gatekeeper-controller-manager 2>/dev/null \
|| echo "Gatekeeper controller-manager deployment not found."
echo
echo "# Gatekeeper ConstraintTemplates (kinds of checks available):"
kubectl get constrainttemplates.templates.gatekeeper.sh 2>/dev/null \
|| echo "No ConstraintTemplates found or Gatekeeper CRDs not installed."
echo
echo "# Gatekeeper Constraints (actual enforcing instances) across all types:"
for kind in $(kubectl api-resources --api-group='constraints.gatekeeper.sh' -o name 2>/dev/null | cut -d. -f1); do
echo "## Constraints of kind: ${kind}"
kubectl get "${kind}.constraints.gatekeeper.sh" -A 2>/dev/null || echo " (none)"
done
echo
echo "=== 4. Spot-check: are example constraints/policies effectively enforcing? ==="
echo "# This section does not perform mutations; it just counts key policy objects."
echo
echo "# Count of namespaces without PSA enforce label (potentially unprotected):"
kubectl get ns -o json | jq '
.items
| map(select(.metadata.labels["pod-security.kubernetes.io/enforce"] == null))
| length
' 2>/dev/null || echo "jq not available or failed to count."
echo
echo "# Count of Kyverno ClusterPolicies in enforce mode:"
kubectl get clusterpolicies.kyverno.io -o json 2>/dev/null | jq '
.items
| map(select(.spec.validationFailureAction == "enforce"))
| length
' 2>/dev/null || echo "Kyverno not present or jq not available."
echo
echo "# Count of Gatekeeper Constraints (all types):"
total_constraints=0
for kind in $(kubectl api-resources --api-group='constraints.gatekeeper.sh' -o name 2>/dev/null | cut -d. -f1); do
count=$(kubectl get "${kind}.constraints.gatekeeper.sh" -A --no-headers 2>/dev/null | wc -l | tr -d ' ')
echo "${kind}: ${count}"
total_constraints=$((total_constraints + count))
done
echo "Total Gatekeeper constraints: ${total_constraints}"
echo
echo "=== Interpretation guidance ==="
cat <<'EOF'
Potential problems indicated by this report:
- Pod Security Admission:
- Many or all namespaces appear without the label:
pod-security.kubernetes.io/enforce
This generally means Pod Security Admission is not configured to enforce
workload policy, or enforcement is not applied to most workloads.
- Kyverno:
- The Kyverno deployment or CRDs are missing: Kyverno is not installed.
- There are zero ClusterPolicies / Policies: no Kyverno-based workload policies.
- All policies show validationFailureAction != "enforce" (e.g., "audit"):
policies are only auditing, not enforcing.
- OPA Gatekeeper:
- The gatekeeper-controller-manager deployment or CRDs are missing:
Gatekeeper is not installed.
- There are zero ConstraintTemplates / Constraints:
no constraint-based admission policies are in place.
This script only reports state; it does not configure OKE. If you see any of the
conditions above and you require enforcement, you must design and enable an
admission policy engine (PSA, Kyverno, or Gatekeeper) via OKE-compatible
manifests and/or OCI/OKE configuration and IaC.
EOF