What is RBAC in Kubernetes, and what are Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings?

7 minintermediaterbacrolesrolebindingssecurity

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 definedGrant scoped to
Role + RoleBindingOne namespaceThat same namespace
ClusterRole + RoleBindingCluster-wide definition, reusedThat RoleBinding's namespace only
ClusterRole + ClusterRoleBindingCluster-wide definitionThe 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.