Kubernetes RBAC Explained
Kubernetes RBAC controls who can do what in a cluster using Roles, ClusterRoles, and bindings. How the pieces fit together, with a worked example.
RBAC (Role-Based Access Control) is the standard authorization system in Kubernetes, controlling which users, groups, and service accounts can perform which actions on which resources. It works through four API objects — Role, ClusterRole, RoleBinding, and ClusterRoleBinding — that together define permissions and grant them to identities. Nearly every managed Kubernetes cluster has RBAC enabled by default, which means understanding these four objects is a prerequisite for running anything beyond a toy cluster safely.
Roles: defining permissions
A Role defines a set of permissions scoped to a single namespace. It doesn’t grant access to anyone by itself — it just describes what actions are possible, expressed as rules combining API groups, resources, and verbs:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: staging
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
This rule says: within the staging namespace, whoever holds this role can read pods — but not create, edit, or delete them, and not touch anything outside that namespace.
ClusterRoles: cluster-wide or reusable permissions
A ClusterRole is the same idea but not tied to a namespace. It’s used two ways: to grant permissions across the entire cluster (like managing nodes or non-namespaced resources), or to define a reusable permission set that gets applied to specific namespaces via a RoleBinding — letting you define “viewer” or “editor” once and bind it wherever needed instead of duplicating the same Role in every namespace.
Bindings: granting the permissions
Roles and ClusterRoles are inert until bound to an identity — a user, a group, or a service account. That’s what RoleBinding and ClusterRoleBinding do.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-staging
namespace: staging
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
The four objects at a glance
| Object | Scope | Purpose |
|---|---|---|
Role | Single namespace | Defines permissions within that namespace |
ClusterRole | Cluster-wide | Defines permissions across the cluster, or a reusable set |
RoleBinding | Single namespace | Grants a Role or ClusterRole to subjects, scoped to that namespace |
ClusterRoleBinding | Cluster-wide | Grants a ClusterRole to subjects across the entire cluster |
The key subtlety: a ClusterRole bound via a RoleBinding grants those permissions only within that binding’s namespace — the permission set is cluster-scoped in definition, but the grant is namespace-scoped. Only a ClusterRoleBinding extends a ClusterRole’s permissions cluster-wide.
A worked example
Say you want a CI pipeline to be able to deploy to the staging namespace but read-only everywhere else. You’d define a Role in staging with create, update, and delete verbs on deployments and services, bind it to the CI system’s service account with a RoleBinding scoped to staging, and separately bind a built-in, more limited view ClusterRole to that same service account via a RoleBinding in any other namespace it needs read access to. Nothing in this setup gives the CI identity permissions outside the namespaces it’s explicitly bound in.
Service accounts and RBAC
Most RBAC subjects in a running cluster aren’t human users at all — they’re service accounts, the identity a Pod uses to talk to the Kubernetes API. Every namespace has a default service account, and any Pod that doesn’t specify one uses it automatically. That default account typically has no permissions bound to it out of the box, which is the safe default — permissions should be granted explicitly to a dedicated service account per workload, not inherited implicitly.
Common mistakes
- Overly broad
ClusterRoleBindings. Bindingcluster-adminto a service account “to make something work” is the single most common RBAC misconfiguration, and it hands that workload unrestricted control over the entire cluster, including Secrets in every namespace. - Wildcard verbs and resources.
verbs: ["*"]orresources: ["*"]are tempting shortcuts during development that often survive into production, silently granting far more than intended. - Forgetting namespace scope. A
RoleBindingreferencing aClusterRoleonly grants access in its own namespace — a common source of confusion when someone expects a binding instagingto also apply inproduction. - Not auditing bindings regularly. RBAC permissions accumulate over time as teams add exceptions; periodically listing all
ClusterRoleBindings (kubectl get clusterrolebindings) surfaces grants nobody remembers making.
Checking what a subject can actually do
Because permissions in RBAC are assembled from potentially many RoleBindings and ClusterRoleBindings scattered across a cluster, it’s rarely obvious just from reading YAML what a given user or service account can actually do. kubectl has a built-in check for exactly this: kubectl auth can-i create pods --namespace staging --as system:serviceaccount:staging:ci-deployer answers the question directly, evaluating every binding that applies to that identity rather than requiring you to trace the bindings by hand. Running this check as part of onboarding a new service account, or during a periodic access review, is a much faster way to catch an over-broad grant than reading raw manifests.
RBAC vs other access-control models
Kubernetes RBAC is a pure role-based model: permissions attach to roles, roles attach to subjects. It doesn’t natively support conditions based on request attributes — like time of day or resource labels — the way ABAC does, though newer admission-control mechanisms in Kubernetes can layer attribute-based logic on top of RBAC’s coarser role grants for teams that need finer-grained policy.
The takeaway
Kubernetes RBAC grants permissions through two layers: Role/ClusterRole define what’s possible, and RoleBinding/ClusterRoleBinding grant that to a subject, scoped to a namespace or the whole cluster respectively. The practical discipline is the same as any access-control system — grant the narrowest role that does the job, prefer per-workload service accounts over the default one, avoid wildcard verbs, and audit ClusterRoleBindings periodically, since a single over-broad one can undo every other restriction in the cluster.
Tagged
Keep reading
Chisato · · 4 min read Kubernetes Network Policies Explained
Kubernetes NetworkPolicies control which pods can talk to which, at the network layer. Here's how they work and why pods are open by default.
Chisato · · 5 min read Kubernetes Admission Controllers, Explained
Admission controllers intercept requests to the Kubernetes API server after authentication, validating or mutating objects before they're persisted.
Chisato · · 5 min read What Are Reproducible Builds? Verifiable Software, Explained
Reproducible builds produce bit-for-bit identical output from the same source, so anyone can verify a binary. Why they matter and how to achieve them.