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

# Apply Security Context To Pods And Containers

### More Info:

Security contexts constrain the privileges and access of pods and containers at runtime. They should be applied following the CIS Google Container-Optimized OS Benchmark guidance.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS GKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **List pods and identify targets** (any machine with kubectl access)
           ```bash theme={null}
           kubectl get pods -A -o wide
           ```
           Decide which namespaces/pods are in scope (exclude managed system namespaces only if your policy allows, e.g. `kube-system`, `gke-system`, etc., after confirming provider ownership).

        2. **Review pod- and container-level securityContext usage** (any machine with kubectl access)\
           For each in-scope namespace, export full specs and check for missing or weak `securityContext` settings:
           ```bash theme={null}
           # Example for one namespace
           kubectl get pods -n <namespace> -o yaml > pods-<namespace>.yaml
           ```
           In the YAML, look for:
           * Pod-level: `.spec.securityContext`
           * Container-level for each container and initContainer: `.spec.containers[].securityContext` and `.spec.initContainers[].securityContext`\
             Note pods/containers where `securityContext` is absent or obviously over-privileged (e.g. `privileged: true`, `runAsUser: 0`, `allowPrivilegeEscalation: true`, `readOnlyRootFilesystem: false`, `capabilities.add` with broad capabilities).

        3. **Classify pods by required privilege** (manual decision)\
           For each application/team:
           * Determine if it truly needs root, host access, or additional Linux capabilities (e.g. CNI, CSI, monitoring agents may require more privileges; most apps do not).
           * Group pods into: **(A)** can run as non-root, **(B)** need limited extra privileges, **(C)** must remain highly privileged (with explicit business/technical justification).

        4. **Design appropriate securityContext settings per group** (manual decision, guided by CIS GKE / COS)\
           For each group, decide the target baseline, for example:
           * Common baseline for A/B (tightest feasible):
             * `runAsNonRoot: true`
             * `runAsUser: <non-root UID>`
             * `allowPrivilegeEscalation: false`
             * `readOnlyRootFilesystem: true` (if writable paths can move to volumes)
             * `capabilities.drop: ["ALL"]` and only minimal `capabilities.add` if needed
             * `seccompProfile: type: RuntimeDefault` (or Localhost profile if you maintain one)
           * For group B/C, document each exception (e.g. `privileged: true`, hostPath mounts, NET\_ADMIN, SYS\_ADMIN, etc.) with rationale and compensating controls.

        5. **Update owning manifests and re-apply** (any machine with kubectl access)
           * Locate the source manifests/Helm charts/Kustomize for the identified pods (Git repo, CI pipeline, or local files).
           * Edit them to add or refine `securityContext` at pod and/or container level, following the design in step 4. Example fragment for a container securityContext:
             ```yaml theme={null}
             securityContext:
               runAsNonRoot: true
               runAsUser: 1000
               allowPrivilegeEscalation: false
               readOnlyRootFilesystem: true
               capabilities:
                 drop: ["ALL"]
               seccompProfile:
                 type: RuntimeDefault
             ```
           * Re-deploy via your normal workflow, e.g.:
             ```bash theme={null}
             kubectl apply -f <updated-manifest>.yaml
             ```
           * Coordinate with app owners to run smoke tests; watch for failures due to tightened permissions and adjust only where strictly necessary.

        6. **Verify and document residual risk** (any machine with kubectl access)\
           Re-run the inspection and confirm security contexts are present and aligned with your decisions:
           ```bash theme={null}
           kubectl get pods -A -o yaml | grep -E "securityContext|privileged|allowPrivilegeEscalation|runAsUser|runAsNonRoot|capabilities|seccompProfile" -n
           ```
           For any remaining highly privileged pods in group C, record:
           * Namespace, pod name, containers
           * Required elevated settings
           * Business justification and review/expiry date\
             Keep this as part of your exception register and periodically repeat steps 2–6.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all pods and their service accounts (for review scope)
        # Run on: any machine with kubectl access
        kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,SA:.spec.serviceAccountName'

        # 2) Show securityContext at pod and container level for a specific pod
        # Replace <namespace> and <pod-name> with values from the previous command
        kubectl get pod <pod-name> -n <namespace> -o yaml | \
          sed -n '/^spec:/,/^status:/p' | \
          egrep -A3 'securityContext|containers:|name:'

        # 3) List pods that have no pod-level securityContext
        kubectl get pods -A -o json | \
          jq -r '
            .items[]
            | select(.spec.securityContext == null)
            | [.metadata.namespace, .metadata.name]
            | @tsv
          '

        # 4) List containers that lack a container-level securityContext
        kubectl get pods -A -o json | \
          jq -r '
            .items[]
            | . as $pod
            | $pod.spec.containers[]
            | select(.securityContext == null)
            | [$pod.metadata.namespace, $pod.metadata.name, .name]
            | @tsv
          '

        # 5) Surface pods/containers that are explicitly privileged
        kubectl get pods -A -o json | \
          jq -r '
            .items[]
            | . as $pod
            | $pod.spec.containers[]
            | select(.securityContext.privileged == true)
            | [$pod.metadata.namespace, $pod.metadata.name, .name, "privileged=true"]
            | @tsv
          '

        # 6) Surface pods/containers that can escalate privileges
        kubectl get pods -A -o json | \
          jq -r '
            .items[]
            | . as $pod
            | $pod.spec.containers[]
            | select(.securityContext.allowPrivilegeEscalation != false)
            | [$pod.metadata.namespace, $pod.metadata.name, .name, "allowPrivilegeEscalation!=false"]
            | @tsv
          '

        # 7) Surface pods/containers that run as root (where explicitly set)
        kubectl get pods -A -o json | \
          jq -r '
            .items[]
            | . as $pod
            | (
                if $pod.spec.securityContext.runAsUser == 0
                then [$pod.metadata.namespace, $pod.metadata.name, "POD", "runAsUser=0"]
                else empty
                end
              ),
              (
                $pod.spec.containers[]
                | select(.securityContext.runAsUser == 0)
                | [$pod.metadata.namespace, $pod.metadata.name, .name, "runAsUser=0"]
              )
            | @tsv
          '

        # 8) Surface pods without readOnlyRootFilesystem set to true
        kubectl get pods -A -o json | \
          jq -r '
            .items[]
            | . as $pod
            | $pod.spec.containers[]
            | select(.securityContext.readOnlyRootFilesystem != true)
            | [$pod.metadata.namespace, $pod.metadata.name, .name, "readOnlyRootFilesystem!=true"]
            | @tsv
          '
        ```

        Interpretation / what indicates a problem (requires human judgement):

        * Pods/containers listed by commands 3 and 4: no securityContext at pod or container level; review against your policy and the CIS guidance to decide if this is acceptable.
        * Entries from command 5: `privileged=true` almost always needs strong justification; likely non-compliant.
        * Entries from command 6: `allowPrivilegeEscalation!=false` means privilege escalation is allowed; typically should be set to `false` unless there is a clear need.
        * Entries from command 7: `runAsUser=0` means explicitly running as root; generally undesirable except for carefully reviewed system workloads.
        * Entries from command 8: `readOnlyRootFilesystem!=true` means the root filesystem is writable; for many workloads CIS-like guidance prefers `readOnlyRootFilesystem: true` unless write access is required.

        Use the detailed `kubectl get pod ... -o yaml` (command 2) for any flagged pod to review all securityContext fields in context (capabilities, seccompProfile, runAsNonRoot, fsGroup, etc.) and then decide specific changes in your manifests.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Report pods and containers without recommended securityContext settings.
        # Run on: any machine with kubectl access
        #
        # Requirements: kubectl, jq

        set -euo pipefail

        # Namespace selector (empty = all)
        NAMESPACE_SELECTOR="${1:-}"

        if [[ -n "$NAMESPACE_SELECTOR" ]]; then
          NS_ARG="-n $NAMESPACE_SELECTOR"
          echo "Scanning namespace: $NAMESPACE_SELECTOR" >&2
        else
          NS_ARG="--all-namespaces"
          echo "Scanning all namespaces" >&2
        fi

        # Fields we’ll check (aligned with common CIS guidance)
        cat <<'HDR'
        === Security Context Report (per container) ===
        Fields:
        - ns             : Namespace
        - pod            : Pod name
        - ctr            : Container name
        - t              : Type (C=container, I=initContainer)
        - pr             : privileged (true/false/empty)
        - capAdd         : Linux capabilities added (comma-separated)
        - capDrop        : Linux capabilities dropped (comma-separated)
        - roFs           : readOnlyRootFilesystem (true/false/empty)
        - runAsNonRoot   : runAsNonRoot (true/false/empty; pod or container)
        - runAsUser      : runAsUser (value/empty; pod or container)
        - seLinux        : SELinux options present (yes/no)
        - allowPrivEsc   : allowPrivilegeEscalation (true/false/empty)

        POTENTIAL PROBLEMS (to review):
        - pr=true
        - allowPrivEsc=true or empty
        - roFs=false or empty
        - runAsNonRoot=false or empty AND runAsUser is 0 or empty
        - capAdd has any value
        - capDrop is empty
        - seLinux=no
        HDR

        # Dump all pods with all fields, then process via jq
        kubectl get pods ${NS_ARG} -o json | \
        jq -r '
          .items[]
          | .metadata as $m
          | .spec as $s
          | .spec.securityContext as $psc
          | [
              # build an array of all containers and initContainers with type marker
              (
                ( .spec.containers      // [] | map(. + { _type: "C" }) ) +
                ( .spec.initContainers? // [] | map(. + { _type: "I" }) )
              )[]
              | . as $ctr
              | $ctr.securityContext as $csc

              # pod-level fields (can be inherited)
              | $psc.runAsNonRoot as $podRunAsNonRoot
              | $psc.runAsUser    as $podRunAsUser
              | $psc.seLinuxOptions as $podSeLinux

              # container-level fields
              | $csc.runAsNonRoot as $ctrRunAsNonRoot
              | $csc.runAsUser    as $ctrRunAsUser
              | $csc.seLinuxOptions as $ctrSeLinux

              # effective runAs* (container overrides pod)
              | ($ctrRunAsNonRoot // $podRunAsNonRoot) as $effRunAsNonRoot
              | ($ctrRunAsUser    // $podRunAsUser)    as $effRunAsUser
              | ($ctrSeLinux      // $podSeLinux)      as $effSeLinux

              # capabilities
              | ($csc.capabilities.add   // []) as $capAdd
              | ($csc.capabilities.drop  // []) as $capDrop

              # other container-level fields
              | $csc.privileged                  as $priv
              | $csc.readOnlyRootFilesystem      as $roFs
              | $csc.allowPrivilegeEscalation    as $allowPE

              # derive simple flags
              | ($effSeLinux | if . == null then "no" else "yes" end) as $seLinuxFlag
              | ($capAdd  | join(","))       as $capAddStr
              | ($capDrop | join(","))       as $capDropStr

              # output TSV line
              | [
                  $m.namespace,
                  $m.name,
                  $ctr.name,
                  $ctr._type,
                  (if $priv        == null then "" else $priv        | tostring end),
                  $capAddStr,
                  $capDropStr,
                  (if $roFs        == null then "" else $roFs        | tostring end),
                  (if $effRunAsNonRoot == null then "" else $effRunAsNonRoot | tostring end),
                  (if $effRunAsUser    == null then "" else $effRunAsUser    | tostring end),
                  $seLinuxFlag,
                  (if $allowPE     == null then "" else $allowPE     | tostring end)
                ] | @tsv
            ]
        ' | \
        awk '
        BEGIN {
          OFS="\t";
          print "ns","pod","ctr","t","pr","capAdd","capDrop","roFs","runAsNonRoot","runAsUser","seLinux","allowPrivEsc","ISSUES";
        }
        {
          ns=$1; pod=$2; ctr=$3; t=$4;
          pr=$5; capAdd=$6; capDrop=$7; roFs=$8;
          runAsNonRoot=$9; runAsUser=$10; seLinux=$11; allowPE=$12;

          issues="";

          # privileged
          if (pr == "true") {
            issues = issues "[privileged=true];";
          }

          # allowPrivilegeEscalation
          if (allowPE == "true" || allowPE == "") {
            issues = issues "[allowPrivilegeEscalation not false];";
          }

          # readOnlyRootFilesystem
          if (roFs == "" || roFs == "false") {
            issues = issues "[readOnlyRootFilesystem not true];";
          }

          # runAsNonRoot / runAsUser
          if (runAsNonRoot == "" || runAsNonRoot == "false") {
            if (runAsUser == "" || runAsUser == "0") {
              issues = issues "[runs as root or not proven non-root];";
            }
          }

          # capabilities
          if (capAdd != "") {
            issues = issues "[capabilities added: " capAdd "];";
          }
          if (capDrop == "") {
            issues = issues "[no capabilities dropped];";
          }

          # SELinux
          if (seLinux == "no") {
            issues = issues "[no SELinux options];";
          }

          print ns,pod,ctr,t,pr,capAdd,capDrop,roFs,runAsNonRoot,runAsUser,seLinux,allowPE,issues;
        }
        '

        cat <<'FOOT'

        INTERPRETING OUTPUT:
        - Each row is a single container or initContainer.
        - The ISSUES column summarizes what needs review.

        Examples of rows needing attention:
        - ISSUES contains [privileged=true]                    -> container is privileged.
        - ISSUES contains [allowPrivilegeEscalation not false] -> not explicitly disabled.
        - ISSUES contains [readOnlyRootFilesystem not true]    -> root FS writable.
        - ISSUES contains [runs as root or not proven non-root]-> runAsNonRoot/runAsUser not set safely.
        - ISSUES contains [capabilities added: ...]            -> extra Linux capabilities granted.
        - ISSUES contains [no capabilities dropped]            -> consider dropping ALL or unneeded caps.
        - ISSUES contains [no SELinux options]                 -> no SELinux confinement configured.

        Use this report to:
        - Identify pods/containers where securityContext is missing or too permissive.
        - Prioritize high‑risk cases (privileged, root user, privilege escalation).
        - Manually adjust pod specs/manifests according to your security policy and CIS guidance.
        FOOT
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
