Skip to main content

Ensure Cluster Admin Role Is Only Used Where Required

More Info:​

The RBAC role cluster-admin provides wide-ranging powers over the environment and should be used only where and when needed.

Risk Level​

High

Address​

Security

Compliance Standards​

  • APRA CPS 234 (Australia)
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS Critical Security Controls v8
  • CIS OKE
  • 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)
  • NIS2 Directive
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • SWIFT Customer Security Controls Framework
  • Sarbanes-Oxley IT General Controls
  • Securities and Exchange Board of India (SEBI) - Cloud Security Adoption Framework
  • UK NCSC Cyber Assessment Framework

Triage and Remediation​

Remediation​

Manual Steps
  1. List all cluster-admin bindings and their subjects

    • Run on: any machine with kubectl access
    kubectl get clusterrolebindings -o jsonpath='{range .items[?(@.roleRef.name=="cluster-admin")]}{.metadata.name}{"\n"}{range .subjects[*]} {"kind:"}{.kind}{" name:"}{.name}{" namespace:"}{.namespace}{"\n"}{end}{"---\n"}{end}'

    Save the output; it shows exactly who/what is bound to cluster-admin.

  2. Assess necessity of cluster-admin for each subject
    For each subject (User/Group/ServiceAccount) in the output:

    • Determine what application, team, or automation owns it.
    • Ask/decide what operations it actually needs (e.g., namespace-scoped, specific CRDs, read-only vs write).
      Document whether full cluster-wide admin is justified or whether a reduced-scope role would be sufficient.
  3. Inspect current permissions and usage context

    • Show the binding definition for detailed review:
      # Replace BINDING_NAME with an actual name from step 1
      kubectl get clusterrolebinding BINDING_NAME -o yaml
    • Optionally, check what clusterroles are already available that might fit better:
      kubectl get clusterroles

    Use this to determine if you can map the subject to an existing lower-privilege ClusterRole/Role or if you must create a custom one.

  4. Design and apply least-privilege replacements (if needed)
    For each subject that does not truly require cluster-admin:

    • Create or choose an appropriate Role or ClusterRole that grants only the required permissions.
    • Bind the subject to it with a RoleBinding (namespace-scoped need) or ClusterRoleBinding (cluster-wide but limited actions). For example:
      # Example: bind a user to a more restricted clusterrole
      kubectl create clusterrolebinding limited-admin-binding \
      --clusterrole=<lower-privilege-clusterrole-name> \
      --user=<user-identifier>

    Confirm the new binding reflects the intended scope and verbs before proceeding.

  5. Remove unneeded cluster-admin bindings
    Once a subject has appropriate replacement bindings and you are confident operations continue to work:

    • Delete the unnecessary cluster-admin binding(s).
    • Run on: any machine with kubectl access
      # Replace BINDING_NAME with the specific clusterrolebinding to remove
      kubectl delete clusterrolebinding BINDING_NAME

    Do this incrementally, prioritizing clearly non-admin use cases; leave truly administrative identities bound to cluster-admin if justified.

  6. Re-verify cluster-admin usage and document exceptions

    • Re-run the evidence command:
      kubectl get clusterrolebindings -o jsonpath='{range .items[?(@.roleRef.name=="cluster-admin")]}{.metadata.name}{"\n"}{range .subjects[*]} {"kind:"}{.kind}{" name:"}{.name}{" namespace:"}{.namespace}{"\n"}{end}{"---\n"}{end}'
    • Confirm that only identities with a clear, documented operational need remain bound to cluster-admin, and record these exceptions (who, why, and approval) for future audits.
Using kubectl

Using kubectl​

Run these commands from any machine with kubectl access.

  1. List all ClusterRoleBindings that grant cluster-admin
kubectl get clusterrolebindings -o jsonpath='{range .items[?(@.roleRef.kind=="ClusterRole" && @.roleRef.name=="cluster-admin")]}{.metadata.name}{"\n"}{end}'

If this prints one or more names, those bindings are candidates for review. Each name is a binding that grants full cluster‑admin privileges.

  1. Inspect each identified ClusterRoleBinding in detail

Replace <binding-name> with one name from the previous command.

kubectl get clusterrolebinding <binding-name> -o yaml

Review the subjects section:

  • Problem indicators:
    • kind: User or kind: Group referring to broad groups such as:
      • system:authenticated
      • system:unauthenticated
      • large IdP groups (e.g. Everyone, Developers, All-Engineers)
    • kind: ServiceAccount referring to:
      • default service accounts (e.g. default in many namespaces)
      • application service accounts that do not truly need full cluster control
    • Multiple, diverse subjects on a single cluster-admin binding, suggesting it’s used as a catch‑all.

These are strong signals that cluster-admin is over‑used and should be replaced with narrower, task‑specific roles.

  1. Summarize which subjects have cluster-admin

To quickly see just subjects and names:

kubectl get clusterrolebindings -o json \
| jq -r '.items[]
| select(.roleRef.kind=="ClusterRole" and .roleRef.name=="cluster-admin")
| "\(.metadata.name):\n" +
( .subjects[]? | " - kind: \(.kind) | name: \(.name) | namespace: \(.namespace // "-") | apiGroup: \(.apiGroup // "-")" )'

Review for:

  • Bindings used as “global admin for everyone”.
  • Service accounts used by workloads rather than by cluster operators.

These outputs tell you who is getting cluster-admin; a human must decide which bindings are justified and where to replace them with less‑privileged roles.

Automation
#!/usr/bin/env bash
#
# Report all ClusterRoleBindings that grant cluster-admin
# and list their subjects for review.
#
# Run on: any machine with kubectl access and correct context
# Usage: ./report-cluster-admin-bindings.sh

set -euo pipefail

echo "=== ClusterRoleBindings granting cluster-admin ==="
echo

# 1) List all ClusterRoleBindings that reference cluster-admin
kubectl get clusterrolebindings -o json \
| jq -r '
.items[]
| select(.roleRef.kind=="ClusterRole" and .roleRef.name=="cluster-admin")
| {
name: .metadata.name,
roleKind: .roleRef.kind,
roleName: .roleRef.name,
subjects: (
.subjects // []
| map({
kind: .kind,
name: .name,
namespace: (.namespace // ""),
apiGroup: (.apiGroup // "")
})
)
}
' | jq -c '.'

echo
echo "=== Human-readable summary ==="
echo

kubectl get clusterrolebindings -o json \
| jq -r '
.items[]
| select(.roleRef.kind=="ClusterRole" and .roleRef.name=="cluster-admin")
| (
"ClusterRoleBinding: " + .metadata.name
+ "\n RoleRef: " + .roleRef.kind + "/" + .roleRef.name
+ (
if (.subjects // [] | length) == 0
then "\n Subjects: (none)"
else (
"\n Subjects:"
+ (
.subjects // []
| map(
"\n - kind: " + .kind
+ ", name: " + .name
+ (if .namespace then ", namespace: " + .namespace else "" end)
+ (if .apiGroup then ", apiGroup: " + .apiGroup else "" end)
)
| join("")
)
)
)
+ "\n"
)
'

echo "=== Notes ==="
cat <<'EOF'
Each listed ClusterRoleBinding grants full cluster-admin privileges to its subjects.

What indicates a potential problem:
- Any binding where the subject is:
- An individual User that does not require full cluster-wide admin.
- A Group that includes many or generic users (e.g., 'developers', 'default', 'system:authenticated').
- A ServiceAccount used by a specific application or namespace-scoped component.
- A broad or unclear identity from an external IdP (e.g., 'everyone', '*', or large SSO groups).

Review actions (manual, per binding/subject):
- Confirm who/what the subject is and why they need cluster-admin.
- If they only need limited permissions, design/create a narrower Role or ClusterRole.
- Rebind them to that lesser-privileged role.
- Then delete the cluster-admin ClusterRoleBinding if it is no longer needed:
kubectl delete clusterrolebinding <binding-name>

This review and adjustment step is manual; it cannot be safely fully automated.
EOF

Interpreting output

  • If the script prints no ClusterRoleBindings in the summary, the check is likely passing: no subjects are granted cluster-admin.
  • Any ClusterRoleBinding shown is a candidate for review; treat especially as problematic when:
    • The subject is a generic group (e.g., system:authenticated, large SSO groups).
    • The subject is an app/service account that only requires namespace or limited actions.
    • The purpose of the binding is unclear to the cluster owner.

Additional Reading:​