> ## 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 Of Containers Capabilities Assigned

### More Info:

Do not generally permit containers with capabilities

### Risk Level

Low

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify namespaces where dropping all capabilities is acceptable**
           * On any machine with kubectl access:
             ```bash theme={null}
             kubectl get ns
             ```
           * With your app/service owners, list namespaces whose workloads are **non-privileged, non-infrastructure** and can reasonably run without extra Linux capabilities (for example, pure HTTP APIs, batch jobs, or frontends).

        2. **Inventory current capability usage in those namespaces**
           * For each candidate namespace (replace `TARGET_NS`):
             ```bash theme={null}
             kubectl get pods -n TARGET_NS -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{range .spec.containers[*]}  {.name}{" caps:"}{.securityContext.capabilities}{"\n"}{end}{"\n"}{end}'
             ```
           * Also capture full security contexts for deeper review:
             ```bash theme={null}
             kubectl get pods -n TARGET_NS -o yaml > TARGET_NS-pods.yaml
             ```
           * Review for any `capAdd` entries and for containers that *do not* specify `drop: ["ALL"]`.

        3. **Decide which workloads actually need capabilities**
           * For each container with `capAdd` (or no `drop: ["ALL"]`), validate with the application owner and documentation whether these capabilities are functionally required.
           * Mark containers that:
             * **Do not need any capabilities** → should drop all.
             * **Need only specific capabilities** → should drop all by default and add back only the minimal required ones.
           * Where uncertain, plan controlled tests with reduced capabilities in a non‑production environment.

        4. **Enforce “drop all capabilities” at the namespace level via policy**
           * If you already use a policy engine (Pod Security Standards / Pod Security Admission, Kyverno, OPA Gatekeeper, or a PSP-like replacement), define or adjust a policy for each selected namespace to require `drop: ["ALL"]` and optionally forbid `capAdd` except for explicitly allowed cases. For example, using Kyverno (on any machine with kubectl access):
             ```bash theme={null}
             kubectl apply -f - << 'EOF'
             apiVersion: kyverno.io/v1
             kind: ClusterPolicy
             metadata:
               name: require-drop-all-capabilities
             spec:
               validationFailureAction: enforce
               rules:
               - name: require-drop-all
                 match:
                   any:
                   - resources:
                       kinds: ["Pod"]
                       namespaces: ["TARGET_NS"]
                 validate:
                   message: "Containers must drop all Linux capabilities."
                   pattern:
                     spec:
                       containers:
                       - securityContext:
                           capabilities:
                             drop:
                             - "ALL"
               # Optionally add a rule to block capAdd, except where explicitly allowed
             EOF
             ```
           * Adjust the example to your policy engine and list of target namespaces; review carefully before enforcing in production.

        5. **Update existing workloads that violate the policy**
           * For each deployment/statefulset/daemonset in the target namespaces, edit the manifest to drop all capabilities (example for a deployment):
             ```bash theme={null}
             kubectl -n TARGET_NS get deploy APP_NAME -o yaml > APP_NAME-deploy.yaml
             ```
             Edit `APP_NAME-deploy.yaml` to include, under each container:
             ```yaml theme={null}
             securityContext:
               capabilities:
                 drop:
                   - "ALL"
             ```
             Then apply:
             ```bash theme={null}
             kubectl apply -f APP_NAME-deploy.yaml
             ```
           * For pods created by other controllers (CronJobs, Jobs, Operators), update the relevant higher-level resource templates similarly.

        6. **Verify effective enforcement and absence of unintended capabilities**
           * Attempt to create a pod **without** dropping all capabilities in the protected namespace; confirm admission is rejected according to your policy engine.
           * Confirm running pods comply:
             ```bash theme={null}
             kubectl get pods -n TARGET_NS -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{range .spec.containers[*]}  {.name}{" caps:"}{.securityContext.capabilities}{"\n"}{end}{"\n"}{end}'
             ```
           * Periodically re-run this review when new workloads are added or when application requirements change.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all namespaces
        # Run on: any machine with kubectl access
        kubectl get ns -o wide
        ```

        Review this list and pick a namespace you expect should *not* need elevated capabilities
        (for example, “frontend”, “dev”, “testing”, or other app-only namespaces).

        ```bash theme={null}
        # 2) Find pods in a namespace that define container capabilities
        # Replace <NAMESPACE> with the namespace under review
        kubectl get pods -n <NAMESPACE> -o jsonpath='
        {range .items[*]}
        POD: {@.metadata.name}{"\n"}
        {range @.spec.containers[*]}
          CONTAINER: {@.name}{"\n"}
            add: {@.securityContext.capabilities.add}{"\n"}
            drop: {@.securityContext.capabilities.drop}{"\n"}
        {end}{"\n"}
        {end}'
        ```

        **Problem indication:**

        * Any non-empty `add:` line (for example `[NET_ADMIN CAP_SYS_ADMIN]`) means the container is requesting extra capabilities.
        * Missing or empty `drop:` where you expect all capabilities to be dropped may be a concern if the app does not need capabilities.

        ```bash theme={null}
        # 3) Show full securityContext for all containers in a namespace
        kubectl get pods -n <NAMESPACE> -o jsonpath='
        {range .items[*]}
        POD: {@.metadata.name}{"\n"}
        {range @.spec.containers[*]}
          CONTAINER: {@.name}{"\n"}
          securityContext: {@.securityContext}{"\n"}
        {end}{"\n"}
        {end}'
        ```

        **Problem indication:**

        * `securityContext.capabilities.add` present with any capability values.
        * No `securityContext.capabilities.drop` and no higher-level policy (see below) in a namespace that should be locked down.

        ```bash theme={null}
        # 4) Inspect PodSecurityPolicy (if in use; deprecated on some platforms)
        kubectl get psp
        kubectl get psp -o yaml
        ```

        **Problem indication:**

        * `allowedCapabilities` contains capabilities beyond what is needed, especially `*`.
        * `requiredDropCapabilities` is empty or does not include `ALL` for namespaces that should drop all capabilities.

        ```bash theme={null}
        # 5) Inspect Pod Security Admission (Pod Security Standards) labels on namespaces (if used)
        kubectl get ns --show-labels
        ```

        Look for labels like `pod-security.kubernetes.io/enforce=privileged|baseline|restricted`.

        **Problem indication:**

        * Namespaces that should run unprivileged workloads but are labeled with `privileged` or have no Pod Security labels and permit capabilities via other policies.

        ```bash theme={null}
        # 6) Inspect admission policies that might control capabilities (PSA/PSP replacements)
        # Example for Kyverno:
        kubectl get clusterpolicy,policy -A -o yaml

        # Example for OPA Gatekeeper:
        kubectl get constrainttemplate,constraint -A -o yaml
        ```

        **Problem indication:**

        * No policy that restricts `securityContext.capabilities` for namespaces that do not need capabilities.
        * Policies explicitly allowing broad or unrestricted capabilities.

        ```bash theme={null}
        # 7) Spot-check specific pods that look suspicious
        # Replace <POD> and <NAMESPACE>
        kubectl get pod <POD> -n <NAMESPACE> -o yaml
        ```

        **Problem indication:**

        * `securityContext.capabilities.add` with capabilities like `NET_ADMIN`, `SYS_ADMIN`, `NET_RAW`, or many entries.
        * Containers running as root plus added capabilities without a clear business need.

        Use the above outputs to decide, per namespace, whether workloads truly require capabilities; if not, plan to introduce or tighten policies that require dropping all capabilities and/or forbid adding new ones.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Report pods and workloads that grant Linux capabilities (add or fail to drop all)
        # Run on: any machine with kubectl access to the cluster

        set -euo pipefail

        echo "=== Cluster-wide capabilities usage report ==="
        echo "Timestamp: $(date -Iseconds)"
        echo

        # 1) Show any Pod security policies / PSS exemptions that might allow capabilities (if PSP still exists)
        echo "== PodSecurityPolicies (if present) =="
        kubectl get psp -o yaml 2>/dev/null | grep -nE 'allowedCapabilities|defaultAddCapabilities|requiredDropCapabilities' || \
          echo "No PSPs found or PSP not enabled."
        echo

        # 2) List all pods with any explicit capabilities in their containers or initContainers
        echo "== Pods with capabilities configured (add/drop) =="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                pod: .metadata.name,
                containers: (
                  ([.spec.containers[], (.spec.initContainers // [])[]]
                   | {
                       name: .name,
                       add: (.securityContext.capabilities.add // [] | map(.)),
                       drop: (.securityContext.capabilities.drop // [] | map(.))
                     })
                )
              }
            | select(
                ([.containers[]?.add[]?] | length) > 0
                or
                (
                  # flag containers that do NOT drop ALL capabilities
                  ([.containers[]?.drop[]?] | length) == 0
                  or
                  ( [.containers[]?.drop[]? | ascii_upcase] | index("ALL") | not )
                )
              )
            | "NAMESPACE=\(.ns) POD=\(.pod)\n"
              + (
                [.containers[]
                 | "  container=\(.name)\n"
                   + "    add:  \(.add | if length==0 then \"[]\" else join(\",\") end)\n"
                   + "    drop: \(.drop | if length==0 then \"[]\" else join(\",\") end)"
                ] | join("\n")
              )
          ' 2>/dev/null || echo "Failed to query pods or jq not installed."
        echo

        # 3) Summarize by namespace: any pod that does NOT drop ALL capabilities
        echo "== Namespaces with pods that do NOT drop all capabilities =="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                pod: .metadata.name,
                containers: (
                  ([.spec.containers[], (.spec.initContainers // [])[]]
                   | {
                       name: .name,
                       drop: (.securityContext.capabilities.drop // [] | map(.))
                     })
                )
              }
            | select(
                # problematic if any container does not drop ALL
                (.containers[]?.drop | map(ascii_upcase) | index("ALL") | not)
              )
            | "\(.ns)"
          ' 2>/dev/null | sort -u || echo "Failed to summarize namespaces."
        echo

        # 4) Show namespaced policies that might be intended to enforce dropping capabilities
        #    (for review: PodSecurity, Gatekeeper, Kyverno, etc. labels/annotations)
        echo "== Namespaces and Pod Security labels (Kubernetes Pod Security Standards) =="
        kubectl get ns --show-labels
        echo

        echo "== Guidance =="
        cat <<'EOF'
        Interpretation:

        1) Problematic capabilities usage:
           - Any container showing a non-empty "add:" list is explicitly requesting extra Linux capabilities.
           - Any container where "drop:" does NOT include "ALL" is potentially retaining capabilities.
           Such pods will appear in the "Pods with capabilities configured" section.

        2) Namespaces of concern:
           - Namespaces listed under "Namespaces with pods that do NOT drop all capabilities"
             contain at least one pod where a container does not drop ALL capabilities.
           - For namespaces whose workloads do not require Linux capabilities, these are the
             prime candidates where you should consider adding admission policy that forbids
             pods unless they drop ALL capabilities.

        3) Manual review:
           - For each flagged namespace and pod, review whether the application truly needs
             the capabilities being retained or added.
           - For namespaces that should be "no-capabilities", implement or tighten admission
             controls (e.g., Pod Security Standards, Gatekeeper/Kyverno policies) to reject
             pods that do not drop ALL capabilities.
        EOF
        ```

        **What output indicates a problem**

        * In the “Pods with capabilities configured” section:
          * Any `add:` list that is not `[]` means the container is explicitly adding Linux capabilities.
          * Any `drop:` list that is `[]` or does not contain `ALL` means the container is not dropping all capabilities.

        * In the “Namespaces with pods that do NOT drop all capabilities” section:
          * Any namespace listed here contains pods where at least one container does not drop `ALL` capabilities; these namespaces should be reviewed, and where workloads do not require capabilities, admission policies should be considered to forbid such pods.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://www.nccgroup.trust/uk/our-research/abusing-privileged-and-unprivileged-linux-containers/](https://www.nccgroup.trust/uk/our-research/abusing-privileged-and-unprivileged-linux-containers/)
