> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Minimize Admission Containers AllowPrivilegeEscalation

### More Info:

Do not generally permit containers to be run with the allowPrivilegeEscalation flag set to true. Allowing this right can lead to a process running a container getting more rights than it started with.

### Risk Level

High

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **List all pods with `allowPrivilegeEscalation=true`** (any machine with kubectl access)
           ```bash theme={null}
           kubectl get pods --all-namespaces -o json \
           | jq -r '.items[]
             | . as $pod
             | .spec.containers[]
             | select(.securityContext.allowPrivilegeEscalation == true)
             | "NAMESPACE=\($pod.metadata.namespace) POD=\($pod.metadata.name) CONTAINER=\(.name)"'
           ```

        2. **Decide which workloads are allowed an exception** (manual review)\
           For each listed pod/container:
           * Determine if it is a user workload vs. a system/infra component.
           * For user workloads, strongly prefer **no privilege escalation**.
           * Only allow escalation if there is a documented, reviewed need (e.g., a process that must gain extra Linux capabilities after start).
           * For system/infra workloads, prefer to run them in dedicated namespaces with a clearly documented exception policy.

        3. **Create or update a baseline policy in each user-workload namespace** (any machine with kubectl access)\
           Example using a `PodSecurityPolicy`-style Kyverno policy (adjust to your chosen admission controller/tooling):
           ```bash theme={null}
           cat << 'EOF' | kubectl apply -f -
           apiVersion: kyverno.io/v1
           kind: ClusterPolicy
           metadata:
             name: disallow-privilege-escalation
           spec:
             validationFailureAction: Enforce
             background: true
             rules:
               - name: disallow-privilege-escalation
                 match:
                   any:
                     - resources:
                         kinds:
                           - Pod
                         namespaces:
                           - "user-namespace-1"
                           - "user-namespace-2"
                 validate:
                   message: "Containers must not enable allowPrivilegeEscalation."
                   pattern:
                     spec:
                       containers:
                         - securityContext:
                             allowPrivilegeEscalation: "false"
           EOF
           ```
           Replace `user-namespace-1`, `user-namespace-2` with the actual namespaces that host user workloads. If you use PSA/PSP, configure the equivalent “restricted” behavior that forbids privilege escalation.

        4. **Update existing workload manifests to disable privilege escalation** (any machine with kubectl access)\
           For each non-exempt Deployment/StatefulSet/DaemonSet/Job in user namespaces, patch containers to set `allowPrivilegeEscalation: false`:
           ```bash theme={null}
           # example for a single Deployment
           kubectl -n user-namespace-1 patch deployment my-app \
             --type='json' \
             -p='[
               {
                 "op": "add",
                 "path": "/spec/template/spec/containers/0/securityContext",
                 "value": {
                   "allowPrivilegeEscalation": false
                 }
               }
             ]'
           ```
           Adjust `namespace`, `deployment`, container index, and, if needed, merge with any existing `securityContext` instead of overwriting it.

        5. **Handle justified exceptions explicitly** (any machine with kubectl access)
           * For workloads you decided must keep `allowPrivilegeEscalation: true`, place them in dedicated namespaces and/or label them, and update your admission policy to **match on those namespaces/labels and allow** the setting.
           * Document each exception: purpose, owner, review date, and risk acceptance.

        6. **Verify no pods are running with `allowPrivilegeEscalation=true` (except approved exceptions)** (any machine with kubectl access)
           ```bash theme={null}
           kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace
           do
             kubectl get pod "${pod_name}" --namespace "${pod_namespace}" -o json \
             | jq -c '.spec.containers[]' | while read -r container
             do
               container_name=$(echo ${container} | jq -r '.name')
               container_allowprivesc=$(echo ${container} | jq -r '.securityContext.allowPrivilegeEscalation' | sed -e 's/null/notset/g')
               if [ "${container_allowprivesc}" = "false" ] || [ "${container_allowprivesc}" = "notset" ]; then
                 echo "***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: true"
               else
                 echo "***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: false"
               fi
             done
           done
           ```
           Investigate any `is_compliant: false` entries and ensure they are either corrected or explicitly approved exceptions.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) Create a baseline Pod Security restricted policy in each user-workload namespace
        #    (run on any machine with kubectl access)

        # Example: apply to one namespace "my-app-namespace"
        cat << 'EOF' | kubectl apply -f -
        apiVersion: v1
        kind: Namespace
        metadata:
          name: my-app-namespace
          labels:
            pod-security.kubernetes.io/enforce: restricted
            pod-security.kubernetes.io/enforce-version: latest
            pod-security.kubernetes.io/warn: restricted
            pod-security.kubernetes.io/warn-version: latest
            pod-security.kubernetes.io/audit: restricted
            pod-security.kubernetes.io/audit-version: latest
        EOF

        # For existing namespaces, patch them to enforce the restricted profile
        kubectl label namespace my-app-namespace \
          pod-security.kubernetes.io/enforce=restricted \
          pod-security.kubernetes.io/enforce-version=latest \
          pod-security.kubernetes.io/warn=restricted \
          pod-security.kubernetes.io/warn-version=latest \
          pod-security.kubernetes.io/audit=restricted \
          pod-security.kubernetes.io/audit-version=latest \
          --overwrite


        # 2) Optionally, add an explicit ValidatingAdmissionPolicy to reject allowPrivilegeEscalation=true
        #    (Kubernetes 1.26+ with validaton admission policies enabled)

        # Create the ValidatingAdmissionPolicy
        cat << 'EOF' | kubectl apply -f -
        apiVersion: admissionregistration.k8s.io/v1
        kind: ValidatingAdmissionPolicy
        metadata:
          name: deny-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, has(c.securityContext) && c.securityContext.allowPrivilegeEscalation == true))"
            message: "Containers must not set securityContext.allowPrivilegeEscalation to true."
          - expression: "!(has(object.spec.initContainers) && object.spec.initContainers.exists(c, has(c.securityContext) && c.securityContext.allowPrivilegeEscalation == true))"
            message: "Init containers must not set securityContext.allowPrivilegeEscalation to true."
        EOF

        # Bind the policy only to user-workload namespaces (example: my-app-namespace)
        cat << 'EOF' | kubectl apply -f -
        apiVersion: admissionregistration.k8s.io/v1
        kind: ValidatingAdmissionPolicyBinding
        metadata:
          name: deny-allow-privilege-escalation-binding
        spec:
          policyName: deny-allow-privilege-escalation
          validationActions: ["Deny"]
          matchResources:
            namespaceSelector:
              matchLabels:
                security.kubernetes.io/user-workload: "true"
        EOF

        # Label user-workload namespaces so the binding applies to them
        kubectl label namespace my-app-namespace security.kubernetes.io/user-workload=true --overwrite


        # 3) Verification (run on any machine with kubectl access)

        # Re-run the original audit; no lines should end with "is_compliant: false"
        kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace
        do
          kubectl get pod "${pod_name}" --namespace "${pod_namespace}" -o json | jq -c '.spec.containers[]' | while read -r container
          do
            container_name=$(echo ${container} | jq -r '.name')
            container_allowprivesc=$(echo ${container} | jq -r '.securityContext.allowPrivilegeEscalation' | sed -e 's/null/notset/g')
            if [ "${container_allowprivesc}" = "false" ] || [ "${container_allowprivesc}" = "notset" ]; then
              echo "***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: true"
            else
              echo "***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: false"
            fi
          done
        done
        ```
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Enforce: Minimize Admission Containers allowPrivilegeEscalation
        # Scope:   Any machine with kubectl access to the cluster
        #
        # Approach:
        # - Create/patch a restrictive policy per namespace (where user workloads run)
        # - Policy denies containers with securityContext.allowPrivilegeEscalation=true
        # - Policy allows pods where allowPrivilegeEscalation is false or not set
        #
        # NOTE:
        # - This script assumes:
        #   * You are using Kubernetes >= 1.25 with Pod Security Admission (PSA), OR
        #   * You can enforce admission via a ValidatingWebhookConfiguration/Policy engine.
        # - Because this benchmark control is MANUAL, there is no single mandatory mechanism.
        #   This script uses built‑in Pod Security Admission labels with the "restricted" profile,
        #   which explicitly disallows privilege escalation by default.
        #
        # Operational impact:
        # - Applying the "restricted" PSA level/versions on namespaces may cause admission
        #   failures for future pod creations in those namespaces if they violate restricted policy.
        #
        # Idempotency:
        # - Namespace labels are applied with "kubectl label --overwrite", so re-running is safe.
        #
        # REQUIREMENTS:
        # - kubectl installed and configured (KUBECONFIG or in-cluster config)
        # - jq installed
        #
        # USAGE:
        #   ./enforce_no_priv_escalation.sh              # target all namespaces EXCEPT system ones
        #   ./enforce_no_priv_escalation.sh ns1 ns2 ...  # target specific namespaces only

        set -euo pipefail

        # -------- Configuration --------

        # System / control namespaces to skip by default
        SYSTEM_NAMESPACES=(
          kube-system
          kube-public
          kube-node-lease
          local-path-storage
          ingress-nginx
          cert-manager
          tigera-operator
        )

        # PSA level/profile and version to enforce
        PSA_LEVEL="restricted"
        PSA_VERSION="latest"

        # -------- Helper functions --------

        is_system_namespace() {
          local ns="$1"
          for s in "${SYSTEM_NAMESPACES[@]}"; do
            if [[ "$ns" == "$s" ]]; then
              return 0
            fi
          done
          return 1
        }

        log() {
          printf '%s\n' "$*" >&2
        }

        # -------- Namespace selection --------

        if [[ "$#" -gt 0 ]]; then
          TARGET_NAMESPACES=("$@")
        else
          # All namespaces except the system ones
          mapfile -t TARGET_NAMESPACES < <(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
        fi

        if [[ "${#TARGET_NAMESPACES[@]}" -eq 0 ]]; then
          log "No target namespaces found."
          exit 0
        fi

        # -------- Apply Pod Security Admission labels --------

        for ns in "${TARGET_NAMESPACES[@]}"; do
          if is_system_namespace "$ns"; then
            log "Skipping system namespace: $ns"
            continue
          fi

          log "Enforcing PSA '${PSA_LEVEL}' on namespace: $ns"

          # Apply pod-security.kubernetes.io/enforce and version labels.
          kubectl label namespace "$ns" \
            "pod-security.kubernetes.io/enforce=${PSA_LEVEL}" \
            "pod-security.kubernetes.io/enforce-version=${PSA_VERSION}" \
            --overwrite >/dev/null

          # Optional: also set 'warn' and 'audit' labels for easier detection/visibility
          kubectl label namespace "$ns" \
            "pod-security.kubernetes.io/warn=${PSA_LEVEL}" \
            "pod-security.kubernetes.io/warn-version=${PSA_VERSION}" \
            "pod-security.kubernetes.io/audit=${PSA_LEVEL}" \
            "pod-security.kubernetes.io/audit-version=${PSA_VERSION}" \
            --overwrite >/dev/null
        done

        # -------- Verification --------
        # Re-run the benchmark audit and show only NON-COMPLIANT pods (if any).
        # This uses the exact logic from the finding.

        log ""
        log "Verification: scanning for containers with allowPrivilegeEscalation=true ..."
        log "Only non-compliant containers (is_compliant: false) will be shown."

        kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | \
        while read -r pod_name pod_namespace; do
          kubectl get pod "${pod_name}" --namespace "${pod_namespace}" -o json | \
          jq -c '.spec.containers[]' | while read -r container; do
            container_name=$(echo "${container}" | jq -r '.name')
            container_allowprivesc=$(echo "${container}" | jq -r '.securityContext.allowPrivilegeEscalation' | sed -e 's/null/notset/g')
            if [ "${container_allowprivesc}" = "false" ] || [ "${container_allowprivesc}" = "notset" ]; then
              :
            else
              echo "***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: false"
            fi
          done
        done

        log ""
        log "If no lines with 'is_compliant: false' are printed above, the cluster is compliant with respect to existing Pods."
        log "New Pods in labeled namespaces will be denied if they attempt to set allowPrivilegeEscalation=true under the restricted profile."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://kubernetes.io/docs/concepts/security/pod-security-standards/](https://kubernetes.io/docs/concepts/security/pod-security-standards/)
