Skip to main content

Minimize The Admission Of Containers With allowPrivilegeEscalation

More Info:​

Containers with allowPrivilegeEscalation set to true can gain more privileges than their parent process. Their admission should be restricted via Pod Security Admission policies.

Risk Level​

High

Address​

Security

Compliance Standards​

  • CIS AKS

Triage and Remediation​

Remediation​

Manual Steps
  1. Identify namespaces with user workloads and current Pod Security labels

    • Run on: any machine with kubectl access
    kubectl get ns --show-labels
    • Decide which namespaces are true “user workload” namespaces (exclude kube-system, gatekeeper-system, aks-*, monitoring/logging system namespaces, etc.), and note if they already have pod-security.kubernetes.io/* labels.
  2. Review current use of allowPrivilegeEscalation in those namespaces

    • Run on: any machine with kubectl access
    # List pods whose containers explicitly set allowPrivilegeEscalation to true
    for ns in NAMESPACE1 NAMESPACE2 NAMESPACE3; do
    echo "=== $ns ==="
    kubectl get pods -n "$ns" -o json | \
    jq -r '
    .items[] |
    {pod: .metadata.name,
    containers: (
    ([.spec.initContainers[]?] + [.spec.containers[]?]) |
    map(select(.securityContext.allowPrivilegeEscalation == true) |
    {name, allowPrivilegeEscalation: .securityContext.allowPrivilegeEscalation})
    )
    } |
    select(.containers | length > 0)
    '
    done
    • If jq is unavailable, save pod specs and review manually:
    kubectl get pods -n NAMESPACE -o yaml > pods-NAMESPACE.yaml
    # Search for allowPrivilegeEscalation: true in the file
  3. Decide which workloads legitimately require allowPrivilegeEscalation=true

    • For each pod/container identified above, review with the owning application/team:
      • Why is allowPrivilegeEscalation: true needed?
      • Can the image or behavior be changed to work with allowPrivilegeEscalation: false?
    • Classify each workload as:
      • “Can be fixed to allowPrivilegeEscalation: false”
      • “Requires exception and must run in a non-restricted namespace”
  4. Harden pod specs where escalation is not required

    • For pods that do not truly need escalation, update their Deployment/StatefulSet/Job manifests to explicitly set:
    securityContext:
    allowPrivilegeEscalation: false
    • Apply the manifest updates:
    kubectl apply -f UPDATED-MANIFEST.yaml
    • Re-run step 2 for the affected namespaces to confirm that no pods retain allowPrivilegeEscalation: true except those intentionally exempt.
  5. Apply Pod Security Admission labels to enforce restricted policy

    • For user-workload namespaces where all (or all but explicit exception) workloads can comply, enforce restricted and enable warnings cluster-wide:
    • Run on: any machine with kubectl access
    # Enable warnings for all namespaces at least at baseline
    kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline

    # Enforce restricted where appropriate
    kubectl label --overwrite ns NAMESPACE1 pod-security.kubernetes.io/enforce=restricted
    kubectl label --overwrite ns NAMESPACE2 pod-security.kubernetes.io/enforce=restricted
    • For namespaces that must host non-compliant workloads, do NOT set enforce=restricted; instead, consider isolating them and documenting the exception.
  6. Verify enforcement and ongoing compliance

    • Attempt to create a test pod with allowPrivilegeEscalation: true in an enforced namespace (it should be rejected):
    cat <<'EOF' > test-ape-true.yaml
    apiVersion: v1
    kind: Pod
    metadata:
    name: test-ape-true
    spec:
    containers:
    - name: c
    image: busybox
    command: ["sh", "-c", "sleep 3600"]
    securityContext:
    allowPrivilegeEscalation: true
    EOF

    kubectl apply -n NAMESPACE1 -f test-ape-true.yaml
    • Confirm the admission failure message references Pod Security restricted and allowPrivilegeEscalation.
    • Periodically repeat step 2 (or integrate into CI) to ensure no new workloads reintroduce allowPrivilegeEscalation: true in restricted namespaces.
Using kubectl
# 1) List all namespaces and their Pod Security Admission labels
# Run on: any machine with kubectl access
kubectl get ns -o custom-columns=NAME:.metadata.name,ENFORCE:.metadata.labels.pod-security\.kubernetes\.io/enforce,WARN:.metadata.labels.pod-security\.kubernetes\.io/warn

# Problem indication:
# - ENFORCE is <none>, empty, or not "restricted" in namespaces that host user workloads.
# - WARN is <none> or not at least "baseline" where you expect warnings.

# 2) Show detailed labels on a specific namespace (replace with the namespace under review)
kubectl get ns default -o yaml | sed -n '/labels:/,/^ [^ ]/p'

# Problem indication:
# - labels section missing, or pod-security.kubernetes.io/enforce not set to "restricted"
# in a user-workload namespace.
# - No pod-security.kubernetes.io/warn label if you expect warnings for policy violations.

# 3) Find pods that explicitly allow privilege escalation
kubectl get pods --all-namespaces -o json \
| jq '.items[]
| {ns: .metadata.namespace, pod: .metadata.name,
containers: ([.spec.containers[], (.spec.initContainers // [])[]?]
| map({name, allowPrivilegeEscalation: (.securityContext.allowPrivilegeEscalation // "unset")}))}'

# Problem indication:
# - Any container or initContainer with "allowPrivilegeEscalation": true
# - Lack of PSA enforcement labels in the same namespace (from step 1) suggests
# there is nothing preventing future similar pods.

# 4) Test how Pod Security Admission would treat a sample pod in a namespace
# (dry-run create with an explicitly privileged container)
cat <<'EOF' | kubectl apply -f - --dry-run=server -n default
apiVersion: v1
kind: Pod
metadata:
name: psa-ape-test
spec:
containers:
- name: c
image: busybox
command: ["sh", "-c", "sleep 3600"]
securityContext:
allowPrivilegeEscalation: true
EOF

# Problem indication:
# - If the namespace is properly enforcing "restricted", this dry-run should fail
# with an admission error referencing PodSecurity restricted level.
# - If it is accepted (exit code 0 and no admission error), the namespace does NOT
# currently block allowPrivilegeEscalation=true.

# 5) Check for existing Azure Policy / Gatekeeper constraints that might also govern this
kubectl get constrainttemplates,constraints --all-namespaces 2>/dev/null

# Problem indication:
# - No constraints related to allowPrivilegeEscalation when your organization expects
# centralized policy enforcement beyond Pod Security Admission.
Automation
#!/usr/bin/env bash
#
# Report pods that allow privilege escalation, and namespaces without
# Pod Security Admission 'restricted' enforcement.
#
# Requirements:
# - Run on any machine with kubectl access to the cluster
# - kubectl must be configured with appropriate permissions

set -euo pipefail

echo "=== 1) Namespaces and Pod Security Admission labels ==="
echo
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.pod-security\.kubernetes\.io/enforce}{"\t"}{.metadata.labels.pod-security\.kubernetes\.io/warn}{"\n"}{end}' \
| awk 'BEGIN { OFS="\t"; print "NAMESPACE","ENFORCE_LABEL","WARN_LABEL" }1' \
| column -t

cat <<'EOF'

Interpretation:
- NAMESPACEs with ENFORCE_LABEL not set to "restricted" do NOT enforce the Restricted Pod Security level.
These namespaces are candidates where allowPrivilegeEscalation=true might still be admitted.
- WARN_LABEL set to "baseline" only emits warnings; it does NOT block pods.

EOF

echo "=== 2) Pods/containers with allowPrivilegeEscalation = true or unset (implicitly true) ==="
echo
# This lists *all* containers where allowPrivilegeEscalation is either explicitly true
# or not specified (which defaults to true).
kubectl get pods -A -o json | \
jq -r '
.items[]
| {
ns: .metadata.namespace,
pod: .metadata.name,
containers: (
([.spec.containers[]? | {name, ape: ( .securityContext.allowPrivilegeEscalation // "UNSET" )}] +
[.spec.initContainers[]? | {name, ape: ( .securityContext.allowPrivilegeEscalation // "UNSET" )}])
)
}
| select(.containers | length > 0)
| .containers[]
| select(.ape == true or .ape == "UNSET")
| "\(.ns)\t\(.pod)\t\(.name)\t\(.ape)"
' 2>/dev/null \
| awk 'BEGIN { OFS="\t"; print "NAMESPACE","POD","CONTAINER","allowPrivilegeEscalation" }1' \
| column -t

cat <<'EOF'

Interpretation:
- Rows where allowPrivilegeEscalation == "true":
Container explicitly allows privilege escalation; this is a policy violation candidate.
- Rows where allowPrivilegeEscalation == "UNSET":
The field is not set, which defaults to true in Kubernetes; these should be reviewed and
considered for explicit allowPrivilegeEscalation: false under a Restricted policy.

Problem indicators:
- User-workload namespaces WITHOUT pod-security.kubernetes.io/enforce=restricted.
- Any container (init or app) listed above with allowPrivilegeEscalation=true or UNSET
in namespaces where you intend to enforce Restricted Pod Security.

NOTE:
- This script is for review and triage; fixing workloads requires case-by-case changes
to pod specs/manifests and careful coordination with application owners.
EOF