19 April 2023
The role-based access control (RBAC) method is often obscure and scary when addressing how to access resources in a Kubernetes cluster. Hopefully, you will have a better understanding and some tools for RBAC policies to become more friendly to you.
The necessary use of RBAC in a Kubernetes cluster
When talking about security, what comes to mind is permissions and accesses. If you have secured your accesses, you have already gone a good way in the security journey.
In various systems, permissions based on roles are used to tackle the security of accesses issues. Kubernetes, through its Role-Based access control (RBAC) method, is no exception.
That being said, to run a secure cluster in Kubernetes, you have to take advantage of RBAC policies. Taking the time to understand how RBAC works is a good investment for securing your cluster in the production environment.
But what is RBAC?
To quote Kubernetes documentation: "Role-based access control (RBAC) is a method of regulating access to a computer or network resources based on the roles of individual users within your organization".
What place has RBAC in Kubernetes?
As you might know, access to the Kubernetes API is controlled through authentication, authorization, and admission control.
After being authenticated (logged in), you can be authorized (grant permission to access) or not.
This authorization phase can be tackled through different methods, and among them, the most used one is Role-based access control.
When access is required for a subject, the RBAC method will check if this subject is enabled to get the access asked:
- The subject can be a user, a group of users, or a service account (the default service account or not).
- Access asked is defined by a resource type (
pods
,secrets
...) and a verb (read
,write
...). Verbs describe the type of access asked in the specific resource.
To learn more about how verbs are defined, you can refer to Kubernetes documentation.
RBAC objects
To answer the access request, RBAC API declares four kinds of Kubernetes objects:
- Role & ClusterRole are used to define a set of permissions. These permissions are described as a list of rules combining resource types and verbs (cf next section for practical examples).
- Roles are at a namespace level (the scope for the set of permissions is the given namespace).
- ClusterRoles are applied across the entire cluster.
- RoleBinding & ClusterRoleBinding are used to connect ("bind") Role or ClusterRole to subjects (user, group, or service account). They hold a list of subjects and a reference to the role being granted (cf next section for practical examples).
- RoleBinding grants the permissions described in a Role or a ClusterRole in a specific namespace (yes you can add a ClusterRole! It will grant the ClusterRole's permissions within the specific namespace of the RoleBinding).
- ClusterRoleBinding grants access cluster-wide.
Why do authorization issues matter?
Through these objects are defined the RBAC policies. The API evaluates all existing policies to allow or deny incoming requests. All parts of an API request must be allowed by some policy in order to proceed. This means that permissions are denied by default.
These policies will enable you to apply the two principles you should remember when managing accesses:
- Principle of least privilege: Every person and application having access to the cluster should have access to the resources he/it needs and not more.
- Separation of duty: Responsibilities in policy implementation should be shared.
Use in Kubernetes
We described where RBAC is used, its components, and why you should dive into authorization issues of your cluster. Great!
And in concrete terms, what does it look like?
RBAC authorization uses the rbac.authorization.k8s.io
API group. To enable RBAC, start the API server with the --authorization-mode
flag, for example:
# Start the API server with RBAC enabled
kube-apiserver --authorization-mode=RBAC --other-options --more-options
# Start the API server with RBAC enabled among other authorization modes
# (ABAC mode is used alongside RBAC mode in this example)
kube-apiserver --authorization-mode=ABAC,RBAC --other-options --more-options
⚠️ As explained, requests are authorized through the API by checking policies. But in case you want to enable another mode as the RBAC, be aware of the behaviour:
The documentation states: "When multiple authorization modules are configured, each is checked in sequence. If any authorizer approves or denies a request, that decision is immediately returned and no other authorizer is consulted. If all modules have no opinion on the request, then the request is denied."
To describe objects (Role, RoleBinding...), or amend them, you can use tools such as kubectl
or write manifests, just like any other Kubernetes object.
Role example from official documentation that can be used to grant read access to pods in the "default" namespace.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
RoleBinding example from official documentation that grants the user "jane" the role defined above. The user will be able to read pods in the "default" namespace.
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
name: jane # "name" is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
# "roleRef" specifies the binding to a Role / ClusterRole
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
Strategies
You are now convinced of the worth of implementing RBAC policies. But how to be practical and invest time to get the advantage of RBAC without drowning yourself in its complexity?
Here are some strategies you can inspire from.
ClusterAdmin for all
You do not have the time to ask yourself who should be authorized to do what? Give all permissions on all resources (cluster-admin
is a built-in high privileged role in Kubernetes) to everyone! Everyone has access to everything, applications can run API commands, developers can access secrets.
❌ You are basically in the worst case in terms of access security. One vulnerability in your cluster and everything can be compromised.
❌ The least privilege and segregation of duties principles are not followed at all.
✅ Your team will however never lack access and complain about restricting policies. And you did not lose time managing RBAC.
❌ But one member of your team can have an unintentional action (developer who deletes secrets thanks to writing access) that will make it difficult to work for the ops team.
If after those warnings, you are nonetheless choosing this strategy, be aware of the consequences it can have. Choose it consciously, by having a high level of trust among your teams and few resources, not by lack of time or laziness.
Create RBAC policies with fine granularity
On the other side of the spectrum from the 'cluster-admin for all' strategy, there are fine granularity policies.
How to implement this strategy?
- At applications level:
- Each application has a specific service account created.
- RBAC policies exist for your service accounts (= a Role linked to your service account through a RoleBinding). These policies only give access to the resources needed by the account (read-only its own secrets and configmap...).
- At users level:
- Same procedure, create RBAC policies to define permissions for all your users.
- Take advantage of groups to make it manageable when having lots of users. You can start with creating a generic reader role, writer role, admin role for example. And getting more precisely by adding specific groups according to your organization's needs
✅ It is one of the best ways in terms of security, you managed the least privilege principle!
❌ The maintenance needs you will encounter are high. Policies need to be updated often and users need to be added to groups manually.
✅ You managed to enforce RBAC really well
Useful tools
After facing different incidents using the 'ClusterAdmin for all' strategy and pulling your hair out on the 'Create RBAC policies with fine granularity' strategy, you will want to get help.
It is time to search for community tools to gain efficiency!
- View accesses
Kube's native way to view access is only at a resource level, for example, kubectl auth can-i list deployments
. If you want to view all resources at once, I suggest you use rakkess, a kubectl plugin (read-only tool). It will show this kind of beautiful access matrix, accessible with the command kubectl access-matrix
if installed via krew
:
-
View unused RBAC objects
Having unused Role, ClusterRole, RoleBinding or ClusterRoleBinding is adding complexity to your RBAC management. To detect them, you can use the sanity scanner Popeye (read-only tool).
- Visualize, analyze and generate your RBAC
You can upgrade from the access matrix given by rakkess with other tools. Both krane and rbac-tool, for example, will enable you to go further in the investigation by generating graphs of accesses, listing specific policies ...
Mastering RBAC policies is a major step for a more secure cluster and you can
achieve it! Remember that you still need other aspects to configure for your cluster to meet
security standards. Good luck on this road to securing your Kubernetes cluster!