Kubernetes RBAC Design
Design and implement role-based access control in Kubernetes that follows least privilege without paralyzing teams. Covers ClusterRoles, RoleBindings, namespace isolation, service accounts, admission webhooks, and RBAC troubleshooting patterns.
Kubernetes RBAC (Role-Based Access Control) determines who can do what in your cluster. A misconfigured RBAC policy can lock teams out of their namespaces or, worse, give every developer cluster-admin access. Effective RBAC balances security (least privilege) with usability (developers can do their jobs).
RBAC Concepts
Subject: Who (User, Group, ServiceAccount)
↓ bound to
Role: What permissions (get, list, create, delete on resources)
↓ scoped to
Namespace: Where (namespace-scoped or cluster-wide)
Role vs ClusterRole
# Role: Permissions within a single namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer
namespace: order-service
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: [""]
resources: ["pods/log", "pods/exec"]
verbs: ["get", "create"]
---
# ClusterRole: Cluster-wide permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-viewer
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list", "watch"]
Common Role Patterns
Developer Role
# Can view pods, logs, exec into pods in their namespace
# Can update deployments (rollout restart)
# Cannot delete resources or create new deployments
rules:
- apiGroups: [""]
resources: ["pods", "pods/log", "services", "configmaps", "events"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/exec", "pods/portforward"]
verbs: ["create"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: ["batch"]
resources: ["jobs", "cronjobs"]
verbs: ["get", "list", "watch"]
Platform Operator Role
# Can manage infrastructure resources
# Can create namespaces, manage RBAC within namespaces
# Cannot access secrets or workload data
rules:
- apiGroups: [""]
resources: ["namespaces", "nodes", "persistentvolumes"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
- apiGroups: ["networking.k8s.io"]
resources: ["networkpolicies", "ingresses"]
verbs: ["*"]
CI/CD Service Account
# Minimal permissions for deployment pipeline
apiVersion: v1
kind: ServiceAccount
metadata:
name: ci-deployer
namespace: order-service
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: ci-deployer
namespace: order-service
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "update", "patch"]
resourceNames: ["order-service"] # Only this specific deployment
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "create", "update"]
Namespace Isolation
# Each team gets their own namespace with isolated RBAC
namespaces:
order-service:
owner: order-team
rbac:
- group: order-team-devs → Role: developer
- group: order-team-leads → Role: namespace-admin
- serviceAccount: ci-deployer → Role: ci-deployer
payment-service:
owner: payment-team
rbac:
- group: payment-team-devs → Role: developer
- group: payment-team-leads → Role: namespace-admin
- serviceAccount: ci-deployer → Role: ci-deployer
# Order team cannot access payment-service namespace (and vice versa)
Troubleshooting
# "Can I do this?" check
kubectl auth can-i get pods --namespace order-service --as john@example.com
# yes
kubectl auth can-i delete deployments --namespace order-service --as john@example.com
# no
# "Who can do this?" audit
kubectl auth can-i --list --namespace order-service --as john@example.com
# Find all bindings for a subject
kubectl get rolebindings,clusterrolebindings --all-namespaces \
-o jsonpath='{range .items[?(@.subjects[*].name=="john")]}{.metadata.name}{"\n"}{end}'
Anti-Patterns
| Anti-Pattern | Consequence | Fix |
|---|---|---|
| cluster-admin for developers | No access control, security risk | Role per team per namespace |
| Single namespace for all teams | No isolation, RBAC complexity | Namespace per service/team |
| Wildcard verbs [”*“] | Overly permissive | Explicit verb lists |
| No service account tokens rotation | Compromised SA = permanent access | Short-lived tokens, bound service accounts |
| RBAC without audit logging | Cannot detect unauthorized access | Enable audit logging, review regularly |
Kubernetes RBAC is the primary access control mechanism for your cluster. Get it right early — retrofitting RBAC into a cluster where everyone is cluster-admin is painful but necessary.