ESC
Type to search guides, tutorials, and reference documentation.
Verified by Garnet Grid

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-PatternConsequenceFix
cluster-admin for developersNo access control, security riskRole per team per namespace
Single namespace for all teamsNo isolation, RBAC complexityNamespace per service/team
Wildcard verbs [”*“]Overly permissiveExplicit verb lists
No service account tokens rotationCompromised SA = permanent accessShort-lived tokens, bound service accounts
RBAC without audit loggingCannot detect unauthorized accessEnable 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.

Jakub Dimitri Rezayev
Jakub Dimitri Rezayev
Founder & Chief Architect • Garnet Grid Consulting

Jakub holds an M.S. in Customer Intelligence & Analytics and a B.S. in Finance & Computer Science from Pace University. With deep expertise spanning D365 F&O, Azure, Power BI, and AI/ML systems, he architects enterprise solutions that bridge legacy systems and modern technology — and has led multi-million dollar ERP implementations for Fortune 500 supply chains.

View Full Profile →