Skip to main content

GCP Minimize Access Create Pods

More Info:

The ability to create pods in a namespace can provide a number of opportunities for privilege escalation, such as assigning privileged service accounts to these pods or mounting hostPaths with access to sensitive data (unless Pod Security Policies are implemented to restrict this access)

Risk Level

Low

Address

Security

Compliance Standards

  • APRA CPS 234 (Australia)
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS Critical Security Controls v8
  • CIS GKE
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • Essential 8
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • SWIFT Customer Security Controls Framework
  • Sarbanes-Oxley IT General Controls
  • UK NCSC Cyber Assessment Framework

Triage and Remediation

Remediation

Manual Steps
  1. Identify who can create Pods in each namespace
    Run on any machine with kubectl access:

    kubectl auth can-i create pods --all-namespaces --as system:serviceaccount:kube-system:default

    To list all subjects with create on pods (Role/RoleBinding + ClusterRole/ClusterRoleBinding):

    kubectl get role,clusterrole -A -o yaml | grep -nA5 "resources:.*pods" | grep -B3 "verbs:.*create"
    kubectl get rolebinding,clusterrolebinding -A -o yaml > /tmp/rb-crb.yaml

    Inspect /tmp/rb-crb.yaml to map roles with create on pods to users/groups/serviceaccounts.

  2. Review necessity of Pod creation for each subject
    For each Role/ClusterRole that allows create on pods, decide if it is truly needed:

    # Example: inspect one role in detail
    kubectl get role -n <namespace> <role-name> -o yaml
    kubectl get clusterrole <clusterrole-name> -o yaml

    Cross-check with application/CI/CD design docs and workload requirements for that namespace; flag any human users or broad groups (e.g. system:authenticated) that don’t require direct pod creation.

  3. Scope down or remove excessive Pod creation permissions
    For each unnecessary permission, edit the binding or role:

    # Edit Role to remove 'create' on pods (least privilege)
    kubectl edit role -n <namespace> <role-name>

    # Or edit ClusterRole
    kubectl edit clusterrole <clusterrole-name>

    # Or remove an overly broad binding entirely
    kubectl delete rolebinding -n <namespace> <binding-name>
    kubectl delete clusterrolebinding <binding-name>

    In the editor, remove create from verbs under the rule with resources: ["pods"], or delete the whole rule if Pod access is not required.

  4. Prefer higher-level or constrained permissions where needed
    For subjects that legitimately need to run workloads, replace direct Pod creation with safer alternatives where possible:

    • Grant permissions on deployments, statefulsets, jobs, etc. instead of pods.
    • If Pod creation is required, constrain it using:
      # Example: ensure a restricted Pod Security configuration / namespace label is in place
      kubectl label namespace <namespace> pod-security.kubernetes.io/enforce=restricted --overwrite=true

    Document each case where create pods remains necessary and why.

  5. Re‑verify effective permissions after changes
    Re-run access checks to confirm that unnecessary Pod creation rights are removed:

    kubectl get role,clusterrole -A -o yaml | grep -nA5 "resources:.*pods" | grep -B3 "verbs:.*create"

    For specific high‑risk identities (e.g. human admins, CI service accounts), validate explicitly:

    kubectl auth can-i create pods -n <namespace> --as <user-or-sa>
  6. Optionally test by simulating Pod creation attempts
    For a sampled set of users/service accounts:

    kubectl --as <user-or-sa> -n <namespace> run test-pod --image=busybox --restart=Never -- sleep 60

    Expect failure (no, or “forbidden”) for identities that should not be able to create Pods, and success only for those explicitly approved. Clean up any test Pods you created:

    kubectl delete pod test-pod -n <namespace> --ignore-not-found
Using kubectl

Using kubectl

Run these commands from any machine with kubectl access.

1. Find who can create pods cluster-wide

kubectl get clusterrole -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{range .rules[*]}{" "}{.verbs}{" -> "}{.resources}{"\n"}{end}{"\n"}{end}' | grep -B1 "pods" | grep -B1 "create"

Problem indication:

  • Any ClusterRole where verbs includes create and resources includes pods means cluster-wide permission to create pods.
  • Especially review broad roles like cluster-admin, edit, or custom roles used by many subjects.

List which subjects are bound to those ClusterRoles:

kubectl get clusterrolebindings -o wide

Problem indication:

  • ClusterRoleBinding objects that bind the above roles to system:authenticated, large groups (e.g. developers), or service accounts not meant to manage workloads indicate over-granting.

To see details for a specific binding:

kubectl get clusterrolebinding <binding-name> -o yaml

2. Find who can create pods in each namespace

List all Roles that allow pod creation:

for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
echo "=== Namespace: $ns ==="
kubectl get role -n "$ns" -o json | \
jq -r '.items[] | select(.rules[]? | (.resources[]? == "pods") and (.verbs[]? == "create")) | .metadata.name'
done

Problem indication:

  • Any Role in sensitive namespaces (e.g. kube-system, security, prod) with resources: ["pods"] and verbs including create needs careful justification.

Show who is bound to those Roles:

for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
echo "=== Namespace: $ns ==="
kubectl get rolebinding -n "$ns" -o yaml | \
grep -E "^(kind: RoleBinding| name: | kind: (User|Group|ServiceAccount)| name: .*| namespace: )"
done

For a specific namespace with many workloads (e.g. prod):

kubectl get role -n prod -o yaml | grep -n "pods" -n
kubectl get rolebinding -n prod -o yaml

Problem indication:

  • RoleBindings that attach pod-creating Roles to broad groups or many service accounts (e.g. generic CI accounts, default service accounts) signal overly permissive pod-creation rights.

3. Use kubectl auth can-i to spot effective access

Test specific identities (substitute actual user or service account):

# As current kubectl identity
kubectl auth can-i create pods --all-namespaces

# As a specific user
kubectl auth can-i create pods --all-namespaces --as=user@example.com

# As a service account in a namespace
kubectl auth can-i create pods -n prod --as=system:serviceaccount:prod:ci-bot

Problem indication:

  • yes for --all-namespaces or in sensitive namespaces for identities that should not manage workloads indicates excessive access to create pods.

These commands show where pod creation is currently allowed; a human must decide which roles/bindings are justified and which should be restricted or removed.

Automation
#!/usr/bin/env bash
# Report who can create pods across the whole cluster
# Runs on: any machine with kubectl access and appropriate RBAC

set -euo pipefail

echo "=== Cluster-wide (non-namespaced) permissions to create pods ==="
kubectl auth can-i create pods --all-namespaces=false --as=system:anonymous 2>/dev/null || true
echo "Note: Above is a simple anonymous check; detailed RBAC is below."

echo
echo "=== Detailed RBAC: Roles/ClusterRoles that allow create on pods ==="

# 1) ClusterRoles with create on pods
echo
echo "---- ClusterRoles with 'create' on pods ----"
kubectl get clusterroles -o json \
| jq -r '
.items[]
| {name: .metadata.name, rules: .rules}
| select(.rules != null)
| select(
.rules[]
| select(
((.verbs // []) | index("create"))
and
(
((.resources // []) | index("pods"))
or
((.resources // []) | index("*"))
)
)
)
| .name' \
| sort -u

# 2) Namespaced Roles with create on pods, grouped by namespace
echo
echo "---- Roles (namespaced) with 'create' on pods ----"
kubectl get roles --all-namespaces -o json \
| jq -r '
.items[]
| {ns: .metadata.namespace, name: .metadata.name, rules: .rules}
| select(.rules != null)
| select(
.rules[]
| select(
((.verbs // []) | index("create"))
and
(
((.resources // []) | index("pods"))
or
((.resources // []) | index("*"))
)
)
)
| "\(.ns) \(.name)"' \
| sort -u

# 3) Bindings: who gets the above roles/clusterroles
echo
echo "=== ClusterRoleBindings (cluster-wide subjects that may create pods) ==="
kubectl get clusterrolebindings -o json \
| jq -r '
.items[]
| {name: .metadata.name, roleRef: .roleRef, subjects: (.subjects // [])}
| select(.roleRef.kind == "ClusterRole")
| select(.roleRef.name != "")
| "\(.name)\trole=\(.roleRef.name)\tsubjects=" +
(if (.subjects | length) == 0 then "NONE"
else (.subjects | map("\(.kind):\(.namespace // "-")/\(.name)") | join(","))
end)
' \
| sort

echo
echo "=== RoleBindings (namespaced subjects that may create pods) ==="
kubectl get rolebindings --all-namespaces -o json \
| jq -r '
.items[]
| {ns: .metadata.namespace, name: .metadata.name, roleRef: .roleRef, subjects: (.subjects // [])}
| "\(.ns)\t\(.name)\troleKind=\(.roleRef.kind)\troleName=\(.roleRef.name)\tsubjects=" +
(if (.subjects | length) == 0 then "NONE"
else (.subjects | map("\(.kind):\(.namespace // "-")/\(.name)") | join(","))
end)
' \
| sort

echo
echo "=== Summary hints ==="
cat <<'EOF'
Review focus:

1) ClusterRoles shown above, especially:
- Roles with resources: ["*"] or including "pods"
- Verbs including "create"
- Roles bound to:
* system:authenticated (all logged-in users)
* system:serviceaccounts or system:serviceaccounts:<ns>
* broad groups (e.g. devs, ci, platform) that do not need pod-creation rights

2) Namespaces:
- Pay attention to production or sensitive namespaces where few identities
should be able to create pods.

Indicators of a potential problem:

- Any ClusterRole with create on pods bound (via ClusterRoleBinding) to:
* system:authenticated
* system:serviceaccounts
* large user groups not tied to a specific app/team
- RoleBindings in sensitive namespaces granting pod creation to:
* Generic groups (e.g. "developers") instead of specific service accounts
* Default service accounts or broad serviceaccount groups
- Roles that include:
* resources: ["*"] and verbs: ["*"] or including "create"
* resources including "pods" with verbs including "create"
for subjects that do not require full pod lifecycle control.

Use this report to decide where to tighten RBAC by:
- Editing or replacing Roles/ClusterRoles to remove "create" on "pods"
- Narrowing or removing RoleBindings/ClusterRoleBindings that grant such roles
in namespaces or to subjects that do not strictly require it.
EOF