If you manage a Kubernetes cluster, sooner or later, you'll need to assign roles and permissions to users so that everyone has visibility and access only to the resources they need. For example, some users must have read-only access, while others must only be able to write to certain resources or APIs. In addition, there must be users with unlimited access to all available resources.
Suppose you have a team of four users:
- Patricia: leader of the dev team
- James: part of the dev team
- Oliver: leader of the QA team
- Amelia: part of the QA team
James works on one of the many projects within the company's cluster and therefore needs access to your namespace. Patricia, being the dev leader, needs full access to all projects. Oliver, likewise, needs full read access to all objects in the cluster. However, Amelia is working on the same project as James and can only have read access in this namespace.
Role-based access control (RBAC) is an authorization mechanism built to handle such cases. In this article, we will discuss what RBAC API is and how you can use Kubernetes RBAC API to develop secure applications.
What is RBAC?
The concept of role-based access control is not something new. RBAC is based on the concepts of roles, permissions, and user groups, and it's one of the most widespread access control models being used in organizations today.
In organizational use, RBAC allows you to create secure access models based on the real functions that people have within the organization rather than on the actions they must be able to perform.
What is the RBAC API, and how is it used in Kubernetes?
Kubernetes (as of version 1.6) introduced the concept of role-based access control as a system for distributing access rights to various objects in a Kubernetes cluster.
Objects in a Kubernetes cluster are YAML manifests, and permissions determine which user can only view the manifests and who can create, modify, or even delete them.
Before we go into how RBAC works in Kubernetes, it's important to understand what a user is in Kubernetes. Everyone who sends requests to the API server is a user in a Kubernetes cluster. This means that not only administrators and developers are users, but also various CI/CD scripts and control plane, kubelet, and kube-proxy components on nodes are considered users.
The RBAC model includes five entities:
- Role
- RoleBinding
- ClusterRole
- ClusterRoleBinding
- ServiceAccount
Let's explore each entity in more detail.
Role
The role is a YAML manifest that describes a set of rights on Kubernetes cluster objects.
Here it's important to understand that cluster objects are YAML manifests stored in etcd. The API server checks all rights as they relate to the requests that the API server receives.
If you restrict the user to execute kubectl exec, but that user has access to the worker node, then they will not be able to block it from entering the worker node and doing docker exec in the RBAC container.
We can go to the cluster, and in ns ingress-nginx, look at the role: ingress-nginx:
Here we are interested in the rules section. This is a list of rules that describe access rights.
In each rule, we have three parameters. Let's look at an example:
Here apiGroups: describes the manifest API group. If only the version is specified in apiVersion—without a group, for example, as in the Pod manifest—then this manifest is considered to have the so-called root group (core-group). In the role, the root group is specified as an empty string.
The resources: parameter refers to a list of resources to which we describe access. You can view the list of resources in your cluster with the command kubectl api-resources. Some sub-resources describe specific actions. For example, the pods/log sub-resource allows you to view container logs in a pod.
The verbs: parameter is a list of actions that you can perform on the resources described above: get, view the list, monitor changes, edit, delete, etc.
RoleBinding
Let's now look at the RoleBinding manifest:
It has two types of fields: roleRef and subjects:
Here's what we have:
- roleRef specifies the role.
- subjects specifies who will be assigned this role.
- kind specifies permissions for requests not authenticated through a token from the service account.
ClusterRole
The role entity is namespace dependent and we can create roles with the same name in different namespaces. While ClusterRole is a cluster object, this entity describes the rights to objects in the entire cluster.
Kubernetes has many preconfigured cluster roles. These include the admin, edit, and view roles, which describe the rights that allow administrating, editing, or only viewing entities. If you have administrator rights, you can view the role in your cluster with the following command:
ClusterRoleBinding
RoleBinding only gives access to entities in the same namespace as the RoleBinding manifest. ClusterRoleBinding allows you to grant access to entities in all cluster namespaces simultaneously.
Service Account
Kubernetes knows nothing about users in the form we are used to seeing them in when it comes to other access restriction systems, where users have a login or a password. Still, it has mechanisms for calling external password verification services, such as oidc, a user certificate verification option, or even the usual HTTP basic auth with the classic Apache file htpasswd.
ServiceAccount was created primarily to limit the rights of applications that run in a cluster. All communication between cluster components goes through requests to the API server, and a special JWT token just authorizes each such request. This token is automatically generated when an object of the ServiceAccount type is created and placed in secret.
How to use RBAC API in Kubernetes
RBAC authorization is one way to assign roles to users in a Kubernetes cluster. Here are the steps:
1. Connect the service account token. Without this token, you will need to re-download kubeconfig after any change in roles.
2. Assign roles. Here's an example manifest that creates two namespaces and two users, each of which will only be able to manage pods in their own namespace:
3. Run the manifest.
4. Create tokens:
5. Manually add tokens to users in the kubeconfig.yaml file for authorization without a password:
6. Check the distribution of roles:
The test-sa-two user now has access to pods in the test-two namespace and no access to the test-one namespace. Similarly, the "test-sa-one" user has access to pods in the test-one namespace but not those in the test-two namespace.
Kubernetes RBAC as a Security Strategy
The RBAC model has proved particularly effective for managing roles and is now considered a Kubernetes security best practice.
RBAC reduces the risk of unwanted access to critical resources and allows you to implement the principle of least privilege by giving access to only needed resources, which makes your cluster more secure.
Moreover, if you are using RBAC, you don't have to check the individual permissions assigned to each user. You can monitor who has access to resources simply by consulting roles, which makes auditing easier.
Conclusion
In summary, RBAC API is a role-based approach to giving permissions to an object in a Kubernetes cluster. By making it part of the Kubernetes pipeline, you can improve governance and significantly strengthen security.
About Release
Release is the simplest way to spin up even the most complicated environments. We specialize in taking your complicated application and data and making reproducible environments on-demand.
Speed up time to production with Release
Get isolated, full-stack environments to test, stage, debug, and experiment with their code freely.