What is Kubernetes RBAC and how do Roles and bindings work?
Kubernetes RBAC (role-based access control) is the authorization system that decides which API requests a user, group or service account may make. A Role or ClusterRole lists allowed verbs on resources, and a RoleBinding or ClusterRoleBinding grants that role to subjects, either in one namespace or across the cluster. Permissions are purely additive: RBAC has no deny rules, so anything not granted is refused.
The four objects
| Object | Scope | What it does |
|---|---|---|
| Role | One namespace | Lists permissions on resources in that namespace |
| ClusterRole | Cluster | Lists permissions on cluster-scoped resources (such as nodes), non-resource URLs (such as /healthz) or namespaced resources in any namespace |
| RoleBinding | One namespace | Grants a Role or a ClusterRole to subjects, within the binding’s namespace |
| ClusterRoleBinding | Cluster | Grants a ClusterRole to subjects in every namespace and for cluster-scoped resources |
The combination that confuses people is a RoleBinding that references a ClusterRole. The RBAC reference is clear that the permissions then apply only inside the RoleBinding’s namespace. This is the normal way to reuse one role definition across namespaces: define app-deployer once as a ClusterRole, then bind it per namespace.
A binding’s roleRef cannot change after creation. To point a binding at a different role, delete it and create a new one.
Rules: API groups, resources and verbs
A rule names API groups, resources and verbs:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: shop
name: deployer
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]The core API group is the empty string "". Subresources are written as resource/subresource, and they are granted separately from the parent: pods/log reads logs, pods/exec opens a shell, pods/portforward tunnels traffic. A role that allows get on pods does not allow exec.
resourceNames narrows a rule to named objects, such as one ConfigMap. It cannot restrict create or deletecollection, because those requests do not name an existing object.
Subjects: users, groups and service accounts
Kubernetes has no user objects. A user or group is whatever name the authenticator reports: the common name and organization of a client certificate, or the username and groups claims of an OIDC token from your identity provider. Bind roles to groups, such as platform-admins from your identity provider, rather than to individual users, so that joining or leaving a team is an identity provider change rather than a cluster change. Service accounts are the in-cluster identity for workloads, written as system:serviceaccount:<namespace>:<name>.
The built-in ClusterRoles are a sensible starting point:
cluster-admin: every action on every resource.admin: full access within a namespace, including Roles and RoleBindings, when bound with a RoleBinding.edit: read and write most namespaced objects, without access to Roles and RoleBindings.view: read most namespaced objects. It excludes Secrets on purpose, because reading Secrets would expose service account credentials.
The group system:masters is bound to cluster-admin and bypasses RBAC authorization entirely, so nobody’s everyday credential should carry it.
Privilege escalation paths
Many permissions look narrow and are not. The RBAC good-practices guide lists these:
| Permission | Why it is dangerous |
|---|---|
list or watch on secrets | Returns the contents of every Secret, not only their names |
create on Pods or workload resources | The Pod can mount any Secret and run as any service account in the namespace; without Pod Security it can be privileged and reach the node |
create on PersistentVolumes | A hostPath volume gives access to the node’s filesystem |
get on nodes/proxy | Grants the kubelet API, which allows running commands in every Pod on the node |
escalate on roles | Lets a user write roles with permissions they do not hold |
bind on roles | Lets a user bind roles with permissions they do not hold |
impersonate | Lets a user act as another user, group or service account |
create on serviceaccounts/token | Lets a user request tokens for existing service accounts |
CSR create plus approval | Lets a user issue client certificates that authenticate to the cluster |
Without escalate or bind, RBAC stops a user from creating a role or binding that grants more than they already hold. Treat those two verbs, impersonate and wildcard rules ("*") as admin-only.
How to audit RBAC
kubectl auth can-i answers “can this subject do this?”:
kubectl auth can-i list secrets -n shop --as=[email protected]
kubectl auth can-i create pods/exec -n shop --as=system:serviceaccount:shop:ci
kubectl auth can-i --list -n shop --as-group=developers --as=test-userThe --list form prints everything a subject may do in a namespace. Run it for each tenant group and each workload service account, and look for the entries in the table above. Pair this with API audit logs, which record who actually used a permission.
Good defaults
- Give workloads their own service account instead of
default, and setautomountServiceAccountToken: falsewhere the workload never calls the API. - Grant humans
vieworeditper namespace through group bindings. Keepcluster-adminfor a small number of break-glass identities. - Prefer namespaced RoleBindings to ClusterRoleBindings.
- Review RBAC whenever you install a Helm chart or operator, because many ship broad ClusterRoles.
RBAC decides what an authenticated caller may do. Who can authenticate, and from where, is covered in how to secure the Kubernetes API. RBAC is also the first layer of Kubernetes multi-tenancy, and the main control over who can read Kubernetes Secrets.
RBAC on Cloudfleet
Cloudfleet Kubernetes Engine (CFKE) uses standard Kubernetes RBAC, and with single sign-on you can bind roles to the groups from your identity provider. User management explains how Cloudfleet roles map to Kubernetes roles.