Configure Kubernetes role-based access control (RBAC) with service accounts, roles, and role bindings to enforce secure access policies and namespace isolation in your cluster.
Prerequisites
- Kubernetes cluster with RBAC enabled
- kubectl configured with cluster admin access
- Basic understanding of Kubernetes concepts
What this solves
Kubernetes RBAC (Role-Based Access Control) controls who can access what resources in your cluster. By default, Kubernetes operates on a principle of least privilege, but without proper RBAC configuration, you may grant excessive permissions or block legitimate access. This tutorial shows you how to create service accounts, define roles with specific permissions, and bind them together for secure, granular access control.
Understanding Kubernetes RBAC fundamentals
RBAC in Kubernetes consists of four main components that work together. Service accounts provide identity for pods and applications. Roles define what actions can be performed on which resources. ClusterRoles work like Roles but apply cluster-wide. RoleBindings and ClusterRoleBindings connect subjects (users, groups, service accounts) to roles.
RBAC operates on the principle of explicit allow - everything is denied by default unless explicitly permitted. Permissions are additive, meaning multiple roles can grant different permissions to the same subject. Namespace-level roles only apply within their specific namespace, while cluster roles can access resources across all namespaces.
Step-by-step configuration
Verify RBAC is enabled
Check that RBAC authorization is enabled in your Kubernetes cluster before proceeding with configuration.
kubectl api-versions | grep rbac
kubectl auth can-i create roles --as=system:serviceaccount:default:default
Create a dedicated namespace
Create a test namespace to demonstrate RBAC policies without affecting existing workloads.
kubectl create namespace rbac-demo
kubectl get namespaces rbac-demo
Create a service account
Service accounts provide an identity for processes that run in pods. Create a service account that will be used by applications needing specific permissions.
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-reader
namespace: rbac-demo
automountServiceAccountToken: true
kubectl apply -f rbac-serviceaccount.yaml
kubectl get serviceaccount -n rbac-demo
Create a namespace-level role
Define a role that grants read-only permissions to pods and services within the rbac-demo namespace. This follows the principle of least privilege by only granting necessary permissions.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: rbac-demo
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "watch", "list"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
kubectl apply -f rbac-role.yaml
kubectl get role -n rbac-demo
Create a role binding
Bind the service account to the role, granting the app-reader service account the permissions defined in the pod-reader role.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: rbac-demo
subjects:
- kind: ServiceAccount
name: app-reader
namespace: rbac-demo
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac-rolebinding.yaml
kubectl get rolebinding -n rbac-demo
Create a cluster-level role
Define a ClusterRole for permissions that span multiple namespaces or cluster-wide resources like nodes. This example grants read access to nodes and persistent volumes.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-reader
rules:
- apiGroups: [""]
resources: ["nodes", "persistentvolumes"]
verbs: ["get", "watch", "list"]
- apiGroups: ["metrics.k8s.io"]
resources: ["nodes", "pods"]
verbs: ["get", "list"]
kubectl apply -f rbac-clusterrole.yaml
kubectl get clusterrole node-reader
Create a cluster role binding
Bind the service account to the cluster role, giving it cluster-wide read permissions for nodes and metrics.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-nodes
subjects:
- kind: ServiceAccount
name: app-reader
namespace: rbac-demo
roleRef:
kind: ClusterRole
name: node-reader
apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac-clusterrolebinding.yaml
kubectl get clusterrolebinding read-nodes
Create a role for write operations
Create a separate role with write permissions for deployment management. This demonstrates separation of concerns between read and write access.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: rbac-demo
name: deployment-manager
rules:
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
kubectl apply -f rbac-deployment-role.yaml
Create a service account for deployment operations
Create a separate service account for deployment operations to demonstrate role separation.
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-deployer
namespace: rbac-demo
kubectl apply -f rbac-deployer-sa.yaml
Bind the deployer role
Create a role binding that grants the app-deployer service account deployment management permissions.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: manage-deployments
namespace: rbac-demo
subjects:
- kind: ServiceAccount
name: app-deployer
namespace: rbac-demo
roleRef:
kind: Role
name: deployment-manager
apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac-deployer-binding.yaml
Testing RBAC policies
Test service account permissions
Use kubectl auth can-i to test what each service account can do. This helps verify your RBAC configuration works as expected.
kubectl auth can-i get pods --as=system:serviceaccount:rbac-demo:app-reader -n rbac-demo
kubectl auth can-i create deployments --as=system:serviceaccount:rbac-demo:app-reader -n rbac-demo
kubectl auth can-i create deployments --as=system:serviceaccount:rbac-demo:app-deployer -n rbac-demo
Create a test pod with service account
Deploy a pod that uses one of your service accounts to verify the RBAC configuration works in practice.
apiVersion: v1
kind: Pod
metadata:
name: rbac-test
namespace: rbac-demo
spec:
serviceAccountName: app-reader
containers:
- name: kubectl-test
image: bitnami/kubectl:latest
command: ['sleep', '3600']
restartPolicy: Never
kubectl apply -f rbac-test-pod.yaml
kubectl get pod rbac-test -n rbac-demo
Test permissions from inside the pod
Execute commands inside the test pod to verify that the service account can only perform allowed operations.
kubectl exec -it rbac-test -n rbac-demo -- kubectl get pods -n rbac-demo
kubectl exec -it rbac-test -n rbac-demo -- kubectl get nodes
kubectl exec -it rbac-test -n rbac-demo -- kubectl create deployment test --image=nginx -n rbac-demo
Implementing advanced RBAC patterns
Create resource-specific permissions
Configure RBAC to allow access to specific resources by name, not just resource types. This provides fine-grained control over individual resources.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: rbac-demo
name: specific-config-reader
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["app-config", "database-config"]
verbs: ["get"]
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["app-secret"]
verbs: ["get"]
kubectl apply -f rbac-specific-resource.yaml
Create role aggregation
Use ClusterRole aggregation to combine multiple roles automatically. This is useful for creating composite roles from smaller, reusable components.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-reader
labels:
rbac.example.com/aggregate-to-monitoring: "true"
rules:
- apiGroups: [""]
resources: ["pods", "services", "endpoints"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: aggregate-monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: []
kubectl apply -f rbac-aggregated-role.yaml
Verify your setup
kubectl get serviceaccounts -n rbac-demo
kubectl get roles -n rbac-demo
kubectl get rolebindings -n rbac-demo
kubectl get clusterroles | grep -E "node-reader|aggregate-monitoring"
kubectl get clusterrolebindings | grep read-nodes
kubectl auth can-i --list --as=system:serviceaccount:rbac-demo:app-reader -n rbac-demo
Troubleshooting access issues
Debug RBAC permissions
Use these commands to troubleshoot when applications can't access required resources.
kubectl auth can-i create pods --as=system:serviceaccount:rbac-demo:app-reader -n rbac-demo
kubectl describe rolebinding -n rbac-demo
kubectl describe clusterrolebinding read-nodes
Check service account tokens
Verify that service accounts have valid tokens and can authenticate to the API server.
kubectl get serviceaccount app-reader -n rbac-demo -o yaml
kubectl get secrets -n rbac-demo | grep app-reader
kubectl describe secret $(kubectl get serviceaccount app-reader -n rbac-demo -o jsonpath='{.secrets[0].name}') -n rbac-demo
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Pod gets "forbidden" errors | Service account lacks permissions | Create role and rolebinding with required verbs and resources |
| RoleBinding doesn't work | Wrong namespace or subject reference | Verify namespace matches and subject kind/name are correct |
| Can't access cluster resources | Using Role instead of ClusterRole | Create ClusterRole and ClusterRoleBinding for cluster-scoped resources |
| Service account not found | automountServiceAccountToken disabled | Set automountServiceAccountToken: true in ServiceAccount |
| Permissions too broad | Using wildcards in rules | Specify exact resources and verbs instead of "*" |
| Multiple bindings conflict | Overlapping role definitions | RBAC permissions are additive - review all bindings for the subject |
Next steps
- Implement Kubernetes network policies for pod-to-pod security and traffic isolation
- Configure Kubernetes secrets management with Vault integration for secure container orchestration
- Set up Kubernetes monitoring with Prometheus Operator and custom metrics
- Configure advanced Kubernetes Pod Security Standards with admission controllers
- Implement Kubernetes policy enforcement with Open Policy Agent Gatekeeper