Kubernetes RBAC Configuration Reference

Type: Software Reference Confidence: 0.94 Sources: 7 Verified: 2026-02-27 Freshness: 2026-02-27

TL;DR

Constraints

Quick Reference

ResourceScopePurposeAPI GroupKey Fields
RoleNamespaceDefine permissions within a single namespacerbac.authorization.k8s.io/v1rules[].apiGroups, resources, verbs
ClusterRoleClusterDefine cluster-wide or cross-namespace permissionsrbac.authorization.k8s.io/v1rules[], aggregationRule
RoleBindingNamespaceBind Role or ClusterRole to subjects in one namespacerbac.authorization.k8s.io/v1subjects[], roleRef (immutable)
ClusterRoleBindingClusterBind ClusterRole to subjects cluster-widerbac.authorization.k8s.io/v1subjects[], roleRef (immutable)
ServiceAccountNamespaceIdentity for pods; bound to Roles via RoleBindingv1automountServiceAccountToken
VerbTypeDescription
getReadRetrieve a single resource by name
listReadList all resources of a type (exposes secret values!)
watchReadStream changes to resources (exposes secret values!)
createWriteCreate a new resource
updateWriteReplace an entire resource
patchWriteModify specific fields of a resource
deleteWriteDelete a single resource
deletecollectionWriteDelete all resources of a type
escalateDangerousModify RBAC rules beyond your own permissions
bindDangerousCreate bindings to roles with higher permissions
impersonateDangerousAct as another user, group, or service account
Default ClusterRolePermissionsUse Case
cluster-adminFull access to ALL resourcesEmergency break-glass only
adminFull access within a namespace (no ResourceQuota/Namespace)Namespace administrators
editRead/write most resources (no Roles/RoleBindings)Developers deploying workloads
viewRead-only most resources (no Secrets)Auditors, read-only dashboards

Decision Tree

START
├── Need cluster-wide access to non-namespaced resources (nodes, namespaces, PVs)?
│   ├── YES → Use ClusterRole + ClusterRoleBinding
│   └── NO ↓
├── Need the same permissions across multiple namespaces?
│   ├── YES → Define a ClusterRole + RoleBinding per namespace
│   └── NO ↓
├── Need permissions in a single namespace only?
│   ├── YES → Use Role + RoleBinding (most secure, preferred)
│   └── NO ↓
├── Need to extend a built-in role (admin/edit/view)?
│   ├── YES → Use aggregated ClusterRole with matching labels
│   └── NO ↓
├── Subject is a pod/workload?
│   ├── YES → Create dedicated ServiceAccount + Role + RoleBinding
│   │         Set automountServiceAccountToken: false on SA
│   └── NO ↓
├── Subject is a human user?
│   ├── YES → Bind to Group (not individual User) for manageability
│   └── NO ↓
└── DEFAULT → Start with the built-in "view" ClusterRole; add permissions incrementally

Step-by-Step Guide

1. Create a ServiceAccount for your workload

Every application should have its own ServiceAccount rather than using the default ServiceAccount. Disable automatic token mounting unless the pod needs Kubernetes API access. [src2] [src3]

apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp-sa
  namespace: production
automountServiceAccountToken: false

Verify: kubectl get sa myapp-sa -n production → should show the ServiceAccount

2. Define a Role with minimum required permissions

Specify exact apiGroups, resources, and verbs. Use resourceNames to restrict access to specific objects when possible. Never use wildcards. [src1] [src2]

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: myapp-role
  namespace: production
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["myapp-config"]
  verbs: ["get", "watch"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

Verify: kubectl describe role myapp-role -n production → should show the rules

3. Bind the Role to the ServiceAccount

Create a RoleBinding that connects the ServiceAccount to the Role. The roleRef is immutable -- to change the role reference, delete and recreate the binding. [src1]

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: myapp-binding
  namespace: production
subjects:
- kind: ServiceAccount
  name: myapp-sa
  namespace: production
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: myapp-role

Verify: kubectl auth can-i get configmaps --as=system:serviceaccount:production:myapp-sa -n productionyes

4. Assign the ServiceAccount to your Pod/Deployment

Reference the ServiceAccount in your pod spec. If the pod does need API access, set automountServiceAccountToken: true in the pod spec. [src3]

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  namespace: production
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      serviceAccountName: myapp-sa
      automountServiceAccountToken: true
      containers:
      - name: myapp
        image: myapp:1.2.3

Verify: kubectl get pods -n production -o jsonpath='{.items[0].spec.serviceAccountName}'myapp-sa

5. Test permissions with kubectl auth can-i

Always verify both positive (allowed) and negative (denied) access after configuring RBAC. [src1]

# Should succeed (allowed by the Role)
kubectl auth can-i get configmaps --as=system:serviceaccount:production:myapp-sa -n production
# Should fail (not granted)
kubectl auth can-i create deployments --as=system:serviceaccount:production:myapp-sa -n production
# Check all permissions for a subject
kubectl auth can-i --list --as=system:serviceaccount:production:myapp-sa -n production

Verify: Positive tests return yes, negative tests return no

6. Apply all manifests with kubectl auth reconcile

Use kubectl auth reconcile for idempotent RBAC application, especially in CI/CD pipelines. [src1]

kubectl auth reconcile -f rbac-manifests/ --dry-run=server
kubectl auth reconcile -f rbac-manifests/

Verify: kubectl get role,rolebinding -n production → should list all created objects

Code Examples

YAML: Namespace-scoped developer Role + RoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer
  namespace: development
rules:
- apiGroups: [""]
  resources: ["pods", "services", "configmaps"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
  resources: ["pods/log", "pods/exec"]
  verbs: ["get", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-binding
  namespace: development
subjects:
- kind: Group
  name: dev-team
  apiGroup: rbac.authorization.k8s.io
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: developer

YAML: ClusterRole with aggregation for monitoring

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: metrics-reader
  labels:
    rbac.authorization.k8s.io/aggregate-to-view: "true"
rules:
- apiGroups: ["metrics.k8s.io"]
  resources: ["pods", "nodes"]
  verbs: ["get", "list"]

YAML: CI/CD ServiceAccount with scoped deployment permissions

apiVersion: v1
kind: ServiceAccount
metadata:
  name: cicd-deployer
  namespace: staging
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deployer
  namespace: staging
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: ["apps"]
  resources: ["deployments/rollback"]
  verbs: ["create"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: cicd-deployer-binding
  namespace: staging
subjects:
- kind: ServiceAccount
  name: cicd-deployer
  namespace: staging
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: deployer

YAML: Read-only ClusterRole for auditors across all namespaces

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: auditor
rules:
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
  resources: ["*"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: auditor-binding
subjects:
- kind: Group
  name: security-auditors
  apiGroup: rbac.authorization.k8s.io
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: auditor

Anti-Patterns

Wrong: Using wildcards for verbs and resources

# BAD -- grants ALL permissions on ALL resources, including secrets,
# admission webhooks, and any future resources added to the cluster
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: super-user
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["*"]

Correct: Explicit verbs and resources

# GOOD -- grants only the specific permissions needed
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: app-manager
  namespace: production
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get", "list"]

Wrong: Binding cluster-admin to a ServiceAccount

# BAD -- if any pod using this SA is compromised, the attacker has
# full cluster-admin access to the entire cluster
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: app-admin
subjects:
- kind: ServiceAccount
  name: default
  namespace: production
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin

Correct: Dedicated ServiceAccount with scoped Role

# GOOD -- dedicated SA with minimum permissions, namespace-scoped
apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp-sa
  namespace: production
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: myapp-binding
  namespace: production
subjects:
- kind: ServiceAccount
  name: myapp-sa
  namespace: production
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: myapp-role

Wrong: Using the default ServiceAccount

# BAD -- the default SA is shared by all pods in the namespace;
# any RBAC granted to it applies to every pod
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:latest

Correct: Dedicated ServiceAccount per workload

# GOOD -- each workload has its own SA with tailored permissions
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      serviceAccountName: myapp-sa
      automountServiceAccountToken: true
      containers:
      - name: myapp
        image: myapp:1.2.3

Wrong: Granting list/watch on secrets cluster-wide

# BAD -- list and watch on secrets exposes ALL secret values
# in plaintext, not just metadata
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: secret-viewer
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "watch"]

Correct: Scope secret access to specific names and namespaces

# GOOD -- access only specific secrets in one namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: app-secret-reader
  namespace: production
rules:
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["myapp-tls", "myapp-db-credentials"]
  verbs: ["get"]

Wrong: Granting escalate or bind verbs to non-admins

# BAD -- allows the subject to grant themselves any permission,
# effectively making them a cluster-admin
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: rbac-manager
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["roles", "clusterroles"]
  verbs: ["get", "list", "create", "update", "patch", "escalate"]
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["rolebindings", "clusterrolebindings"]
  verbs: ["get", "list", "create", "update", "patch", "bind"]

Correct: Restrict RBAC management to cluster admins

# GOOD -- only cluster-admin (via break-glass) should modify RBAC objects
# Regular users should request RBAC changes through GitOps/PR workflow
# Do NOT create custom roles with escalate/bind verbs

Common Pitfalls

Diagnostic Commands

# Check if a specific user/SA can perform an action
kubectl auth can-i get pods --as=jane -n production

# Check if a ServiceAccount can perform an action
kubectl auth can-i create deployments --as=system:serviceaccount:staging:cicd-deployer -n staging

# List all permissions for a subject in a namespace
kubectl auth can-i --list --as=system:serviceaccount:production:myapp-sa -n production

# List all Roles and RoleBindings in a namespace
kubectl get roles,rolebindings -n production

# List all ClusterRoles and ClusterRoleBindings
kubectl get clusterroles,clusterrolebindings

# Describe a specific Role to see its rules
kubectl describe role myapp-role -n production

# Find all bindings referencing cluster-admin
kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name=="cluster-admin") | .metadata.name'

# Audit: find all subjects with cluster-admin access
kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name=="cluster-admin") | {name: .metadata.name, subjects: .subjects}'

# Dry-run RBAC reconciliation (safe for CI/CD)
kubectl auth reconcile -f rbac-manifests/ --dry-run=server

# Check which API groups/resources are available
kubectl api-resources --verbs=list -o wide

Version History & Compatibility

VersionStatusBreaking ChangesMigration Notes
K8s 1.32+CurrentNo RBAC-specific changes--
K8s 1.30CurrentValidatingAdmissionPolicy GA -- supplements RBACUse VAP for complex admission rules beyond RBAC
K8s 1.24SupportedBoundServiceAccountTokenVolume GA; auto secret-based tokens removedTokens now auto-rotated via TokenRequest API
K8s 1.22Minimum recommendedrbac.authorization.k8s.io/v1beta1 REMOVEDUpdate all manifests to rbac.authorization.k8s.io/v1
K8s 1.8HistoricalRBAC promoted to GA (rbac.authorization.k8s.io/v1)--
K8s 1.6Historical (EOL)RBAC introduced as beta--

When to Use / When Not to Use

Use WhenDon't Use WhenUse Instead
Controlling who can access which Kubernetes API resourcesNeed network-level traffic control between podsNetworkPolicy
Restricting ServiceAccount permissions for workloadsNeed to enforce pod security constraints (no privileged, no hostPath)Pod Security Admission / Pod Security Standards
Granting namespace-scoped developer accessNeed complex conditional policies (e.g., "allow only images from approved registries")OPA/Gatekeeper or ValidatingAdmissionPolicy
Setting up CI/CD pipeline access to deployNeed to restrict API access based on source IP or time of dayAdmission webhooks or API server audit policies
Auditor read-only access across namespacesNeed data-level encryption or secret managementExternal secrets management (Vault, AWS Secrets Manager)

Important Caveats

Related Units