Protecting your cluster with RBAC

Alex Izuka
5 min readMar 29, 2023

--

One of the reasons people will use an application is knowing it’s safe. Once an application becomes compromised, its usage will drop drastically. This is more reason security is of utmost importance when building an application. We understand that Kubernetes host most application we use today, this is a reason we will be examining ways we can protect our cluster, and one of those ways is through RBAC.

Protecting a cluster with RBAC

Role-Based Access control

Role-Based Access Control (also known as RBAC) is a security mechanism used in controlling access into a Kubernetes cluster. RBAC allows administrators to define access policies that grant access or limit users or system access to our Kubernetes.

RBAC is implemented using a set of Kubernetes objects, including roles, role bindings, and service accounts.

A role is a set of rules that define what actions can be performed on a specific resource, a role binding is used to bind a role to a user or group of users, while a service account represents an identity that can be used by pods running in a Kubernetes cluster.

Working with RBAC

Role and Role Binding

We will be illustrating the usage of an RBAC in a cluster. We will first start with roles and role-binding.

Before we get our hands dirty, we have to understand that role-binding work within a namespace. What is a namespace? A namespace can be described as a way to organize clusters into virtual sub-clusters — they can be helpful when different teams or projects share a Kubernetes cluster.

Normally, when you deploy your cluster and pods and don’t define a namespace, Kubernetes creates a namespace by default for you, and any pod you deploy will be found in the default namespace, but this is not the best practice, as your resources are vulnerable to anyone that has access to your cluster. So, it’s advised your resources are placed within a namespace, so you can control access with the developers that have access to it.

To create a namespace, we use this command:

kubectl create namespace development

We called our namespace development

To view our namespace and others created alongside our cluster, we use this command:

kubectl get namespaces

To describe our newly created, we use this command:

kubectl describe namespace development

After creating our namespace, let’s assume we want to grant a user named Frank access to our resources as one of our engineers, we will then create a role that allows Frank to view and work with our pods (where our application), and also create a role binding that binds the role to Frank

For our Role, we use this Kubernetes object:

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

The kind is called role, apiVersionis from Kubernetesrbac authorization , our created namespace development as we created (it is important to indicate our namespace in our manifest file), then we describe the rules; that it can interact with our pods, and do the following activities like get, watch and list .

We create the role on the terminal with this command:

kubectl apply -f </path-to-role-manifest-file.yaml>

Next, we create our role binding, which binds our user Frank to our pods/resources and gives him access:

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

You will note in our manifest file that our kind is now RoleBinding which means we are now binding our user to our pods in our development. What this means is that Frank has access to all pods in our created development namespace. You will observe that frank’s name was indicated in our manifest file.

We create our role binding with the command below on our terminal:

kubectl apply -f </path-to-role-binding-manifest-file.yaml>

Doing this protects your application and gives you an idea of to has access to your pods, avoiding security breaches.

To check our created role, we use the command:

kubectl get roles <role-name> -n <namespace>

To check the status of the role binding, we use this command:

kubectl get rolebindings <role-binding-name> -n <namespace>

Cluster role and its binding.

While role binding protects against or limits usage to just a namespace, cluster binding has to do with all information to the cluster. This means if a cluster binding is in place, even with your configuration credentials you won’t still have access to the cluster. With the cluster role and its binding in place, you can have access to all namespaces in the cluster.

We will still be using Frank as our user in this scenario, to create the cluster role we will use the Kubernetes object below:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-manager
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "get", "watch", "list", "update", "patch", "delete"]

Our kind in this scenario is called ClusterRole and the rule is to have access to all pods within the cluster. The actions it can carry out within the cluster are to create, get, watch, list, update, patch, and delete.

To create the cluster role, we use the command below on our terminal:

kubectl apply -f </path-to-cluster-role-manifest-file.yaml>

With this created, we can create the Cluster role binding:

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: manage-pods
subjects:
- kind: User
name: frank
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: pod-manager
apiGroup: rbac.authorization.k8s.io

With this in place, if we configure our cluster, only frank will have access to it even though others have the Kubernetes credentials.

To create our cluster role binding, we use this command:

kubectl apply -f </path-to-cluster-role-binding-manifest-file.yaml>

To check our created cluster role, we use this command:

kubectl get roles <cluster-role-name> -n <namespace>

To get the status of our cluster role binding, we use this command:

kubectl get clusterrolebindings <cluster-role-binding-name>

Summary

We have seen one of the ways we can limit access to both our cluster and our application. This is one measure that guarantees safety and reduces security breaches.

--

--

Alex Izuka
Alex Izuka

No responses yet