Module 1.6: RBAC - Role-Based Access Control
Complexity:
[MEDIUM]- Common exam topicTime to Complete: 40-50 minutes
Prerequisites: Module 1.1 (Control Plane), understanding of namespaces
What You’ll Be Able to Do
Section titled “What You’ll Be Able to Do”After this module, you will be able to:
- Configure Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings for least-privilege access
- Debug “forbidden” errors by tracing the RBAC chain (user → binding → role → permission)
- Design an RBAC scheme for a multi-team cluster with namespace isolation
- Audit existing RBAC rules to find overly permissive access (wildcard verbs, cluster-admin bindings)
Why This Module Matters
Section titled “Why This Module Matters”In a real cluster, you don’t want everyone to have admin access. Developers should deploy their apps but not delete production namespaces. CI/CD systems should manage deployments but not read secrets. Monitoring tools should read metrics but not modify resources.
RBAC (Role-Based Access Control) solves this. It’s how Kubernetes answers: “Who can do what to which resources?”
The CKA exam regularly tests RBAC. You’ll be asked to create Roles, ClusterRoles, and bind them to users or ServiceAccounts. Get comfortable with these concepts—they’re essential for security and daily operations.
The Security Guard Analogy
Think of RBAC like a building’s security system. A Role is like an access badge type—“Developer Badge” can access floors 2-3, “Admin Badge” can access all floors. A RoleBinding is giving someone a specific badge—“Alice gets a Developer Badge.” The security system (API server) checks the badge before allowing entry to any floor (resource).
What You’ll Learn
Section titled “What You’ll Learn”By the end of this module, you’ll be able to:
- Understand RBAC concepts (Roles, ClusterRoles, Bindings)
- Create Roles and ClusterRoles
- Bind roles to users, groups, and ServiceAccounts
- Test permissions with
kubectl auth can-i - Debug RBAC issues
Part 1: RBAC Concepts
Section titled “Part 1: RBAC Concepts”1.1 The Four RBAC Resources
Section titled “1.1 The Four RBAC Resources”| Resource | Scope | Purpose |
|---|---|---|
| Role | Namespace | Grants permissions within a namespace |
| ClusterRole | Cluster | Grants permissions cluster-wide |
| RoleBinding | Namespace | Binds Role/ClusterRole to subjects in a namespace |
| ClusterRoleBinding | Cluster | Binds ClusterRole to subjects cluster-wide |
1.2 How RBAC Works
Section titled “1.2 How RBAC Works”┌────────────────────────────────────────────────────────────────┐│ RBAC Flow ││ ││ Subject Role Resources ││ (Who?) (What permissions?) (Which things?) ││ ││ ┌─────────┐ ┌──────────────┐ ┌─────────────┐ ││ │ User │ │ Role │ │ pods │ ││ │ Alice │◄─────────►│ verbs: │─────►│ services │ ││ └─────────┘ Bound │ - get │ │ secrets │ ││ via │ - list │ └─────────────┘ ││ ┌─────────┐ Binding │ - create │ ││ │ Service │ └──────────────┘ ││ │ Account │ ││ └─────────┘ ││ ││ ┌─────────┐ ││ │ Group │ ││ └─────────┘ ││ │└────────────────────────────────────────────────────────────────┘1.3 Subjects: Who Gets Access
Section titled “1.3 Subjects: Who Gets Access”- User: Human identity (managed outside Kubernetes)
- Group: Collection of users
- ServiceAccount: Identity for pods/applications
1.4 Verbs: What Actions Are Allowed
Section titled “1.4 Verbs: What Actions Are Allowed”| Verb | Description |
|---|---|
get | Read a single resource |
list | List resources (get all) |
watch | Watch for changes |
create | Create new resources |
update | Modify existing resources |
patch | Partially modify resources |
delete | Delete resources |
deletecollection | Delete multiple resources |
Common verb groups:
- Read-only:
get,list,watch - Read-write:
get,list,watch,create,update,patch,delete - Full control:
*(all verbs)
Part 2: Roles and ClusterRoles
Section titled “Part 2: Roles and ClusterRoles”2.1 Creating a Role (Namespace-Scoped)
Section titled “2.1 Creating a Role (Namespace-Scoped)”apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: pod-reader namespace: defaultrules: - apiGroups: [""] # "" = core API group (pods, services, etc.) resources: ["pods"] verbs: ["get", "list", "watch"]# Apply the Rolekubectl apply -f role-pod-reader.yaml
# Or create imperativelykubectl create role pod-reader \ --verb=get,list,watch \ --resource=pods \ -n default2.2 Creating a ClusterRole (Cluster-Scoped)
Section titled “2.2 Creating a ClusterRole (Cluster-Scoped)”apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: node-readerrules: - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list", "watch"]# Applykubectl apply -f clusterrole-node-reader.yaml
# Or imperativelykubectl create clusterrole node-reader \ --verb=get,list,watch \ --resource=nodesPause and predict: You create a Role with
verbs: ["get", "list"]forresources: ["pods"]in namespacedev. Can the user with this Role see pods in theproductionnamespace? What about cluster-scoped resources like Nodes?
2.3 Multiple Rules
Section titled “2.3 Multiple Rules”apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: developer namespace: devrules: # Pods: full access - apiGroups: [""] resources: ["pods", "pods/log", "pods/exec"] verbs: ["*"]
# Deployments: full access - apiGroups: ["apps"] resources: ["deployments", "replicasets"] verbs: ["*"]
# Services: create and view - apiGroups: [""] resources: ["services"] verbs: ["get", "list", "create", "delete"]
# ConfigMaps: read only - apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list"]
# Secrets: no access (not listed = denied)2.4 API Groups Reference
Section titled “2.4 API Groups Reference”| API Group | Resources |
|---|---|
"" (core) | pods, services, configmaps, secrets, namespaces, nodes, persistentvolumes |
apps | deployments, replicasets, statefulsets, daemonsets |
batch | jobs, cronjobs |
networking.k8s.io | networkpolicies, ingresses |
rbac.authorization.k8s.io | roles, clusterroles, rolebindings, clusterrolebindings |
storage.k8s.io | storageclasses, volumeattachments |
# Find the API group for any resourcekubectl api-resources | grep deployment# NAME SHORTNAMES APIVERSION NAMESPACED KIND# deployments deploy apps/v1 true Deployment# ^^^^# API group is "apps"Gotcha: Core API Group
The core API group is an empty string
"". Resources like pods, services, configmaps useapiGroups: [""], notapiGroups: ["core"].
Part 3: RoleBindings and ClusterRoleBindings
Section titled “Part 3: RoleBindings and ClusterRoleBindings”3.1 RoleBinding (Namespace-Scoped)
Section titled “3.1 RoleBinding (Namespace-Scoped)”Binds a Role or ClusterRole to subjects within a namespace:
apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: alice-pod-reader namespace: defaultsubjects: - kind: User name: alice apiGroup: rbac.authorization.k8s.ioroleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io# Imperative commandkubectl create rolebinding alice-pod-reader \ --role=pod-reader \ --user=alice \ -n default3.2 ClusterRoleBinding (Cluster-Scoped)
Section titled “3.2 ClusterRoleBinding (Cluster-Scoped)”Binds a ClusterRole to subjects cluster-wide:
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: bob-node-readersubjects: - kind: User name: bob apiGroup: rbac.authorization.k8s.ioroleRef: kind: ClusterRole name: node-reader apiGroup: rbac.authorization.k8s.io# Imperative commandkubectl create clusterrolebinding bob-node-reader \ --clusterrole=node-reader \ --user=bob3.3 Binding to Multiple Subjects
Section titled “3.3 Binding to Multiple Subjects”apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: dev-team-access namespace: developmentsubjects: # Bind to a user - kind: User name: alice apiGroup: rbac.authorization.k8s.io
# Bind to a group - kind: Group name: developers apiGroup: rbac.authorization.k8s.io
# Bind to a ServiceAccount - kind: ServiceAccount name: cicd-deployer namespace: developmentroleRef: kind: Role name: developer apiGroup: rbac.authorization.k8s.ioStop and think: You need to give a developer read-only access to pods in the
stagingnamespace but notproduction. Would you use a Role or ClusterRole? Would you use a RoleBinding or ClusterRoleBinding? There’s more than one correct answer — think about which approach is most reusable.
3.4 Using ClusterRole in RoleBinding
Section titled “3.4 Using ClusterRole in RoleBinding”A powerful pattern: define a ClusterRole once, bind it in specific namespaces:
# Use the built-in "edit" ClusterRole in the "production" namespace onlyapiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: alice-edit-production namespace: productionsubjects: - kind: User name: alice apiGroup: rbac.authorization.k8s.ioroleRef: kind: ClusterRole # Using ClusterRole name: edit # Built-in ClusterRole apiGroup: rbac.authorization.k8s.io
# Alice can edit resources in "production" namespace onlyPart 4: ServiceAccounts
Section titled “Part 4: ServiceAccounts”4.1 What Are ServiceAccounts?
Section titled “4.1 What Are ServiceAccounts?”ServiceAccounts provide identity for pods. When a pod runs, it can use its ServiceAccount’s permissions to talk to the API server.
# List ServiceAccountskubectl get serviceaccountskubectl get sa
# Every namespace has a "default" ServiceAccountkubectl get sa default -o yaml4.2 Creating a ServiceAccount
Section titled “4.2 Creating a ServiceAccount”# Create a ServiceAccountkubectl create serviceaccount myapp-sa
# Or with YAMLcat > myapp-sa.yaml << 'EOF'apiVersion: v1kind: ServiceAccountmetadata: name: myapp-sa namespace: defaultEOFkubectl apply -f myapp-sa.yaml4.3 Binding Roles to ServiceAccounts
Section titled “4.3 Binding Roles to ServiceAccounts”# Create a Rolekubectl create role pod-reader \ --verb=get,list,watch \ --resource=pods
# Bind it to the ServiceAccountkubectl create rolebinding myapp-pod-reader \ --role=pod-reader \ --serviceaccount=default:myapp-sa# ^^^^^^^^^^^^^^^^^# namespace:name format4.4 Using ServiceAccount in a Pod
Section titled “4.4 Using ServiceAccount in a Pod”apiVersion: v1kind: Podmetadata: name: myappspec: serviceAccountName: myapp-sa # Use this ServiceAccount containers: - name: myapp image: nginxThe pod now has the permissions granted to myapp-sa.
Did You Know?
By default, pods use the
defaultServiceAccount in their namespace. This account typically has no permissions. Always create dedicated ServiceAccounts with minimal required permissions.
Part 5: Built-in ClusterRoles
Section titled “Part 5: Built-in ClusterRoles”Kubernetes comes with useful ClusterRoles:
| ClusterRole | Permissions |
|---|---|
cluster-admin | Full access to everything (superuser) |
admin | Full access within a namespace |
edit | Read/write most resources, no RBAC |
view | Read-only access to most resources |
# See all built-in ClusterRoleskubectl get clusterroles | grep -v "^system:"
# Inspect a ClusterRolekubectl describe clusterrole editUsing Built-in ClusterRoles
Section titled “Using Built-in ClusterRoles”# Give alice admin access to namespace "myapp"kubectl create rolebinding alice-admin \ --clusterrole=admin \ --user=alice \ -n myapp
# Give bob view access to namespace "production"kubectl create rolebinding bob-view \ --clusterrole=view \ --user=bob \ -n productionPart 6: Testing Permissions
Section titled “Part 6: Testing Permissions”What would happen if: You create two RoleBindings in the same namespace — one grants a user
geton pods, the other grantsdeleteon pods. Does the user get both permissions, or does one override the other? What if you wanted to explicitly denydelete?
6.1 kubectl auth can-i
Section titled “6.1 kubectl auth can-i”Check if you (or someone else) can perform an action:
# Check your own permissionskubectl auth can-i create podskubectl auth can-i delete deploymentskubectl auth can-i '*' '*' # Am I admin?
# Check in a specific namespacekubectl auth can-i create pods -n production
# Check for another user (requires admin)kubectl auth can-i create pods --as=alicekubectl auth can-i delete nodes --as=bob
# Check for a ServiceAccountkubectl auth can-i list secrets --as=system:serviceaccount:default:myapp-sa6.2 List All Permissions
Section titled “6.2 List All Permissions”# What can I do in this namespace?kubectl auth can-i --list
# What can alice do?kubectl auth can-i --list --as=alice
# What can a ServiceAccount do?kubectl auth can-i --list --as=system:serviceaccount:default:myapp-sa6.3 Debugging Permission Denied
Section titled “6.3 Debugging Permission Denied”# Error: pods is forbiddenkubectl get pods# Error: User "alice" cannot list resource "pods" in API group "" in namespace "default"
# Debug steps:# 1. Check what permissions the user haskubectl auth can-i --list --as=alice
# 2. Check what roles are bound to the userkubectl get rolebindings -A -o wide | grep alicekubectl get clusterrolebindings -o wide | grep alice
# 3. Check the role's ruleskubectl describe role <role-name> -n <namespace>kubectl describe clusterrole <clusterrole-name>War Story: The 403 Mystery
An engineer spent hours debugging why their CI/CD pipeline couldn’t deploy.
kubectl auth can-ishowed permissions were correct. The issue? The ServiceAccount was in namespacecicd, but the RoleBinding was in namespaceproductionwith a typo:namespace: prduction. One missing letter, hours of debugging. Always double-check namespaces in bindings.
Part 7: Common RBAC Patterns
Section titled “Part 7: Common RBAC Patterns”7.1 Developer Access
Section titled “7.1 Developer Access”# Create namespacekubectl create namespace development
# Create ServiceAccountkubectl create serviceaccount developer -n development
# Bind edit ClusterRole (read/write most resources)kubectl create rolebinding developer-edit \ --clusterrole=edit \ --serviceaccount=development:developer \ -n development7.2 Read-Only Monitoring
Section titled “7.2 Read-Only Monitoring”# ServiceAccount for monitoring toolskubectl create serviceaccount monitoring -n monitoring
# Cluster-wide read accesskubectl create clusterrolebinding monitoring-view \ --clusterrole=view \ --serviceaccount=monitoring:monitoring7.3 CI/CD Deployer
Section titled “7.3 CI/CD Deployer”# Create role for deployments onlykubectl create role deployer \ --verb=get,list,watch,create,update,patch,delete \ --resource=deployments,services,configmaps \ -n production
# Bind to CI/CD ServiceAccountkubectl create rolebinding cicd-deployer \ --role=deployer \ --serviceaccount=cicd:pipeline \ -n productionPart 8: Exam Scenarios
Section titled “Part 8: Exam Scenarios”8.1 Quick RBAC Creation
Section titled “8.1 Quick RBAC Creation”# Task: Create a Role that can get, list, and watch pods and services in namespace "app"
kubectl create role app-reader \ --verb=get,list,watch \ --resource=pods,services \ -n app
# Task: Bind the role to user "john"
kubectl create rolebinding john-app-reader \ --role=app-reader \ --user=john \ -n app
# Verifykubectl auth can-i get pods -n app --as=john# yeskubectl auth can-i delete pods -n app --as=john# no8.2 ServiceAccount with Cluster Access
Section titled “8.2 ServiceAccount with Cluster Access”# Task: Create ServiceAccount "dashboard" that can list pods across all namespaces
kubectl create serviceaccount dashboard -n kube-system
kubectl create clusterrole pod-list \ --verb=list \ --resource=pods
kubectl create clusterrolebinding dashboard-pod-list \ --clusterrole=pod-list \ --serviceaccount=kube-system:dashboardDid You Know?
Section titled “Did You Know?”-
RBAC is additive. There’s no “deny” rule. If any Role grants a permission, it’s allowed. You can’t explicitly block access—you can only not grant it.
-
Aggregated ClusterRoles let you combine multiple ClusterRoles. The built-in
admin,edit, andviewroles are aggregated—additional rules can be added to them. -
system: ClusterRoles* are for internal Kubernetes components. Don’t modify them unless you know what you’re doing.
Common Mistakes
Section titled “Common Mistakes”| Mistake | Problem | Solution |
|---|---|---|
| Wrong apiGroup | Role doesn’t grant access | Check kubectl api-resources for correct group |
| Missing namespace in binding | Wrong permissions | Always verify -n namespace |
| Forgetting ServiceAccount namespace | Binding doesn’t work | Use namespace:name format |
| Using Role for cluster resources | Can’t access nodes, PVs | Use ClusterRole for cluster-scoped resources |
| Empty apiGroup not quoted | YAML error | Use apiGroups: [""] with quotes |
Missing create verb on exec/attach subresources | kubectl exec silently fails (K8s 1.35+) | Add create verb to pods/exec, pods/attach, pods/portforward — see note below |
K8s 1.35 Breaking Change: WebSocket Streaming RBAC
Starting in Kubernetes 1.35,
kubectl exec,attach, andport-forwarduse WebSocket connections that require thecreateverb on the relevant subresource (e.g.,pods/exec). Previously, onlygetwas needed. Existing RBAC policies that grantget pods/execwill silently fail — commands hang or return permission errors. Audit your ClusterRoles and Roles:# OLD (broken in 1.35+):- resources: ["pods/exec"]verbs: ["get"]# FIXED:- resources: ["pods/exec", "pods/attach", "pods/portforward"]verbs: ["get", "create"]
-
Your company has 5 development teams, each with their own namespace. All teams need the same set of permissions: read/write Deployments, Services, and ConfigMaps but no access to Secrets. You could create 5 separate Roles (one per namespace) or use a different approach. What’s the most maintainable way to set this up, and why?
Answer
Create a single ClusterRole with the desired permissions, then create a RoleBinding in each team's namespace that references that ClusterRole. When you bind a ClusterRole with a RoleBinding, the permissions are scoped to that namespace only. This way, if permissions need to change (e.g., adding `pods/log` access), you update one ClusterRole instead of five Roles. The commands would be: `kubectl create clusterrole team-developer --verb=get,list,watch,create,update,delete --resource=deployments,services,configmaps` followed by `kubectl create rolebinding team-dev --clusterrole=team-developer --group=team-alpha -n alpha-ns` for each namespace. This is the standard pattern used by the built-in `edit` and `view` ClusterRoles. -
A CI/CD pipeline ServiceAccount in the
cicdnamespace needs to deploy applications to theproductionnamespace. The team creates a Role inproductionand a RoleBinding, butkubectl auth can-i create deployments -n production --as=system:serviceaccount:cicd:pipelinereturns “no.” The Role and RoleBinding YAML look correct. What’s the most likely mistake?Answer
The most likely mistake is in the RoleBinding's `subjects` section. When binding to a ServiceAccount from a different namespace, you must specify the ServiceAccount's namespace in the subject: `namespace: cicd`. A common error is omitting the namespace field or setting it to `production` (the RoleBinding's namespace) instead of `cicd` (where the ServiceAccount lives). The correct subject should be: `kind: ServiceAccount, name: pipeline, namespace: cicd`. Another possibility is the Role's `apiGroups` field — Deployments are in the `apps` group, not the core group. Check with `kubectl get rolebinding -n production -o yaml` and verify both the subject namespace and the role's apiGroups match `["apps"]` for deployments. -
During a security audit, you find a ClusterRoleBinding that grants
cluster-adminto a ServiceAccount calledmonitoringin themonitoringnamespace. The monitoring tool only needs to read pod metrics across all namespaces. Why is this dangerous, and what’s the least-privilege replacement?Answer
`cluster-admin` grants unrestricted access to everything in the cluster — create, delete, and modify any resource in any namespace, including Secrets, RBAC rules, and even the ability to escalate its own privileges. If the monitoring pod is compromised, an attacker gains full cluster control. The least-privilege replacement is to create a ClusterRole with only the read permissions needed: `kubectl create clusterrole monitoring-reader --verb=get,list,watch --resource=pods,nodes,namespaces` and bind it with a ClusterRoleBinding. If the tool needs metrics specifically, add `pods/metrics` or `nodes/metrics` resources. The principle is: RBAC is additive (there's no "deny"), so grant only what's needed. Audit regularly with `kubectl auth can-i --list --as=system:serviceaccount:monitoring:monitoring` to verify permissions are minimal. -
A developer runs
kubectl exec -it my-pod -- bashin thedevnamespace and gets “forbidden.” You check their Role and see it grants["get", "list", "watch"]on["pods", "pods/exec"]. On a Kubernetes 1.34 cluster this worked fine, but after upgrading to 1.35 it broke. What changed and how do you fix it?Answer
Starting in Kubernetes 1.35, `kubectl exec`, `attach`, and `port-forward` use WebSocket connections that require the `create` verb on the relevant subresource. Previously, only `get` was needed for `pods/exec`. The fix is to add the `create` verb to the Role rule for subresources: update the rule to `verbs: ["get", "create"]` for `resources: ["pods/exec", "pods/attach", "pods/portforward"]`. This is a breaking change that affects any existing RBAC policies relying on the old `get`-only pattern. Audit all Roles and ClusterRoles that reference `pods/exec` by running `kubectl get roles,clusterroles -A -o yaml | grep -B5 "pods/exec"` to find and update them all.
Hands-On Exercise
Section titled “Hands-On Exercise”Task: Set up RBAC for a development team.
Steps:
- Create a namespace:
kubectl create namespace dev-team- Create a ServiceAccount:
kubectl create serviceaccount dev-sa -n dev-team- Create a Role for developers:
kubectl create role developer \ --verb=get,list,watch,create,update,delete \ --resource=pods,deployments,services,configmaps \ -n dev-team- Bind the Role to the ServiceAccount:
kubectl create rolebinding dev-sa-developer \ --role=developer \ --serviceaccount=dev-team:dev-sa \ -n dev-team- Test the permissions:
# Test as the ServiceAccountkubectl auth can-i get pods -n dev-team \ --as=system:serviceaccount:dev-team:dev-sa# yes
kubectl auth can-i delete pods -n dev-team \ --as=system:serviceaccount:dev-team:dev-sa# yes
kubectl auth can-i get secrets -n dev-team \ --as=system:serviceaccount:dev-team:dev-sa# no (we didn't grant access to secrets)
kubectl auth can-i get pods -n default \ --as=system:serviceaccount:dev-team:dev-sa# no (role only applies in dev-team namespace)- Create a pod using the ServiceAccount:
cat > dev-pod.yaml << 'EOF'apiVersion: v1kind: Podmetadata: name: dev-shell namespace: dev-teamspec: serviceAccountName: dev-sa containers: - name: shell image: bitnami/kubectl command: ["sleep", "infinity"]EOF
kubectl apply -f dev-pod.yaml- Test from inside the pod:
kubectl exec -it dev-shell -n dev-team -- /bin/bash
# Inside the pod:kubectl get pods # Should workkubectl get secrets # Should fail (forbidden)kubectl get pods -n default # Should fail (forbidden)exit- Add read-only cluster access (bonus):
kubectl create clusterrolebinding dev-sa-view \ --clusterrole=view \ --serviceaccount=dev-team:dev-sa
# Now the ServiceAccount can read resources cluster-widekubectl auth can-i get pods -n default \ --as=system:serviceaccount:dev-team:dev-sa# yes (but read-only)- Cleanup:
kubectl delete namespace dev-teamkubectl delete clusterrolebinding dev-sa-viewrm dev-pod.yamlSuccess Criteria:
- Can create Roles and ClusterRoles
- Can create RoleBindings and ClusterRoleBindings
- Can bind to Users, Groups, and ServiceAccounts
- Can test permissions with
kubectl auth can-i - Understand namespace vs cluster scope
Practice Drills
Section titled “Practice Drills”Drill 1: RBAC Speed Test (Target: 3 minutes)
Section titled “Drill 1: RBAC Speed Test (Target: 3 minutes)”Create RBAC resources as fast as possible:
# Create namespacekubectl create ns rbac-drill
# Create ServiceAccountkubectl create sa drill-sa -n rbac-drill
# Create Role (read pods)kubectl create role pod-reader --verb=get,list,watch --resource=pods -n rbac-drill
# Create RoleBindingkubectl create rolebinding drill-binding --role=pod-reader --serviceaccount=rbac-drill:drill-sa -n rbac-drill
# Testkubectl auth can-i get pods -n rbac-drill --as=system:serviceaccount:rbac-drill:drill-sa
# Cleanupkubectl delete ns rbac-drillDrill 2: Permission Testing (Target: 5 minutes)
Section titled “Drill 2: Permission Testing (Target: 5 minutes)”kubectl create ns perm-testkubectl create sa test-sa -n perm-test
# Create limited rolekubectl create role limited --verb=get,list --resource=pods,services -n perm-testkubectl create rolebinding limited-binding --role=limited --serviceaccount=perm-test:test-sa -n perm-test
# Test various permissionsecho "=== Testing as test-sa ==="kubectl auth can-i get pods -n perm-test --as=system:serviceaccount:perm-test:test-sa # yeskubectl auth can-i create pods -n perm-test --as=system:serviceaccount:perm-test:test-sa # nokubectl auth can-i get secrets -n perm-test --as=system:serviceaccount:perm-test:test-sa # nokubectl auth can-i get pods -n default --as=system:serviceaccount:perm-test:test-sa # nokubectl auth can-i get services -n perm-test --as=system:serviceaccount:perm-test:test-sa # yes
# Cleanupkubectl delete ns perm-testDrill 3: ClusterRole vs Role (Target: 5 minutes)
Section titled “Drill 3: ClusterRole vs Role (Target: 5 minutes)”# Create namespaceskubectl create ns ns-akubectl create ns ns-bkubectl create sa cross-ns-sa -n ns-a
# Option 1: Role (namespace-scoped) - only works in ns-akubectl create role ns-a-reader --verb=get,list --resource=pods -n ns-akubectl create rolebinding ns-a-binding --role=ns-a-reader --serviceaccount=ns-a:cross-ns-sa -n ns-a
# Testkubectl auth can-i get pods -n ns-a --as=system:serviceaccount:ns-a:cross-ns-sa # yeskubectl auth can-i get pods -n ns-b --as=system:serviceaccount:ns-a:cross-ns-sa # no
# Option 2: ClusterRole + RoleBinding (still namespace-scoped binding)kubectl create clusterrole pod-reader-cluster --verb=get,list --resource=podskubectl create rolebinding ns-b-binding -n ns-b --clusterrole=pod-reader-cluster --serviceaccount=ns-a:cross-ns-sa
# Now can read ns-b tookubectl auth can-i get pods -n ns-b --as=system:serviceaccount:ns-a:cross-ns-sa # yes
# Cleanupkubectl delete ns ns-a ns-bkubectl delete clusterrole pod-reader-clusterDrill 4: Troubleshooting - Permission Denied (Target: 5 minutes)
Section titled “Drill 4: Troubleshooting - Permission Denied (Target: 5 minutes)”# Setup: Create SA with intentionally wrong bindingkubectl create ns debug-rbackubectl create sa debug-sa -n debug-rbackubectl create role secret-reader --verb=get,list --resource=secrets -n debug-rbac# WRONG: binding role to different SA namekubectl create rolebinding wrong-binding --role=secret-reader --serviceaccount=debug-rbac:other-sa -n debug-rbac
# User reports: "I can't read secrets!"kubectl auth can-i get secrets -n debug-rbac --as=system:serviceaccount:debug-rbac:debug-sa# no
# YOUR TASK: Diagnose and fixSolution
# Check what the rolebinding referenceskubectl get rolebinding wrong-binding -n debug-rbac -o yaml | grep -A5 subjects# Shows: other-sa, not debug-sa
# Fix: Create correct bindingkubectl delete rolebinding wrong-binding -n debug-rbackubectl create rolebinding correct-binding --role=secret-reader --serviceaccount=debug-rbac:debug-sa -n debug-rbac
# Verifykubectl auth can-i get secrets -n debug-rbac --as=system:serviceaccount:debug-rbac:debug-sa# yes
# Cleanupkubectl delete ns debug-rbacDrill 5: Aggregate ClusterRoles (Target: 5 minutes)
Section titled “Drill 5: Aggregate ClusterRoles (Target: 5 minutes)”# Create aggregated rolecat << 'EOF' | kubectl apply -f -apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: aggregate-reader labels: rbac.authorization.k8s.io/aggregate-to-view: "true"rules: - apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list"]EOF
# The built-in 'view' ClusterRole automatically includes rules from# any ClusterRole with label aggregate-to-view: "true"
# Check what 'view' includeskubectl get clusterrole view -o yaml | grep -A20 "rules:"
# Cleanupkubectl delete clusterrole aggregate-readerDrill 6: RBAC for User (Target: 5 minutes)
Section titled “Drill 6: RBAC for User (Target: 5 minutes)”# Create role for hypothetical user "alice"kubectl create ns alice-nskubectl create role alice-admin --verb='*' --resource='*' -n alice-nskubectl create rolebinding alice-is-admin --role=alice-admin --user=alice -n alice-ns
# Test as alicekubectl auth can-i create deployments -n alice-ns --as=alice # yeskubectl auth can-i delete pods -n alice-ns --as=alice # yeskubectl auth can-i get secrets -n default --as=alice # no (different ns)kubectl auth can-i create namespaces --as=alice # no (cluster scope)
# List what alice can dokubectl auth can-i --list -n alice-ns --as=alice
# Cleanupkubectl delete ns alice-nsDrill 7: Challenge - Least Privilege Setup
Section titled “Drill 7: Challenge - Least Privilege Setup”Create RBAC for a “deployment-manager” that can:
- Create, update, delete Deployments in namespace
app - View (but not modify) Services in namespace
app - View Pods in any namespace (read-only cluster-wide)
kubectl create ns app# YOUR TASK: Create the necessary Role, ClusterRole, and bindingsSolution
# Role for deployment management in 'app' namespacekubectl create role deployment-manager \ --verb=create,update,delete,get,list,watch \ --resource=deployments \ -n app
# Role for service viewing in 'app' namespacekubectl create role service-viewer \ --verb=get,list,watch \ --resource=services \ -n app
# ClusterRole for cluster-wide pod viewingkubectl create clusterrole pod-viewer \ --verb=get,list,watch \ --resource=pods
# Create ServiceAccountkubectl create sa deployment-manager -n app
# Bind all roleskubectl create rolebinding dm-deployments \ --role=deployment-manager \ --serviceaccount=app:deployment-manager \ -n app
kubectl create rolebinding dm-services \ --role=service-viewer \ --serviceaccount=app:deployment-manager \ -n app
kubectl create clusterrolebinding dm-pods \ --clusterrole=pod-viewer \ --serviceaccount=app:deployment-manager
# Testkubectl auth can-i create deployments -n app --as=system:serviceaccount:app:deployment-manager # yeskubectl auth can-i delete services -n app --as=system:serviceaccount:app:deployment-manager # nokubectl auth can-i get pods -n default --as=system:serviceaccount:app:deployment-manager # yes
# Cleanupkubectl delete ns appkubectl delete clusterrole pod-viewerkubectl delete clusterrolebinding dm-podsNext Module
Section titled “Next Module”Module 1.7: kubeadm Basics - Cluster bootstrap and node management.