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

### More Info:

Security contexts restrict privileges, capabilities, volumes, and root access for pods and containers. Apply restrictive policies broadly and scope privileged access to specific service accounts and namespaces.

### Risk Level

Low

### Address

Security

### Compliance Standards

* CIS OKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify pods and namespaces with missing or weak securityContext**
           * On any machine with kubectl access:
             ```bash theme={null}
             # Pods missing any pod-level or container-level securityContext
             kubectl get pods --all-namespaces -o json \
               | jq -r '.items[]
                 | select((.spec.securityContext // {} | length) == 0
                          or ([.spec.containers[].securityContext] | map(select(. != null)) | length) == 0)
                 | [.metadata.namespace, .metadata.name]
                 | @tsv'
             ```
             ```bash theme={null}
             # Pods allowing privilege escalation or running privileged / as root
             kubectl get pods --all-namespaces -o json \
               | jq -r '.items[]
                 | select(
                     [.spec.containers[]?][]
                     | (
                         (.securityContext.privileged // false) == true
                         or (.securityContext.allowPrivilegeEscalation // true) == true
                         or ((.securityContext.runAsUser // 0) == 0)
                       )
                   )
                 | [.metadata.namespace, .metadata.name]
                 | @tsv'
             ```

        2. **Review securityContext details for suspicious pods**
           * For each namespace/pod pair from step 1, inspect full spec:
             ```bash theme={null}
             kubectl -n <namespace> get pod <pod-name> -o yaml
             ```
           * Manually check for:
             * `securityContext.privileged: true`
             * `allowPrivilegeEscalation: true` or unset
             * `runAsUser: 0` or `runAsNonRoot: false`/unset
             * Use of `hostNetwork`, `hostPID`, `hostIPC`, and `hostPath` volumes
             * Absence of `capabilities.drop: ["ALL"]`

        3. **Decide which workloads truly need elevated privileges and scope them**
           * Classify each privileged/high‑risk pod as:
             * **System-critical (needs elevated privileges)** – e.g. CNI, kube-proxy, node/logging/monitoring agents. Prefer to run these in a dedicated namespace like `kube-system` or another clearly named “system” namespace.
             * **Business application (should be restricted)** – typical app workloads that should run non-root and non-privileged.
           * For system-critical pods:
             * Ensure they use dedicated service accounts and namespaces.
             * Plan to bind any future privileged policies only to those service accounts/namespaces.

        4. **Define or tighten restrictive security policies for normal workloads**
           * On any machine with kubectl access, create a baseline “restricted” policy object aligned with the remediation (adapted to your cluster’s API support; PodSecurityPolicy is deprecated in newer versions, so you may instead implement equivalent Pod Security Admission or OPA/Gatekeeper):
             ```bash theme={null}
             cat << 'EOF' > restricted-psp.yaml
             apiVersion: policy/v1beta1
             kind: PodSecurityPolicy
             metadata:
               name: restricted
             annotations:
               seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default'
               apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
               seccomp.security.alpha.kubernetes.io/defaultProfileName: 'runtime/default'
               apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
             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

             kubectl apply -f restricted-psp.yaml
             ```
           * Bind this policy only to non-privileged service accounts/namespaces via RBAC (cluster roles/rolebindings) after confirming PodSecurityPolicy is enabled in your cluster.

        5. **Refactor pod specs for non-privileged workloads**
           * For each business/application workload identified in step 3, update the Deployment/DaemonSet/StatefulSet (not the live pod) to add safe security contexts, for example:
             ```bash theme={null}
             kubectl -n <namespace> edit deployment <deployment-name>
             ```
             * Under `spec.template.spec.securityContext` and each container’s `securityContext`, add fields such as:
               ```yaml theme={null}
               securityContext:
                 runAsNonRoot: true
                 runAsUser: 1000
                 allowPrivilegeEscalation: false
                 capabilities:
                   drop:
                     - ALL
               ```
             * Remove `privileged: true`, `hostPath` volumes, `hostNetwork: true`, `hostPID: true`, `hostIPC: true` unless strictly required.
           * Save to trigger a rolling restart.

        6. **Verify improved posture and monitor regressions**
           * Re-run discovery to ensure no remaining obviously insecure pods:
             ```bash theme={null}
             kubectl get pods --all-namespaces -o json \
               | jq -r '.items[]
                 | select(
                     [.spec.containers[]?][]
                     | (
                         (.securityContext.privileged // false) == true
                         or (.securityContext.allowPrivilegeEscalation // true) == true
                         or ((.securityContext.runAsUser // 0) == 0)
                       )
                   )
                 | [.metadata.namespace, .metadata.name]
                 | @tsv'
             ```
           * Optionally, enforce admission controls (Pod Security Admission “restricted” level or equivalent policy engine) to prevent future pods without appropriate security contexts from being admitted.
      </Accordion>

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

        Look for non-system namespaces hosting your workloads (not `kube-system`, `kube-public`, `kube-node-lease`).

        ***

        ```bash theme={null}
        # 2) For each relevant namespace, list pods and show basic securityContext fields
        # Example for namespace "default"
        kubectl get pods -n default -o custom-columns=\
        NAME:.metadata.name,\
        SC_POD:.spec.securityContext,\
        SC_CONT:.spec.containers[*].securityContext,\
        SA:.spec.serviceAccountName
        ```

        Red flags in the output:

        * `SC_POD=<none>` and `SC_CONT=<none>` (no securityContext at all on pod or containers).
        * Service account is generic (e.g., `default`) and used by many pods that may need different privilege levels.

        ***

        ```bash theme={null}
        # 3) Inspect full spec for specific pods that look suspicious or important
        # Replace <pod> and <ns>
        kubectl get pod <pod> -n <ns> -o yaml
        ```

        In the YAML, look for:

        Pod-level (under `.spec.securityContext`):

        * Missing entirely (no `securityContext:` block).
        * `fsGroup` / `supplementalGroups` with values including `0`.
        * `runAsUser: 0` or `runAsGroup: 0` without strong need.

        Container-level (for each entry under `.spec.containers[]` and `.spec.initContainers[]`):

        * `securityContext` missing completely.
        * `privileged: true`.
        * `allowPrivilegeEscalation: true` or not set.
        * `runAsUser: 0` or `runAsNonRoot: false` or not set.
        * `capabilities.add` with broad capabilities (or no `capabilities.drop`).
        * `readOnlyRootFilesystem: false` or not set.

        Host-level access (still under each container):

        * `hostNetwork: true`, `hostPID: true`, or `hostIPC: true` (these are at pod spec level).
        * Volumes with `hostPath:` under `.spec.volumes[]` without strong justification.

        These indicate pods/containers lack restrictive security contexts or have excessive privileges compared to the benchmark example.

        ***

        ```bash theme={null}
        # 4) Check how many pods are running privileged or allowing privilege escalation
        kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.name}{" "}{.securityContext.privileged}{" "}{.securityContext.allowPrivilegeEscalation}{"\n"}{end}{end}' \
        | sort
        ```

        Concerning lines:

        * `true` in the `privileged` position.
        * `true` or `<no value>` in the `allowPrivilegeEscalation` position for general application workloads.

        ***

        ```bash theme={null}
        # 5) Check for containers running as root or without non-root enforcement
        kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.name}{" "}{.securityContext.runAsUser}{" "}{.securityContext.runAsNonRoot}{"\n"}{end}{end}' \
        | sort
        ```

        Concerning lines:

        * `0` for `runAsUser`.
        * `false` or `<no value>` for `runAsNonRoot` on general workloads.

        ***

        ```bash theme={null}
        # 6) Check volume types per pod
        kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.volumes[*]}{.name}{"="}{.hostPath}{";"}{end}{"\n"}{end}' \
        | sort
        ```

        Concerning output:

        * Any `hostPath` object (not `null`) used by regular application pods, instead of more controlled volume types (configMap, secret, PVC, etc.), unless clearly justified (e.g., logging agents, node-level tooling).

        ***

        ```bash theme={null}
        # 7) Review service accounts bound to elevated permissions
        kubectl get clusterrolebindings.rbac.authorization.k8s.io -o wide
        kubectl get rolebindings.rbac.authorization.k8s.io --all-namespaces -o wide
        ```

        Then for suspicious bindings (especially those granting broad or cluster-admin-like roles), inspect them:

        ```bash theme={null}
        # Example for one binding
        kubectl get clusterrolebinding <name> -o yaml
        kubectl get rolebinding <name> -n <ns> -o yaml
        ```

        Concerning situations:

        * Service accounts outside tightly controlled namespaces (e.g., not `kube-system`) bound to highly privileged roles.
        * Generic service accounts (`default`) having elevated roles, which may be used by pods lacking restrictive security contexts.

        ***

        ```bash theme={null}
        # 8) (If using Pod Security Admission labels instead of PodSecurityPolicy) list namespace policies
        kubectl get ns -o 'custom-columns=NAME:.metadata.name,PSA:.metadata.labels'
        ```

        Concerning output:

        * Workload namespaces without `pod-security.kubernetes.io/enforce` labels.
        * Enforce levels weaker than `restricted` for general application namespaces (e.g., `enforce=privileged` or missing).
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Purpose: Cluster-wide securityContext review for pods/containers.
        # Runs with: any machine with kubectl access and cluster‑admin or equivalent.

        set -euo pipefail

        # 1) Basic environment info
        echo "=== Cluster Info ==="
        kubectl version --short || true
        kubectl config current-context || true
        echo

        # 2) List namespaces without any Pod-level or Container-level securityContext
        echo "=== Namespaces with pods missing ANY securityContext ==="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                pod: .metadata.name,
                podSC: .spec.securityContext,
                containers: (.spec.containers // []),
                initContainers: (.spec.initContainers // [])
              }
            | select(
                # pod has no pod-level securityContext
                ( .podSC == null )
                and
                # AND every container AND initContainer has no securityContext
                ( ([.containers[], .initContainers[]] | length == 0)
                  or
                  ( [(.containers[]?, .initContainers[]?)
                      | select(.securityContext != null)
                    ] | length == 0
                  )
                )
              )
            | "\(.ns) \(.pod)"
          ' | sort -u || echo "jq not installed or no pods found"
        echo

        # 3) Pods/containers with obviously risky settings
        echo "=== Pods/containers with risky securityContext fields ==="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | . as $pod
            | ($pod.spec.containers // []) + ($pod.spec.initContainers // [])
            | map({
                ns: $pod.metadata.namespace,
                pod: $pod.metadata.name,
                cname: .name,
                sc: .securityContext
              })
            | .[]
            | select(.sc != null)
            | . as $c
            | (
                if ($c.sc.privileged == true) then
                  "PRIVILEGED|\($c.ns)|\($c.pod)|\($c.cname)"
                elif ($c.sc.allowPrivilegeEscalation == true) then
                  "ALLOW_PRIV_ESC|\($c.ns)|\($c.pod)|\($c.cname)"
                elif ($c.sc.runAsUser == 0) or ($c.sc.runAsNonRoot == false) then
                  "ROOT_USER|\($c.ns)|\($c.pod)|\($c.cname)"
                elif ($c.sc.readOnlyRootFilesystem == false) then
                  "RW_ROOTFS|\($c.ns)|\($c.pod)|\($c.cname)"
                else
                  empty
                end
              )
          ' | sort -u || echo "jq not installed or no risky containers found"
        echo

        # 4) Pods using host features (hostNetwork/IPC/PID) or hostPath volumes
        echo "=== Pods using host features or hostPath volumes ==="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                pod: .metadata.name,
                hostNetwork: (.spec.hostNetwork // false),
                hostIPC: (.spec.hostIPC // false),
                hostPID: (.spec.hostPID // false),
                hostPathVolumes: (
                  (.spec.volumes // [])
                  | map(select(.hostPath != null) | .name)
                )
              }
            | select(.hostNetwork or .hostIPC or .hostPID or (.hostPathVolumes | length > 0))
            | "\(.ns)|\(.pod)|hostNetwork=\(.hostNetwork)|hostIPC=\(.hostIPC)|hostPID=\(.hostPID)|hostPathVolumes=\((.hostPathVolumes | join(\",\")))"
          ' | sort -u || echo "jq not installed or no pods with host features"
        echo

        # 5) Summary of securityContext usage per namespace
        echo "=== Per-namespace securityContext usage summary ==="
        kubectl get pods --all-namespaces -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                podSC: .spec.securityContext,
                containers: (.spec.containers // []),
                initContainers: (.spec.initContainers // [])
              }
            | {
                ns,
                hasPodSC: (.podSC != null),
                hasAnyContainerSC: (
                  [(.containers[]?, .initContainers[]?)
                    | select(.securityContext != null)
                  ] | length > 0
                )
              }
            | "\(.ns)|podSC=\(.hasPodSC)|containerSC=\(.hasAnyContainerSC)"
          ' | sort -u || echo "jq not installed or no pods"
        echo

        # 6) Optional: show any PodSecurity or PodSecurityPolicy objects, if present
        echo "=== Cluster-level Pod security policies (if any) ==="
        kubectl get psp 2>/dev/null || echo "No PodSecurityPolicy objects or PSP API disabled"
        kubectl get podsecuritypolicies.policy 2>/dev/null || true
        kubectl get ns --show-labels | grep -E 'pod-security|pod_security' || true
        ```

        Explanation of problematic output to review manually:

        * Section “Namespaces with pods missing ANY securityContext”:
          * Any listed `<namespace> <pod>` means that pod and all its containers lack explicit `securityContext`. These are candidates to harden by adding non-root, dropping capabilities, read-only root filesystem, etc.

        * Section “Pods/containers with risky securityContext fields”:
          * Lines beginning with:
            * `PRIVILEGED|...` – containers running with `securityContext.privileged: true` (highest risk; should be tightly scoped to specific service accounts/namespaces like `kube-system` if truly required).
            * `ALLOW_PRIV_ESC|...` – containers that allow privilege escalation.
            * `ROOT_USER|...` – containers explicitly running as root (`runAsUser: 0` or `runAsNonRoot: false`).
            * `RW_ROOTFS|...` – containers with `readOnlyRootFilesystem: false` (less restrictive; often acceptable but should be intentional).

        * Section “Pods using host features or hostPath volumes”:
          * Any line indicates a pod using `hostNetwork`, `hostIPC`, `hostPID`, or `hostPath` volumes, which breaks the isolation the benchmark’s example policy expects. These should be limited to well‑understood system workloads in tightly controlled namespaces.

        * Section “Per-namespace securityContext usage summary”:
          * For each namespace:
            * `podSC=false|containerSC=false` – all pods in that namespace lack explicit securityContext; namespace is a prime target for enforcing more restrictive defaults.
            * Namespaces with many `false` values should be prioritized for adding restrictive policies and explicit pod/container securityContext.

        Use this script to identify where securityContext is missing or too permissive, then update manifests and apply namespace/service-account–scoped restrictive policies accordingly.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
