RBAC — Role-Based Access Control
Who can create Deployments? Who can view Secrets? Who can delete Pods? RBAC (Role-Based Access Control) answers all these questions by controlling what users and service accounts can do in your cluster.
What is RBAC?
RBAC regulates access to Kubernetes resources based on the roles assigned to users, groups, or service accounts. It answers three questions:
- Who — the subject (User, Group, or ServiceAccount)
- What — the action (get, list, create, delete, etc.)
- Which — the resource (Pods, Deployments, Secrets, etc.)
User "alice" ──► Role "pod-reader" ──► Can GET and LIST Pods in namespace "default"
RBAC Components
| Component | Scope | Purpose |
|---|---|---|
| Role | Namespace | Defines permissions within a namespace |
| ClusterRole | Cluster-wide | Defines permissions cluster-wide |
| RoleBinding | Namespace | Binds a Role/ClusterRole to a subject in a namespace |
| ClusterRoleBinding | Cluster-wide | Binds a ClusterRole to a subject cluster-wide |
┌──────────────────────────────────────────────┐
│ │
│ Subject ──► RoleBinding ──► Role │
│ (who) (binding) (permissions) │
│ │
└──────────────────────────────────────────────┘
Roles and ClusterRoles
Role (Namespace-Scoped)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: development
name: pod-reader
rules:
- apiGroups: [""] # "" = core API group (Pods, Services, etc.)
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: [""]
resources: ["pods/log"] # Sub-resource
verbs: ["get"]
ClusterRole (Cluster-Scoped)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-pod-reader # No namespace — applies cluster-wide
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: ["apps"] # apps API group (Deployments, ReplicaSets, etc.)
resources: ["deployments"]
verbs: ["get", "list"]
API Groups and Resources
| API Group | Resources |
|---|---|
"" (core) |
pods, services, configmaps, secrets, namespaces, nodes |
apps |
deployments, replicasets, statefulsets, daemonsets |
batch |
jobs, cronjobs |
networking.k8s.io |
ingresses, networkpolicies |
rbac.authorization.k8s.io |
roles, rolebindings, clusterroles |
Verbs
| Verb | Description |
|---|---|
get |
Read a single resource |
list |
List multiple resources |
watch |
Watch for changes |
create |
Create a resource |
update |
Modify entire resource |
patch |
Modify specific fields |
delete |
Delete a single resource |
deletecollection |
Delete multiple resources |
* |
All verbs (use cautiously) |
RoleBindings and ClusterRoleBindings
RoleBinding (Namespace-Scoped)
Binds a Role to a subject within a specific namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: development
subjects:
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
ClusterRoleBinding (Cluster-Wide)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-admin-binding
subjects:
- kind: User
name: admin
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin # Built-in superuser role
apiGroup: rbac.authorization.k8s.io
Bind a ClusterRole to a Namespace (Common Pattern)
You can use a RoleBinding to bind a ClusterRole to a specific namespace. This reuses ClusterRole definitions without granting cluster-wide access:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-pod-reader
namespace: development # Only applies in this namespace
subjects:
- kind: User
name: alice
roleRef:
kind: ClusterRole # Reusing a ClusterRole
name: cluster-pod-reader # But limited to "development" namespace
apiGroup: rbac.authorization.k8s.io
Service Accounts
Service Accounts are identities for Pods (not humans). Every Pod runs as a Service Account.
Default Service Account
Every namespace has a default Service Account:
kubectl get serviceaccounts
# NAME SECRETS AGE
# default 0 5d
Create a Custom Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-service-account
namespace: development
Assign to a Pod
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
serviceAccountName: app-service-account # Run as this SA
containers:
- name: app
image: my-app:1.0
Grant Permissions to a Service Account
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-sa-binding
namespace: development
subjects:
- kind: ServiceAccount
name: app-service-account
namespace: development
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Built-in ClusterRoles
Kubernetes includes several default ClusterRoles:
| ClusterRole | Permissions |
|---|---|
| cluster-admin | Full access to everything (superuser) |
| admin | Full access within a namespace (no resource quotas) |
| edit | Read/write access to most resources in a namespace |
| view | Read-only access to most resources in a namespace |
# List all ClusterRoles
kubectl get clusterroles
# Describe a built-in role
kubectl describe clusterrole view
Hands-On: RBAC in Practice
# 1. Create a namespace
apiVersion: v1
kind: Namespace
metadata:
name: team-alpha
---
# 2. Create a Service Account for the team
apiVersion: v1
kind: ServiceAccount
metadata:
name: team-alpha-sa
namespace: team-alpha
---
# 3. Create a Role with specific permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: team-alpha-developer
namespace: team-alpha
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["pods", "deployments", "services", "configmaps", "jobs"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"] # Read-only for secrets
- apiGroups: [""]
resources: ["pods/log", "pods/exec"]
verbs: ["get", "create"]
---
# 4. Bind the Role to the Service Account
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-alpha-binding
namespace: team-alpha
subjects:
- kind: ServiceAccount
name: team-alpha-sa
namespace: team-alpha
roleRef:
kind: Role
name: team-alpha-developer
apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac-demo.yaml
# Test: Can the SA list Pods?
kubectl auth can-i list pods --namespace team-alpha --as system:serviceaccount:team-alpha:team-alpha-sa
# yes
# Test: Can the SA delete secrets?
kubectl auth can-i delete secrets --namespace team-alpha --as system:serviceaccount:team-alpha:team-alpha-sa
# no
# Test: Can the SA access another namespace?
kubectl auth can-i list pods --namespace default --as system:serviceaccount:team-alpha:team-alpha-sa
# no
Checking Permissions
# Can I do X?
kubectl auth can-i create deployments
kubectl auth can-i delete pods --namespace production
# Can a specific user do X?
kubectl auth can-i list secrets --as alice --namespace development
# Can a service account do X?
kubectl auth can-i get pods --as system:serviceaccount:default:my-sa
# List all permissions for current user
kubectl auth can-i --list
# List permissions in a specific namespace
kubectl auth can-i --list --namespace production
Best Practices
| Practice | Reason |
|---|---|
| Principle of least privilege | Grant only the permissions that are needed |
| Use Roles over ClusterRoles when possible | Limit blast radius to a namespace |
| Avoid cluster-admin for regular users | Too powerful for daily use |
| Use Service Accounts for applications | Don’t use personal credentials in Pods |
| Audit RBAC regularly | Permissions accumulate over time |
| Group users with similar access needs | Easier to manage than individual bindings |
Summary
- RBAC controls who can do what in your Kubernetes cluster
- Roles define permissions; RoleBindings assign them to subjects
- ClusterRoles/ClusterRoleBindings work cluster-wide
- Service Accounts provide identities for Pods
- Use
kubectl auth can-ito test permissions - Follow the principle of least privilege
What’s Next?
Now let’s learn how to manage cluster resources effectively with Resource Management — setting CPU and memory requests and limits to ensure fair sharing and prevent resource starvation.