> ## 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 For Pods And Containers

### More Info:

Apply Security Context to Your Pods and Containers

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **List pods that lack any pod-level securityContext**
           * Run on: any machine with kubectl access
           ```bash theme={null}
           kubectl get pods --all-namespaces -o json \
           | jq -r '.items[]
             | select(.spec.securityContext == null)
             | [.metadata.namespace, .metadata.name]
             | @tsv'
           ```
           * Record which namespaces/workloads (especially production or internet-facing) show up.

        2. **Inspect container-level securityContext usage in those pods**
           * For each `<namespace> <pod>` pair from step 1, run:
           ```bash theme={null}
           kubectl get pod <pod-name> -n <namespace> -o json \
           | jq '.spec.containers[] | {name: .name, securityContext: .securityContext}'
           ```
           * Flag containers where `.securityContext` is `null` or missing important fields such as `runAsNonRoot`, `runAsUser`, `readOnlyRootFilesystem`, `allowPrivilegeEscalation`, `capabilities`, and `seccompProfile`.

        3. **Review security requirements with workload owners**
           * For each affected workload (Deployment/StatefulSet/DaemonSet/Job/CronJob), identify the controller:
           ```bash theme={null}
           kubectl get pod <pod-name> -n <namespace> -o json \
           | jq -r '.metadata.ownerReferences[]? | .kind + "/" + .name'
           ```
           * Discuss with owners whether the application truly needs root, writable root FS, added capabilities, or privilege escalation. Prefer the most restrictive settings that still allow the app to function.

        4. **Update the controller manifests to define appropriate securityContext**
           * Export the managing object manifest:
           ```bash theme={null}
           kubectl get <kind> <name> -n <namespace> -o yaml > /tmp/<namespace>-<kind>-<name>.yaml
           ```
           * Edit the file to add securityContext at pod spec and/or container level, for example under `spec.template.spec` (for controllers) or `spec` (for standalone Pods), setting fields such as:
             * `runAsNonRoot: true`
             * `runAsUser: 1000`
             * `readOnlyRootFilesystem: true`
             * `allowPrivilegeEscalation: false`
             * `capabilities: { drop: ["ALL"] }`
             * `seccompProfile: { type: "RuntimeDefault" }`
           * Apply the updated manifest:
           ```bash theme={null}
           kubectl apply -f /tmp/<namespace>-<kind>-<name>.yaml
           ```

        5. **Optionally enforce baseline via namespace or cluster policies**
           * If using Pod Security Admission, label namespaces to require at least baseline or restricted where appropriate:
           ```bash theme={null}
           kubectl label namespace <namespace> pod-security.kubernetes.io/enforce=baseline --overwrite
           ```
           * Or review/create PodSecurityPolicy (legacy), OPA Gatekeeper, or Kyverno policies to require reasonable securityContext defaults, tuned to your environment.

        6. **Re-verify pods and document accepted exceptions**
           * Re-run step 1 and 2 to confirm that high-value workloads now have explicit, restrictive securityContexts.
           * For any pods that cannot comply (e.g., vendors requiring privileged containers), document the justification, scope them tightly (dedicated namespaces, node selectors, or policies), and ensure they are deliberately excluded or handled by your policy tooling.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all pods and their service accounts (for triage)
        # 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 pods that define NO pod-level securityContext
        # Run on: any machine with kubectl access
        kubectl get pods -A -o json | \
          jq -r '
            .items[]
            | select(.spec.securityContext == null)
            | [.metadata.namespace, .metadata.name]
            | @tsv
          '

        # 3) Show containers that define NO container-level securityContext
        # Run on: any machine with kubectl access
        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
          '

        # 4) Show privileged containers
        # Run on: any machine with kubectl access
        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
          '

        # 5) Show containers that allow privilege escalation (or don’t specify it)
        # Run on: any machine with kubectl access
        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=" + ((.securityContext.allowPrivilegeEscalation|tostring) // "null")]
            | @tsv
          '

        # 6) Show containers running as root UID (0) or with no runAsUser set
        # Run on: any machine with kubectl access
        kubectl get pods -A -o json | \
          jq -r '
            .items[]
            | . as $pod
            | ($pod.spec.containers // [])[]
            | . as $ctr
            | ($pod.spec.securityContext.runAsUser // .securityContext.runAsUser // "unset") as $uid
            | select($uid == 0 or $uid == "unset")
            | [$pod.metadata.namespace, $pod.metadata.name, $ctr.name, "runAsUser=" + ($uid|tostring)]
            | @tsv
          '

        # 7) Show containers that can write to root filesystem (readOnlyRootFilesystem not true)
        # Run on: any machine with kubectl access
        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=" + ((.securityContext.readOnlyRootFilesystem|tostring) // "null")]
            | @tsv
          '
        ```

        **How to interpret the output**

        A pod or container likely needs review when:

        * It appears in commands (2) or (3): no `securityContext` at pod or container level.
        * It appears in command (4): `privileged=true` containers are high risk and should only exist when strictly required.
        * It appears in command (5): `allowPrivilegeEscalation` is not explicitly `false` (either `true` or `null`); default-allow may be unacceptable for sensitive workloads.
        * It appears in command (6): `runAsUser=0` or `runAsUser=unset`; running as root or relying on image defaults should be reviewed.
        * It appears in command (7): `readOnlyRootFilesystem` is `false` or `null`; writable roots should be justified.

        These commands only surface candidates for review. A human must decide which securityContext fields are appropriate for each workload and then update the Pod templates (Deployments, DaemonSets, etc.) accordingly.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Report pods and containers without securityContext defined (pod-level or container-level)
        # Run on: any machine with kubectl access and current-context pointing to the target cluster

        set -euo pipefail

        # Optionally scope by namespace via env var NAMESPACE (default: all namespaces)
        NS_SELECTOR="${NAMESPACE:---all-namespaces}"

        echo "Scanning pods for missing securityContext (pod-level and container-level)..."
        echo

        # 1) High‑level summary per namespace
        echo "=== Summary: pods and containers missing securityContext (per namespace) ==="
        kubectl get pods ${NS_SELECTOR} -o json \
          | jq -r '
            [
              .items[]
              | {
                  ns: .metadata.namespace,
                  pod: .metadata.name,
                  podSecurityContextMissing: (has("spec") | not or (.spec | has("securityContext") | not)),
                  containers: (
                    (.spec.containers // [])
                    | map({
                        name: .name,
                        missingSecCtx: (has("securityContext") | not)
                      })
                  ),
                  initContainers: (
                    (.spec.initContainers // [])
                    | map({
                        name: .name,
                        missingSecCtx: (has("securityContext") | not)
                      })
                  )
                }
            ]
            | group_by(.ns)
            | map({
                namespace: .[0].ns,
                podsWithoutPodSecurityContext: (
                  map(select(.podSecurityContextMissing)) | length
                ),
                containersWithoutSecurityContext: (
                  [.[].containers[] | select(.missingSecCtx)] | length
                ),
                initContainersWithoutSecurityContext: (
                  [.[].initContainers[] | select(.missingSecCtx)] | length
                )
              })
            | sort_by(.namespace)
            | (["namespace","pods_no_pod_sc","containers_no_sc","init_containers_no_sc"],
               (.[] | [ .namespace,
                        (.podsWithoutPodSecurityContext|tostring),
                        (.containersWithoutSecurityContext|tostring),
                        (.initContainersWithoutSecurityContext|tostring)
               ]))
            | @tsv
          ' | column -t
        echo

        # 2) Detailed listing of problematic pods/containers
        echo "=== Detailed: objects missing securityContext ==="
        kubectl get pods ${NS_SELECTOR} -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                pod: .metadata.name,
                podSecurityContextMissing: (has("spec") | not or (.spec | has("securityContext") | not)),
                containers: (
                  (.spec.containers // [])
                  | map(select(has("securityContext") | not) | .name)
                ),
                initContainers: (
                  (.spec.initContainers // [])
                  | map(select(has("securityContext") | not) | .name)
                )
              }
            | select(.podSecurityContextMissing or (.containers|length>0) or (.initContainers|length>0))
            | [
                .ns,
                .pod,
                (if .podSecurityContextMissing then "POD_NO_SECURITYCONTEXT" else "-" end),
                (if (.containers|length>0) then ("CONTAINERS_NO_SECURITYCONTEXT=" + ((.containers|join(",")))) else "-" end),
                (if (.initContainers|length>0) then ("INIT_CONTAINERS_NO_SECURITYCONTEXT=" + ((.initContainers|join(",")))) else "-" end)
              ]
            | @tsv
          ' | column -t

        cat <<'EOF'

        INTERPRETING RESULTS
        --------------------
        Any non-zero counts or lines in the "Detailed" section indicate pods or containers
        without a defined securityContext and should be reviewed:

        - "pods_no_pod_sc" > 0:
            Pod specs missing .spec.securityContext entirely.
        - "containers_no_sc" or "init_containers_no_sc" > 0:
            One or more (init)containers in those pods lack .securityContext.

        These pods/containers need manual review and, where appropriate, explicit
        securityContext settings added to their manifests in line with your policy
        and the CIS guidance.
        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://kubernetes.io/docs/concepts/policy/security-context/](https://kubernetes.io/docs/concepts/policy/security-context/)
