- Authors
- Name
- 1. What Is RBAC?
- 2. Role and ClusterRole in Detail
- 3. RoleBinding and ClusterRoleBinding
- 4. ServiceAccount and RBAC
- 5. Hands-On: Multi-Tenant RBAC Configuration
- 6. CKS Exam Frequently Tested RBAC Scenarios
- 7. RBAC Best Practices
- 8. Common Mistakes and Solutions
- 9. Quiz
1. What Is RBAC?
Kubernetes RBAC (Role-Based Access Control) is an authorization mechanism that controls access to API resources within a cluster based on roles. It is enabled when the --authorization-mode=RBAC flag is set on the kube-apiserver.
The core principle of RBAC is the Principle of Least Privilege. Every user and service account should be granted only the minimum permissions necessary to perform their duties.
1.1 The 4 Core RBAC Resources
| Resource | Scope | Purpose |
|---|---|---|
Role | Namespace | Defines permissions for resources within a specific namespace |
ClusterRole | Cluster-wide | Defines permissions for cluster-scoped resources or common permissions across multiple namespaces |
RoleBinding | Namespace | Binds a Role or ClusterRole to subjects within a specific namespace |
ClusterRoleBinding | Cluster-wide | Binds a ClusterRole to subjects across the entire cluster |
2. Role and ClusterRole in Detail
2.1 Creating a Namespace Role
# dev-reader-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: development
name: pod-reader
rules:
- apiGroups: [''] # core API group
resources: ['pods']
verbs: ['get', 'watch', 'list']
- apiGroups: ['']
resources: ['pods/log']
verbs: ['get']
- apiGroups: ['apps']
resources: ['deployments']
verbs: ['get', 'list']
2.2 Creating a ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-viewer
rules:
- apiGroups: ['']
resources: ['nodes']
verbs: ['get', 'list', 'watch']
- apiGroups: ['metrics.k8s.io']
resources: ['nodes']
verbs: ['get', 'list']
2.3 Aggregated ClusterRole
The Aggregated ClusterRole pattern, frequently tested in the CKS exam:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-endpoints
labels:
rbac.example.com/aggregate-to-monitoring: 'true'
rules:
- apiGroups: ['']
resources: ['services', 'endpoints', 'pods']
verbs: ['get', 'list', 'watch']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: 'true'
rules: [] # Automatically populated
3. RoleBinding and ClusterRoleBinding
3.1 RoleBinding: Granting Permissions Within a Namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: development
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
- kind: ServiceAccount
name: ci-bot
namespace: development
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
3.2 Using a ClusterRole with a RoleBinding (Important!)
When a ClusterRole is bound via a RoleBinding, it is only effective within that namespace. This is very useful for reusing a common set of permissions across multiple namespaces:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-staging
namespace: staging
subjects:
- kind: Group
name: dev-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole # It's a ClusterRole, but
name: pod-reader # since it's a RoleBinding, it's only effective in the staging NS
apiGroup: rbac.authorization.k8s.io
4. ServiceAccount and RBAC
4.1 ServiceAccount Tokens (1.24+)
Starting from Kubernetes 1.24, automatic Secret creation for SAs has been discontinued:
# Create a ServiceAccount
kubectl create serviceaccount monitoring-sa -n monitoring
# Create a short-lived token (1 hour)
kubectl create token monitoring-sa -n monitoring --duration=3600s
# Long-lived token (for legacy compatibility)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: monitoring-sa-token
namespace: monitoring
annotations:
kubernetes.io/service-account.name: monitoring-sa
type: kubernetes.io/service-account-token
EOF
4.2 Disabling SA Token Mount on Pods
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
automountServiceAccountToken: false
containers:
- name: app
image: nginx:1.27
5. Hands-On: Multi-Tenant RBAC Configuration
5.1 Scenario
- frontend-team:
frontendNS — Manage Deployments, Services, ConfigMaps - backend-team:
backendNS — All workloads + read Secrets - platform-team: Cluster-wide — Read-only + Node/PV management
5.2 Implementation
kubectl create ns frontend
kubectl create ns backend
# 1) frontend-team
cat <<'EOF' | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: frontend
name: frontend-developer
rules:
- apiGroups: ["", "apps"]
resources: ["deployments", "services", "configmaps", "pods"]
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:
namespace: frontend
name: frontend-team-binding
subjects:
- kind: Group
name: frontend-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: frontend-developer
apiGroup: rbac.authorization.k8s.io
EOF
# 2) backend-team
cat <<'EOF' | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: backend
name: backend-developer
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["*"]
verbs: ["*"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: backend
name: backend-team-binding
subjects:
- kind: Group
name: backend-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: backend-developer
apiGroup: rbac.authorization.k8s.io
EOF
# 3) platform-team
cat <<'EOF' | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: platform-admin
rules:
- apiGroups: [""]
resources: ["nodes", "persistentvolumes"]
verbs: ["*"]
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
resources: ["*"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: platform-team-binding
subjects:
- kind: Group
name: platform-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: platform-admin
apiGroup: rbac.authorization.k8s.io
EOF
5.3 Permission Verification
# Can frontend-team list pods in the frontend NS?
kubectl auth can-i list pods --namespace=frontend --as=jane --as-group=frontend-team
# yes
# Can frontend-team delete pods in the backend NS?
kubectl auth can-i delete pods --namespace=backend --as=jane --as-group=frontend-team
# no
# Full permission list (CKS exam tip!)
kubectl auth can-i --list --as=jane --as-group=frontend-team -n frontend
6. CKS Exam Frequently Tested RBAC Scenarios
6.1 Detecting Dangerous Permissions
# Find cluster-admin bindings
kubectl get clusterrolebindings -o json | jq -r '
.items[] |
select(.roleRef.name == "cluster-admin") |
.metadata.name + " -> " +
(.subjects[]? | .kind + "/" + .name)'
# Find Roles with wildcard (*) permissions
kubectl get roles,clusterroles -A -o json | jq -r '
.items[] |
select(.rules[]?.verbs[]? == "*" or .rules[]?.resources[]? == "*") |
.metadata.namespace + "/" + .metadata.name'
6.2 Secret Access Auditing
kubectl get roles,clusterroles -A -o json | jq -r '
.items[] |
select(.rules[]? | .resources[]? == "secrets") |
"\(.metadata.namespace // "cluster")/\(.metadata.name)"'
6.3 Pod Security Standards + RBAC Combination
apiVersion: v1
kind: Namespace
metadata:
name: secure-ns
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
7. RBAC Best Practices
- Principle of Least Privilege: Avoid wildcards (
*), explicitly specify only the required verbs - Minimize ClusterRoleBindings: Use RoleBinding + ClusterRole combinations whenever possible
- Separate ServiceAccounts: Create dedicated SAs per Pod, avoid using the default SA
- Disable Token Mounting: Set
automountServiceAccountToken: falseby default - Regular Auditing: Periodically review permissions with
kubectl auth can-i --list - Leverage Aggregated ClusterRoles: Modularized permission management
- Use Impersonation: Test permissions with the
--asflag before applying
8. Common Mistakes and Solutions
| Mistake | Problem | Solution |
|---|---|---|
| Confusing ClusterRole + RoleBinding vs ClusterRoleBinding | Scope mismatch | The Binding type determines the scope |
Missing apiGroups: [""] | Cannot access core resources | Core API = empty string |
| Not including subresources | Cannot access pods/log, pods/exec | Must be explicitly specified |
| Unaware of SA token expiration | 1.24+ uses short-lived tokens by default | Set --duration |
9. Quiz
Q1. What is the main difference between Role and ClusterRole?
A Role is only effective within a specific namespace, while a ClusterRole defines permissions with cluster-wide scope. ClusterRoles can also grant permissions on non-namespaced resources like Nodes and PVs.
Q2. What happens when a ClusterRole is bound to a RoleBinding?
The permissions defined in the ClusterRole become effective only within the namespace where the RoleBinding belongs.
Q3. What changed regarding ServiceAccount tokens after Kubernetes 1.24+?
Automatic Secret creation was discontinued. You must create short-lived tokens (default 1 hour) with kubectl create token or manually create a kubernetes.io/service-account-token Secret.
Q4. Why should you set automountServiceAccountToken: false?
To prevent unnecessary SA token mounting inside Pods, blocking an attacker's access to the K8s API in case of container compromise. This is part of the Principle of Least Privilege.
Q5. What does kubectl auth can-i delete pods --as=jane -n production do?
Using the Impersonation feature, it checks whether user jane has permission to delete Pods in the production namespace.
Q6. How does Aggregated ClusterRole work?
Rules from other ClusterRoles that match the label selector in aggregationRule are automatically merged. When a new matching ClusterRole is added, it is automatically reflected.
Q7. How can you find excessive (cluster-admin) permission bindings?
Filter bindings where roleRef.name == "cluster-admin" using kubectl get clusterrolebindings -o json | jq.
Q8. What are the 3 key RBAC topics tested in the KCSA exam?
(1) Principle of Least Privilege — avoid wildcards (2) SA Security — disable token mounting, don't use the default SA (3) Regular Auditing — can-i --list, detect excessive ClusterRoleBindings