All Articles

What is RBAC in Kubernetes? Explained Simply (2026)

Kubernetes RBAC controls who can do what in your cluster. Here's what Role, ClusterRole, RoleBinding, and ServiceAccount mean — explained simply with real examples.

DevOpsBoysApr 12, 20264 min read
Share:Tweet

RBAC stands for Role-Based Access Control. In Kubernetes, it answers: who is allowed to do what on which resources?

Why RBAC Matters

Without RBAC, every app and every user in your cluster would have full access to everything. That's dangerous:

  • A compromised app pod could delete other pods
  • A junior developer could accidentally delete production deployments
  • An external attacker could escalate to cluster-admin

RBAC locks this down. Each identity gets only the permissions it needs.


The 4 RBAC Objects

1. Role

Defines what actions are allowed on which resourceswithin one namespace.

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: production
rules:
- apiGroups: [""]        # "" = core API group
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

This Role allows reading pods in the production namespace. Nothing else.

2. ClusterRole

Same as Role, but applies across all namespaces (or to cluster-wide resources like Nodes).

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-reader
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

Nodes aren't namespaced — you need ClusterRole for them.

3. RoleBinding

Connects a user/group/ServiceAccount to a Role — within a namespace.

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-binding
  namespace: production
subjects:
- kind: User
  name: alice             # ← the identity
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader        # ← the Role defined above
  apiGroup: rbac.authorization.k8s.io

Now alice can read pods in production. Only production. Only pods.

4. ClusterRoleBinding

Connects an identity to a ClusterRole — cluster-wide.

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-binding
subjects:
- kind: User
  name: bob
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin     # built-in ClusterRole = full access
  apiGroup: rbac.authorization.k8s.io

Bob is now cluster-admin. Be careful with this.


Verbs (What Actions)

VerbWhat it does
getRead a single resource
listList all resources of a type
watchStream changes (used by controllers)
createCreate new resources
updateModify existing resources
patchPartially modify resources
deleteDelete resources
execExecute commands in pods (kubectl exec)
*All verbs (wildcard)

Resources (What Objects)

Common resources:

yaml
resources: ["pods", "services", "deployments", "configmaps", "secrets", "nodes", "namespaces"]
 
# Subresources (e.g., pod logs, exec)
resources: ["pods/log", "pods/exec", "pods/portforward"]

ServiceAccounts — RBAC for Pods

When a pod needs to call the Kubernetes API (e.g., an app that lists its own pods), it uses a ServiceAccount.

yaml
# 1. Create a ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app-sa
  namespace: production
 
---
# 2. Create a Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-lister
  namespace: production
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["list", "get"]
 
---
# 3. Bind them
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: my-app-pod-lister
  namespace: production
subjects:
- kind: ServiceAccount
  name: my-app-sa
  namespace: production
roleRef:
  kind: Role
  name: pod-lister
  apiGroup: rbac.authorization.k8s.io
 
---
# 4. Use in Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: production
spec:
  template:
    spec:
      serviceAccountName: my-app-sa   # ← use this SA
      containers:
      - name: app
        image: myapp:latest

Built-in ClusterRoles

Kubernetes ships with useful ClusterRoles:

ClusterRoleWho should get it
cluster-adminPlatform admins only
adminNamespace owners
editDevelopers (can create/modify, no RBAC changes)
viewRead-only access
bash
# Grant a developer edit access to one namespace
kubectl create rolebinding dev-edit \
  --clusterrole=edit \
  --user=john@company.com \
  --namespace=staging

Check Permissions

bash
# Can I list pods in production?
kubectl auth can-i list pods -n production
 
# Can alice list pods in production?
kubectl auth can-i list pods -n production --as alice
 
# What can alice do?
kubectl auth can-i --list --as alice -n production
 
# Check ServiceAccount permissions
kubectl auth can-i list pods \
  --as system:serviceaccount:production:my-app-sa \
  -n production

Common RBAC Patterns

Developer access (namespace-scoped)

yaml
# Give dev team edit access to staging namespace
kubectl create rolebinding dev-edit \
  --clusterrole=edit \
  --group=dev-team \
  --namespace=staging

CI/CD pipeline ServiceAccount

yaml
# Deployment pipeline needs to update Deployments
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "update", "patch"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

Read-only monitoring access

yaml
# Prometheus needs to read metrics from pods/nodes
rules:
- apiGroups: [""]
  resources: ["nodes", "pods", "services", "endpoints"]
  verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]

RBAC vs No RBAC

Without RBAC (--authorization-mode=AlwaysAllow):

  • Every pod, user, and service account has full cluster access
  • Compromise of one pod = full cluster compromise

With RBAC (default since K8s 1.6):

  • Principle of least privilege
  • Blast radius is contained
  • Audit trail (who did what)

Debug RBAC Issues

bash
# User getting "forbidden" errors?
# 1. Check what they're trying to do
kubectl get events --all-namespaces | grep Forbidden
 
# 2. Verify their bindings
kubectl get rolebindings,clusterrolebindings --all-namespaces \
  -o custom-columns='NAME:metadata.name,SUBJECT:.subjects[*].name' | grep alice
 
# 3. Test as them
kubectl auth can-i create deployments --as alice -n production

Summary

ObjectScopePurpose
RoleNamespaceDefine permissions in one namespace
ClusterRoleCluster-wideDefine permissions across all namespaces
RoleBindingNamespaceAttach Role to user/SA
ClusterRoleBindingCluster-wideAttach ClusterRole to user/SA
ServiceAccountNamespaceIdentity for pods

RBAC is not optional in production. Start with least-privilege and grant more as needed, not the other way around.


Learn More

Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments