RBAC
Role-Based Access Control (RBAC) is how Kubernetes decides what an authenticated identity may do. You grant permissions through Roles (sets of allowed verbs on resources) and bindings that attach those roles to users, groups, or ServiceAccounts. It is the primary authorization mechanism, and the one you will configure most.
RBAC is additive and deny-by-default: nothing is allowed until a binding grants it. The discipline it demands — and the one most often skipped — is least privilege, because the easy path of broad grants quietly undoes the whole point.
Roles and ClusterRoles
A Role is a namespaced set of rules: these verbs (get, list, create, delete…) on these resources (pods, configmaps…), in one namespace. A ClusterRole is the same idea but cluster-wide, and is also used for cluster-scoped resources (nodes, PVs) and for permissions you want to reuse across namespaces.
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: shop name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"]
Bindings
A role grants nothing until it is bound. A RoleBinding attaches a Role (or a ClusterRole) to subjects within one namespace; a ClusterRoleBinding attaches a ClusterRole cluster-wide. Subjects are users, groups, or ServiceAccounts. A common and useful pattern is binding a ClusterRole into a single namespace with a RoleBinding, reusing the permission definition while scoping where it applies.
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: namespace: shop name: read-pods subjects: - kind: ServiceAccount name: viewer namespace: shop roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io
Least Privilege in Practice
RBAC's value is entirely in the discipline of granting only what is needed. The anti-patterns are well worn: binding cluster-admin because it is easy, using verbs: ["*"] or resources: ["*"], and binding to the system:authenticated group (which is everyone). Particularly dangerous are the escalate, bind, and impersonate verbs and write access to RBAC objects themselves — they let a subject grant itself more. Audit these specifically.
Auditing and Aggregation
Over time RBAC sprawls. kubectl auth can-i checks whether a subject can perform an action, which is invaluable for verifying intent. Aggregated ClusterRoles let you compose roles from labeled rule sets, useful for extending the built-in roles cleanly. The built-in view, edit, and admin ClusterRoles are good starting points — prefer binding and composing them over hand-writing broad rules.
Role — permissions within one namespace, on namespaced resources. Bound with a RoleBinding.
ClusterRole — cluster-wide permissions, cluster-scoped resources, or reusable rule sets. Bound cluster-wide or into a namespace.
- Binding
cluster-adminfor convenience, handing out full control of the cluster. - Using wildcard verbs or resources (
"*") instead of enumerating exactly what is needed. - Binding permissions to
system:authenticated, which is every authenticated identity. - Ignoring the
escalate,bind, andimpersonateverbs that let a subject grant itself more. - Confusing namespaced and cluster scope — using a ClusterRoleBinding where a namespaced RoleBinding was intended.
- Grant least privilege — enumerate verbs and resources; never reach for
cluster-adminas a default. - Start from the built-in
view/edit/adminClusterRoles and compose with aggregation. - Bind a ClusterRole into a single namespace with a RoleBinding to reuse definitions while scoping access.
- Verify grants with
kubectl auth can-iand audit who holds escalate/bind/impersonate. - Give each workload its own ServiceAccount with a minimal role rather than sharing broad ones.
Knowledge Check
What is the difference between a Role and a ClusterRole?
- A Role is namespaced; a ClusterRole is cluster-wide and covers cluster-scoped resources or reusable rule sets
- A Role may only be bound to human users, while a ClusterRole may only be bound to ServiceAccounts and system groups
- A ClusterRole grants nothing until you first convert it into a namespaced Role object
- They are functionally identical, differing only in the kind name you write in YAML
Why is binding to the system:authenticated group dangerous?
- It grants the permission to every authenticated user and ServiceAccount in the cluster
- It disables authentication for every request that matches the bound group
- It only takes effect inside the kube-system namespace and nowhere else
- It prevents ServiceAccounts in the cluster from being used at all
A Role grants permissions but a subject still can't act. What is most likely missing?
- A binding, whether a RoleBinding or ClusterRoleBinding, since a Role grants nothing at all until it is bound
- A ServiceAccount token freshly mounted into the calling Pod's filesystem at the projected path
- A NetworkPolicy rule explicitly allowing the outbound call to the API server
- A higher QoS class on the calling Pod, so the API server stops throttling the Pod's API requests
You got correct