Kubernetes RBAC: Concepts, Examples & Top Misconfigurations

What Is Kubernetes RBAC?

The Kubernetes API provides access to sensitive data, including deployment details, persistent storage settings, and secrets.  Kubernetes RBAC (Role-Based Access Control) is a security feature that restricts access to Kubernetes resources based on the role the user holds. RBAC helps protect Kubernetes clusters by letting you control who has access to each API resource. Several misconfigurations can lead to weak access controls that fail to implement the principle of least privilege.

RBAC is a method of regulating access to computer resources based on the roles of individual users within an organization. Within Kubernetes, It is a key security control to ensure that cluster users and workloads only have access to the resources they need. It lets you create fine-grained permissions to manage what actions users and workloads can perform on resources. You can use RBAC policies to define access rights of human users (individuals or groups), and also of service accounts, which are software resources interacting with the Kubernetes cluster.

RBAC is enabled by default in Kubernetes. To enable Kubernetes RBAC for a cluster, start the API server with the --authorization-mode flag. The flag accepts a comma-separated list, and one of the options in the list should be RBAC. You can check whether RBAC is enabled by executing the command kubectl api-versions.

This is part of a series of articles about Kubernetes architecture.

Why Does RBAC Matter, and How Does It Work?

An RBAC mechanism provides fine-grained control over user privileges for software applications. RBAC assigns permissions based on the role of each user within an organization. RBAC policies can be used to define the access rights of human users as well as service accounts (access by APIs and automated tools). This helps avoid accounts with excessive privileges by assigning functions to the individual users or systems who need them.

Providing users with too many access privileges increases the risk of stolen or lost credentials, and exposes the organization to insider threats. For example, developers should not have permission to delete a production deployment. Even if you trust every employee in your organization, malicious outsiders could gain control over privileged accounts through social engineering or phishing attacks. 

In Kubernetes, RBAC is a key security control to ensure that users and workloads in clusters only have access to the resources required to execute. RBAC in Kubernetes allows you to create policies that prevent users from performing admin-level actions, such as deleting pods.

There are several ways to use RBAC in a Kubernetes project:

  • Integrate with an existing enterprise solution—the RBAC solution manages access to protected resources via a central role directory. Users can authenticate their identity and access resources in a Kubernetes pod, typically using a single sign-on (SSO) solution.
  • Maintain fine-grained control over user access within a cluster—you can use RBAC to control which users have access to the Kubernetes cluster and the level of access to various parts of the project. This fine-grained control allows team members to access only the specific resources they need.

Note: Historically, Kubernetes enabled authorization via attribute-based access control (ABAC). However, RBAC is now preferred over ABAC, which is difficult to manage and understand. ABAC is considered deprecated in Kubernetes and users are encouraged to use RBAC authorization.

expert-icon-header

Tips from the expert

Itiel Shwartz

Co-Founder & CTO

Itiel is the CTO and co-founder of Komodor. He’s a big believer in dev empowerment and moving fast, has worked at eBay, Forter and Rookout (as the founding engineer). Itiel is a backend and infra developer turned “DevOps”, an avid public speaker that loves talking about things such as cloud infrastructure, Kubernetes, Python, observability, and R&D culture.

In my experience, here are tips that can help you better utilize Kubernetes RBAC:

Namespace-specific roles

Assign roles and role bindings at the namespace level to adhere to the principle of least privilege.

Audit logs

Enable and review audit logs regularly to monitor RBAC changes and access attempts.

Role aggregation

Use role aggregation judiciously to avoid unintentional privilege escalation.

Regular reviews

Periodically review roles and bindings to remove unused or outdated permissions.

Custom roles

Create custom roles tailored to specific needs rather than over-relying on default roles.

Kubernetes RBAC Basic Concepts 

Here are some of the main Kubernetes elements for RBAC.

Enabling RBAC in Kubernetes

RBAC is enabled by default in Kubernetes, from version 1.6 onwards. 

To enable Kubernetes RBAC for a Kubernetes cluster

Start the API server with the --authorization-mode flag. The flag accepts a comma-separated list, and one of the options in the list should be RBAC. For example:

kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options

To check if RBAC is enabled for a cluster:

You can check whether RBAC is enabled by executing the command kubectl api-versions. In the response, check if the API version starts with rbac.authorization, like this: 

.rbac.authorization.k8s.io/v1

RBAC and Cluster Roles 

A Role or ClusterRole in Kubernetes contains the rules and permissions for a RBAC given role. These permissions are always additive, so there are no negative rules like “deny.” 

RBAC roles set the permissions for a specific namespace. When you create a new role, you must specify its namespace. In contrast, a cluster role is a resource without a namespace. These two resources (Role, ClusterRole) have different names because all Kubernetes objects must always be namespaced or non-namespaced—the same object cannot be both. 

Cluster roles serve a variety of purposes, including:

  1. Defining permissions for namespace resources that provide access to a specific namespace.
  2. Defining permissions for namespace resources that provide access to all namespaces.
  3. Defining permissions for cluster-wide resources.

You can use roles to define the permission in a specific namespace, while cluster roles can define permissions across the entire cluster.

Role and Cluster Role Bindings

Role bindings—RoleBinding—grant the permissions defined by roles to the relevant user or user group. They contain a list of service accounts, users, or groups—subjects—and references to the relevant roles. While a role binding grants permissions in a specified namespace, a cluster role binding
—ClusterRoleBinding- grants access across the cluster.

Role bindings can reference any role in a given namespace. Alternatively, a role binding can reference a cluster role and bind it to the role binding’s namespace. You can use cluster role bindings to bind cluster roles to cluster-wide namespaces.

The name of either type of binding must include a valid path segment.

Resource References

The Kubernetes API represents and enables access to most resources using the string representing the object’s name—for example, “pods” to represent a pod. The RBAC system can refer to a resource using the name displayed in the URL of the associated API endpoint. A Kubernetes API might also refer to sub-resources such as pod logs.

Aggregated Cluster Roles

You can combine multiple cluster roles into an aggregated cluster role. A Kubernetes controller that runs in your cluster control plane will detect a ClusterRole object with aggregation rule settings. An aggregationRule defines the label selector the controller must use to match all the cluster role objects to be included in the aggregated cluster role’s rules field.

When you create a cluster role matching an existing aggregated cluster role’s label selector, the controller will add the new rule to the aggregated cluster role. For example, you can add a new rule to a specific cluster role (i.e., “monitoring”) by creating another cluster role marked rbac.role.com/aggregate-to-monitoring: true.

All default user roles will use this cluster role aggregation, allowing cluster administrators to include custom resource rules. You can use the rules served by aggregated API servers or custom resource definitions to extend your default roles. For example, a cluster role might allow the default “admin” role to manage specific custom resources, while the “view” role can only read, but not edit, the resources.

User Accounts and Service Accounts

Kubernetes allows you to define access permissions for a human user (or group users) using RBAC policies. Kubernetes recognizes each human user as a user account. Alternatively, you can use RBAC policies to control the behavior of a software resource that Kubernetes recognizes as a service account.

Kubernetes conceptually distinguishes between user and service accounts, but this distinction is irrelevant to RBAC policies.

Verbs for Permissions Management

However, Kubernetes RBAC defines specific actions, providing a set of verbs to describe the actions an account can run on a given resource.

For instance, you might allow users to “create” and “list” specific resources, specifying the relevant verbs in your RBAC policy.

Run the following to see the list of all available verbs in a cluster:

kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get
--show-kind --ignore-not-found -l = -n
Code language: HTML, XML (xml)

Kubernetes RBAC Example

Create Role and Rolebinding

To create objects for granting a service account access to a namespace:

  1. Use the following YAML definition to create resources and save them in a file named demoConfig.yml:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: demoAdmin
  namespace: demo
rules:
  - apiGroups: ['*']
    resources: ['*']
    verbs: ['*']
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: demoBinding
  namespace: demo
subjects:
  - kind: ServiceAccount
    name: demoAccount
    namespace: demo
roleRef:
  kind: Role
  name: demoAdmin
  apiGroup: rbac.authorization.k8s.io

This creates a role that grants access to resources, and the RoleBinding connects a service account to a role.

  1. Use the following commands to submit the defined resources:
kubectl apply -f demoConfig.yaml
role.rbac.authorization.k8s.io/demoAdmin created
rolebinding.rbac.authorization.k8s.io/demoBinding created

Test Access to Resource

The command auth can-i can be used to query the RBAC authorization mode. The -n flag specifies the namespace, and the --as flag identifies the service account. For service accounts, you need to prefix the role binding with system:serviceaccount.

To test if a service account can access resources:

  1. Use the following command for user-impersonation:
    kubectl <verb-name> <resource-name> --as=jenkins
  1. Use the following command to verify API access:
    kubectl auth can-i <verb-name> <resource-name>
  1. Run the following command to see if requests can be made from the service account and list pod in the namespace:
    kubectl auth can-i get pods -n demo --as=system:serviceaccount:test:demoAccount

Top 4 RBAC Misconfigurations

Here are some common configuration issues with role-based access control.

1. Upgrading from ABAC

If your cluster ran an older Kubernetes version, it might have weak ABAC policies, such as full API access privileges to service accounts.

A default RBAC policy grants scoped permissions to a set of nodes, controllers, and components on the control plane. Still, it doesn’t grant access to any service account beyond the kube-system namespace (except discovery permissions granted to every authenticated user).

While this approach is secure, it can disrupt the existing workloads that expect to receive API permissions automatically. You can manage the transition to RBAC by running both authorizers (ABAC and RBAC) and specifying a policy file with your existing ABAC policy:

--authorization-mode=...,RBAC,ABAC
--authorization-policy-file=mypolicy.json

Here is a detailed explanation of the first command line option:

  • If an early authorizer like Node denies a request, the RBAC authorizer will attempt to authorize the relevant API request. 
  • If the RBAC authorizer denies the API request, the ABAC authorizer will run. 
  • The system will allow any request authorized by one of the policies (ABAC or RBAC), even if the other component does not.

When you run the kube-apiserver at a log level of five or above for the RBAC policy, you can view the RBAC-denied requests in the API server log with the RBAC prefix. This information is useful for determining the appropriate roles for each service account, user, and group.

After you grant roles to each service account and the workloads run without RBAC denials in the server logs, it is safe to remove your ABAC authorizer.

2. Improperly Using Role Aggregation

Role aggregation is available in Kubernetes versions 1.9 and up, allowing you to simplify granting privileges by combining them in defined roles. However, if you don’t carefully review every role aggregation, they can modify the role’s intended use. For example, a 

system:view role might improperly combine rules that violate the role’s purpose, such as using verbs that allow users to modify clusters. 

3. Granting Duplicated Roles

Role definitions can overlap and give users the same level of access in multiple ways. Sometimes, roles may overlap intentionally, with administrators knowingly granting duplicate privileges. However, this configuration is complex and makes it harder to understand which users have each access permission. 

Another issue is that revoking access is more difficult when the administrator doesn’t realize that different role bindings provide the same access.

4. Keeping Unused Roles

If you create a role but don’t grant it to any user, it adds to the complexity of managing RBAC policies without improving security. Likewise, roles that only relate to deleted users (such as a service account in a deleted namespace or a former employee) create excess noise, obscuring the relevant configurations. Removing inactive or unused roles is usually safe, allowing you to focus on active ones.

Kubernetes RBAC Best Practices 

Least Privilege 

Users and service accounts should be assigned the least RBAC permissions they need to perform their roles. Here are some general recommendations for achieving the principle of least privilege:

  • Assign permissions at the namespace level and not for the entire cluster, using RoleBindings instead of ClusterRoleBindings.
  • Avoid providing wildcard permissions, especially for all resources. Kubernetes is a scalable system, so providing wildcard access grants permission for existing object types and also future object types that do not exist today.
  • Do not allow admins to use cluster administrator account. Instead, grant access to less privileged accounts for day-to-day administration tasks. This will prevents accidental modifications to cluster resources and can reduce the impact of insider threats.
  • Do not add users to the system:masters group—any user who is a member of this group bypasses all RBAC permission checks and always has unrestricted superuser access. This action cannot be undone by removing RoleBindings or ClusterRoleBindings. In addition, if the cluster uses an authentication webhook, members of the group can bypass it.

Minimize Distribution of Privileged Tokens

Ideally, you should not assign service accounts with strong privileges to your pods. If your workload requires strong privileges, consider the following:

  • Limit the number of nodes with pods running sensitive workloads—make sure all DaemonSets are really required and run with least privileges to limit the blast radius for container escapes.
  • Do not run sensitive pods next to untrusted or public pods—you can achieve this using taints, tolerations, NodeAffinity, or PodAntiAffinity. Pay particular attention to situations where untrusted pods do not meet the security standards of sensitive pods.

Cluster Administrator Roles

The built-in cluster-admin role grants virtually unlimited access to your cluster. During the migration from legacy ABAC controllers to RBAC, some administrators and users ignored warnings in the documentation and duplicated the broad cluster-admin permission from the old ABAC configuration. Identify if this was done in your cluster and remove this permission.

If a user or group is regularly granted cluster administrator rights, an account compromise or mistake can have dangerously far-reaching effects. Service accounts generally do not need this access. In either case, you should create a more granular role or cluster role and grant it only to specific users who need it.

Kubernetes RBAC with Komodor

Allowing non-experts to easily manipulate and change K8s resources empowers them to troubleshoot independently and reduces toil on DevOps and SRE teams. But, as the saying goes; “with great power comes great responsibility”, and you can’t grant full access without some restrictions.

We’re aware of the fine line between giving too many permissions to giving too little. DevOps and SREs don’t want to do everything alone and become a bottleneck, but are also reluctant to give non-K8s experts too much autonomy and direct shell access, which could potentially result in an ‘elephant in a china shop’ scenario.

We also know that, in most organizations, too many changes to K8s resources can go un-audited. DevOps teams lack visibility into developer access and cannot fully track actions done within the cluster itself.

Hence, we’ve added RBAC support. It allows DevOps, SRE, and Platform teams to customize policies and access control for different teams, as they see fit, without losing track of changes across their Kubernetes infrastructure. This solves the pain of not knowing if and when someone made a change to the cluster, who did it, and what were the ramifications.

Read our documentation for an overview of RBAC in Komodor.

Related content: Read our guide to cluster autoscaler.