Set up role-based access control in Kubernetes using service accounts, roles, and role bindings to implement least-privilege security principles and granular permission management for applications and users.
Prerequisites
- Running Kubernetes cluster with kubectl access
- Cluster admin permissions
- Basic understanding of Kubernetes concepts
What this solves
Kubernetes RBAC (Role-Based Access Control) provides fine-grained access control for cluster resources by defining who can perform what actions on which resources. Without proper RBAC configuration, applications and users might have excessive permissions, creating security risks and violating the principle of least privilege.
Understanding Kubernetes RBAC fundamentals
RBAC in Kubernetes consists of four main components that work together to control access. Service accounts represent identities for pods and applications running in the cluster. Roles define sets of permissions for resources within a namespace, while ClusterRoles define permissions across the entire cluster.
Role bindings connect roles to subjects (users, groups, or service accounts) within a namespace, while ClusterRole bindings work at the cluster level. This separation allows you to create reusable permission sets and apply them selectively to different identities.
--authorization-mode parameter includes RBAC in your API server configuration.Step-by-step configuration
Verify RBAC is enabled
First, confirm that RBAC authorization is active in your cluster.
kubectl cluster-info dump | grep authorization-mode
kubectl auth can-i list pods --as=system:serviceaccount:default:default
Create a dedicated namespace
Set up a separate namespace for testing RBAC configurations without affecting existing workloads.
kubectl create namespace rbac-demo
kubectl get namespaces
Create a service account
Service accounts provide identities for applications running in pods. Create one for our demo application.
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-reader
namespace: rbac-demo
labels:
purpose: rbac-demonstration
automountServiceAccountToken: true
kubectl apply -f rbac-service-account.yaml
kubectl get serviceaccounts -n rbac-demo
Create a role with specific permissions
Define a role that grants read-only access to pods and services within the namespace.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: rbac-demo
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["app-config"]
verbs: ["get"]
kubectl apply -f rbac-role.yaml
kubectl describe role pod-reader -n rbac-demo
Create a role binding
Bind the role to the service account to grant the defined permissions.
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-role-binding.yaml
kubectl describe rolebinding read-pods -n rbac-demo
Create a cluster role for cross-namespace access
For permissions that span multiple namespaces, create a ClusterRole instead of a namespace-scoped Role.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-reader
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list"]
- apiGroups: ["metrics.k8s.io"]
resources: ["nodes", "pods"]
verbs: ["get", "list"]
kubectl apply -f rbac-cluster-role.yaml
kubectl describe clusterrole namespace-reader
Create a cluster role binding
Bind the ClusterRole to a service account to grant cluster-wide permissions.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-namespaces
subjects:
- kind: ServiceAccount
name: app-reader
namespace: rbac-demo
roleRef:
kind: ClusterRole
name: namespace-reader
apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac-cluster-role-binding.yaml
kubectl describe clusterrolebinding read-namespaces
Create a test pod with the service account
Deploy a pod that uses the service account to test the RBAC configuration.
apiVersion: v1
kind: Pod
metadata:
name: rbac-test-pod
namespace: rbac-demo
spec:
serviceAccountName: app-reader
containers:
- name: kubectl-container
image: bitnami/kubectl:latest
command: ["sleep", "3600"]
restartPolicy: Never
kubectl apply -f test-pod.yaml
kubectl get pods -n rbac-demo
Configure advanced role permissions
Create a more complex role that demonstrates resource filtering and specific action permissions.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: deployment-manager
namespace: rbac-demo
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: ["apps"]
resources: ["deployments/scale"]
verbs: ["update", "patch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["app-secret", "db-secret"]
verbs: ["get"]
kubectl apply -f advanced-role.yaml
Verify your setup
Test the RBAC configuration by checking what actions the service account can perform.
# Test permissions from within the pod
kubectl exec -it rbac-test-pod -n rbac-demo -- kubectl get pods
kubectl exec -it rbac-test-pod -n rbac-demo -- kubectl get namespaces
Test permissions using kubectl auth can-i
kubectl auth can-i list 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 delete pods --as=system:serviceaccount:rbac-demo:app-reader -n rbac-demo
Check what resources the service account can access
kubectl auth can-i --list --as=system:serviceaccount:rbac-demo:app-reader -n rbac-demo
You can also verify the service account token and permissions are correctly mounted.
# Check mounted service account token
kubectl exec rbac-test-pod -n rbac-demo -- ls -la /var/run/secrets/kubernetes.io/serviceaccount/
View the token content (base64 decoded)
kubectl exec rbac-test-pod -n rbac-demo -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
Check namespace
kubectl exec rbac-test-pod -n rbac-demo -- cat /var/run/secrets/kubernetes.io/serviceaccount/namespace
Managing user access with RBAC
RBAC also controls human user access to the cluster. Create role bindings for users and groups from your authentication provider.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-access
namespace: rbac-demo
subjects:
- kind: User
name: jane.doe@example.com
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: developers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: deployment-manager
apiGroup: rbac.authorization.k8s.io
kubectl apply -f user-role-binding.yaml
Implementing network policies for additional security
Combine RBAC with network policies for comprehensive security. While RBAC controls API access, network policies control pod-to-pod communication.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: rbac-demo-netpol
namespace: rbac-demo
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 8080
egress:
- to:
- namespaceSelector:
matchLabels:
name: database
ports:
- protocol: TCP
port: 5432
For comprehensive network security configuration, you can reference our Kubernetes network policies guide for detailed network isolation strategies.
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Forbidden: access denied | Missing role or role binding | Create appropriate role and binding with required permissions |
| Service account not found | Service account not created in correct namespace | Verify namespace and recreate service account |
| Role binding has no effect | Incorrect subject reference or roleRef | Check subject kind, name, and namespace match exactly |
| Cannot access cluster resources | Using Role instead of ClusterRole | Create ClusterRole and ClusterRoleBinding for cluster-scoped resources |
| Pod cannot mount service account | Service account token automounting disabled | Set automountServiceAccountToken: true in service account |
| Excessive permissions granted | Using wildcard permissions or admin roles | Create specific roles with minimal required permissions |
Next steps
- Configure network policies for pod security
- Set up Kubernetes monitoring with Prometheus
- Implement secrets management with Sealed Secrets
- Configure Pod Security Standards for enhanced security
- Set up OPA Gatekeeper for policy enforcement