Kubernetes RBAC

Role-Based Access Control (RBAC) is the modern standard for Kubernetes authorization. It replaces legacy ABAC with four declarative API objects — Role, ClusterRole, RoleBinding, and ClusterRoleBinding — that grant fine-grained permissions to users, groups, and ServiceAccounts. Source: CKA Day 22 Source: CKA Day 23 Source: CKA Day 24 Source: CKA Day 25

The Four RBAC Objects

ObjectScopePurpose
RoleNamespaceDefines a set of permissions (rules) within a single Namespace
ClusterRoleCluster-wideDefines a set of permissions across all Namespaces or on cluster-scoped resources
RoleBindingNamespaceBinds a Role (or ClusterRole) to subjects within a single Namespace
ClusterRoleBindingCluster-wideBinds a ClusterRole to subjects across the entire cluster

A critical distinction: ClusterRoles can be bound with RoleBindings to grant cluster-level permissions inside a single Namespace. However, Roles cannot be bound with ClusterRoleBindings — a ClusterRoleBinding requires a ClusterRole.

YAML Anatomy

Role

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

ClusterRole

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

RoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: devops
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

Important: roleRef is immutable after creation. To change the bound Role, you must delete and recreate the Binding. Source: CKA Day 22

Rules: Verbs, Resources, and apiGroups

Each rule is a triple of (apiGroups, resources, verbs):

FieldDescriptionExamples
apiGroupsThe API group of the resource"" for core, "apps" for Deployments, "networking.k8s.io" for Ingress
resourcesThe plural resource namepods, services, deployments, secrets, configmaps
verbsThe allowed actionsget, list, watch, create, update, patch, delete, deletecollection
resourceNamesOptional: restrict to specific named instances["my-pod", "my-secret"]

API Groups: Core vs Named — Every Kubernetes resource belongs to an API group. The “core” group (e.g., v1 for Pods, Services, ConfigMaps) has no group suffix and is referenced in RBAC rules as "" (empty string). Named groups include apps (Deployments, ReplicaSets), rbac.authorization.k8s.io (Roles, Bindings), networking.k8s.io (Ingress, NetworkPolicies), and batch (Jobs, CronJobs). When writing a Role, always specify the correct apiGroups field — a blank value targets only core resources, not Deployments or other named-group objects. Source: CKA Day 23

Wildcard caution: verbs: ["*"] and resources: ["*"] grant broad permissions. In production, enumerate exact verbs and resources.

Subjects: Who Gets Access

A subject can be one of three kinds:

KindExampleUse Case
Username: aliceHuman operators authenticated via client certs or OIDC
Groupname: developersOIDC groups or certificate Organization fields
ServiceAccountname: prometheus, namespace: monitoringIn-cluster workloads that call the API server

ServiceAccount namespace trap: When binding a ServiceAccount, you must specify its Namespace in the subjects block, even if the Binding is in the same Namespace. Source: CKA Day 22

Built-in ClusterRoles

Kubernetes ships with several default ClusterRoles:

ClusterRolePurpose
cluster-adminFull control over every resource in the cluster
adminFull control within a Namespace, including RBAC management
editRead/write access to most namespace resources (cannot manage RBAC)
viewRead-only access to most namespace resources

These are designed to be bound with RoleBindings for namespace-level delegation or ClusterRoleBindings for cluster-wide access.

Namespace-Scoped vs Cluster-Scoped Resources

ScopeExamplesRBAC Object
Namespace-scopedPods, Services, ConfigMaps, Secrets, DeploymentsRole + RoleBinding
Cluster-scopedNodes, PersistentVolumes, ClusterRoles, Namespaces themselvesClusterRole + ClusterRoleBinding

A common CKA exam pattern: granting a user the ability to create Namespaces requires a ClusterRole with create on namespaces, bound via ClusterRoleBinding. Source: CKA Day 22

ClusterRole Deep-Dive

Non-Resource URLs

ClusterRoles uniquely support permissions on API server paths that do not map to Kubernetes objects. This is essential for health probes and metrics scraping:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: health-monitor
rules:
- nonResourceURLs: ["/healthz", "/livez", "/readyz", "/metrics"]
  verbs: ["get"]

Important: nonResourceURLs can only appear in ClusterRoles, not Roles. They are typically bound with ClusterRoleBindings to monitoring ServiceAccounts. Source: CKA Day 24

ClusterRole Aggregation Rules

Kubernetes supports aggregated ClusterRoles that dynamically combine rules from other ClusterRoles matching a label selector. This is how the built-in admin, edit, and view roles are composed:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: aggregated-monitoring
  labels:
    rbac.example.com/aggregate-to-monitoring: "true"
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      rbac.example.com/aggregate-to-monitoring: "true"
rules: []  # Populated automatically by the controller

Any ClusterRole with the matching label will have its rules merged into the aggregated role. This pattern is used by Helm charts and operators to extend default roles without modifying them. Source: CKA Day 24

The RoleBinding + ClusterRole Pattern

The most flexible and DRY pattern in Kubernetes RBAC is binding a ClusterRole with a RoleBinding. This grants cluster-level permissions (as defined in the ClusterRole) but restricts them to a single Namespace:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-edit
  namespace: dev
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: edit
  apiGroup: rbac.authorization.k8s.io
PatternBindingRole TypeScope of Permissions
Role + RoleBindingRoleBindingRoleOne Namespace
ClusterRole + RoleBindingRoleBindingClusterRoleOne Namespace (the Binding’s namespace)
ClusterRole + ClusterRoleBindingClusterRoleBindingClusterRoleEntire cluster

Production use case: Define team permissions once in a custom ClusterRole, then create a RoleBinding in each team’s Namespace. This avoids duplicating Role YAML across namespaces while maintaining isolation. Source: CKA Day 24

Critical restriction: A RoleBinding can reference a ClusterRole, but a ClusterRoleBinding cannot reference a Role. ClusterRoleBindings always require ClusterRoles.

Imperative RBAC Generation

For exam speed, generate roles and bindings without hand-editing YAML:

Namespace-Scoped (Role + RoleBinding)

# Create a Role imperatively
kubectl create role pod-reader --verb=get,list,watch --resource=pods --dry-run=client -o yaml
 
# Create a RoleBinding imperatively
kubectl create rolebinding read-pods --role=pod-reader --user=krishna --dry-run=client -o yaml
 
# Bind a ClusterRole to a namespace (common for admin/edit/view delegation)
kubectl create rolebinding dev-edit --clusterrole=edit --user=dev1 --namespace=default --dry-run=client -o yaml

Cluster-Scoped (ClusterRole + ClusterRoleBinding)

# Create a ClusterRole imperatively
kubectl create clusterrole node-reader --verb=get,list --resource=nodes --dry-run=client -o yaml
 
# Create a ClusterRoleBinding imperatively
kubectl create clusterrolebinding node-reader-binding --clusterrole=node-reader --user=alice --dry-run=client -o yaml
 
# Grant cluster-admin globally
kubectl create clusterrolebinding alice-admin --clusterrole=cluster-admin --user=alice --dry-run=client -o yaml

Exam trap: kubectl create rolebinding requires --role for Roles and --clusterrole for ClusterRoles. Mixing them produces an invalid binding. Similarly, kubectl create clusterrolebinding only accepts --clusterrole; using --role errors because ClusterRoleBindings must reference ClusterRoles. Source: CKA Day 23 Source: CKA Day 24

Testing and Debugging Permissions

kubectl auth can-i

The fastest way to verify RBAC without switching users is impersonation:

# Check if user "krishna" can get pods in a namespace
kubectl auth can-i get pods --as krishna --namespace default
 
# Check if user can create deployments (useful after editing a Role)
kubectl auth can-i create deployments --as krishna --namespace default
 
# Check cluster-scoped permissions (omit --namespace for cluster-wide resources)
kubectl auth can-i list nodes --as alice
kubectl auth can-i get persistentvolumes --as alice
kubectl auth can-i create namespaces --as alice
 
# List all permissions for the current user
kubectl auth can-i --list
 
# List all permissions for a specific user
kubectl auth can-i --list --as alice

Cluster admin advantage: Users with impersonate rights (e.g., cluster-admin) can test any user’s permissions without logging in as them. This is the standard CKA exam debugging pattern. For cluster-scoped checks, omit the --namespace flag to verify true cluster-wide access. Source: CKA Day 23 Source: CKA Day 24

Counting RBAC Objects (Exam Task Pattern)

When the exam asks “how many roles exist in the cluster?”, suppress headers and count lines:

kubectl get roles --no-headers --all-namespaces | wc -l
kubectl get rolebindings --no-headers --all-namespaces | wc -l

Inspecting Role and Binding Details

# Describe a Role to see its rules
kubectl describe role pod-reader --namespace default
 
# Describe a RoleBinding to see which subjects are bound
kubectl describe rolebinding read-pods --namespace default
 
# List all bindings referencing a specific role
kubectl get rolebindings -o json | jq '.items[] | select(.roleRef.name=="pod-reader")'

CKA Speed Patterns

Namespace-Scoped

  • Generate manifest: kubectl create role pod-reader --verb=get,list,watch --resource=pods --dry-run=client -o yaml
  • Generate binding: kubectl create rolebinding read-pods --role=pod-reader --user=jane --dry-run=client -o yaml
  • Test permissions: kubectl auth can-i create deployments --as jane --namespace default
  • List bindings for a role: kubectl get rolebindings -o json | jq '.items[] | select(.roleRef.name=="pod-reader")'

Cluster-Scoped

  • Generate ClusterRole: kubectl create clusterrole node-reader --verb=get,list --resource=nodes --dry-run=client -o yaml
  • Generate ClusterRoleBinding: kubectl create clusterrolebinding alice-nodes --clusterrole=node-reader --user=alice --dry-run=client -o yaml
  • Test cluster permissions: kubectl auth can-i list nodes --as alice
  • Count cluster roles: kubectl get clusterroles --no-headers | wc -l
  • Count cluster bindings: kubectl get clusterrolebindings --no-headers | wc -l
  • Inspect built-in ClusterRole: kubectl describe clusterrole view

Practical Practice

Exam-style hands-on tasks for this topic. Complete each task before reviewing the solution. Time yourself — CKA tasks average 5–7 minutes.

Task 1: Create a Namespace-Scoped Role You are asked to create a Role named pod-reader in namespace dev with permissions to get, list, and watch Pods. Requirements: Use imperative generation; target only core resources. Verification: kubectl describe role pod-reader -n dev Solution:

kubectl create role pod-reader --verb=get,list,watch --resource=pods -n dev --dry-run=client -o yaml | kubectl apply -f -

Task 2: Bind a Role to a User You are asked to bind the Role pod-reader in namespace dev to user jane. Requirements: Create a RoleBinding named jane-pod-reader. Verification: kubectl auth can-i get pods --as jane --namespace dev Solution:

kubectl create rolebinding jane-pod-reader --role=pod-reader --user=jane -n dev --dry-run=client -o yaml | kubectl apply -f -
kubectl auth can-i get pods --as jane --namespace dev

Task 3: Create a ClusterRole for Nodes You are asked to create a ClusterRole named node-reader with permissions to get and list nodes. Requirements: Must be cluster-scoped. Verification: kubectl describe clusterrole node-reader Solution:

kubectl create clusterrole node-reader --verb=get,list --resource=nodes --dry-run=client -o yaml | kubectl apply -f -

Task 4: Test Permissions with Impersonation You are asked to verify whether user jane can create Deployments in namespace dev. Requirements: Do not log in as jane; use impersonation. Verification: Command should return no (or yes if granted). Solution:

kubectl auth can-i create deployments --as jane --namespace dev

Tags: kubernetes rbac security authorization cka role clusterrole rolebinding devsecops