Skip to main content

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

Manual Steps
  1. Identify current use of allowPrivilegeEscalation across 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.
  2. 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”.
  3. 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.
  4. 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 describe on the policy object to see violations.
  5. 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
    • 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.
  6. 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.
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