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

# Restrict Use Of Cluster-Admin Role

### More Info:

The cluster-admin role grants unrestricted access and should be bound only where absolutely required. Rebind subjects to lower-privileged roles and remove unnecessary cluster-admin bindings.

### Risk Level

Critical

### Address

Security

### Compliance Standards

* CIS OKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **List all cluster-admin bindings** (any machine with kubectl access)
           ```bash theme={null}
           kubectl get clusterrolebinding -o jsonpath='{range .items[?(@.roleRef.kind=="ClusterRole" && @.roleRef.name=="cluster-admin")]}{.metadata.name}{"\n"}{end}'
           kubectl get clusterrolebinding -o wide
           ```

        2. **Inspect each binding’s subjects and usage context**\
           For each binding name from step 1:
           ```bash theme={null}
           kubectl get clusterrolebinding <BINDING_NAME> -o yaml
           ```
           Review:
           * `subjects`: kind (User, Group, ServiceAccount), names, namespaces.
           * Any associated namespace or application these subjects belong to (e.g., by matching serviceAccount names to workloads).

        3. **Decide if cluster-admin is truly required**\
           For each subject, answer:
           * Does it need cluster-wide permissions (across all namespaces, nodes, CRDs)?
           * Is it for a human user (often does *not* need full admin; consider namespace-scoped roles) or a system component (may need elevated but often more targeted rights)?
           * Is it used only for a specific app/namespace/action that could be covered by a custom `ClusterRole` or namespaced `Role` instead of `cluster-admin`?

        4. **Design and apply least-privilege alternatives**\
           Where full cluster-admin is not justified:
           * Identify the minimal API groups, resources, and verbs needed.
           * Create a custom role/clusterrole manifest and apply it:
             ```bash theme={null}
             kubectl apply -f <NEW_ROLE_OR_CLUSTERROLE_MANIFEST>.yaml
             kubectl apply -f <NEW_ROLEBINDING_OR_CLUSTERROLEBINDING_MANIFEST>.yaml
             ```
           * Ensure the new binding targets the same subject(s) (user/group/serviceaccount) as the old cluster-admin binding.

        5. **Safely remove unnecessary cluster-admin bindings**\
           After confirming the replacement role works (e.g., subject can perform required operations but nothing more):
           ```bash theme={null}
           kubectl delete clusterrolebinding <BINDING_NAME>
           ```
           If unsure, disable in stages (e.g., remove for non-production users first, or test in a staging cluster) before removing in production.

        6. **Re-verify cluster-admin usage**\
           Confirm only justified bindings remain:
           ```bash theme={null}
           kubectl get clusterrolebinding -o jsonpath='{range .items[?(@.roleRef.kind=="ClusterRole" && @.roleRef.name=="cluster-admin")]}{.metadata.name}{"\n"}{end}'
           ```
           Manually validate each remaining binding is documented and explicitly approved as requiring unrestricted cluster access.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1. List all ClusterRoleBindings that grant cluster-admin
        # Run on: any machine with kubectl access
        kubectl get clusterrolebindings \
          -o jsonpath='{range .items[?(@.roleRef.kind=="ClusterRole" && @.roleRef.name=="cluster-admin")]}{.metadata.name}{"\n"}{end}'
        ```

        If this prints any names, those bindings grant `cluster-admin` and must be reviewed.

        ```bash theme={null}
        # 2. Inspect each suspicious ClusterRoleBinding in detail
        # Replace BINDING_NAME with each name from the previous command
        kubectl get clusterrolebinding BINDING_NAME -o yaml
        ```

        In the `subjects:` section, look for:

        * Broad subjects such as:
          * `kind: Group` with names like `system:authenticated`, `system:serviceaccounts`, or any large team group.
          * `kind: ServiceAccount` without namespace scoping issues (e.g., generic default SAs).
        * Non-essential human users or CI/CD accounts that do not genuinely need full-cluster admin.

        These indicate over-privileged access.

        ```bash theme={null}
        # 3. Get a concise view of who has cluster-admin
        kubectl get clusterrolebinding \
          -o custom-columns='NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT_KIND:.subjects[*].kind,SUBJECT_NAME:.subjects[*].name,SUBJECT_NS:.subjects[*].namespace' \
          | grep cluster-admin
        ```

        Lines where `ROLE` is `cluster-admin` and `SUBJECT_KIND` is a broad group or a non-critical user/service account are likely problematic and should be reviewed for least privilege.

        ```bash theme={null}
        # 4. (Optional) See all subjects bound to any role with admin-like power
        kubectl get clusterrolebindings -o yaml | \
          egrep '^(kind: ClusterRoleBinding|  name: |  roleRef:|    name: cluster-admin)' -n
        ```

        Use this to visually confirm where `cluster-admin` appears and cross-check against your identity / RBAC design. Any unexpected or legacy bindings here are candidates for replacement with more restrictive roles and eventual deletion.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Report all uses of the cluster-admin role across the cluster.
        # Run on: any machine with kubectl access and current-context pointing to the target cluster.

        set -o errexit
        set -o nounset
        set -o pipefail

        echo "=== ClusterRoleBindings referencing cluster-admin ==="
        kubectl get clusterrolebindings -o json \
          | jq -r '
            .items[]
            | select(.roleRef.kind=="ClusterRole" and .roleRef.name=="cluster-admin")
            | .metadata.name as $crb
            | .subjects[]
              | [$crb, .kind, (.namespace // "-"), .name]
              | @tsv
          ' 2>/dev/null || {
            echo "Failed to list clusterrolebindings or parse with jq." >&2
            exit 1
          }

        echo
        echo "Columns: CLUSTERROLEBINDING  SUBJECT_KIND  SUBJECT_NAMESPACE  SUBJECT_NAME"
        echo

        echo "=== Namespaced RoleBindings that (possibly) escalate to cluster-admin via aggregation or misconfiguration ==="
        echo "(These DO NOT necessarily grant cluster-admin, but should be reviewed if they reference a ClusterRole named cluster-admin.)"
        kubectl get rolebindings --all-namespaces -o json \
          | jq -r '
            .items[]
            | select(.roleRef.kind=="ClusterRole" and .roleRef.name=="cluster-admin")
            | .metadata.namespace as $ns
            | .metadata.name as $rb
            | .subjects[]
              | [$ns, $rb, .kind, (.namespace // "-"), .name]
              | @tsv
          ' 2>/dev/null || echo "No RoleBindings directly referencing a ClusterRole named cluster-admin found."

        echo
        echo "Columns: BINDING_NAMESPACE  ROLEBINDING  SUBJECT_KIND  SUBJECT_NAMESPACE  SUBJECT_NAME"
        echo

        echo "=== ServiceAccounts with cluster-admin via ClusterRoleBinding (quick summary) ==="
        kubectl get clusterrolebindings -o json \
          | jq -r '
            .items[]
            | select(.roleRef.kind=="ClusterRole" and .roleRef.name=="cluster-admin")
            | .metadata.name as $crb
            | .subjects[]
            | select(.kind=="ServiceAccount")
            | [$crb, .namespace, .name]
            | @tsv
          ' 2>/dev/null || echo "No ServiceAccounts bound to cluster-admin via ClusterRoleBinding."

        echo
        echo "Columns: CLUSTERROLEBINDING  SA_NAMESPACE  SA_NAME"
        echo

        cat <<'EOF'

        HOW TO INTERPRET RESULTS

        Problematic / needs review:
        - Any ClusterRoleBinding listed above, especially where:
          - SUBJECT_KIND is "User" or "Group" for broad identities (e.g., "system:authenticated", large SSO groups).
          - SUBJECT_KIND is "ServiceAccount" in default or application namespaces that do not require full cluster control.

        Lower risk (but still review):
        - A small number of tightly controlled admin identities, with clear operational justification.

        Next steps (manual review required):
        - For each subject, decide if full cluster-admin is truly required.
        - Where possible, create or reuse a less-privileged ClusterRole/Role and:
          - Bind the subject to that role instead.
          - Then delete the cluster-admin ClusterRoleBinding:
              kubectl delete clusterrolebinding <CLUSTERROLEBINDING_NAME>
        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
