RBAC Least Privilege Kubernetes
Configure Kubernetes RBAC with least-privilege Roles, ClusterRoles, and service account bindings. Audit permissions, restrict secrets access.
π‘ Quick Answer: Use namespace-scoped
Role(notClusterRole) wherever possible, bind to specificServiceAccount(notdefault), never grant*verbs on secrets, and audit withkubectl auth can-i --list --as=system:serviceaccount:ns:sa.
The Problem
The default Kubernetes ServiceAccount in each namespace may have more permissions than needed. Common RBAC mistakes: granting cluster-admin to CI/CD pipelines, using ClusterRoleBinding when RoleBinding suffices, and wildcard verbs on sensitive resources like secrets.
The Solution
Application Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app
namespace: production
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-app-role
namespace: production
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "watch"]
resourceNames: ["my-app-config"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
resourceNames: ["my-app-tls"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-app-binding
namespace: production
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: my-app-role
subjects:
- kind: ServiceAccount
name: my-app
namespace: productionCI/CD Runner (Minimal Permissions)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: cicd-runner
namespace: staging
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "patch", "update"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]Audit Permissions
# What can this service account do?
kubectl auth can-i --list \
--as=system:serviceaccount:production:my-app \
-n production
# Can it read secrets?
kubectl auth can-i get secrets \
--as=system:serviceaccount:production:my-app \
-n production
# Find overprivileged ClusterRoleBindings
kubectl get clusterrolebindings -o json | \
jq '.items[] | select(.roleRef.name=="cluster-admin") | .subjects[]'Common Issues
Pod canβt read ConfigMaps after RBAC lockdown
Set automountServiceAccountToken: true (or mount token explicitly) and ensure the Role includes the specific ConfigMap name in resourceNames.
βforbiddenβ errors in CI/CD pipeline
Check which ServiceAccount the runner uses and what Role is bound. Use kubectl auth can-i to debug.
Best Practices
automountServiceAccountToken: falseby default β only mount when the pod needs API accessresourceNamesto restrict access to specific ConfigMaps/Secrets β not all in the namespace- Role (not ClusterRole) for application workloads β namespace-scoped by default
- Separate ServiceAccount per application β donβt share the
defaultSA - Audit regularly β
kubectl auth can-i --listfor each service account
Key Takeaways
- Default ServiceAccount may have more permissions than expected β always create dedicated SAs
- Use
resourceNamesto restrict access to specific resources, not all of a type automountServiceAccountToken: falseprevents unnecessary API server accesskubectl auth can-iis your RBAC debugging tool- Role + RoleBinding for namespaced access; ClusterRole + ClusterRoleBinding only when truly needed

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
