What is RBAC in Kubernetes, and what are Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings?
Quick Answer
RBAC (Role-Based Access Control) governs what actions a given identity can perform against the Kubernetes API. A **Role** defines a set of permissions (verbs on resources) scoped to one namespace; a **ClusterRole** defines the same kind of permissions but cluster-wide (or for cluster-scoped resources). A **RoleBinding** grants a Role's (or a ClusterRole's) permissions to specific users/groups/ServiceAccounts, scoped to one namespace; a **ClusterRoleBinding** grants a ClusterRole's permissions cluster-wide. The permissions and the grant are deliberately separate objects, so the same Role can be reused across many bindings.
Detailed Answer
Role — namespace-scoped permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
Defines a set of permitted actions (verbs) on specific resource types, scoped to exist only within the production namespace — this Role has no effect on Pods in any other namespace.
RoleBinding — granting a Role to an identity, within a namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-binding
namespace: production
subjects:
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Grants the pod-reader Role's permissions specifically to the user alice, and specifically within the production namespace. A RoleBinding can also reference a ClusterRole (not just a namespace-scoped Role) — in that case, it grants that ClusterRole's permissions, but still only within the binding's own namespace, which is a useful pattern for reusing one common set of permissions (defined once as a ClusterRole) across many different namespace-scoped bindings.
ClusterRole — cluster-wide (or cluster-scoped-resource) permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-reader
rules:
- apiGroups: [""]
resources: ["nodes"] # Nodes are a cluster-scoped resource -- no namespace applies
verbs: ["get", "list", "watch"]
Needed for any permission concerning cluster-scoped resources (Nodes, PersistentVolumes, ClusterRoles/ClusterRoleBindings themselves) since these don't belong to any namespace at all — a namespaced Role simply has no way to grant access to them.
ClusterRoleBinding — granting a ClusterRole cluster-wide
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-nodes-global
subjects:
- kind: Group
name: platform-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: node-reader
apiGroup: rbac.authorization.k8s.io
Grants the node-reader ClusterRole's permissions across the entire cluster, to everyone in the platform-team group — the broadest possible scope of grant.
The four-way combination, summarized
| Permissions defined | Grant scoped to | |
|---|---|---|
| Role + RoleBinding | One namespace | That same namespace |
| ClusterRole + RoleBinding | Cluster-wide definition, reused | That RoleBinding's namespace only |
| ClusterRole + ClusterRoleBinding | Cluster-wide definition | The whole cluster |
Why the separation between "permission definition" and "grant" exists
Defining permissions (Role/ClusterRole) separately from granting them (RoleBinding/ClusterRoleBinding) to a specific subject lets one reusable permission set be bound to many different users/teams/namespaces without redefining the underlying rules each time — e.g., a single pod-reader ClusterRole can be bound via separate RoleBindings in team-a's namespace and team-b's namespace, each granting the same read-only pod access, scoped independently to each team's own namespace.
Default to the most narrowly-scoped combination that satisfies the real need — a namespaced Role + RoleBinding for anything that can be namespace-scoped, reserving ClusterRole + ClusterRoleBinding for genuinely cluster-wide needs (platform/infrastructure teams, cluster-scoped resources) — this is a direct application of the least-privilege principle to Kubernetes's own access model.