Minimize The Admission Of Containers With
More Info:
Containers with allowPrivilegeEscalation set to true can gain more privileges than their parent process. Restrict their admission via namespace policies.
Risk Level
High
Address
Security
Compliance Standards
- CIS EKS
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Identify namespaces with user workloads that allow privilege escalation
Run on: any machine with kubectl accesskubectl get pods --all-namespaces -o json | \jq -r '.items[]| select(any(.spec.containers[]?; .securityContext?.allowPrivilegeEscalation == true))| .metadata.namespace' | sort -u -
Create or update a Pod Security Admission configuration to forbid allowPrivilegeEscalation
Run on: any machine with kubectl access
Save this to a file, for example/tmp/psa-restrict-allow-priv-escalation.yaml:apiVersion: policy/v1kind: PodDisruptionBudget # placeholder kind to indicate MANUAL POLICY STEPmetadata:name: MANUAL-REVIEW-POD-SECURITY-POLICYPodSecurityPolicy is deprecated/removed in most EKS clusters and there is no single standard policy object defined in the benchmark text. You must choose and configure a namespace-level admission control mechanism supported by your environment (for example: built-in Pod Security Admission labels
pod-security.kubernetes.io/enforce=restricted, or a validating admission webhook such as Kyverno or OPA/Gatekeeper) to reject pods where any container hassecurityContext.allowPrivilegeEscalation: true. Follow your chosen tool’s documentation to create that policy and apply it to each user-workload namespace. -
Label user-workload namespaces to use the chosen restrictive policy mechanism
Run on: any machine with kubectl access
Example for built-in Pod Security Admission (if enabled in your cluster):# Replace <namespace> with each namespace from step 1 that holds user workloadskubectl label namespace <namespace> \pod-security.kubernetes.io/enforce=restricted \pod-security.kubernetes.io/audit=restricted \pod-security.kubernetes.io/warn=restricted --overwriteIf using another mechanism (Kyverno, Gatekeeper, etc.), apply the equivalent namespace selectors/labels that make your “no allowPrivilegeEscalation=true” policy apply to those namespaces.
-
Manually review and update existing workloads that currently set allowPrivilegeEscalation: true
Run on: any machine with kubectl access
List offending pods with owners to identify the controllers you must edit:kubectl get pods --all-namespaces -o json | \jq -r '.items[]| select(any(.spec.containers[]?; .securityContext?.allowPrivilegeEscalation == true))| .metadata.namespace + " " + .metadata.name + " " +( .metadata.ownerReferences[0].kind // "Pod" ) + " " +( .metadata.ownerReferences[0].name // .metadata.name )'For each controller (Deployment/DaemonSet/StatefulSet/Job/etc.), edit the manifest so that every container and initContainer either omits
allowPrivilegeEscalationor explicitly sets it tofalse:# Example for a Deploymentkubectl -n <namespace> edit deployment <name>In the editor, under each
spec.template.spec.containers[].securityContext(andinitContainersif present), ensure:securityContext:allowPrivilegeEscalation: false -
Recreate or restart workloads if needed to pick up policy-compliant settings
Run on: any machine with kubectl access
If you changed manifests in Git/IaC instead of withkubectl edit, apply them:kubectl apply -f <updated-manifest>.yamlFor Helm-managed workloads, update the values and upgrade:
helm upgrade <release-name> <chart> -n <namespace> -f <values>.yaml -
Verification
Run on: any machine with kubectl accesskubectl get pods --all-namespaces -o json | \jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.allowPrivilegeEscalation == true)then "ALLOWPRIVILEGEESCALTION_FOUND"else "NO_ALLOWPRIVILEGEESCALATION"end'Confirm the output is:
NO_ALLOWPRIVILEGEESCALATION
Using kubectl
# 1) Create a baseline policy in each user workload namespace
# Replace <NAMESPACE> with your workload namespace name
# Run on: any machine with kubectl access
cat << 'EOF' | kubectl apply -f -
apiVersion: policy/v1
kind: PodSecurityPolicy
metadata:
name: disallow-allow-privilege-escalation
labels:
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/enforce: restricted
spec:
privileged: false
allowPrivilegeEscalation: false
defaultAllowPrivilegeEscalation: false
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
fsGroup:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- '*'
EOF
# 2) Bind the policy in a specific namespace
# Replace <NAMESPACE> with your workload namespace name
cat << 'EOF' | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: use-psp-disallow-allow-privilege-escalation
namespace: <NAMESPACE>
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames:
- disallow-allow-privilege-escalation
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: use-psp-disallow-allow-privilege-escalation
namespace: <NAMESPACE>
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: use-psp-disallow-allow-privilege-escalation
subjects:
# Adjust subjects to match who creates pods in this namespace
- kind: Group
name: system:serviceaccounts:<NAMESPACE>
apiGroup: rbac.authorization.k8s.io
EOF
# 3) (Optional) Repeat step 2 for each additional workload namespace
# Example for another namespace:
sed 's/namespace: <NAMESPACE>/namespace: my-workload-namespace-2/g' \
use-psp-disallow-allow-privilege-escalation.yaml | kubectl apply -f -
# 4) Verification: ensure no admitted pods have allowPrivilegeEscalation=true
kubectl get pods --all-namespaces -o json | \
jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.allowPrivilegeEscalation == true) then "ALLOWPRIVILEGEESCALTION_FOUND" else "NO_ALLOWPRIVILEGEESCALATION" end'
Automation
#!/usr/bin/env bash
set -euo pipefail
# This script:
# - Creates a Pod Security Admission restricted policy that disallows allowPrivilegeEscalation=true
# - Labels all non-system namespaces to use that policy
# - Verifies that no pods with allowPrivilegeEscalation=true exist
#
# Run on: any machine with kubectl access and context pointing to the target cluster.
# 1) Create/Update a restricted Pod Security Admission policy via a ValidatingAdmissionPolicy
# that forbids allowPrivilegeEscalation=true (in containers and initContainers).
# This is idempotent (kubectl apply).
cat <<'EOF' | kubectl apply -f -
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: disallow-allow-privilege-escalation
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
validations:
- expression: "!(has(object.spec.containers) && object.spec.containers.exists(c, c.securityContext != null && c.securityContext.allowPrivilegeEscalation == true))"
message: "Containers must not set securityContext.allowPrivilegeEscalation=true"
- expression: "!(has(object.spec.initContainers) && object.spec.initContainers.exists(c, c.securityContext != null && c.securityContext.allowPrivilegeEscalation == true))"
message: "Init containers must not set securityContext.allowPrivilegeEscalation=true"
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: disallow-allow-privilege-escalation-binding
spec:
policyName: disallow-allow-privilege-escalation
validationActions:
- Deny
matchResources:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values:
- kube-system
- kube-public
- kube-node-lease
- default
EOF
# 2) Label all non-system namespaces that host user workloads, so they are clearly identified.
# Adjust the excluded list if needed. This is safe and idempotent.
for ns in $(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'); do
case "$ns" in
kube-system|kube-public|kube-node-lease)
continue
;;
esac
# Label as a user-workload namespace (key is arbitrary but stable).
kubectl label ns "$ns" pod-security.kubernetes.io/user-workload=true --overwrite
done
# 3) Verification: ensure there are no pods with allowPrivilegeEscalation=true
# Matches the benchmark audit command.
echo "Running verification..."
kubectl get pods --all-namespaces -o json | \
jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.allowPrivilegeEscalation == true) then "ALLOWPRIVILEGEESCALTION_FOUND" else "NO_ALLOWPRIVILEGEESCALATION" end'