Introduction When a pod's service account lacks the required RBAC permissions, API requests return "Forbidden: user xxx cannot xxx resource yyy." This blocks operators, controllers, and applications that need to interact with the Kubernetes API.
Symptoms - Application logs: "forbidden: User 'system:serviceaccount:ns:sa' cannot list resource 'pods'" - kubectl from inside pod: "Error from server (Forbidden)" - Controller or operator not reconciling resources - Error: "serviceaccounts 'xxx' is forbidden"
Common Causes - Service account not bound to any Role or ClusterRole - Role missing the required apiGroups, resources, or verbs - RoleBinding referencing wrong service account or namespace - Token mounted but RBAC not configured for the service account - Cluster-wide permission needed but only namespace Role granted
Step-by-Step Fix 1. **Check the service account used by the pod**: ```bash kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.spec.serviceAccountName}' ```
- 1.Check existing RoleBindings for the service account:
- 2.```bash
- 3.kubectl get rolebinding,clusterrolebinding -n <namespace> \
- 4.-o jsonpath='{range .items[*]}{.metadata.name}: {.subjects[*].name}{"\n"}{end}' | grep <sa-name>
- 5.
` - 6.Create the missing Role and RoleBinding:
- 7.```yaml
- 8.apiVersion: rbac.authorization.k8s.io/v1
- 9.kind: Role
- 10.metadata:
- 11.name: app-role
- 12.namespace: my-namespace
- 13.rules:
- 14.- apiGroups: [""]
- 15.resources: ["pods", "services", "configmaps"]
- 16.verbs: ["get", "list", "watch", "create", "update"]
- 17.---
- 18.apiVersion: rbac.authorization.k8s.io/v1
- 19.kind: RoleBinding
- 20.metadata:
- 21.name: app-rolebinding
- 22.namespace: my-namespace
- 23.subjects:
- 24.- kind: ServiceAccount
- 25.name: my-app-sa
- 26.namespace: my-namespace
- 27.roleRef:
- 28.kind: Role
- 29.name: app-role
- 30.apiGroup: rbac.authorization.k8s.io
- 31.
` - 32.Test permissions:
- 33.```bash
- 34.kubectl auth can-i list pods --as=system:serviceaccount:my-namespace:my-app-sa -n my-namespace
- 35.
`