RBAC — Role-Based Access Control

5 minute read

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:

  1. Who — the subject (User, Group, or ServiceAccount)
  2. What — the action (get, list, create, delete, etc.)
  3. 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-i to 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.

Next: Resource Management →

Updated: