Role-based access control (RBAC) involves authorizing end-user access to systems, applications, networks, or resources based on their predefined role within an organization. Instead of assigning permissions to each user individually, RBAC provides a simpler, manageable approach by allowing administrators to assign users a preconfigured set of permissions based on their job function or qualifications.
RBAC is essential in Kubernetes because even a small misconfigured permission can expose your cluster. It enforces the principle of least privilege by making sure that users, service accounts, and workloads only have access to the specific resources and operations they need. With RBAC, administrators can define fine-grained permissions through roles and then assign those roles to users, groups, or service accounts.
By the end of this article, you'll understand how Kubernetes's RBAC works and how it protects your cluster. You'll learn to write and bind RBAC policies using YAML, avoid common configuration mistakes, and debug permission issues using Kubernetes tools. You will also see how tools like mogenius help you manage RBAC visually and conveniently, making access control more intuitive and reducing reliance on complex YAML files.
In Kubernetes, as clusters grow in complexity with more users, teams, and services interacting with the system, managing access manually becomes risky and inefficient. RBAC gives you a consistent, scalable way to control access to Kubernetes resources based on clearly defined roles.
RBAC addresses three key challenges in Kubernetes environments:
The RBAC API defines four types of Kubernetes objects: Role, ClusterRole, RoleBinding, and ClusterRoleBinding. You can create, view, and update these using tools like kubectl. They're managed by the rbac.authorization.k8s.io
API group, which lets you configure access permissions directly through the Kubernetes API.
A Role grants access to resources within a specific namespace. You must specify the namespace when creating one.
Here's an example Role in the "staging" namespace that can be used to grant read access to pods:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: staging
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
A ClusterRole is not tied to any namespace. It can be used to:
This ClusterRole grants read-only access to all nodes at the cluster level:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-inspector
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
To summarize, use a Role when you want to limit access within a namespace; use a ClusterRole in two cases:
Before you dive into bindings, it is important to understand the concept of a subject. A subject is the identity that receives the permissions granted by a Role or ClusterRole. There are three kinds of subjects in Kubernetes:
A RoleBinding grants the permissions defined in a role to one or more subjects. A ClusterRoleBinding applies the binding across all namespaces, granting cluster-wide access to the referenced subjects.
While a RoleBinding typically references a Role defined in the same namespace, it can also reference a ClusterRole. This allows you to create reusable permission sets (as ClusterRoles) and apply them selectively to namespaces via RoleBindings. Note that when a ClusterRole is referenced in a RoleBinding, the permissions granted are limited to the RoleBinding's namespace. If you want a ClusterRole to apply across the entire cluster, use a ClusterRoleBinding.
The name of a Role, ClusterRole, RoleBinding, and ClusterRoleBinding object must be a valid path segment name.
This RoleBinding gives user john
permission to read Pods in the default namespace, assuming a Role named pod-reader
already exists in that namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: john # case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
You can also bind a ClusterRole inside a namespace using a RoleBinding. In the following example, the ClusterRole config-reader
is reused to give a service account the permission to view ConfigMaps in just the dev
namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-configmaps
namespace: dev
subjects:
- kind: ServiceAccount
name: dashboard-viewer
namespace: dev
roleRef:
kind: ClusterRole
name: config-reader
apiGroup: rbac.authorization.k8s.io
The following example binds the secret-reader ClusterRole to every user in the group ops-team
, giving them permission to read Secrets in all namespaces:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ops-read-secrets
subjects:
- kind: Group
name: ops-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io