Kubernetes Role-Based Access Control (RBAC) is a critical security mechanism for controlling access to cluster resources. This guide walks you through creating Roles and ClusterRoles, binding them to users or service accounts using RoleBindings and ClusterRoleBindings, and verifying permissions with kubectl auth can-i. You'll learn the difference between namespaced and cluster-scoped resources, how to write precise RBAC rules, and how to test your configuration. Real-world examples include granting read-only access to pods, allowing deployments in a namespace, and giving full cluster admin to a service account. These skills are essential for the CNCF CKA and CKAD exams.
Create a Namespace for Testing
Start by creating a dedicated namespace to isolate your RBAC testing. This prevents accidental interference with production resources. Use kubectl create namespace to set up a namespace called 'rbac-demo'. Verify it exists with kubectl get namespaces.
kubectl create namespace rbac-demo
kubectl get namespaces | grep rbac-demoAlways test RBAC in a separate namespace before applying to production.
Do not use the default namespace for RBAC testing as it may conflict with existing resources.
Create a Service Account
Service accounts are used by pods or external tools to authenticate to the Kubernetes API. Create a service account named 'dev-sa' in the rbac-demo namespace. Then retrieve the token secret name and decode the token for later use in authentication tests.
kubectl create serviceaccount dev-sa -n rbac-demo
kubectl get serviceaccount dev-sa -n rbac-demo -o yaml
# Get the secret name
SECRET=$(kubectl get serviceaccount dev-sa -n rbac-demo -o jsonpath='{.secrets[0].name}')
kubectl get secret $SECRET -n rbac-demo -o jsonpath='{.data.token}' | base64 --decodeIn Kubernetes 1.24+, service account tokens are not automatically created. Use kubectl create token dev-sa -n rbac-demo to generate a time-bound token.
Never share service account tokens in logs or version control.
Define a Role with Namespaced Permissions
A Role grants permissions within a specific namespace. Create a Role named 'pod-reader' that allows get, list, and watch on pods in the rbac-demo namespace. Use kubectl create role with the --verb and --resource flags. Verify the Role with kubectl describe role.
kubectl create role pod-reader --verb=get,list,watch --resource=pods -n rbac-demo
kubectl describe role pod-reader -n rbac-demoUse --resource=pods/status to grant access to pod status subresource separately.
Roles are namespaced; they cannot grant access to cluster-scoped resources like nodes or namespaces.
Bind the Role to the Service Account
A RoleBinding links a Role to a user, group, or service account within the same namespace. Create a RoleBinding named 'dev-sa-pod-reader' that binds the pod-reader Role to the dev-sa service account in the rbac-demo namespace. Use kubectl create rolebinding with the --role and --serviceaccount flags.
kubectl create rolebinding dev-sa-pod-reader --role=pod-reader --serviceaccount=rbac-demo:dev-sa -n rbac-demo
kubectl describe rolebinding dev-sa-pod-reader -n rbac-demoYou can bind a Role to multiple subjects by editing the YAML and adding more subjects under the subjects array.
RoleBindings only apply within the namespace where they are created.
Test Permissions with kubectl auth can-i
Use kubectl auth can-i to verify what actions the service account can perform. First, test with the current user, then impersonate the service account using --as=system:serviceaccount:rbac-demo:dev-sa. Check if it can list pods, get deployments, and delete pods.
# Test as current user
kubectl auth can-i list pods -n rbac-demo
# Impersonate the service account
kubectl auth can-i list pods -n rbac-demo --as=system:serviceaccount:rbac-demo:dev-sa
kubectl auth can-i get deployments -n rbac-demo --as=system:serviceaccount:rbac-demo:dev-sa
kubectl auth can-i delete pods -n rbac-demo --as=system:serviceaccount:rbac-demo:dev-saUse kubectl auth can-i --list --as=... to see all allowed and denied actions for a subject.
Impersonation requires cluster-admin privileges or the impersonate verb on the subject.
Create a ClusterRole for Cluster-Scoped Access
ClusterRoles grant permissions across all namespaces or on cluster-scoped resources. Create a ClusterRole named 'node-reader' that allows get, list, and watch on nodes. Use kubectl create clusterrole with the appropriate flags. Verify with kubectl describe clusterrole.
kubectl create clusterrole node-reader --verb=get,list,watch --resource=nodes
kubectl describe clusterrole node-readerClusterRoles can also be used in namespaced RoleBindings to grant access to all namespaces for namespaced resources.
ClusterRoles are powerful; avoid granting cluster-admin unless absolutely necessary.
Bind the ClusterRole with a ClusterRoleBinding
A ClusterRoleBinding grants a ClusterRole's permissions cluster-wide. Create a ClusterRoleBinding named 'dev-sa-node-reader' that binds the node-reader ClusterRole to the dev-sa service account. Use kubectl create clusterrolebinding with the --clusterrole and --serviceaccount flags. Verify with kubectl describe clusterrolebinding.
kubectl create clusterrolebinding dev-sa-node-reader --clusterrole=node-reader --serviceaccount=rbac-demo:dev-sa
kubectl describe clusterrolebinding dev-sa-node-reader
# Test the permission
kubectl auth can-i list nodes --as=system:serviceaccount:rbac-demo:dev-saUse --user or --group instead of --serviceaccount to bind to human users or LDAP groups.
ClusterRoleBindings are global; ensure the service account is intended to have cluster-wide access.
Key tips
Always use the principle of least privilege: grant only the minimum permissions needed for a task.
Use kubectl auth can-i --list to audit permissions for any user or service account before deploying.
Leverage aggregation labels in ClusterRoles to combine multiple roles without duplication.
For production, use external secrets management (e.g., HashiCorp Vault) instead of static service account tokens.
Test RBAC changes in a non-production cluster first to avoid accidental lockouts.
Use kubectl describe clusterrolebinding and kubectl describe rolebinding to verify bindings are correct.
Frequently asked questions
What is the difference between a Role and a ClusterRole?
A Role grants permissions within a specific namespace and can only be used for namespaced resources (e.g., pods, services). A ClusterRole grants permissions cluster-wide and can be used for cluster-scoped resources (e.g., nodes, namespaces) or namespaced resources across all namespaces. ClusterRoles can also be bound to a RoleBinding to grant access to all namespaces for namespaced resources.
How do I grant a service account read-only access to all pods in the cluster?
Create a ClusterRole with verbs get, list, watch on the pods resource. Then create a ClusterRoleBinding that binds that ClusterRole to the service account. This gives the service account read-only access to pods across all namespaces.
Can I use a RoleBinding to bind a ClusterRole?
Yes. A RoleBinding can bind a ClusterRole to subjects within a specific namespace. This grants the permissions defined in the ClusterRole only for resources in that namespace. This is useful when you want to reuse a ClusterRole but limit its scope to a single namespace.
How do I revoke permissions from a service account?
Delete the RoleBinding or ClusterRoleBinding that grants the permissions using kubectl delete rolebinding <name> -n <namespace> or kubectl delete clusterrolebinding <name>. Alternatively, you can delete the service account itself, which removes all associated bindings.
What is the default RBAC behavior if no roles are defined?
By default, Kubernetes RBAC is enabled and denies all actions unless explicitly allowed. If no RoleBinding or ClusterRoleBinding exists for a user or service account, they have no permissions. The cluster-admin ClusterRoleBinding is created by default for the admin user during cluster setup.
Related glossary terms
Container Runtime
A container runtime is software that runs containers by using the host operating system's kernel to isolate processes, manage filesystem layers, and handle networking.
kubectl Command Reference
kubectl is the command-line tool used to interact with and manage Kubernetes clusters by sending commands to the Kubernetes API.
DaemonSets
A DaemonSet is a Kubernetes object that ensures a copy of a specific pod runs on every node in a cluster, or on a subset of nodes.
Jobs and CronJobs
A Kubernetes Job is a controller that runs one or more Pods to completion for a finite task, while a CronJob schedules Jobs to run at specific times or intervals.
Taints and Tolerations
Taints and tolerations are Kubernetes features that control which pods can be scheduled onto which nodes by marking nodes with a taint and allowing pods to declare a toleration to the taint.
Kubernetes Services
A Kubernetes Service is a stable network endpoint that connects a set of pods to internal or external traffic, providing consistent access even as pods change.
Practice with real exam questions
Apply what you just learned with exam-style practice questions.