> ## 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 With Allow Privilege Escalation

### 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

* APRA CPS 234 (Australia)
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CIS EKS
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* DPDPA
* Digital Operational Resilience Act (EU)
* Essential 8
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. List namespaces that host user workloads (to decide where to apply restriction)
           * Run on: any machine with kubectl access
           ```bash theme={null}
           kubectl get namespaces
           ```
           Identify all non-system namespaces (exclude those starting with kube- and the default system ones used by your provider) where you deploy applications.

        2. For each selected namespace, create a baseline Pod Security admission label set (if not already present) that disallows privilege escalation (Pod Security “restricted” level)
           * Run on: any machine with kubectl access
           * Example for one namespace named `prod-apps` (repeat for each target namespace, adjusting the name):
           ```bash theme={null}
           kubectl label namespace prod-apps \
             pod-security.kubernetes.io/enforce=restricted \
             pod-security.kubernetes.io/enforce-version=latest \
             pod-security.kubernetes.io/audit=restricted \
             pod-security.kubernetes.io/audit-version=latest \
             pod-security.kubernetes.io/warn=restricted \
             pod-security.kubernetes.io/warn-version=latest \
             --overwrite
           ```

        3. If Pod Security Admission is not available in your cluster, create a restrictive policy object (e.g., Kyverno or Gatekeeper) that denies `allowPrivilegeEscalation: true` in target namespaces
           * Run on: any machine with kubectl access
           * Example: Kyverno ClusterPolicy (save as `/tmp/deny-allow-priv-escalation.yaml`, then apply):
           ```yaml theme={null}
           apiVersion: kyverno.io/v1
           kind: ClusterPolicy
           metadata:
             name: deny-allow-privilege-escalation
           spec:
             validationFailureAction: enforce
             background: true
             rules:
               - name: disallow-allow-privilege-escalation
                 match:
                   resources:
                     kinds:
                       - Pod
                     namespaces:
                       - prod-apps
                       # add more namespaces here as needed
                 validate:
                   message: "Containers must not set securityContext.allowPrivilegeEscalation to true."
                   pattern:
                     spec:
                       containers:
                         - =(securityContext):
                             =(allowPrivilegeEscalation): "false"
           ```
           Apply it:
           ```bash theme={null}
           kubectl apply -f /tmp/deny-allow-priv-escalation.yaml
           ```

        4. Update existing workload manifests in target namespaces so that containers cannot request privilege escalation
           * Run on: any machine with kubectl access
           * Export and edit a workload (example Deployment in `prod-apps`):
           ```bash theme={null}
           kubectl -n prod-apps get deploy myapp -o yaml > /tmp/myapp-deploy.yaml
           ```
           * In `/tmp/myapp-deploy.yaml`, under each container, ensure:
           ```yaml theme={null}
           securityContext:
             allowPrivilegeEscalation: false
           ```
           * Apply the updated manifest:
           ```bash theme={null}
           kubectl apply -f /tmp/myapp-deploy.yaml
           ```

        5. Proactively block future changes that reintroduce `allowPrivilegeEscalation: true` by placing the namespace-level restriction under version control and reviewing any exception requests
           * Run on: any machine with kubectl access
           * Export namespace config (for Git/IaC management):
           ```bash theme={null}
           kubectl get namespace prod-apps -o yaml > prod-apps-namespace.yaml
           ```

        6. Verification (no pods with `allowPrivilegeEscalation: true` remain)
           * Run on: any machine with kubectl access
           ```bash theme={null}
           kubectl get pods --all-namespaces -o json | \
             jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.allowPrivilegeEscalation == true) then "ALLOWPRIVILEGEESCALTION_FOUND" else "NO_ALLOWPRIVILEGEESCALATION" end'
           ```
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) Create a baseline Pod Security restricted policy (applies to all namespaces)
        # Run on: any machine with kubectl access
        cat << 'EOF' | kubectl apply -f -
        apiVersion: policy/v1
        kind: PodSecurityPolicy
        metadata:
          name: restricted-no-priv-esc
          labels:
            app.kubernetes.io/part-of: cis-hardening
            pod-security.kubernetes.io/enforce: "restricted"
        spec:
          privileged: false
          allowPrivilegeEscalation: false
          requiredDropCapabilities:
            - ALL
          volumes:
            - 'configMap'
            - 'emptyDir'
            - 'projected'
            - 'secret'
            - 'downwardAPI'
            - 'persistentVolumeClaim'
          hostNetwork: false
          hostIPC: false
          hostPID: false
          runAsUser:
            rule: 'MustRunAsNonRoot'
          seLinux:
            rule: 'RunAsAny'
          supplementalGroups:
            rule: 'MustRunAs'
            ranges:
              - min: 1
                max: 65535
          fsGroup:
            rule: 'MustRunAs'
            ranges:
              - min: 1
                max: 65535
          readOnlyRootFilesystem: false
        EOF
        ```

        > If your cluster does not support PodSecurityPolicy (PSP is removed in newer Kubernetes/EKS versions), use a ValidatingAdmissionPolicy or a policy engine like Gatekeeper/Kyverno instead. Below is an example with `ValidatingAdmissionPolicy` (Kubernetes ≥ 1.30 or EKS with this feature enabled).

        ```bash theme={null}
        # 2) Create a ValidatingAdmissionPolicy to deny allowPrivilegeEscalation=true
        cat << 'EOF' | kubectl apply -f -
        apiVersion: admissionregistration.k8s.io/v1
        kind: ValidatingAdmissionPolicy
        metadata:
          name: deny-privilege-escalation
        spec:
          failurePolicy: Fail
          matchConstraints:
            resourceRules:
              - apiGroups: [""]
                apiVersions: ["v1"]
                operations: ["CREATE","UPDATE"]
                resources: ["pods"]
          validations:
            - expression: "!(has(object.spec) && object.spec != null && object.spec.containers.exists(c, has(c.securityContext) && has(c.securityContext.allowPrivilegeEscalation) && c.securityContext.allowPrivilegeEscalation == true))"
              message: "Containers must not set securityContext.allowPrivilegeEscalation=true"
        EOF

        # 3) Bind this policy to all user namespaces (example: all non-system namespaces)
        # Adjust the namespaces: list only namespaces with user workloads
        kubectl get ns --no-headers | awk '$1 !~ /^(kube-system|kube-public|kube-node-lease)$/ {print $1}' | while read ns; do
          cat << EOF | kubectl apply -f -
        apiVersion: admissionregistration.k8s.io/v1
        kind: ValidatingAdmissionPolicyBinding
        metadata:
          name: deny-privilege-escalation-${ns}
        spec:
          policyName: deny-privilege-escalation
          validationActions: [ "Deny" ]
          matchResources:
            namespaceSelector:
              matchLabels:
                cis/priv-escalation-protected: "true"
        EOF
          kubectl label namespace "${ns}" cis/priv-escalation-protected=true --overwrite
        done
        ```

        ```bash theme={null}
        # 4) (Optional but recommended) Fix existing pods that violate the policy
        #    This will restart Deployments/DaemonSets/StatefulSets with corrected securityContext
        #    Adjust workloads manually where needed.
        # Example for a single deployment in namespace 'app-namespace':
        kubectl -n app-namespace patch deployment my-deployment \
          --type='json' \
          -p='[{"op":"add","path":"/spec/template/spec/containers/0/securityContext","value":{"allowPrivilegeEscalation":false}}]'
        ```

        ```bash theme={null}
        # 5) Verification (same as audit, run on any machine with kubectl access)
        kubectl get pods --all-namespaces -o json | \
          jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.allowPrivilegeEscalation == true) then "ALLOWPRIVILEGEESCALTION_FOUND" else "NO_ALLOWPRIVILEGEESCALATION" end'
        ```
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        set -euo pipefail

        # Purpose:
        # - For every namespace that contains user workloads (i.e., any pod),
        #   create/patch a namespace-scoped PodSecurityPolicy-style restriction
        #   using Kyverno to deny allowPrivilegeEscalation=true.
        # - Idempotent and safe to re-run.
        #
        # Requirements:
        # - Run on any machine with kubectl access and Kyverno installed in the cluster.
        # - kubectl must be configured with cluster-admin privileges.

        # 1. Discover namespaces that have user workloads (pods)
        echo "Discovering namespaces with pods..."
        NS_LIST=$(kubectl get pods --all-namespaces --no-headers 2>/dev/null | awk '{print $1}' | sort -u)

        if [[ -z "${NS_LIST}" ]]; then
          echo "No namespaces with pods were found. Nothing to do."
          exit 0
        fi

        # 2. Create Kyverno ClusterPolicy (global) to deny allowPrivilegeEscalation=true,
        #    but scoped by namespace selector based on label:
        #    security.kubernetes.io/allow-privilege-escalation=false
        #
        #    This policy is created once and reused by all namespaces that opt in
        #    via the label.
        cat <<'EOF' | kubectl apply -f -
        apiVersion: kyverno.io/v1
        kind: ClusterPolicy
        metadata:
          name: disallow-allow-privilege-escalation
        spec:
          validationFailureAction: Enforce
          background: true
          rules:
            - name: disallow-allow-privilege-escalation
              match:
                any:
                  - resources:
                      kinds:
                        - Pod
                      namespaces:
                        - "*"
                      selector:
                        matchLabels:
                          security.kubernetes.io/allow-privilege-escalation: "false"
              validate:
                message: "Containers must not set securityContext.allowPrivilegeEscalation=true."
                pattern:
                  spec:
                    containers:
                      - =(securityContext):
                          =(allowPrivilegeEscalation): "false"
                    =(initContainers):
                      - =(securityContext):
                          =(allowPrivilegeEscalation): "false"
        EOF

        echo "ClusterPolicy 'disallow-allow-privilege-escalation' ensured."

        # 3. Label each namespace with workloads to opt in to the restriction.
        for ns in ${NS_LIST}; do
          # Skip kube-system and kyverno namespaces by default, as they often run privileged components.
          if [[ "${ns}" == "kube-system" ]] || [[ "${ns}" == "kyverno" ]]; then
            echo "Skipping system namespace: ${ns}"
            continue
          fi

          echo "Labeling namespace ${ns} with security.kubernetes.io/allow-privilege-escalation=false"
          kubectl label namespace "${ns}" \
            security.kubernetes.io/allow-privilege-escalation=false \
            --overwrite
        done

        # 4. Verification
        #    - Run the benchmark audit command.
        #    - Note: existing pods that already have allowPrivilegeEscalation=true
        #      will not be changed by admission control; they must be redeployed
        #      with corrected securityContext.
        echo
        echo "Verification: checking for pods with allowPrivilegeEscalation=true..."
        kubectl get pods --all-namespaces -o json | \
          jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.allowPrivilegeEscalation == true) then "ALLOWPRIVILEGEESCALTION_FOUND" else "NO_ALLOWPRIVILEGEESCALATION" end'
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

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