✓A running Kubernetes cluster (v1.20+), kubectl installed and configured, basic understanding of Kubernetes objects (Pods, Namespaces), and cluster-admin access to create RBAC resources.
✦ Definition~90s read
What is Kubernetes RBAC?
Kubernetes RBAC (Role-Based Access Control) is the mechanism for controlling access to the Kubernetes API. It defines who can do what to which resources. Use RBAC to enforce least-privilege access, prevent accidental or malicious cluster changes, and audit user and service actions. Every production cluster must have RBAC enabled and properly configured.
★
Think of Kubernetes RBAC — Service Accounts, Roles, and Bindings like a tool in your DevOps toolkit — once you understand what it does and when to reach for it, managing Kubernetes clusters becomes second nature.
Plain-English First
Think of Kubernetes RBAC — Service Accounts, Roles, and Bindings like a tool in your DevOps toolkit — once you understand what it does and when to reach for it, managing Kubernetes clusters becomes second nature.
⚙ Browser compatibility
Latest versions — ✓ supported
Chrome
Firefox
Safari
Edge
✓
✓
✓
✓
Welcome to Kubernetes RBAC — Service Accounts, Roles, and Bindings. We'll break this down from first principles.
Why RBAC Matters in Production
In production Kubernetes clusters, security is non-negotiable. Without RBAC, any user or service account with network access to the API server can perform any action — including deleting namespaces, reading secrets, or modifying deployments. RBAC provides granular control by binding roles (sets of permissions) to subjects (users, groups, or service accounts). This prevents lateral movement and limits blast radius. For example, a CI/CD pipeline should only be able to deploy to its own namespace, not touch production secrets. RBAC is the primary defense against insider threats and compromised credentials. Always enable RBAC from day one; retrofitting it is painful and risky.
RBAC is enabled by passing --authorization-mode=RBAC to the API server. The Node authorizer is also included for node-level permissions.
⚠ Don't Forget the Node Authorizer
Always include 'Node' in the authorization-mode list. Without it, nodes cannot authenticate properly, causing kubelet failures.
📊 Production Insight
We once had a cluster where RBAC was disabled for 'simplicity'. A developer accidentally ran 'kubectl delete pods --all' in the wrong context, taking down production for 20 minutes.
🎯 Key Takeaway
RBAC is mandatory for production; it's the foundation of Kubernetes security.
Core Concepts: Subjects, Roles, and Bindings
RBAC has three core components: Subjects (who), Roles (what), and RoleBindings (binding). Subjects can be users (external), groups, or ServiceAccounts (internal to the cluster). Roles define a set of rules — verbs (get, list, watch, create, update, patch, delete) on resources (pods, secrets, deployments, etc.). RoleBindings associate a Role with a Subject within a namespace. ClusterRoles and ClusterRoleBindings work cluster-wide. Understanding these building blocks is essential. A Role is scoped to a namespace; a ClusterRole is not. Use Roles for namespace-scoped permissions and ClusterRoles for cluster-scoped resources (nodes, PVs, namespaces) or for reuse across namespaces.
Creates a Role named 'pod-reader' in the 'default' namespace that allows reading pods.
🔥Verbs Are Explicit
There is no 'read' verb. Use 'get', 'list', 'watch' for read access. 'get' retrieves a single resource, 'list' lists a collection, 'watch' streams changes.
📊 Production Insight
Always use the principle of least privilege. Start with minimal verbs and expand only when necessary. Overly permissive roles are a common source of security incidents.
🎯 Key Takeaway
Roles define permissions; RoleBindings assign them to subjects. ClusterRoles work cluster-wide.
thecodeforge.io
Kubernetes Rbac
ServiceAccounts: Identity for Pods
ServiceAccounts are Kubernetes identities for pods. Every namespace has a default ServiceAccount, but it's best practice to create dedicated ones. Pods authenticate to the API server using a token mounted as a volume (usually at /var/run/secrets/kubernetes.io/serviceaccount/token). ServiceAccounts are subjects in RBAC bindings. Use them to give pods specific permissions — e.g., a pod that needs to list pods should have a ServiceAccount bound to a role with list pods permission. Never use the default ServiceAccount for production workloads; it often has no permissions or too many. Create a ServiceAccount per application or microservice.
Creates a ServiceAccount 'my-app-sa' and assigns it to a pod. The pod will use this identity to authenticate to the API server.
💡Token Projection
For better security, use projected service account tokens with a short lifetime and audience. This reduces the risk of token theft.
📊 Production Insight
We had a breach where an attacker exploited a pod using the default ServiceAccount with cluster-admin privileges. Now we enforce that every namespace has its own ServiceAccounts with minimal permissions.
🎯 Key Takeaway
ServiceAccounts provide pod identity. Always create dedicated ones per application.
Creating Roles and RoleBindings
Roles and RoleBindings are namespace-scoped. To create a Role, define rules with apiGroups, resources, and verbs. For core resources (pods, services), apiGroups is empty string "". For apps (deployments, statefulsets), apiGroups is "apps". RoleBindings link a Role to a subject (User, Group, or ServiceAccount). The subject must include the kind and name. For ServiceAccounts, the namespace must match the ServiceAccount's namespace. You can bind multiple subjects to one Role, but it's cleaner to create separate bindings for clarity.
Binds the 'pod-reader' Role to the ServiceAccount 'my-app-sa' in namespace 'my-app'. The ServiceAccount can now read pods in the 'default' namespace.
⚠ Cross-Namespace Bindings
A RoleBinding can only reference a Role in the same namespace. To grant access to resources in another namespace, use a ClusterRole and a RoleBinding in the target namespace.
📊 Production Insight
We once accidentally bound a ServiceAccount to a Role in the wrong namespace, causing permission denied errors. Always verify the namespace of both the Role and the subject.
🎯 Key Takeaway
RoleBindings are namespace-scoped and link subjects to Roles within that namespace.
ClusterRoles and ClusterRoleBindings
ClusterRoles are not bound to a namespace. They can grant permissions to cluster-scoped resources (nodes, PVs, namespaces) or be reused across namespaces via RoleBindings. ClusterRoleBindings bind subjects to ClusterRoles cluster-wide. Use ClusterRoles for: (1) permissions on cluster-scoped resources, (2) permissions that should be available in all namespaces (e.g., a 'view' ClusterRole). Be careful with cluster-admin — it grants full access. Never bind a ServiceAccount to cluster-admin unless absolutely necessary. Prefer using ClusterRoles with specific permissions and binding them via RoleBindings in specific namespaces.
Creates a ClusterRole that can read namespaces, and binds it to user 'alice' cluster-wide.
🔥Aggregated ClusterRoles
Kubernetes supports aggregated ClusterRoles that combine permissions from multiple ClusterRoles via label selectors. Useful for dynamic permission sets.
📊 Production Insight
We limit cluster-admin bindings to a break-glass procedure. For daily operations, we use custom ClusterRoles with minimal permissions.
🎯 Key Takeaway
ClusterRoles grant permissions cluster-wide or can be reused across namespaces via RoleBindings.
Verbs and Resources: The Permission Grammar
RBAC rules consist of apiGroups, resources, and verbs. Verbs: get, list, watch, create, update, patch, delete, deletecollection. Resources: pods, services, deployments, secrets, configmaps, etc. You can also use subresources like pods/log, pods/exec. Wildcards: '' for all verbs or resources. Use wildcards sparingly. For apiGroups, '' matches all API groups. Be explicit to avoid over-permission. For example, to allow reading pods and logs: resources: ["pods", "pods/log"], verbs: ["get", "list"].
A Role that grants full CRUD on core resources, apps, and batch in the 'dev' namespace.
💡Subresources
To access pod logs, you need permission on 'pods/log' subresource. Similarly, 'pods/exec' for exec. These are separate from 'pods'.
📊 Production Insight
We once gave a CI/CD pipeline 'delete' on pods, and it accidentally deleted a critical pod during a rollout. Now we restrict delete to specific scenarios.
🎯 Key Takeaway
Be explicit with verbs and resources. Avoid wildcards to enforce least privilege.
Aggregation and Default ClusterRoles
Kubernetes ships with default ClusterRoles: view, edit, admin, cluster-admin. These are aggregated — they combine multiple rules. For example, 'view' grants read-only access to most resources, 'edit' adds write access, 'admin' adds full control within a namespace (except ResourceQuota and namespace itself), and 'cluster-admin' is superuser. You can create custom aggregated ClusterRoles by adding labels to your ClusterRoles. This is useful for building role hierarchies. However, be aware that default roles may change across versions. For production, define your own roles rather than relying solely on defaults.
This ClusterRole will be aggregated into the 'view' ClusterRole because of the label. Users with 'view' will also get these permissions.
🔥Aggregation Labels
Use labels like 'rbac.authorization.k8s.io/aggregate-to-view: "true"' to add permissions to default roles. This is a clean way to extend them.
📊 Production Insight
We avoid using 'edit' and 'admin' directly because they grant broad permissions. Instead, we create fine-grained roles per team.
🎯 Key Takeaway
Default ClusterRoles are aggregated. Extend them with labels, but prefer custom roles for production.
thecodeforge.io
Kubernetes Rbac
Testing RBAC with kubectl auth can-i
Before deploying, test RBAC permissions using 'kubectl auth can-i'. This command checks if a user or ServiceAccount can perform an action. Use it to validate your roles. Example: 'kubectl auth can-i get pods --as=system:serviceaccount:my-app:my-app-sa'. You can also use '--list' to see all permissions. This is invaluable for debugging permission issues. Always test with the exact subject and namespace. Remember that 'can-i' checks against the current kubeconfig context; use '--as' to impersonate.
test-rbac.shBASH
1
2
3
4
5
6
7
8
9
# CheckifServiceAccount can list pods in namespace default
kubectl auth can-i list pods \
--as=system:serviceaccount:my-app:my-app-sa \
--namespace=default
# List all permissions for a user
kubectl auth can-i --list \
--as=alice \
--namespace=default
Output
yes
<list of permissions>
💡Impersonation Headers
You can also use '--as-group' to test group memberships. This is useful for testing group-based RBAC.
📊 Production Insight
We include RBAC tests in our CI pipeline. Every change to roles or bindings triggers a 'can-i' check to catch regressions.
🎯 Key Takeaway
Use 'kubectl auth can-i' to validate RBAC permissions before relying on them in production.
Auditing RBAC with kubectl describe and get
Audit your RBAC configuration regularly. Use 'kubectl describe rolebinding' and 'kubectl describe clusterrolebinding' to see subjects and roleRefs. Use 'kubectl get roles --all-namespaces' to list all roles. For a comprehensive view, use tools like 'rbac-tool' or 'kubectl rbac'. Look for overly permissive roles, unused bindings, and subjects with cluster-admin. Remove stale ServiceAccounts and bindings. Audit logs from the API server can also show denied requests due to RBAC — monitor them to detect misconfigurations or attacks.
audit-rbac.shBASH
1
2
3
4
5
6
7
8
9
10
11
# List all ClusterRoleBindings
kubectl get clusterrolebindings -o wide
# Describe a specific RoleBinding
kubectl describe rolebinding pod-reader-binding -n default
# List all roles in all namespaces
kubectl get roles --all-namespaces
# Checkfor subjects with cluster-admin
kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name=="cluster-admin") | .subjects'
When you delete a ServiceAccount, its RoleBindings remain. They become dangling references and can cause confusion. Clean them up.
📊 Production Insight
We run a weekly cronjob that lists all subjects with cluster-admin and sends an alert. This caught an engineer who accidentally bound a CI account to cluster-admin.
🎯 Key Takeaway
Regular audits of RBAC resources prevent permission creep and security gaps.
Common Pitfalls and How to Avoid Them
Pitfall 1: Using the default ServiceAccount. Always create dedicated ones. Pitfall 2: Overusing cluster-admin. It's rarely needed. Pitfall 3: Forgetting to specify apiGroups. For core resources, apiGroups is "". Pitfall 4: Using '*' for verbs or resources without understanding the blast radius. Pitfall 5: Binding a ClusterRole to a ServiceAccount via ClusterRoleBinding when you only need namespace-scoped access. Use RoleBinding instead. Pitfall 6: Not testing permissions before deployment. Use 'can-i'. Pitfall 7: Ignoring subresource permissions. For example, 'pods/exec' is separate from 'pods'. Pitfall 8: Not cleaning up old bindings. They accumulate and become a security risk.
This grants cluster-admin to any pod using the default ServiceAccount in the default namespace. Extremely dangerous.
⚠ Never Bind Default ServiceAccount to cluster-admin
This is a common misconfiguration that gives every pod in the namespace full cluster access. Always create dedicated ServiceAccounts.
📊 Production Insight
We had a security audit that flagged a default ServiceAccount with cluster-admin. The fix was to create a dedicated ServiceAccount with minimal permissions and update the pod spec.
🎯 Key Takeaway
Avoid common pitfalls: use dedicated ServiceAccounts, least privilege, and test permissions.
RBAC Best Practices for Production
Enable RBAC and the Node authorizer. 2. Use dedicated ServiceAccounts per application. 3. Apply least privilege: start with minimal permissions and add as needed. 4. Use namespaces to isolate environments (dev, staging, prod) and apply different roles. 5. Use ClusterRoles for reusable permissions but bind them via RoleBindings. 6. Regularly audit RBAC resources. 7. Use external authentication (OIDC, LDAP) for users, not static tokens. 8. Rotate ServiceAccount tokens periodically. 9. Monitor API server audit logs for RBAC failures. 10. Document your RBAC design and review it with your team.
A production-ready setup: a dedicated ServiceAccount for monitoring with read-only access to pods, services, endpoints, and deployments.
💡Use Namespace Scoping
Always scope roles to the smallest namespace possible. Avoid cluster-wide permissions unless absolutely necessary.
📊 Production Insight
We enforce RBAC policies via GitOps. Any change to roles or bindings must go through a pull request and be reviewed by the security team.
🎯 Key Takeaway
Follow best practices: least privilege, dedicated identities, regular audits, and external auth.
Role vs ClusterRole in RBACScope and use cases for namespace vs cluster-wide permissionsRoleClusterRoleScopeNamespace-scopedCluster-scopedResources coveredNamespaced resources (pods, services)Cluster resources (nodes, PVs) + namespaBinding methodRoleBinding (same namespace)ClusterRoleBinding (cluster-wide) or RolUse caseRestrict access to a single namespaceAdminister cluster-wide or reuse across Default examplesCustom app-specific rolesadmin, edit, view (predefined)THECODEFORGE.IO
thecodeforge.io
Kubernetes Rbac
Troubleshooting RBAC Issues
Common symptoms: 'Forbidden' errors when accessing resources. Steps: 1. Verify the subject (ServiceAccount or user) is correct. 2. Check if the Role exists and has the right rules. 3. Ensure the RoleBinding exists and references the correct Role and subject. 4. Use 'kubectl auth can-i' to test. 5. Check if the resource is cluster-scoped or namespace-scoped. 6. Look for typos in apiGroups, resources, or verbs. 7. Check if the ServiceAccount token is valid and mounted. 8. Review API server logs for RBAC decisions. 9. If using OIDC, verify group mappings. 10. Remember that RBAC changes take effect immediately; no restart needed.
troubleshoot.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Step1: CheckifServiceAccount exists
kubectl get sa my-app-sa -n my-app
# Step2: CheckRole
kubectl get role pod-reader -n default
# Step3: CheckRoleBinding
kubectl get rolebinding pod-reader-binding -n default
# Step4: Test permission
kubectl auth can-i get pods \
--as=system:serviceaccount:my-app:my-app-sa \
--namespace=default
# Step5: CheckAPI server logs (if accessible)
kubectl logs -n kube-system kube-apiserver-<node> | grep -i rbac
Output
serviceaccount/my-app-sa created
role.rbac.authorization.k8s.io/pod-reader created
rolebinding.rbac.authorization.k8s.io/pod-reader-binding created
yes
<logs showing RBAC decision>
🔥RBAC is Immediate
Unlike some Kubernetes objects, RBAC changes take effect instantly. No need to restart pods or the API server.
📊 Production Insight
We have a runbook for RBAC issues. The first step is always 'kubectl auth can-i' with the exact subject and resource. This resolves 90% of cases.
🎯 Key Takeaway
Systematic troubleshooting: verify subjects, roles, bindings, and test with 'can-i'.
⚙ Quick Reference
12 commands from this guide
File
Command / Code
Purpose
enable-rbac.yaml
apiVersion: v1
Why RBAC Matters in Production
basic-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
Core Concepts
service-account.yaml
apiVersion: v1
ServiceAccounts
role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
Creating Roles and RoleBindings
cluster-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
ClusterRoles and ClusterRoleBindings
detailed-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
Verbs and Resources
aggregated-cluster-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
Aggregation and Default ClusterRoles
test-rbac.sh
kubectl auth can-i list pods \
Testing RBAC with kubectl auth can-i
audit-rbac.sh
kubectl get clusterrolebindings -o wide
Auditing RBAC with kubectl describe and get
pitfall-example.yaml
apiVersion: v1
Common Pitfalls and How to Avoid Them
best-practice-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
RBAC Best Practices for Production
troubleshoot.sh
kubectl get sa my-app-sa -n my-app
Troubleshooting RBAC Issues
Key takeaways
1
RBAC is mandatory
Enable it from day one to prevent unauthorized access and limit blast radius.
2
Use dedicated ServiceAccounts
Never rely on the default ServiceAccount; create one per application with minimal permissions.
3
Test permissions with 'kubectl auth can-i'
Validate RBAC before deploying to catch misconfigurations early.
4
Audit regularly
Review roles, bindings, and subjects to remove stale entries and prevent permission creep.
INTERVIEW PREP · PRACTICE MODE
Interview Questions on This Topic
Q01JUNIOR
What is the difference between a Role and a ClusterRole?
Q02JUNIOR
How do I grant a ServiceAccount access to read pods in another namespace...
Q03JUNIOR
Can I use RBAC to restrict access to custom resources?
Q01 of 03JUNIOR
What is the difference between a Role and a ClusterRole?
ANSWER
A Role is namespace-scoped; it grants permissions only within a specific namespace. A ClusterRole is cluster-scoped; it can grant permissions to cluster-scoped resources (like nodes) or be reused acro
Q02 of 03JUNIOR
How do I grant a ServiceAccount access to read pods in another namespace?
ANSWER
Create a Role in the target namespace with the desired permissions, then create a RoleBinding in that namespace that references the ServiceAccount (which may be in a different namespace). The RoleBind
Q03 of 03JUNIOR
Can I use RBAC to restrict access to custom resources?
ANSWER
Yes. Custom resources (CRDs) are part of their own API group. You can define rules with the appropriate apiGroups (e.g., 'stable.example.com') and resources (e.g., 'crontabs').
01
What is the difference between a Role and a ClusterRole?
JUNIOR
02
How do I grant a ServiceAccount access to read pods in another namespace?
JUNIOR
03
Can I use RBAC to restrict access to custom resources?
JUNIOR
FAQ · 6 QUESTIONS
Frequently Asked Questions
01
What is the difference between a Role and a ClusterRole?
A Role is namespace-scoped; it grants permissions only within a specific namespace. A ClusterRole is cluster-scoped; it can grant permissions to cluster-scoped resources (like nodes) or be reused across namespaces via RoleBindings.
Was this helpful?
02
How do I grant a ServiceAccount access to read pods in another namespace?
Create a Role in the target namespace with the desired permissions, then create a RoleBinding in that namespace that references the ServiceAccount (which may be in a different namespace). The RoleBinding's subjects can include ServiceAccounts from other namespaces.
Was this helpful?
03
Can I use RBAC to restrict access to custom resources?
Yes. Custom resources (CRDs) are part of their own API group. You can define rules with the appropriate apiGroups (e.g., 'stable.example.com') and resources (e.g., 'crontabs').
Was this helpful?
04
How do I revoke a ServiceAccount's permissions?
Delete the RoleBinding(s) that reference the ServiceAccount. The change takes effect immediately. You can also delete the ServiceAccount itself, but dangling RoleBindings will remain.
Was this helpful?
05
What is the best way to manage RBAC for multiple teams?
Use namespaces per team, create dedicated ServiceAccounts per application, and use ClusterRoles for common permissions (like read-only) bound via RoleBindings in each namespace. Use external authentication (OIDC) for users and map them to groups. Regularly audit with tools like 'rbac-tool'.
Was this helpful?
06
Why am I getting 'Forbidden' even though I created a RoleBinding?
Common causes: the RoleBinding is in the wrong namespace, the subject's namespace is incorrect, the Role doesn't have the required permissions, or you're trying to access a cluster-scoped resource with a namespace-scoped Role. Use 'kubectl auth can-i' to debug.