close icon
daily.dev platform

Discover more from daily.dev

Personalized news feed, dev communities and search, much better than what’s out there. Maybe ;)

Start reading - Free forever
Start reading - Free forever
Continue reading >

Kubernetes RBAC Roles and Permissions Guide

Kubernetes RBAC Roles and Permissions Guide
Author
Nimrod Kramer
Related tags on daily.dev
toc
Table of contents
arrow-down

🎯

Clear guide to Kubernetes RBAC: Roles, ClusterRoles, bindings, best practices, auditing, and troubleshooting for least-privilege access.

Kubernetes RBAC (Role-Based Access Control) helps you control who can do what in a Kubernetes cluster. It’s based on roles, rules, and bindings to enforce permissions. RBAC is critical for securing resources like pods, secrets, and nodes while ensuring users and workloads have only the access they need.

Key Points:

  • Roles are namespace-specific and define permissions for resources like pods or services.
  • ClusterRoles apply cluster-wide and can manage both namespaced and cluster-scoped resources.
  • RoleBindings assign Roles to users or service accounts within a namespace.
  • ClusterRoleBindings extend ClusterRoles to all namespaces and cluster-wide resources.
  • RBAC follows a “deny by default” model: permissions must be explicitly granted.

Best Practices:

  • Use least privilege by granting only necessary permissions.
  • Avoid using wildcards (*) in roles to prevent unintended access.
  • Regularly audit and review RBAC settings to remove unused permissions.
  • Test configurations with kubectl auth can-i to validate proper access control.

RBAC is essential for maintaining security, preventing accidental changes, and ensuring compliance. Proper setup and regular reviews can help keep your Kubernetes cluster secure.

Kubernetes RBAC full tutorial with examples

Kubernetes

Core Components of Kubernetes RBAC

Kubernetes RBAC Components Comparison: Roles vs ClusterRoles and RoleBindings vs ClusterRoleBindings

Kubernetes RBAC Components Comparison: Roles vs ClusterRoles and RoleBindings vs ClusterRoleBindings

Kubernetes RBAC uses four key components to manage access: Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings. Roles and ClusterRoles define permissions, while RoleBindings and ClusterRoleBindings assign those permissions to users, groups, or service accounts. Understanding how these components work together is crucial for securing your Kubernetes cluster.

Roles and ClusterRoles

A Role is tied to a single namespace, specifying what actions can be performed on resources like Pods, Services, or ConfigMaps. For instance, a Role in the "development" namespace might allow developers to create and delete Pods, but only within that namespace. This limits the scope of potential damage if credentials are compromised.

A ClusterRole, on the other hand, operates at the cluster level. It can grant permissions for cluster-wide resources, non-resource endpoints (like /healthz), and namespaced resources across all namespaces. ClusterRoles are often used by tools like Prometheus, which need access to metrics from all namespaces, or by SRE teams managing infrastructure across the cluster.

Kubernetes includes built-in ClusterRoles, such as:

  • cluster-admin: Full access across the cluster.
  • admin: Administrator access within a namespace.
  • edit: Read/write access to resources in a namespace.
  • view: Read-only access.

These default roles cover many common scenarios, but you can also create custom roles to fit specific needs. By defining a ClusterRole once, you can reuse it across multiple namespaces using RoleBindings, reducing redundancy.

Feature Role ClusterRole
Scope Namespace-specific Cluster-wide
Resource Access Namespaced resources only Cluster-scoped and namespaced resources
Common Use Case Developer access to a specific namespace Monitoring tools (e.g., Prometheus) or cluster-wide management
Binding Options RoleBinding RoleBinding (local) or ClusterRoleBinding (global)

Next, let’s see how Roles and ClusterRoles are assigned to users through RoleBindings and ClusterRoleBindings.

RoleBindings and ClusterRoleBindings

"Role is the Permission, Binding is the Grant." – Charles Wan

RoleBindings link a Role or ClusterRole to users, groups, or service accounts within a specific namespace. Even if a ClusterRole is referenced, the permissions are confined to that namespace. This is useful for scenarios like granting view-only access across multiple namespaces without duplicating roles.

ClusterRoleBindings, however, apply permissions across the entire cluster. These bindings can only reference ClusterRoles and extend permissions to all namespaces and cluster-scoped resources. Use them cautiously, as they can increase the impact of a compromised account. For example, a service account with cluster-wide access to read Secrets could expose sensitive data across your entire infrastructure.

Important Note: The roleRef field in both RoleBindings and ClusterRoleBindings is immutable. If you need to change the referenced role, you must delete and recreate the binding. This design choice helps prevent accidental privilege escalation.

To check permissions granted by a binding, use this command:

kubectl auth can-i <verb> <resource> --as <user> -n <namespace>

This is a handy way to test and verify user permissions during configuration.

How to Configure Roles and Permissions

RBAC Permissions Structure

RBAC policies boil down to a straightforward formula: "Who" (Subject) + "Can Do What" (Verbs) + "On Which Resources". The rules section in a Role or ClusterRole defines these permissions with three key elements.

  • apiGroups: This determines the API group for the targeted resource. The core API group, represented by an empty string "", covers essential resources like pods, services, and secrets. Other groups include apps (for deployments and statefulsets), batch (for jobs and cronjobs), and networking.k8s.io (for ingresses).
  • resources: This specifies the Kubernetes objects the rule applies to, such as pods, configmaps, or deployments. You can even narrow it down further with subresources like pods/log for logs or pods/exec for shell access.
  • verbs: These define the actions allowed. For example, get retrieves a specific resource, list fetches all resources of a type, watch enables real-time updates, and create, update, patch, or delete allow modifications.

Here’s an example of a basic Role manifest:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: development
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list"]

Before setting up RBAC, ensure it’s enabled by running kubectl api-versions | grep rbac. Avoid using wildcards (*) in the resources or verbs fields, as this could unintentionally grant access to future resource types. You can also use the optional resourceNames field to limit access to specific objects by name.

API Group Common Resources
"" (Core) pods, services, configmaps, secrets, nodes, namespaces
apps deployments, statefulsets, daemonsets
batch jobs, cronjobs
networking.k8s.io ingresses, networkpolicies
rbac.authorization.k8s.io roles, rolebindings, clusterroles

Once you’ve structured the permissions, you can implement them in your YAML manifests.

Creating and Applying RBAC Policies

Start by creating a YAML file for your Role or ClusterRole. While the structure is similar for both, ClusterRoles omit the namespace field in metadata and can manage cluster-wide resources like nodes or persistent volumes.

After defining the role, you’ll need to bind it to a subject to enforce the permissions. This is done through a RoleBinding or ClusterRoleBinding. The subjects section specifies who gets the permissions - this could be a User, Group, or ServiceAccount. The roleRef section links to the name and type of the role being assigned:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: development
subjects:
- kind: User
  name: jane@example.com
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

Apply the configuration using kubectl apply -f <filename>.yaml. Keep in mind that the roleRef field is immutable, so if you need to change it, you’ll have to delete and recreate the binding. You can also use a RoleBinding to assign a ClusterRole, limiting its scope to a specific namespace.

To verify permissions, use commands like kubectl auth can-i list pods --as jane@example.com -n development. This checks whether Jane can list pods in the development namespace.

"Default to Namespace-Scoped Roles for Granular Control: Use Roles and RoleBindings to grant permissions within a single namespace." – Plural.sh

For better manageability, create smaller, focused roles (e.g., pod-reader or config-updater) instead of a single large role. This makes auditing easier and aligns with the principle of least privilege. Start with read-only actions (get, list, watch) and add write permissions only when absolutely necessary.

Best Practices for Kubernetes RBAC

Building on our RBAC configuration guides, these tips aim to strengthen the security of your Kubernetes clusters.

Enforce Least Privilege

At the heart of RBAC security is the principle of granting only the permissions necessary for a user or service account to perform their tasks. This means prioritizing namespace-scoped Roles and RoleBindings over cluster-wide access. By doing so, you reduce the potential damage if credentials are compromised.

To further limit access, use the resourceNames field. For instance, you can configure a service account to access only a specific ConfigMap by name, rather than all ConfigMaps in a namespace. Similarly, when defining verbs, include only the essential actions, like get or list, and avoid permissions such as delete or escalate, unless absolutely necessary.

"Ideally, minimal RBAC rights should be assigned to users and service accounts. Only permissions explicitly required for their operation should be used." - Kubernetes Documentation

Another key practice is disabling automatic service account token mounting. You can do this by setting automountServiceAccountToken: false in your Pod specifications. This prevents unused tokens from being exposed inside containers. Additionally, avoid adding users to the system:masters group. Members of this group bypass all RBAC checks and authorization webhooks, effectively granting unrestricted superuser access that cannot be revoked through standard bindings.

For administrative tasks, consider using impersonation rights. This allows low-privileged accounts to temporarily perform high-privilege actions without permanently elevating their access.

Now, let’s explore common mistakes that can undermine RBAC security.

Common RBAC Mistakes to Avoid

One of the most frequent errors is assigning the built-in cluster-admin role to users or service accounts. This role provides unrestricted access to the cluster, creating a significant security risk. Similarly, using wildcards (*) for resources or verbs is dangerous - it grants access to all current and future object types, which could include sensitive resources you haven’t even created yet.

Some permissions may also have unintended consequences. For example, granting get access to the nodes/proxy subresource isn’t just about reading data - it allows command execution on any pod within that node via websocket HTTP GET requests. Similarly, permissions like list or watch for Secrets are essentially equivalent to get access, as the returned data includes the full contents of all Secrets.

Other risky verbs include bind, escalate, and impersonate. These can allow users to bypass RBAC restrictions entirely. Additionally, granting patch access to Namespace objects can lead to unintentional security gaps, such as modifying labels in a way that bypasses NetworkPolicies or Pod Security Admission settings.

To avoid these pitfalls, regular audits are crucial.

Regular Auditing and Reviews

Over time, RBAC configurations can accumulate unused or "temporary" permissions, leading to over-privileged accounts. A monthly review of roles and bindings can help identify and remove these unnecessary permissions.

"It is vital to periodically review the Kubernetes RBAC settings for redundant entries and possible privilege escalations." - Kubernetes Documentation

Enable Kubernetes API server audit logging to track all requests and monitor changes to RBAC settings. Use tools like kubectl auth can-i --as <user> to verify that users have the exact permissions intended - nothing more, nothing less. Pay particular attention to wildcard permissions in apiGroups, resources, and verbs, and replace them with more specific, granular permissions.

Another issue to watch for is "ghost" bindings. If a user account is deleted but its RoleBindings remain, a new user with the same name could inherit those permissions. Regular audits can help you catch and remove these lingering bindings before they become a problem. Lastly, keep a close eye on the system:masters group, ensuring it remains either empty or tightly controlled to prevent unrestricted access.

Troubleshooting RBAC Issues

Now that we've covered RBAC configuration and best practices, let's dive into how to resolve and validate common permission errors. Even with careful planning, RBAC configurations can sometimes fail. Thankfully, Kubernetes error messages are precise and can point directly to the missing permission details.

Common Errors and How to Fix Them

The "Forbidden" error is one of the most common RBAC issues. This error occurs when a user or service account lacks the necessary permissions. Kubernetes error messages are very specific - they outline the subject, verb, resource, API group, and namespace that failed. As Nawaz Dhandala from OneUptime puts it:

"The error message tells you exactly what permission is missing and for which service account".

One common pitfall is assuming the default service account has sufficient access - it doesn’t. By default, this account has very limited permissions. If your pods don’t explicitly specify a serviceAccountName, they’ll default to using this account, which often leads to failures when interacting with the API server.

Another frequent issue arises with RoleBindings and namespaces. A RoleBinding must exist in the same namespace as the service account it’s intended for. For example, if a service account in the default namespace needs access to resources in the production namespace, the RoleBinding must be created in production.

API group mismatches can also cause headaches. Resources need to be associated with their correct API group. For instance, deployments belong to the apps group, while pods are part of the core group (notated as ""). Assigning the wrong API group will result in permission failures, even if the verb and resource name are correct. To avoid this, use kubectl api-resources to confirm the API group for a resource.

Subresources like pods/log, pods/exec, and pods/portforward require explicit permissions. Granting access to pods doesn’t automatically include these subresources, so you’ll need to define them separately.

If you encounter an immutable roleRef issue, the only solution is to delete and recreate the binding. Once a RoleBinding or ClusterRoleBinding is created, you cannot change its associated role.

After making these adjustments, use Kubernetes tools to validate your fixes and confirm that permissions are correctly enforced.

Testing and Validating RBAC Configurations

Once you've addressed common errors, it's time to validate your RBAC setup. The go-to tool for this is kubectl auth can-i, which provides a straightforward "yes" or "no" answer. You can use the --as flag to test permissions for a specific user or service account. For example:

kubectl auth can-i get pods --as=system:serviceaccount:default:my-app -n production

This command checks whether the specified service account can perform the get action on pods in the production namespace.

For a broader view, use kubectl auth can-i --list --as=<user> to see a complete list of actions allowed for a user or service account in a given namespace. This is especially helpful when troubleshooting complex permission setups.

Before rolling out RBAC changes to production, create a sandbox namespace to test your configurations. Run both commands expected to succeed (like get or list) and commands expected to fail (like delete or exec). This ensures your permissions strike the right balance - not too restrictive, but not overly permissive either. As the team at Atmosly advises:

"RBAC should be treated like code: you test it before trusting it. That avoids 'grant random extra permissions until it works' in production".

For deeper debugging, you can use the -v=8 flag with kubectl to get detailed output. This verbose mode shows how RBAC rules are evaluated, helping you pinpoint issues like missing Roles, incorrect API groups, or namespace mismatches.

Lastly, consider integrating RBAC validation into your CI/CD pipeline. Since kubectl auth can-i exits with a status code of 0 for allowed actions and 1 for denied actions, you can write simple scripts to catch missing permissions before deployment. This proactive approach prevents runtime failures caused by misconfigurations.

Conclusion

Key Takeaways

Kubernetes RBAC plays a crucial role in maintaining security in production environments. As James Walker, Founder of Heron Web, points out:

"RBAC should be enabled in every production Kubernetes cluster. Restrict the use of default administrator accounts; instead, ensure every user, application, and integration has its own identity and individual roles".

The principle of least privilege is the cornerstone of effective RBAC. This means granting only the permissions absolutely necessary for each task and favoring namespace-scoped Roles over cluster-wide permissions. Avoid using wildcards in your configurations to prevent accidental access to new resource types.

Treat RBAC policies as you would code. Use GitOps for version control and policy reviews, and always validate configurations before deploying to production. Tools like kubectl auth can-i can help confirm that permissions are set correctly. Regular audits are equally important - review roles and bindings periodically to identify and fix privilege creep, remove unused permissions, and maintain compliance with security standards.

Keep in mind that RBAC permissions are cumulative. Kubernetes does not support "deny" rules, so every permission granted adds to the overall access. Be especially cautious with powerful verbs like escalate, bind, and impersonate, as they can bypass standard RBAC protections. For pods that don’t require API server communication, setting automountServiceAccountToken: false can further reduce the risk of token theft.

These practices form the foundation of secure RBAC management. For those looking to dive deeper, the resources below offer additional guidance.

Additional Resources

  • daily.dev: A developer-focused platform that curates the latest news on Kubernetes updates, security patches, and RBAC trends, helping you stay informed without being overwhelmed.
  • Official Kubernetes Documentation: The go-to source for detailed RBAC API references and security hardening best practices.
  • Visualization Tools: Tools like rakkess, rbac-lookup, and KubeView can help you map out and understand permission hierarchies within your cluster.

FAQs

When should I use a Role vs. a ClusterRole?

Roles and ClusterRoles are used to manage permissions in Kubernetes, but they serve different scopes:

  • Role: This is used to set permissions within a specific namespace. It allows you to define what actions can be performed on resources within that particular namespace.
  • ClusterRole: This is used for permissions that apply across the entire cluster or for resources that aren't tied to a specific namespace. It provides cluster-wide access.

In short, Roles are limited to a namespace, while ClusterRoles operate at the cluster level.

How can I safely grant cross-namespace access without cluster-wide permissions?

To enable secure cross-namespace access without giving cluster-wide permissions, you can leverage Kubernetes RBAC by using ClusterRoles and ClusterRoleBindings. Here's how you can set it up:

  • Define a ClusterRole: Specify the exact permissions needed for the access.
  • Create a ServiceAccount: Set this up in the namespace where the workload resides.
  • Bind the ClusterRole to the ServiceAccount: Use a ClusterRoleBinding to establish the connection.

This approach ensures minimal permissions are granted, maintaining security while allowing controlled access across namespaces.

What are the easiest ways to debug a Kubernetes RBAC “Forbidden” error?

If you encounter a "Forbidden" error in Kubernetes, the first step is to check permissions using the kubectl auth can-i command. Here's how you can do it:

  • Run:
    kubectl auth can-i <action> <resource> --namespace=<namespace> --as=<user or service account>
    This checks whether the specified user or service account has the required permissions for a particular action on a resource within a namespace.
  • To list all permissions for a service account, use:
    kubectl auth can-i --list --as=<service account> -n <namespace>

Beyond these checks, examining logs can provide more clarity. Look for errors such as missing roles or improperly configured role bindings. These details can help pinpoint and fix the root cause of the issue.

Related Blog Posts

Why not level up your reading with

Stay up-to-date with the latest developer news every time you open a new tab.

Read more