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

### More Info:

Added Linux capabilities expand a containers privileges beyond the default set. Drop all capabilities where applications do not need them.

### 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. **Identify pods using capabilities** (any machine with kubectl access)
           ```bash theme={null}
           kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.containers[*].securityContext.capabilities}{"\n"}{end}' \
           | grep -v '{}'
           ```
           Also include init containers:
           ```bash theme={null}
           kubectl get pods -A -o json | \
             jq -r '.items[] |
               .metadata.namespace as $ns |
               .metadata.name as $pod |
               (.spec.containers[]?,
                .spec.initContainers[]?) as $c |
               select($c.securityContext.capabilities != null) |
               [$ns, $pod, $c.name, ($c.securityContext.capabilities // {})] | @tsv'
           ```

        2. **Map capabilities to owning teams and justify need**\
           For each pod/container from step 1, capture its manifest and share with the owning team/application owner:
           ```bash theme={null}
           kubectl get pod <pod-name> -n <namespace> -o yaml > /tmp/<namespace>-<pod-name>.yaml
           ```
           Ask them to confirm which listed capabilities are strictly required and whether the container can run with `ALL` dropped.

        3. **Decide namespace policy: which namespaces can/should forbid capabilities**\
           Using the information from step 2, classify namespaces:
           * Namespaces where **no containers need extra capabilities** → candidates to enforce “drop all capabilities”.
           * Namespaces with **a few exceptional workloads** → decide whether to:
             * Move those workloads to a separate namespace, or
             * Exempt the namespace for now and document the risk.

        4. **Design the admission policy to enforce dropping capabilities**\
           Decide on your enforcement mechanism (example options to prepare for implementation):
           * ValidatingAdmissionPolicy / ValidatingAdmissionWebhook that rejects pods/containers unless:
             * `securityContext.capabilities.drop` contains `"ALL"`, and
             * `securityContext.capabilities.add` is unset/empty.
           * Limit the policy’s `namespaceSelector` or similar scoping so it only applies to namespaces identified in step 3.

        5. **Update application manifests to be compliant before enforcing**\
           For each workload in namespaces you plan to protect, adjust the manifests (local Git/IaC repo, not directly in-cluster) so containers explicitly drop all capabilities, for example:
           ```yaml theme={null}
           securityContext:
             runAsNonRoot: true
             capabilities:
               drop:
                 - ALL
           ```
           Where teams have justified specific capabilities as required, either:
           * Keep those workloads out of the strict namespaces, or
           * Document and prepare explicit policy exceptions in the admission policy design.

        6. **Verify resulting posture after policy deployment**\
           After implementing your chosen admission policy (outside the scope of this manual review), confirm:
           * New pods can only be created in protected namespaces if they drop all capabilities and do not add any.
           * Periodically re-run:
             ```bash theme={null}
             kubectl get pods -A -o json | \
               jq -r '.items[] |
                 .metadata.namespace as $ns |
                 .metadata.name as $pod |
                 (.spec.containers[]?,
                  .spec.initContainers[]?) as $c |
                 select($c.securityContext.capabilities.add != null and
                        ($c.securityContext.capabilities.add | length) > 0) |
                 [$ns, $pod, $c.name, ($c.securityContext.capabilities.add // [])] | @tsv'
             ```
             Review any remaining capabilities and update namespace classification and policies as needed.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all pods with any explicit capabilities set (all namespaces)
        # Run on: any machine with kubectl access
        kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.containers[*].securityContext.capabilities)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'

        # Same for initContainers
        kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.initContainers[*].securityContext.capabilities)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
        ```

        Problem indication: Any pod listed here has at least one container or initContainer with capabilities defined; these need review.

        ***

        ```bash theme={null}
        # 2) For a specific namespace, show pods and whether any container sets capabilities
        NAMESPACE=default
        kubectl get pods -n "$NAMESPACE" -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,CAPS:.spec.containers[*].securityContext.capabilities
        ```

        Problem indication: Any non-empty `CAPS` field (e.g. `map[add:[NET_ADMIN] drop:[ALL]]`) means the pod is explicitly manipulating capabilities and must be reviewed.

        ***

        ```bash theme={null}
        # 3) Inspect full capability settings for a specific pod
        NAMESPACE=default
        POD=my-pod
        kubectl get pod "$POD" -n "$NAMESPACE" -o yaml
        ```

        What to look for as potential problems in the YAML:

        * `securityContext.capabilities.add` present and non-empty, for example:
          * `add: ["NET_ADMIN"]`
          * `add: ["SYS_ADMIN", "NET_RAW"]`
        * `securityContext.capabilities.drop` missing, empty, or does not include `ALL`.
        * Containers with no `drop: ["ALL"]` in namespaces where applications do not require Linux capabilities.

        These locations should be checked:

        * `.spec.containers[*].securityContext.capabilities`
        * `.spec.initContainers[*].securityContext.capabilities`
        * `.spec.ephemeralContainers[*].securityContext.capabilities` (if used)

        ***

        ```bash theme={null}
        # 4) Summarize all added capabilities cluster-wide
        kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.name}{": "}{.securityContext.capabilities.add}{"; "}{end}{"\n"}{end}' \
          | grep -v '\[\]'  # filter out lines with empty add lists
        ```

        Problem indication: Any line showing a non-empty `add` list (e.g. `[NET_ADMIN]`, `[SYS_ADMIN NET_RAW]`) is a potential risk and should be justified or removed.

        ***

        ```bash theme={null}
        # 5) Verify after manual remediation (spot-check)
        # Re-run capability listing for a namespace after you update manifests
        NAMESPACE=default
        kubectl get pods -n "$NAMESPACE" -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,CAPS:.spec.containers[*].securityContext.capabilities
        ```

        Verification indication: For namespaces where you decided all applications can run without Linux capabilities, the `CAPS` column should be empty or show only `drop:[ALL]` and no `add` entries.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Report pods whose containers add Linux capabilities or fail to drop all capabilities.
        # Run on: any machine with kubectl access and current context set.
        #
        # Requires: kubectl, jq

        set -euo pipefail

        echo "Scanning all namespaces for capability usage..."

        # 1) Pods where any container explicitly *adds* capabilities
        echo
        echo "=== Pods with explicitly ADDED capabilities (potentially high risk) ==="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                pod: .metadata.name,
                containers: (
                  [
                    (.spec.initContainers // [] )[],
                    (.spec.containers // [] )[]
                  ]
                )
              }
            | .containers[]
            | {
                ns: .ns,
                pod: .pod,
                cname: .name,
                adds: (.securityContext.capabilities.add // []),
                drops: (.securityContext.capabilities.drop // [])
              }
            | select((.adds | length) > 0)
            | "\(.ns)\t\(.pod)\t\(.cname)\tadd=\(.adds | join(\";\"))\tdrop=\(.drops | join(\";\"))"
          ' | column -t || echo "None found or jq error."

        # 2) Pods where containers define capabilities but do NOT drop ALL
        echo
        echo "=== Pods with capabilities defined but NOT dropping ALL (review) ==="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                pod: .metadata.name,
                containers: (
                  [
                    (.spec.initContainers // [] )[],
                    (.spec.containers // [] )[]
                  ]
                )
              }
            | .containers[]
            | {
                ns: .ns,
                pod: .pod,
                cname: .name,
                adds: (.securityContext.capabilities.add // []),
                drops: (.securityContext.capabilities.drop // [])
              }
            # Container has a capabilities section at all
            | select((.adds | length) > 0 or (.drops | length) > 0)
            # but does not drop ALL
            | select((.drops | map(ascii_upcase) | index("ALL")) | not)
            | "\(.ns)\t\(.pod)\t\(.cname)\tadd=\(.adds | join(\";\"))\tdrop=\(.drops | join(\";\"))"
          ' | column -t || echo "None found or jq error."

        # 3) Summary counts
        echo
        echo "=== Summary ==="
        echo "- Pods with any container that ADDS capabilities:"
        kubectl get pods --all-namespaces -o json \
          | jq '
            .items[]
            | [
                (.spec.initContainers // [] )[],
                (.spec.containers // [] )[]
              ]
            | map(.securityContext.capabilities.add // [])
            | map(length)
            | add
          ' | awk '{ if ($1=="") print 0; else print $1; }'

        echo "- Containers defining capabilities but NOT dropping ALL:"
        kubectl get pods --all-namespaces -o json \
          | jq '
            [
              .items[]
              | {
                  ns: .metadata.namespace,
                  pod: .metadata.name,
                  containers: [
                    (.spec.initContainers // [] )[],
                    (.spec.containers // [] )[]
                  ]
                }
              | .containers[]
              | {
                  adds: (.securityContext.capabilities.add // []),
                  drops: (.securityContext.capabilities.drop // [])
                }
              | select((.adds | length) > 0 or (.drops | length) > 0)
              | select((.drops | map(ascii_upcase) | index("ALL")) | not)
            ] | length
          '

        echo
        echo "Review guidance:"
        echo "- Any line in the first section (ADDED capabilities) indicates a pod that expands beyond default capabilities."
        echo "- Any line in the second section indicates a container that defines capabilities but does not drop ALL."
        echo "- For namespaces where applications do not require capabilities, ensure containers drop ALL and avoid add= entries."
        ```

        **How to interpret problematic output**

        * Any row in `Pods with explicitly ADDED capabilities (potentially high risk)` indicates a container that is explicitly requesting extra Linux capabilities. These should be reviewed and justified; in namespaces that should not use capabilities, they are a problem.
        * Any row in `Pods with capabilities defined but NOT dropping ALL (review)` shows containers that configure capabilities but do not include `drop: ["ALL"]`. In namespaces that should drop all capabilities, these are non-compliant and should be redesigned or restricted by admission policy.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
