Kubernetes(K8s) role-based access control is a powerful tool in restricting access to resources within a Kubernetes cluster. In this post, we shall briefly discuss what role-based access control is, and how to set it up in Kubernetes. I promise, it's not as long a process as you may think. What is role-based access control? Role-based access control(RBAC) is a security model in which users are assigned roles, and can then be granted access to certain resources based on those roles. For example, an organisation can have a role-based access control system that allows DevOps engineers to perform privileged operations within the entire Kubernetes cluster, while restricting the application developers to only viewing information about their applications deployed in a given namespace. Definitions Before setting up RBAC in Kubernetes, let's review some of the key concepts that we are going to be dealing with: are identities that can be used to delegate access to Kubernetes resources within a namespace. They can be used by users or services. We shall do some minor tweaks later on in the article using clusterrolebindings to enable us override the "namespacedness" limitation. Service accounts are objects within a Kubernetes cluster that we aim to implement role-based access control around. Examples include pods, deployments, replicasets, configmaps, and services. Resources are collections of permissions that are applied within a given namespace. In most cases, these consist of a set of permissions that can be granted to service accounts. Roles are the association of a role with a service account. In other words, rolebindings are used to assign roles. Think of a rolebinding as a mechanism to plug a set of permissions(a ) to a service account. Rolebindings role are roles that can be assigned to service accounts within a Kubernetes cluster. Whereas roles are namespaced, clusterroles apply to the entire cluster. Some default ones in a k8s cluster include view, edit, admin, and cluster-admin. Clusterroles are associations of a clusterrole with a service account. As you might have guessed, clusterrolebindings enable us assign cluster wide permissions to a service accounts through clusterroles. Clusterrolebindings Now let us see how we can set up RBAC in Kubernetes. How to set up a Kubernetes cluster using RBAC Prerequisites A working Kubernetes cluster. If you don't have one yet, you might find helpful. It lists a couple of ways you could setup a K8s cluster. this post Kubectl. You can install kubectl following . this guide Kubernetes 1.20 or later. Earlier versions of Kubernetes are no longer actively maintained and RBAC in those versions is not as stable. can guide you through the process. This documentation if you intend on using it in the section later on. The Kubernetes Dashboard Access the Kubernetes dashboard Setting up RBAC within a namespace First, let us create a namespace which we are going to be working with. Let's call it . dev-env kubectl create namespace dev-env Enter fullscreen mode Exit fullscreen mode Output: Next, create a service account called which we shall use all through out. app-dev kubectl create serviceaccount app-dev --namespace dev-env Enter fullscreen mode Exit fullscreen mode Output: We shall follow this up by creating an admin role that has all rights within the namespace. Below is its manifest, which is also available . dev-env on GitHub kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: admin namespace: dev-env rules: - apiGroups: ["*"] resources: ["*"] verbs: ["*"] Enter fullscreen mode Exit fullscreen mode Apply the file to create the role. admin kubectl apply -f https://raw.githubusercontent.com/123MwanjeMike/k8s-rbac/main/admin-role.yaml Enter fullscreen mode Exit fullscreen mode Output: Note: We shall be creating the rest of the Kubernetes resources in this tutorial from the pre-written manifest files in as we have done above. However, you may also edit these manifests if you wish to create K8s resources tailored to your needs. this repository / 123MwanjeMike k8s-rbac Setting up Kubernetes role based access control tutorial manifests k8s-rbac A list of Kubernetes resources for setting up of role-based access control in the article Set up Kubernetes role based access control View on GitHub Next,create a rolebinding, , of the role to the service account. Below is the manifest. app-dev-rolebinding admin app-dev kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: app-dev-rolebinding namespace: dev-env subjects: - kind: ServiceAccount name: app-dev namespace: dev-env roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: admin Enter fullscreen mode Exit fullscreen mode Run the command below to create it. kubectl apply -f https://raw.githubusercontent.com/123MwanjeMike/k8s-rbac/main/rolebinding.yaml Enter fullscreen mode Exit fullscreen mode Output: Our service account is now an admin within the namespace. We can even go further and define access rights for it across the entire cluster. Let's say, basing on our DevOps engineer and application developer example we had at the start, that we want our application developers to view any resource cluster wide and even to use the Kubernetes dashboard. How we can we do this? dev-env Setting up RBAC for the entire cluster For the first part, we're in luck! Kubernetes has a default view clusterrole which can be used for viewing of all resources in a cluster; and so we shall just leverage this. We shall create a clusterrolebinding, , that does just that. app-dev-view kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: app-dev-view subjects: - kind: ServiceAccount name: app-dev namespace: dev-env roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: view Enter fullscreen mode Exit fullscreen mode Create the clusterrolebinding kubectl apply -f https://raw.githubusercontent.com/123MwanjeMike/k8s-rbac/main/clusterrolebindings/view.yaml Enter fullscreen mode Exit fullscreen mode Now, for to access the Kubernetes dashboard, we could easily just create a bind the default clusterrole to it since it has the access rights needed for this. However, this would also give the service account more permissions than it should have and so we want to use a more fine-grained clusterrole in accordance to the principle of least privileges. app-dev edit So, we shall create a custom clusterrole with only the required permissions needed to access the K8s dashboard on top of those already held by the service account through default clusterrole. view kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: view-addition-for-k8s-dashboard-access rules: - apiGroups: [""] resources: ["pods/attach", "pods/exec", "pods/portforward", "pods/proxy", "services/proxy"] verbs: ["get", "list", "watch", "create"] - apiGroups: [""] resources: ["services"] verbs: ["proxy"] Enter fullscreen mode Exit fullscreen mode Run the command below to create the clusterrole with the above definition. view-addition-for-k8s-dashboard-access kubectl apply -f https://raw.githubusercontent.com/123MwanjeMike/k8s-rbac/main/custom-clusterrole.yaml Enter fullscreen mode Exit fullscreen mode We can now bind clusterrole to the service account for it access the K8s dashboard. Let's have a look at the clusterrolebinding manifest for this. view-addition-for-k8s-dashboard-access app-dev kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: app-dev-use-k8s-dashboard subjects: - kind: ServiceAccount name: app-dev namespace: dev-env roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: view-addition-for-k8s-dashboard-access Enter fullscreen mode Exit fullscreen mode Create the clusterrolebinding app-dev-use-k8s-dashboard kubectl apply -f https://raw.githubusercontent.com/123MwanjeMike/k8s-rbac/main/clusterrolebindings/use-k8s-dashboard.yaml Enter fullscreen mode Exit fullscreen mode Our service account can now be used by our "application developers" to create applications in the namespace and conveniently access the k8s dashboard. app-dev dev-env Putting it to use Create a kubectl configuration We are going to need a token for the service account and so to get it, run the commands below app-dev export NAMESPACE="dev-env" export SERVICE_ACCOUNT="app-dev" kubectl -n ${NAMESPACE} describe secret $(kubectl -n ${NAMESPACE} get secret | (grep ${SERVICE_ACCOUNT} || echo "$_") | awk '{print $1}') | grep token: | awk '{print $2}'\n Enter fullscreen mode Exit fullscreen mode Your output will be some long string. It should start with something similar to what I have below. Save that somewhere temporarily. token Next, get the certificate data by running the command below in the same terminal where you had defined the and variables. NAMESPACE SERVICE_ACCOUNT kubectl -n ${NAMESPACE} get secret `kubectl -n ${NAMESPACE} get secret | (grep ${SERVICE_ACCOUNT} || echo "$_") | awk '{print $1}'` -o "jsonpath={.data['ca\.crt']}" Enter fullscreen mode Exit fullscreen mode Your output will be another long string whose beginning is something similar to what I have below. Save that somewhere temporarily. certificate data With these two, we let's create our kubectl config file. You might already have a *.kube/config *which you might still need. So, we shall back it up as .kube/config.bak and create a new one for the . Run the commands below to do precisely that. app-dev cd mv .kube/config .kube/config.bak nano .kube/config Enter fullscreen mode Exit fullscreen mode This will open the nano text editor. Fill in the template below paste in the editor. Make sure to substitute the , , , and with the correct values before saving the changes. Remember to delete the token and certificate data from where you had temporarily saved them. certificate-data server-ip-address cluster-name token apiVersion: v1 clusters: - cluster: certificate-authority-data: <certificate-data> server: https://<server-ip-address>:6443 name: <cluster-name> contexts: - context: cluster: <cluster-name> namespace: dev-env user: app-dev name: <cluster-name> current-context: dev-env kind: Config preferences: {} users: - name: app-dev user: client-key-data: <certificate-data> token: <token> Enter fullscreen mode Exit fullscreen mode Access the Kubernetes dashboard Run and click to access the dashboard. kubectl proxy here Sign in with the .kube/config we created in the previous step. Attempt to create a user role in the dev-env namespace with the manifest below. All should go on well. kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: test-admin namespace: dev-env rules: apiGroups: [" "] verbs: ["*"] "] resources: [" Enter fullscreen mode Exit fullscreen mode Attempt to create the user role in the kube-public namespace with the manifest below. kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: test-admin namespace: kube-public rules: apiGroups: [" "] verbs: ["*"] "] resources: [" Enter fullscreen mode Exit fullscreen mode Tadaa We did it. has no such rights outside the namespace. All application developers can now use that .kube/config file to gain controlled access to the cluster app-dev dev-env Conclusion In this post, we looked at how we can implement RBAC not only at the namespace level, but also at the cluster level. We specifically used a service account given that it is managed by Kubernetes taking away this task from us. It is also important to note that Kubernetes also user accounts as much as it does service accounts. One key difference between the two is that user accounts represent actual Kubernetes users unlike the service accounts. I hope you enjoyed this article and that you'll show support of some sort as I'd greatly appreciate that. And if you have any thoughts or questions in relation to this, feel free to drop them via the comments section. I'd love to hear from you. Happy hacking Additional resources Using RBAC Authorization Kubernetes default clusterroles definitions The principle of least privileges Also published . here