Logo

Kubernetes API authorization using RBAC (Role-based Access Control)

In the previous article we talked about authentication in Kubernetes using TLS certificates. Once the user or service account is authenticated, the kube-api server validates if the action is allowed for whoever making the request.

Kubernetes authorizes API requests using one of the following four different authorization modes and mechanism:

  • Node: A special-purpose authorization mode that grants permissions to kubelets (node component) based on the pods they are scheduled to run.
  • ABAC: Attribute-based access control (ABAC) defines an access control paradigm whereby access rights are granted to users through the use of policies which combine attributes together. The policies can use any type of attributes (user attributes, resource attributes, object, environment attributes, etc.).
  • RBAC: Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within an enterprise. In this context, access is the ability of an individual user to perform a specific task, such as view, create, or modify a file.
  • Webhook: A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST. A web application implementing WebHooks will POST a message to a URL when certain things happen.


For authorization of users and service accounts, it is better to use RBAC. This mechanism declares four kinds of Kubernetes object: Role, Cluster Role, Role Binding and Cluster Role Binding.

Basically, an RBAC Role or Cluster Role contains rules that represent a set of permissions over Kubernetes resources. Permissions are purely additive (there are no "deny" rules as by default all is denied).

What is the difference between a Role and a Cluster Role? An RBAC Role always sets permissions over resources within a particular Kubernetes namespace; when creating a Role, it is necessary to specify the namespace it belongs in. By contrast, a Cluster Role has a scope cluster-wide.

Once a Role or Cluster Role is created, it can be bound to the users and service accounts that need those permissions. For doing that, the Role Binding and Cluster Role Binding objects are used.

How are Roles, Cluster Roles and their respective Binding objects created?

 

Role and Role Binding

In a Role definition file, it is necessary to specify verbs and resources. The verbs are the actions that users or service accounts can perform, and the resources are the objects those actions can be executed upon.

Below is an example of a Role definition file that allows for either 'list' or 'get' of 'pods' in the “backend” namespace.


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

 

Create the role by executing:

$ kubectl create -f role-definition.yaml

 

Now a Role Binding definition file can be created to bind this Role to a user or service account. Inside this definition, it is necessary to specify the name of the user / service account and the name of the existing Role.

The file below binds the previously defined Role to a service account named “sa-token”.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
 
metadata:
  name: pod-reader-binding
  namespace: backend
 
subjects:
- kind: ServiceAccount
  name: sa-token
  apiGroup: rbac.authorization.k8s.io
 
roleRef:
  kind: Role
  name: pod-reader-role
  apiGroup: rbac.authorization.k8s.io

 

Create the Role Binding by running:

$ kubectl create -f role-binding.yaml

 


To find out if the permissions have been applied correctly it is possible to use the kubectl command "auth can i", impersonating the service account with the parameter "--as".  For example:

$ kubectl auth can-i get pods --as system:serviceaccount:backend:sa-token --namespace backend

 

It should return “yes” while the next one should return “no”:

$ kubectl auth can-I create pods --as system:serviceaccount:backend:sa-token --namespace backend

 


In the image above, the RBAC can be observed working properly.

 

Cluster Role and Cluster Role Binding

The definition file for Cluster Roles is very similar to the one  for Roles. The main difference is that in this case it is not necessary to specify any namespace since Cluster Roles are cluster-wide.

Below is an example of a Cluster Role definition.


apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
 
metadata:
  name: secret-reader
 
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list"]

 

The above Cluster Role definition that allows for either 'get' or 'list' of 'secrets' across all the cluster’s namespaces. It is possible to bind Cluster Roles to any user or service account, for doing that a Cluster Role Binding must be created.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
 
metadata:
  name: read-secrets-global
 
subjects:
- kind: Group
  name: manager
  apiGroup: rbac.authorization.k8s.io
 
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io


It is interesting to note that in the Role Binding defined on the previous page the subject was of kind "ServiceAccount". In this example, the kind is "Group". Roles and Cluster Roles can be bound to users (User), groups (Group) and service accounts (ServiceAccount).

Another interesting aspect is that the subjects are an array (defined by a hyphen), that means that there can be many subjects one below the other. In the same definition file of a Role Binding or Cluster Role Binding, we can specify several users, groups or service accounts bound to the same Role or Cluster Role.

To considerably improve the security of a Kubernetes cluster it is important to carry out a correct implementation of RBAC. It is a good practice not only for users and groups but also for service accounts. If a Role or Cluster Role is not bound to a service account, a token called "default" will be used for the Pods; if an attacker compromises one of them, the security of the entire cluster could be endangered.

It is possible to disable the automounting of the default token by specifying “automountServiceAccountToken: false” in the Pod Spec. Although, as mentioned, it is recommended to use RBAC to fully control the authorization of Kubernetes subjects.

Do you want to learn more?

We will give a training about pentesting and securing docker swarm & kubernetes environments at Black Hat USA, HITB and Ekoparty!

Get your ticket!

 

__________

References

Sheila A. Berta
Head of Research at Dreamlab Technologies

Kubernetes API authorization using RBAC (Role-based Access Control)

All blog posts