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

# pods/exec Should Not Be Granted To Broad Subjects

### More Info:

Advisory: review Roles/ClusterRoles that grant create on pods/exec. Exec into a running pod bypasses image immutability and admission controls.

### Risk Level

High

### Address

Security

### Compliance Standards

* Cloudanix Best Practice

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **List all Roles/ClusterRoles that grant `create` on `pods/exec`.**
           * Run on: any machine with kubectl access
           ```bash theme={null}
           kubectl get clusterroles -o json | jq -r '
             .items[]
             | select(.rules[]? 
               | (.resources[]? == "pods/exec") 
               and (.verbs[]? == "create")
             )
             | .metadata.name
           '
           kubectl get roles -A -o json | jq -r '
             .items[]
             | select(.rules[]? 
               | (.resources[]? == "pods/exec") 
               and (.verbs[]? == "create")
             )
             | (.metadata.namespace + ":" + .metadata.name)
           '
           ```

        2. **Identify which subjects are bound to those Roles/ClusterRoles.**
           * Run on: any machine with kubectl access
           ```bash theme={null}
           # For each ClusterRole name found above, substitute into:
           kubectl get clusterrolebindings -o yaml | \
             yq 'select(.roleRef.kind == "ClusterRole" and .roleRef.name == "NAME_HERE") | {metadata:{name}, roleRef, subjects}'

           # For each namespaced Role "NAMESPACE:NAME" found above:
           kubectl get rolebindings -n NAMESPACE -o yaml | \
             yq 'select(.roleRef.kind == "Role" and .roleRef.name == "NAME_HERE") | {metadata:{name,namespace}, roleRef, subjects}'
           ```

        3. **Evaluate whether subjects are “broad” and if they truly need exec.**
           * Treat these as broad and usually inappropriate for `pods/exec`:
             * `system:authenticated`, `system:unauthenticated`, `system:serviceaccounts`, `system:serviceaccounts:*`
             * Any group that represents all developers or all users
             * Wildcard subjects like many service accounts across multiple namespaces
           * Keep `create` on `pods/exec` only for:
             * A small, named set of human users or groups (e.g. on-call SRE group)
             * Very limited support automation, with strong justification

        4. **Design the least-privilege change.**\
           For each over‑broad binding you found:
           * Decide whether to:
             * Remove the binding entirely, **or**
             * Replace broad groups with specific human users/groups, **or**
             * Move `pods/exec` into a separate, more restricted Role/ClusterRole and bind only to a small operator group.\
               Document which Role/ClusterRole and which RoleBinding/ClusterRoleBinding you will edit and the new subject list.

        5. **Apply the RBAC changes via manifests or kubectl edit.**
           * Preferred (GitOps-friendly): export, edit, and apply.
           * Run on: any machine with kubectl access
           ```bash theme={null}
           # Example: export an existing ClusterRoleBinding for editing
           kubectl get clusterrolebinding NAME_HERE -o yaml > crb-updated.yaml
           # Edit subjects: remove broad groups, keep only named human operators
           vi crb-updated.yaml
           # Apply the change
           kubectl apply -f crb-updated.yaml

           # Similarly for RoleBinding:
           kubectl get rolebinding NAME_HERE -n NAMESPACE -o yaml > rb-updated.yaml
           vi rb-updated.yaml
           kubectl apply -f rb-updated.yaml
           ```
           If manifests are managed by IaC, make equivalent edits in the source repo instead of using `kubectl edit`, then redeploy.

        6. **Verify that `pods/exec` is only granted to the intended narrow subjects.**
           * Run on: any machine with kubectl access
           ```bash theme={null}
           # Re-run evidence gathering
           kubectl get clusterroles -o json | jq -r '
             .items[]
             | select(.rules[]? 
               | (.resources[]? == "pods/exec") 
               and (.verbs[]? == "create")
             )
             | .metadata.name
           '
           kubectl get roles -N -o json | jq -r '
             .items[]
             | select(.rules[]? 
               | (.resources[]? == "pods/exec") 
               and (.verbs[]? == "create")
             )
             | (.metadata.namespace + ":" + .metadata.name)
           '

           # For each Role/ClusterRole listed, confirm subjects are only the small, named operator set:
           kubectl get clusterrolebindings -o yaml | yq 'select(.roleRef.name == "NAME_HERE") | {metadata:{name}, roleRef, subjects}'
           kubectl get rolebindings -n NAMESPACE -o yaml | yq 'select(.roleRef.name == "NAME_HERE") | {metadata:{name,namespace}, roleRef, subjects}'
           ```
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all Roles/ClusterRoles that mention pods/exec
        # Run on: any machine with kubectl access

        kubectl get clusterroles -o yaml | grep -nE "pods/exec|pods\/exec" -A5 -B5
        kubectl get roles --all-namespaces -o yaml | grep -nE "pods/exec|pods\/exec" -A5 -B5
        ```

        What to look for:

        * Any rule with:
          * `resources: ["pods/exec"]` (or included in a list)
          * AND `verbs` including `create` (or `*`)

        Example problematic rule snippet:

        ```yaml theme={null}
        rules:
        - apiGroups: [""]
          resources: ["pods/exec"]
          verbs: ["get", "list", "watch", "create"]
        ```

        or:

        ```yaml theme={null}
        rules:
        - apiGroups: [""]
          resources: ["pods", "pods/exec", "pods/log"]
          verbs: ["*"]
        ```

        ***

        ```bash theme={null}
        # 2) Show full definitions for candidate ClusterRoles/Roles
        # Replace <name> / <namespace> with names you saw above

        # ClusterRoles
        kubectl get clusterrole <name> -o yaml

        # Namespaced Roles
        kubectl get role <name> -n <namespace> -o yaml
        ```

        What to look for:

        * Under `rules:`:
          * `resources` includes `pods/exec` (explicitly or as part of a broader pattern like `["*"]`).
          * `verbs` includes `create` or `*`.

        Flag as higher-risk if:

        * The role is clearly generic or broad, e.g. `cluster-admin`, `edit`, `view` customizations, or any “developer”, “default”, or “\*” style role used by many users/groups/service accounts.

        ***

        ```bash theme={null}
        # 3) Identify *who* gets each risky Role/ClusterRole (RoleBindings and ClusterRoleBindings)
        # Run on: any machine with kubectl access

        # List all bindings so you can correlate names
        kubectl get clusterrolebindings -o yaml > /tmp/clusterrolebindings.yaml
        kubectl get rolebindings --all-namespaces -o yaml > /tmp/rolebindings.yaml
        ```

        Then search for each Role/ClusterRole name that can `create` on `pods/exec`:

        ```bash theme={null}
        # Example: find all bindings for ClusterRole 'dev-ops'
        grep -n "name: dev-ops" -A4 -B4 /tmp/clusterrolebindings.yaml
        grep -n "name: dev-ops" -A4 -B4 /tmp/rolebindings.yaml
        ```

        What indicates a problem:

        * Bindings that attach a `pods/exec` `create`-capable role to broad subjects, such as:
          * `system:authenticated`
          * Large identity groups (e.g., `developers`, `all-users`, `ci-users`) used by many people
          * Generic service accounts used cluster-wide (e.g., `default` in many namespaces)
        * Bindings in many namespaces for the same permissive Role.

        Example concerning binding snippet:

        ```yaml theme={null}
        subjects:
        - kind: Group
          name: developers
          apiGroup: rbac.authorization.k8s.io
        roleRef:
          kind: ClusterRole
          name: dev-ops       # this ClusterRole can create on pods/exec
          apiGroup: rbac.authorization.k8s.io
        ```

        ***

        ```bash theme={null}
        # 4) Focus on the default high-privilege roles for context (read-only)
        kubectl get clusterrole admin -o yaml
        kubectl get clusterrole edit -o yaml
        kubectl get clusterrole cluster-admin -o yaml
        ```

        What to note:

        * These built-in roles are intentionally broad; if they (or custom equivalents) are widely granted, then many subjects may indirectly get `pods/exec` `create`.
        * This does NOT by itself say “fix this” — it tells you where exec is inherited from.

        ***

        ```bash theme={null}
        # 5) Optional: summarize all roles that include pods/exec with create
        # (uses jsonpath and jq; jq must be installed)
        kubectl get clusterroles -o json \
          | jq '.items[]
            | {name: .metadata.name,
               rules: (.rules // [])
              | map(select((.resources // []) | index("pods/exec"))
                    | select(((.verbs // []) | index("create")) or ((.verbs // []) | index("*"))))
              }
            | select(.rules | length > 0)'
        ```

        Interpretation:

        * Every object printed is a ClusterRole that grants `create` (or `*`) on `pods/exec`.
        * For each of these, you must manually review:
          * Is this meant only for a very small, named set of human operators?
          * Are its bindings limited to those identities?
        * If the same role shows up here and is bound to broad groups or many service accounts (as seen in step 3), that’s a likely policy concern that needs design and approval rather than an automatic change.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Report Roles/ClusterRoles that grant create on pods/exec, and who can use them.
        # Run on: any machine with kubectl access and current context set to target cluster.

        set -euo pipefail

        echo "=== Searching for Roles and ClusterRoles that grant create on pods/exec ==="
        echo

        echo "--- ClusterRoles ---"
        kubectl get clusterroles -o json \
          | jq -r '
            .items[]
            | select(
                (.rules // [])
                | map(
                    (.resources // [] | index("pods/exec"))
                    and
                    (.verbs // [] | index("create"))
                )
                | any
              )
            | .metadata.name
          ' | sort -u | tee /tmp/pods-exec-clusterroles.txt

        echo
        echo "--- Namespaced Roles ---"
        kubectl get roles -A -o json \
          | jq -r '
            .items[]
            | select(
                (.rules // [])
                | map(
                    (.resources // [] | index("pods/exec"))
                    and
                    (.verbs // [] | index("create"))
                )
                | any
              )
            | [.metadata.namespace, .metadata.name] | @tsv
          ' | sort -u | tee /tmp/pods-exec-roles.txt

        echo
        echo "=== Finding Subjects bound to these Roles/ClusterRoles ==="
        echo

        echo "--- ClusterRoleBindings using affected ClusterRoles ---"
        if [ -s /tmp/pods-exec-clusterroles.txt ]; then
          cr_list=$(paste -sd, /tmp/pods-exec-clusterroles.txt)
          kubectl get clusterrolebindings -o json \
            | jq -r --argjson crs '("'"$cr_list"'")|split(",")' '
                .items[]
                | select(.roleRef.kind=="ClusterRole" and (.roleRef.name as $n | $crs | index($n)))
                | {
                    name: .metadata.name,
                    roleRef: .roleRef.name,
                    subjects: (.subjects // [])
                  }
                | "ClusterRoleBinding: \(.name)\n  Role: \(.roleRef)\n  Subjects:\n" +
                  ( .subjects[]
                    | "    - kind=\(.kind) name=\(.name) namespace=\(.namespace // "-")"
                  )
              '
        else
          echo "No ClusterRoles grant create on pods/exec."
        fi

        echo
        echo "--- RoleBindings using affected Roles (namespaced) ---"
        if [ -s /tmp/pods-exec-roles.txt ]; then
          # Build a set of "namespace|name" for quick checking in jq
          mapfile -t role_lines < /tmp/pods-exec-roles.txt
          roles_json=$(printf '%s\n' "${role_lines[@]}" | awk -F '\t' '{print "{\"ns\":\""$1"\",\"name\":\""$2"\"}"}' | jq -s '.')
          kubectl get rolebindings -A -o json \
            | jq -r --argjson roles "$roles_json" '
                .items[]
                | select(
                    .roleRef.kind=="Role" and
                    ([$.metadata.namespace, .roleRef.name] as $pair
                     | $roles | map(select(.ns==$pair[0] and .name==$pair[1])) | length > 0)
                  )
                | {
                    namespace: .metadata.namespace,
                    name: .metadata.name,
                    roleRef: .roleRef.name,
                    subjects: (.subjects // [])
                  }
                | "RoleBinding: \(.namespace)/\(.name)\n  Role: \(.roleRef)\n  Subjects:\n" +
                  ( .subjects[]
                    | "    - kind=\(.kind) name=\(.name) namespace=\(.namespace // "-")"
                  )
              '
        else
          echo "No namespaced Roles grant create on pods/exec."
        fi

        echo
        echo "=== Interpretation Guidance ==="
        cat <<'EOF'
        Potential problems to review manually:

        1) Very broad subjects:
           - kind=Group name=system:authenticated
           - kind=Group name=system:serviceaccounts
           - kind=Group name=system:serviceaccounts:<namespace>
           - Wildcard-like or catch-all groups (e.g. "developers", "everyone").

        2) Non-human subjects:
           - kind=ServiceAccount for application workloads.

        3) Cluster-wide scope:
           - ClusterRoles with pods/exec create bound cluster-wide when most users
             only need exec in specific namespaces.

        4) Excessive bindings:
           - Same pods/exec-granting role bound to many users/groups/namespaces.

        Remediation is manual: restrict pods/exec (create) to a small, named set of
        trusted human operators, and use separate, tightly scoped Roles where needed.
        EOF
        ```

        **What output indicates a problem**

        * Any ClusterRole or Role listed at the top sections is a candidate for review.
        * In the bindings sections, pay special attention if:
          * `Subjects` include wide groups like `system:authenticated`, `system:serviceaccounts`, or generic org-wide groups.
          * `Subjects` are `ServiceAccount` objects for workloads instead of human users.
          * The same exec-granting role is bound in many namespaces or via ClusterRoleBindings.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
