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 — 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. For example, 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.