Portal | Level: L2: Operations | Topics: RBAC | Domain: Kubernetes
Runbook: RBAC Forbidden Error¶
Symptoms¶
- API calls return
403 ForbiddenorError from server (Forbidden) - Service account can't perform expected operations
- Deployment or CI job fails with permission error
Fast Triage¶
# Check what the service account can do
kubectl auth can-i --list --as=system:serviceaccount:grokdevops:default -n grokdevops
# Check specific permission
kubectl auth can-i get pods --as=system:serviceaccount:grokdevops:default -n grokdevops
# List roles and bindings
kubectl get roles,rolebindings -n grokdevops
kubectl get clusterroles,clusterrolebindings | grep grokdevops
# Check the service account
kubectl get serviceaccount -n grokdevops
Likely Causes (ranked)¶
- Missing RoleBinding — Role exists but not bound to the service account
- Wrong namespace — RoleBinding in different namespace than the resource
- ClusterRole needed — operation requires cluster-wide permission
- Service account mismatch — pod using wrong service account
Evidence Interpretation¶
What bad looks like:
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:grokdevops:default"
cannot list resource "pods" in API group "" in the namespace "grokdevops"
list), the resource (pods), the API group (""), and the namespace (grokdevops).
- Parse the service account name: system:serviceaccount:<namespace>:<name> — verify the pod is using the expected service account.
- kubectl auth can-i with --as flag lets you test permissions without deploying anything.
Fix Steps¶
- Identify what permission is needed from the error message
- Create or fix RoleBinding:
- For cluster-wide permissions:
Verification¶
Cleanup¶
Remove any overly permissive bindings created during debugging:
Unknown Unknowns¶
- RBAC is deny-by-default. If no Role/ClusterRole grants a permission, it is denied — there is no "implicit allow."
- A
Roleis namespaced (only grants access within one namespace). AClusterRolecan grant cluster-wide access or be reused across namespaces via RoleBindings. - A
RoleBindingcan reference aClusterRole— this grants the ClusterRole's permissions but scoped to the RoleBinding's namespace. This is a common and intentional pattern. - Aggregated ClusterRoles (using
aggregationRule) automatically combine permissions from other ClusterRoles matching certain labels. Editing them directly gets overwritten.
Pitfalls¶
- Creating overly permissive bindings — granting
cluster-adminto fix a 403 works but violates least privilege. Identify the exact verb and resource needed. - Forgetting to specify namespace — a RoleBinding in namespace
defaultdoes not grant access to namespacegrokdevops. Always check the namespace of both the binding and the resource. - Confusing Role with ClusterRole scope — a Role only works in its namespace. If the workload needs cross-namespace or cluster-scoped resources (nodes, PVs), you need a ClusterRole + ClusterRoleBinding.
See Also¶
training/interactive/exercises/levels/level-41/k8s-rbac-permission/training/interview-scenarios/09-rbac-forbidden.mdtraining/library/guides/troubleshooting.md
Wiki Navigation¶
Related Content¶
- Interview: RBAC Forbidden (Scenario, L2) — RBAC
- K8s RBAC (Topic Pack, L1) — RBAC
- Kubernetes Exercises (Quest Ladder) (CLI) (Exercise Set, L1) — RBAC
- Kubernetes RBAC Flashcards (CLI) (flashcard_deck, L1) — RBAC
- Kubernetes Security Flashcards (CLI) (flashcard_deck, L1) — RBAC
- Multi-Tenancy Patterns (Topic Pack, L2) — RBAC
- Policy Engines (OPA / Kyverno) (Topic Pack, L2) — RBAC
- Track: Kubernetes Core (Reference, L1) — RBAC