Role-Based Access Control (RBAC) in Kubernetes



Imagine managing a bustling Kubernetes cluster where multiple teams deploy applications, monitor services, and troubleshoot issues. Without proper access controls, chaos can occur, leading to developers accidentally modifying critical resources, or unauthorized users accessing sensitive data. To prevent such scenarios, Kubernetes offers Role-Based Access Control (RBAC), a mechanism that regulates access based on user roles.

In this chapter, we'll explore RBAC in Kubernetes, understand its components, and learn how to implement it using YAML configurations. By the end, we'll be equipped to define roles, assign permissions, and maintain a secure cluster environment.

What is RBAC?

RBAC is a security mechanism that helps us manage user permissions based on their roles. It ensures that only authorized users can access or modify resources in Kubernetes. It operates on four key components:

  • Role − Defines what actions can be performed on which resources.
  • RoleBinding − Assigns a Role to a user or group.
  • ClusterRole − A Role that applies cluster-wide.
  • ClusterRoleBinding − Grants ClusterRoles to users or groups.

Why Do We Need RBAC?

Without RBAC, any user with access to the cluster can delete pods, modify configurations, or even shut down services. Thats a security nightmare!

With RBAC, we can:

  • Restrict access to sensitive data.
  • Prevent accidental or malicious actions.
  • Organize permissions based on team responsibilities.

Step 1: Enabling RBAC

RBAC is enabled by default in most modern Kubernetes distributions. To verify its status, run:

kubectl api-versions | grep rbac.authorization.k8s.io

If RBAC is enabled, well see the following output:

rbac.authorization.k8s.io/v1

If not, you can simply enable it in your Kubernetes API server using the --authorization-mode=RBAC flag.

Step 2: Creating a Role

A Role in Kubernetes defines permissions within a specific namespace. Suppose we want to grant our developer team permission to list and get pods in the development namespace.

Create the Namespace

Before defining the Role, well first ensure that the development namespace exists:

$ kubectl create namespace development

Output

namespace/development created

Create the Role Definition

Using an editor, create a file named role.yaml and add the following content:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: development
  name: developer-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

Apply the Role:

$ kubectl apply -f role.yaml

Output

role.rbac.authorization.k8s.io/developer-role created

This ensures the Role is successfully created in the development namespace.

Step 3: Binding a Role to a User

A RoleBinding links a Role to a user or group. Let's assign our developer-role to a user named alice.

Using an editor, create the following file named rolebinding.yaml and add the following content:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-rolebinding
  namespace: development
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: developer-role
  apiGroup: rbac.authorization.k8s.io

Apply the RoleBinding:

$ kubectl apply -f rolebinding.yaml

Output

role.rbac.authorization.k8s.io/developer-role created

Now, Alice can list and get pods in the development namespace but cannot make changes.

Step 4: Creating a ClusterRole

If we need a role to apply across all namespaces, we can simply create a ClusterRole instead. For instance, let's allow Alice to view all pods in the cluster.

Using an editor, create the following file named clusterrole.yaml and add the following content:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-viewer
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

Apply the ClusterRole:

$ kubectl apply -f clusterrole.yaml

Output

clusterrole.rbac.authorization.k8s.io/cluster-viewer created

Step 5: Binding a ClusterRole

Since this role applies cluster-wide, we can use a ClusterRoleBinding to grant Alice these permissions.

Using an editor, create the following file named clusterrolebinding.yaml and add the following content:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-viewer-binding
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-viewer
  apiGroup: rbac.authorization.k8s.io

Apply the ClusterRoleBinding:

kubectl apply -f clusterrolebinding.yaml

Output

clusterrolebinding.rbac.authorization.k8s.io/cluster-viewer-binding created

Now, Alice can list pods in any namespace.

Step 6: Verifying RBAC Permissions

To confirm Alice's permissions, use kubectl auth can-i:

kubectl auth can-i list pods --namespace=development --as=alice

If permissions are set correctly, well see the following output:

yes

If Alice tries an unauthorized action, like deleting a pod:

kubectl auth can-i delete pods --namespace=development --as=alice

The output will be:

no

Step 7: Managing and Auditing RBAC

Listing Existing Roles

To see all roles in a namespace:

$ kubectl get roles -n development

Output

NAME             CREATED AT
developer-role   2025-03-06T17:13:24Z

For ClusterRoles:

$ kubectl get clusterroles

Output

NAME                                                                   CREATED AT
admin                                                                  2025-02-25T10:07:12Z
argocd-application-controller                                          2025-02-27T11:38:34Z
argocd-applicationset-controller                                       2025-02-27T11:38:34Z
argocd-server                                                          2025-02-27T11:38:34Z
calico-cni-plugin                                                      2025-02-26T13:55:30Z
calico-kube-controllers                                                2025-02-26T13:55:30Z
calico-node                                                            2025-02-26T13:55:30Z
cluster-admin                                                          2025-02-25T10:07:11Z
cluster-viewer                                                         2025-03-06T17:25:05Z
edit                                                                   2025-02-25T10:07:12Z
kubeadm:get-nodes                                                      2025-02-25T10:07:18Z
system:aggregate-to-admin                                              2025-02-25T10:07:12Z
system:aggregate-to-edit                                               2025-02-25T10:07:12Z
system:aggregate-to-view                                               2025-02-25T10:07:12Z
system:auth-delegator                                                  2025-02-25T10:07:13Z
system:basic-user                                                      2025-02-25T10:07:12Z
system:certificates.k8s.io:certificatesigningrequests:nodeclient       2025-02-25T10:07:13Z
system:certificates.k8s.io:certificatesigningrequests:selfnodeclient   2025-02-25T10:07:13Z
system:certificates.k8s.io:kube-apiserver-client-approver              2025-02-25T10:07:13Z
system:certificates.k8s.io:kube-apiserver-client-kubelet-approver      2025-02-25T10:07:14Z
system:certificates.k8s.io:kubelet-serving-approver                    2025-02-25T10:07:13Z
system:certificates.k8s.io:legacy-unknown-approver                     2025-02-25T10:07:13Z
system:controller:attachdetach-controller                              2025-02-25T10:07:14Z
system:controller:certificate-controller                               2025-02-25T10:07:15Z
system:controller:clusterrole-aggregation-controller                   2025-02-25T10:07:14Z
system:controller:cronjob-controller                                   2025-02-25T10:07:14Z
system:controller:daemon-set-controller                                2025-02-25T10:07:14Z

Checking RoleBindings

To view RoleBindings in a namespace:

$ kubectl get rolebindings -n development

Output

NAME                    ROLE                  AGE
developer-rolebinding   Role/developer-role   13m

For ClusterRoleBindings:

$ kubectl get clusterrolebindings

Output

NAME                                                            ROLE                                                                               AGE
argocd-application-controller                                   ClusterRole/argocd-application-controller                                          7d5h
argocd-applicationset-controller                                ClusterRole/argocd-applicationset-controller                                       7d5h
argocd-server                                                   ClusterRole/argocd-server                                                          7d5h
calico-cni-plugin                                               ClusterRole/calico-cni-plugin                                                      8d
calico-kube-controllers                                         ClusterRole/calico-kube-controllers                                                8d
calico-node                                                     ClusterRole/calico-node                                                            8d
cluster-admin                                                   ClusterRole/cluster-admin                                                          9d
cluster-viewer-binding                                          ClusterRole/cluster-viewer                                                         9m52s
kubeadm:cluster-admins                                          ClusterRole/cluster-admin                                                          9d
kubeadm:get-nodes                                               ClusterRole/kubeadm:get-nodes                                                      9d
kubeadm:kubelet-bootstrap                                       ClusterRole/system:node-bootstrapper                                               9d

Deleting a Role or RoleBinding

To delete a Role:

$ kubectl delete role developer-role -n development

Output

role.rbac.authorization.k8s.io "developer-role" deleted

To remove a RoleBinding:

$ kubectl delete rolebinding developer-rolebinding -n development

Output

rolebinding.rbac.authorization.k8s.io "developer-rolebinding" deleted

Conclusion

Implementing Role-Based Access Control (RBAC) in Kubernetes is fundamental to securing your cluster and ensuring that you have appropriate access to resources.

Regularly auditing and managing RBAC configurations ensures that your access controls adapt to evolving team structures and project needs. As your Kubernetes environment grows, a well-implemented RBAC strategy becomes indispensable for maintaining a secure and efficient infrastructure.

By following the steps outlined in this chapter, you can confidently set up and manage RBAC in your Kubernetes clusters.

Advertisements