Back to Checks
kubernetes

Cluster role binding does not grant the cluster-admin role

rbac_cluster_admin_usage
Service: rbacSeverity: critical
OfficialBuilt-inVerified
Categories:identity-accesscluster-security
Resource Type:ClusterRoleBinding

RBAC ClusterRoleBindings that bind to the cluster-admin ClusterRole are identified, showing where subjects receive super-user permissions across all namespaces.

Risk

Excessive cluster-admin grants give full API control, risking:

  • Secret exfiltration (confidentiality)
  • RBAC tampering (integrity)
  • Destructive actions causing outages (availability)

A compromised subject can escalate, persist via new bindings, and laterally impact all namespaces.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler kubernetes --checks rbac_cluster_admin_usage

Recommendation

Apply least privilege: replace cluster-admin with narrowly scoped Roles/ClusterRoles and bind per namespace. Reserve super-user access for break-glass, time-bound with approval and audit. Enforce separation of duties, review RBAC regularly, and monitor role/binding changes for defense in depth.

Remediation

CLI

kubectl delete clusterrolebinding <example_resource_name>

Terraform

resource "kubernetes_cluster_role_binding" "<example_resource_name>" {
  metadata { name = "<example_resource_name>" }
  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "ClusterRole"
    name      = "view" # Critical: replace any "cluster-admin" binding with a limited role
  }
  subject {
    kind = "User"
    name = "<example_resource_id>"
  }
}

Other

1List ClusterRoleBindings that use cluster-admin:
2```
3kubectl get clusterrolebindings -o json | jq -r '.items[] | select(.roleRef.name=="cluster-admin") | .metadata.name'
4```
5For each name returned, delete the binding:
6```
7kubectl delete clusterrolebinding <example_resource_name>
8```
9If access is still required, recreate with least privilege (example uses view):
10```
11kubectl create clusterrolebinding <example_resource_name> --clusterrole=view --user=<example_resource_id>
12```

Check Code

from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.rbac.rbac_client import rbac_client


class rbac_cluster_admin_usage(Check):
    def execute(self) -> Check_Report_Kubernetes:
        findings = []
        # Iterate through the bindings
        for binding in rbac_client.cluster_role_bindings.values():
            # Check if the binding refers to the cluster-admin role
            if binding.roleRef.name == "cluster-admin":
                report = Check_Report_Kubernetes(
                    metadata=self.metadata(), resource=binding.metadata
                )
                report.namespace = (
                    "cluster-wide"
                    if not binding.metadata.namespace
                    else binding.metadata.namespace
                )
                report.status = "MANUAL"
                report.status_extended = f"Cluster Role Binding {binding.metadata.name} uses cluster-admin role."
                findings.append(report)
        return findings