Minimize Admission Of Containers With
More Info:
Containers with allowPrivilegeEscalation set to true can gain more privileges than their parent process. Enforce policies that restrict admission of such containers.
Risk Level
High
Address
Security
Compliance Standards
- CIS OKE
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Identify current use of
allowPrivilegeEscalationacross workloads- Run on: any machine with kubectl access
- Command:
kubectl get pods --all-namespaces -o json \| jq -r '.items[]| {ns:.metadata.namespace, pod:.metadata.name, ctrs:(.spec.containers + (.spec.initContainers // []))}| .ctrs[]| select(.securityContext.allowPrivilegeEscalation == true)| "\(.ns) \(.pod) \(.name) allowPrivilegeEscalation=true"'
- Save the output and review which namespaces/pods/containers currently rely on
allowPrivilegeEscalation=true.
-
Assess necessity and impact per workload
- For each listed container:
- Check its manifest:
kubectl get pod <pod-name> -n <namespace> -o yaml
- Review with the workload owner whether privilege escalation is truly required (e.g., needs to setuid, load kernel modules, manipulate other users’ processes).
- Classify each as: “must have”, “can be removed now”, or “needs migration work”.
- Check its manifest:
- For each listed container:
-
Design namespace-level policy using Pod Security Admission or a policy engine
- If using Pod Security Admission (recommended for OKE where available):
- Decide which namespaces need to run privileged or legacy workloads and which should be restricted.
- Example: mark “restricted” namespaces to block privilege escalation:
kubectl label namespace <namespace> \pod-security.kubernetes.io/enforce=restricted \pod-security.kubernetes.io/enforce-version=latest \--overwrite
- If using a policy engine (e.g., Gatekeeper/Kyverno), plan a policy that denies pods where any container has
securityContext.allowPrivilegeEscalation=true, with explicit exceptions for approved namespaces or workloads.
- If using Pod Security Admission (recommended for OKE where available):
-
Implement or tighten the policy and test against current workloads
- Apply or update the chosen policy configuration (namespace labels or policy CRDs) according to your platform’s standard process.
- Before enforcing, use “audit” or “dry-run” modes where supported to detect which existing pods/Deployments would be blocked:
- For Pod Security Admission, inspect namespace warnings when applying manifests.
- For Gatekeeper/Kyverno, check policy “audit” reports or
kubectl describeon the policy object to see violations.
-
Remediate or exempt necessary workloads
- For each container classified as “can be removed now”:
- Update its Deployment/StatefulSet/Pod manifest to explicitly set:
securityContext:allowPrivilegeEscalation: false
- Apply the change:
kubectl apply -f <updated-manifest>.yaml
- Update its Deployment/StatefulSet/Pod manifest to explicitly set:
- For each “must have” or “needs migration work” workload:
- Either place it in a dedicated namespace with a less-restrictive policy and clear justification, or define a narrowly scoped exception in your policy engine.
- Document the justification and planned timeline for reduction where possible.
- For each container classified as “can be removed now”:
-
Verify policy effectiveness and ongoing compliance
- Re-run the evidence command:
kubectl get pods --all-namespaces -o json \| jq -r '.items[]| {ns:.metadata.namespace, pod:.metadata.name, ctrs:(.spec.containers + (.spec.initContainers // []))}| .ctrs[]| select(.securityContext.allowPrivilegeEscalation == true)| "\(.ns) \(.pod) \(.name) allowPrivilegeEscalation=true"'
- Confirm that:
- “Restricted” namespaces no longer admit new pods with
allowPrivilegeEscalation=true. - Any remaining instances are explicitly approved exceptions with documented risk and controls.
- “Restricted” namespaces no longer admit new pods with
- Re-run the evidence command:
Using kubectl
# 1) List all namespaces that may need policies
# Run on: any machine with kubectl access
kubectl get ns
Review which namespaces contain user workloads (exclude system namespaces such as kube-system, kube-public, kube-node-lease, and provider-specific system namespaces). For each user namespace, inspect current pods:
# 2) List all pods in a namespace, including their security context
# Replace <namespace> with the namespace to review
kubectl get pods -n <namespace> -o yaml | grep -nE 'name:|securityContext:|allowPrivilegeEscalation'
Output is a YAML stream; lines like:
securityContext:
allowPrivilegeEscalation: true
or container-level:
containers:
- name: app
securityContext:
allowPrivilegeEscalation: true
indicate containers that currently allow privilege escalation and therefore should be reviewed.
To see the full definition for a specific pod with a suspect setting:
# 3) Describe a specific pod
kubectl get pod <pod-name> -n <namespace> -o yaml
Look for securityContext at both pod and container level; any explicit allowPrivilegeEscalation: true is a potential problem.
Next, inspect whether the namespace has any admission policies (Pod Security Standards, PodSecurityPolicy if legacy, or custom policies) that would restrict such pods:
# 4) Check Pod Security admission labels on the namespace (if using built-in Pod Security)
kubectl get ns <namespace> -o yaml | grep -n 'pod-security.kubernetes.io'
If there are no pod-security.kubernetes.io/* labels, or they are set to a privileged mode (e.g. privileged or a custom relaxed configuration elsewhere), the namespace likely does not restrict allowPrivilegeEscalation: true.
If you are using admission webhooks (e.g., Gatekeeper, Kyverno), list related resources for review:
# 5) (Gatekeeper example) List constraints that might govern allowPrivilegeEscalation
kubectl get constrainttemplates,gkconstraints,validatingwebhookconfigurations -A
Absence of any constraints or webhook configurations that mention allowPrivilegeEscalation or container privilege in their names/annotations suggests the cluster may not be enforcing restrictions.
Verification after any policy changes (manual, outside the scope of these commands):
# 6) Re-scan pods in the namespace to confirm where allowPrivilegeEscalation is still in use
kubectl get pods -n <namespace> -o yaml | grep -n 'allowPrivilegeEscalation'
Any remaining allowPrivilegeEscalation: true entries highlight pods that are either exempted by policy or running in namespaces without restrictive policies and need human review against your risk tolerance.
Automation
#!/usr/bin/env bash
# Report pods whose containers can escalate privileges (allowPrivilegeEscalation=true or unset)
set -euo pipefail
# Requires: kubectl, jq
# Runs on: any machine with kubectl access and cluster-wide read permissions
echo "=== Scanning all namespaces for pods with allowPrivilegeEscalation risk ===" >&2
# 1) List all pods with full spec as JSON
pods_json="$(kubectl get pods --all-namespaces -o json)"
# 2) For each pod, print containers where allowPrivilegeEscalation is true or not set
echo
echo "Namespace,Pod,Container,Type,allowPrivilegeEscalation,Source"
echo "---------,---,---------,----,------------------------,------"
echo "${pods_json}" | jq -r '
.items[]
| . as $pod
| (
# normal containers
($pod.spec.containers[]? | {type:"container", name:.name, secc: .securityContext})
),
(
# initContainers
($pod.spec.initContainers[]? | {type:"initContainer", name:.name, secc: .securityContext})
),
(
# ephemeralContainers
($pod.spec.ephemeralContainers[]? | {type:"ephemeralContainer", name:.name, secc: .securityContext})
)
| . as $c
| ($pod.metadata.namespace // "default") as $ns
| ($pod.metadata.name) as $podname
| ($c.name) as $cname
| ($c.type) as $ctype
| ($c.secc // {}) as $secc
|
# Determine effective allowPrivilegeEscalation for the container:
# 1. Container.securityContext.allowPrivilegeEscalation if set
# 2. Else Pod.spec.securityContext.allowPrivilegeEscalation if set
# 3. Else "unset" (treated as risky)
(
if ($secc.allowPrivilegeEscalation != null) then
{ape: $secc.allowPrivilegeEscalation, source: "container.securityContext"}
else
(
if ($pod.spec.securityContext.allowPrivilegeEscalation != null) then
{ape: $pod.spec.securityContext.allowPrivilegeEscalation, source: "pod.securityContext"}
else
{ape: "unset", source: "not-specified"}
end
)
end
) as $eff
|
# Only print rows that are risky: allowPrivilegeEscalation=true or unset
select($eff.ape == true or $eff.ape == "unset")
|
[
$ns,
$podname,
$cname,
$ctype,
($eff.ape|tostring),
$eff.source
]
| @csv
'
cat <<'EOF'
Interpretation:
- Every printed line represents a container that is NOT compliant with the intent
of "Minimize admission of containers with allowPrivilegeEscalation":
Columns:
Namespace Namespace of the pod
Pod Pod name
Container Container name
Type container | initContainer | ephemeralContainer
allowPrivilegeEscalation "true" or "unset"
Source Where the value comes from:
- container.securityContext
- pod.securityContext
- not-specified (no explicit setting)
- Problematic output:
- allowPrivilegeEscalation == "true":
The container explicitly allows privilege escalation and should be reviewed
and restricted by admission policies if not strictly required.
- allowPrivilegeEscalation == "unset":
No explicit setting; effective behavior depends on cluster defaults.
Treat these as needing review and policy coverage.
- If the script prints NO data rows (only the header and this explanation),
then all containers explicitly set allowPrivilegeEscalation=false, which is
the desired state from a workload perspective. You still need to ensure
admission policies are in place per namespace as required by the benchmark.
EOF