RBAC stands for Role-Based Access Control. In Kubernetes, you use RBAC to define which actions each user or ServiceAccount may perform on which resources.
RBAC is particularly important when multiple applications, pipelines, or administrators use the same cluster. Without RBAC, you can easily grant too many permissions, for example to a CI pipeline or an application that only needs to read pods but would also be able to retrieve Secrets.
- Use a Role for permissions within a single namespace.
- Use a ClusterRole only for cluster-wide permissions or resources that are not namespaced.
- Always assign permissions through a separate ServiceAccount or user, not to `default`.
- Start with the smallest possible set of permissions and expand it only when necessary.
When do you use RBAC or a ClusterRole?
Use RBAC when multiple identities in your cluster have different tasks. Keeping Roles, bindings, and ServiceAccounts small and explicit prevents applications or automation from receiving more permissions than necessary.
Use a ClusterRole only if you need permissions for non-namespaced resources or multiple namespaces at the same time. Examples include:
- Reading nodes: a cluster observer or auditor may need to read all nodes.
- Ingress or gateway controllers: controllers that process resources in multiple namespaces often need broader permissions.
- Platform management: administrators or operators who manage cluster-wide components.
Use ClusterRoleBindings sparingly. A mistake in a ClusterRoleBinding immediately affects the entire cluster.
First determine what you need
- Role + RoleBinding: use this if an application only needs to operate in one namespace.
- ClusterRole + RoleBinding: use this to reuse an existing ClusterRole while restricting its permissions to a single namespace.
- ClusterRole + ClusterRoleBinding: use this only if the permissions are genuinely required across the cluster.
A regular Role is sufficient for many workloads. This is usually the safest choice.
A simple RBAC example
Step 1
Create a manifest file on your server or computer, for example:
nano rbac-demo.yamlAdd the following content to the file:
apiVersion: v1
kind: Namespace
metadata:
name: kb-rbac-test
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader
namespace: kb-rbac-test
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: kb-rbac-test
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader
namespace: kb-rbac-test
subjects:
- kind: ServiceAccount
name: pod-reader
namespace: kb-rbac-test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-readerSave the changes and close the file (ctrl + x > y > enter).
Step 2
Create the namespace, ServiceAccount, and RBAC resources:
kubectl apply -f rbac-demo.yamlThis ServiceAccount now has read-only permissions for pods within the namespace `kb-rbac-test`.
Explicitly check the permissions of a ServiceAccount
Step 1
Check whether the ServiceAccount is allowed to read pods in its own namespace:
kubectl auth can-i list pods \
--as=system:serviceaccount:kb-rbac-test:pod-reader \
-n kb-rbac-testThe expected result is `yes`.
Step 2
Then check that the same ServiceAccount is not allowed to read Secrets:
kubectl auth can-i list secrets \
--as=system:serviceaccount:kb-rbac-test:pod-reader \
-n kb-rbac-testThe expected result is `no`.
Step 3
Also check that the same ServiceAccount cannot read pods from another namespace:
kubectl auth can-i list pods \
--as=system:serviceaccount:kb-rbac-test:pod-reader \
-n defaultThe expected result is also `no`. This shows that a namespaced Role does not automatically apply outside its own namespace.