Skip to main content

Minimize The Admission Of Containers With

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