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

# Ensure Pod Security Policy Is Enabled And Set As Appropriate

### More Info:

Pod Security Policy Should Be Used To Prevent Privileged Containers Where Possible And Enforce Namespace And Workload Configurations.

### Risk Level

Low

### Address

Security

### Compliance Standards

* CIS GKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify clusters and current PSP setting**
           * On any machine with `gcloud` configured for your GCP project, list clusters and check whether PSP is enabled:
             ```bash theme={null}
             gcloud container clusters list --format="table(name,location,releaseChannel.channel)"
             gcloud container clusters describe CLUSTER_NAME --zone ZONE \
               --format="value(podSecurityPolicyConfig.enabled)"
             ```
           * If the value is empty or `false`, PSP is not enabled on that cluster.

        2. **Review current use of privileged features in workloads**
           * On any machine with `gcloud` and `kubectl` access, inspect workloads that might require elevated privileges:
             ```bash theme={null}
             kubectl get pods --all-namespaces -o json \
               | jq '.items[]
                 | {ns:.metadata.namespace, name:.metadata.name,
                    privileged:(.spec.containers[]?.securityContext.privileged // false),
                    hostPID:(.spec.hostPID // false),
                    hostNetwork:(.spec.hostNetwork // false),
                    hostIPC:(.spec.hostIPC // false)}' \
               | uniq
             ```
           * Note namespaces and workloads that rely on privileged, hostPID, hostNetwork, hostIPC, or hostPath volumes; these will need either exceptions or refactoring before strict policies are enforced.

        3. **Decide PSP (or modern equivalent) strategy for the cluster**
           * For clusters running a GKE version that still supports PodSecurityPolicy and where you want to enforce it at the control-plane level, plan PSPs that:
             * Deny privileged containers and host namespaces by default.
             * Allow only specific system namespaces (for example, `kube-system`) or known DaemonSets to use required privileges.
           * For newer clusters or where PSP is deprecated/removed, decide whether to instead use the built‑in Pod Security Admission (`pod-security.kubernetes.io/*` labels on namespaces) or a policy engine such as GKE Policy Controller (OPA/Gatekeeper).

        4. **Enable or adjust Pod Security / policy enforcement at the control-plane**
           * If the cluster supports PSP and you decide to use it, enable PSP via the control-plane configuration from any machine with `gcloud` access:
             ```bash theme={null}
             gcloud beta container clusters update CLUSTER_NAME \
               --zone ZONE \
               --enable-pod-security-policy
             ```
           * If PSP cannot be enabled (for example, because it is not supported in your GKE version), configure an alternative:
             * Namespace Pod Security Admission levels:
               ```bash theme={null}
               kubectl label namespace NAMESPACE \
                 pod-security.kubernetes.io/enforce=baseline \
                 pod-security.kubernetes.io/enforce-version=latest
               ```
             * Or enable and configure GKE Policy Controller via the GKE console or `gcloud alpha container hub config-management` commands, according to your organization’s policy.

        5. **Implement and test policy scope to avoid disruption**
           * Begin with non-production namespaces:
             * Apply restrictive settings (PSP or Pod Security Admission labels / Policy Controller constraints).
             * Attempt to deploy workloads that should be allowed and disallowed, and confirm behavior matches expectations.
           * For workloads that legitimately need higher privileges, design narrowly scoped exceptions (dedicated PSPs, less restrictive namespace labels, or specific policy constraints) and validate those workloads can still run.

        6. **Verify and document the final configuration**
           * Confirm PSP is enabled at the cluster level (if applicable):
             ```bash theme={null}
             gcloud container clusters describe CLUSTER_NAME --zone ZONE \
               --format="value(podSecurityPolicyConfig.enabled)"
             ```
           * List active Pod Security Policies (if in use):
             ```bash theme={null}
             kubectl get psp
             ```
           * For Pod Security Admission, verify namespace labels:
             ```bash theme={null}
             kubectl get ns --show-labels
             ```
           * For Policy Controller, list constraint templates and constraints:
             ```bash theme={null}
             kubectl get constrainttemplates --all-namespaces
             kubectl get constraints --all-namespaces
             ```
           * Record which mechanism is in use, which namespaces are protected, and any approved exceptions for future audits.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot enable or configure Pod Security Policy because this setting is controlled at the GKE cluster (managed control plane) level via gcloud/console/IaC. To remediate, follow the guidance in the Manual Steps section, which covers enabling Pod Security Policy through the cloud provider configuration.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Audit Pod Security Policy (PSP) usage and risk indicators in a GKE cluster.
        # Runs read-only checks using kubectl.
        #
        # Requirements:
        #   - Run on any machine with kubectl access and context set to the target cluster.
        #   - kubectl must be authorized with cluster-admin or equivalent read access.

        set -euo pipefail

        echo "=== 1) CLUSTER-LEVEL INDICATORS (GKE FEATURES) ==="
        echo
        echo "NOTE: Enabling/disabling Pod Security Policy itself is done via gcloud, not kubectl."
        echo "      This script only inspects PSP objects and workload risk indicators."
        echo

        echo "--- a) Check for PodSecurityPolicy resources ---"
        kubectl get podsecuritypolicies.policy 2>/dev/null || \
          kubectl get psp 2>/dev/null || \
          echo "No PodSecurityPolicy resources found (or PSP API disabled)."

        echo
        echo "Interpretation:"
        echo "  - If no PSPs are listed but the cluster is configured to use PSPs, pods may be blocked"
        echo "    from scheduling unless other admission controls are in place."
        echo "  - If the cluster is not configured to use PSPs (gcloud --enable-pod-security-policy not set),"
        echo "    then this benchmark finding is NOT satisfied: PSP is not enabled at the control plane."

        echo
        echo "--- b) List PSPs with key security-relevant settings ---"
        # This surfaces PSPs that allow privileged or broad host access
        kubectl get podsecuritypolicies.policy -o custom-columns=NAME:.metadata.name,PRIV:.spec.privileged,HOSTPID:.spec.hostPID,HOSTIPC:.spec.hostIPC,HOSTNET:.spec.hostNetwork,ALLOW_PRIV_ESC:.spec.allowPrivilegeEscalation,SELINUX:.spec.seLinux.rule,RUNASUSER:.spec.runAsUser.rule,FSGROUP:.spec.fsGroup.rule,SUPPGRP:.spec.supplementalGroups.rule 2>/dev/null || true

        echo
        echo "Problem indicators here include:"
        echo "  - PRIV=true                : PSP allows privileged containers."
        echo "  - HOSTPID/HOSTIPC/HOSTNET=true : PSP allows host namespace sharing."
        echo "  - ALLOW_PRIV_ESC=true or empty : PSP allows privilege escalation."
        echo "  - SELINUX/RUNASUSER/FSGROUP/SUPPGRP = RunAsAny : no restriction on IDs/labels."

        echo
        echo "=== 2) RBAC BINDINGS TO PSPs (WHO CAN USE WHICH PSP) ==="
        echo
        echo "--- a) ClusterRoleBindings referencing use of PSPs ---"
        kubectl get clusterrolebindings -o json | \
          jq -r '
            .items[]
            | select(.roleRef.kind=="ClusterRole")
            | . as $crb
            | $crb
            | .metadata.name as $crbName
            | $crb
            | .roleRef.name as $roleName
            | "CRB:\($crbName) -> ClusterRole:\($roleName)"
          ' 2>/dev/null || echo "jq not available; skipping detailed RBAC inspection."

        echo
        echo "--- b) ClusterRoles that grant use of PSPs ---"
        kubectl get clusterroles -o json 2>/dev/null | \
          jq -r '
            .items[]
            | . as $cr
            | select(
                (.rules[]? | .resources[]? == "podsecuritypolicies" and .verbs[]? == "use")
              )
            | "ClusterRole:\(.metadata.name)"
          ' 2>/dev/null || true

        echo
        echo "Review guidance:"
        echo "  - Any ClusterRole with rules on resource=podsecuritypolicies, verb=use grants PSP usage."
        echo "  - Check which subjects (users/groups/serviceaccounts) are bound to those ClusterRoles."
        echo "  - A problem is indicated if broad groups (e.g., system:authenticated, system:masters, or"
        echo "    large app teams) are bound to overly-permissive PSPs."

        echo
        echo "--- c) Show which subjects can use each PSP (approximate) ---"
        echo "This uses RBAC info to approximate PSP usage:"
        kubectl get clusterroles -o json 2>/dev/null | \
          jq -r '
            .items[]
            | . as $cr
            | select(
                (.rules[]? | .resources[]? == "podsecuritypolicies" and .verbs[]? == "use")
              )
            | "ClusterRole:\($cr.metadata.name)"
          ' 2>/dev/null | while read -r role; do
            rname="${role#ClusterRole:}"
            echo
            echo "ClusterRole: ${rname}"
            echo "  Bound via ClusterRoleBinding(s):"
            kubectl get clusterrolebindings -o json 2>/dev/null | \
              jq -r --arg ROLE "$rname" '
                .items[]
                | select(.roleRef.kind=="ClusterRole" and .roleRef.name==$ROLE)
                | "    CRB:\(.metadata.name) subjects: " +
                  ( .subjects // [] | map(.kind + "/" + .name) | join(", ") )
              ' || true
          done

        echo
        echo "Problem indicators in this section:"
        echo "  - ClusterRoles that allow use of PSPs with PRIV=true or broad host access,"
        echo "    bound to wide subjects like system:authenticated."
        echo "  - Service accounts used by less-trusted workloads bound to very permissive PSPs."

        echo
        echo "=== 3) WORKLOAD RISK SAMPLING (PODS THAT WOULD REQUIRE PERMISSIVE PSPs) ==="
        echo
        echo "--- a) List pods running privileged or with host namespaces ---"
        kubectl get pods --all-namespaces -o json | \
          jq -r '
            .items[]
            | .metadata as $m
            | .spec as $s
            | .status as $st
            | [
                ($m.namespace),
                ($m.name),
                ([$s.initContainers[], $s.containers[]]?
                  | map(
                      {
                        name: .name,
                        privileged: (.securityContext.privileged // false),
                        hostPID: ($s.hostPID // false),
                        hostIPC: ($s.hostIPC // false),
                        hostNetwork: ($s.hostNetwork // false),
                        allowPrivEsc: (.securityContext.allowPrivilegeEscalation // "null")
                      }
                    )
                )
              ]
            | select(.[2] != null)
            | . as [$ns, $pod, $cs]
            | $cs[]
            | select(.privileged == true or .hostPID == true or .hostIPC == true or .hostNetwork == true or .allowPrivEsc == true)
            | "NS=\($ns) POD=\($pod) CONTAINER=\(.name) privileged=\(.privileged) hostPID=\(.hostPID) hostIPC=\(.hostIPC) hostNetwork=\(.hostNetwork) allowPrivEsc=\(.allowPrivEsc)"
          ' 2>/dev/null || echo "jq not available; skipping pod-level risk sampling."

        echo
        echo "Problem indicators here:"
        echo "  - Non-system workloads (namespaces other than kube-system, gke-system, etc.)"
        echo "    running privileged or sharing host namespaces."
        echo "  - If such workloads exist and require permissive PSPs, strong segregation and"
        echo "    explicit justification are required."

        echo
        echo "=== 4) SUMMARY OF WHAT INDICATES A PROBLEM FOR THIS BENCHMARK ==="
        echo
        echo "The benchmark finding is NOT satisfied if ANY of the following apply:"
        echo "  1) The cluster control-plane is not configured with Pod Security Policy admission"
        echo "     (gcloud --enable-pod-security-policy not set for the cluster)."
        echo "  2) PSPs exist but:"
        echo "       - Default / commonly used PSPs allow privileged=true or broad host* access,"
        echo "         AND are bound to wide subjects (e.g. system:authenticated)."
        echo "       - Most workloads could run with stricter PSPs but are not constrained."
        echo
        echo "To remediate the control-plane setting itself, use the provider tooling, e.g.:"
        echo "  gcloud beta container clusters update CLUSTER_NAME --zone COMPUTE_ZONE --enable-pod-security-policy"
        echo
        echo "This script only helps you identify the current state and potential misconfigurations."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://cloud.google.com/kubernetes-engine/docs/how-to/pod-security-policies](https://cloud.google.com/kubernetes-engine/docs/how-to/pod-security-policies)
