Kubernetes Role Based Access Control with Service Account

Happy devSecOps

(λx.x)eranga
Effectz.AI
6 min readJun 17, 2022

--

Background

Access control processes and techniques enable you to control which applications and users are either allowed or denied certain access or permissions. Access control is a foundation of Kubernetes security. Kubernetes provides two main access control options, Role-Based Access Control (RBAC) and Attribute-Based Access Control (ABAC). In this post I’m gonna discuss about RBAC. All the deployments which related to this post available in gitlab. Please clone the repo and continue the post.

Kubernetes Authentication and Authorization

Assume you deploying a pod with kubectl apply command. When you type kubectl apply, a few things happen, 1) Reads the configs from your KUBECONFIG, 2) Discovers APIs and objects from the API, 3) Validates the resource client-side (is there any obvious error?), 4) Sends a request with the payload to the kube-apiserver. When the kube-apiserver receives the request, it doesn't store it in etcd immediately. First, it has to verify that the requester is legitimate. In other words, it has to authenticate the request. Just because you have access to the cluster doesn’t mean you can create or read all the resources. So, once authenticated, it checks the requester have permission to create the resource. In other words, check request authorization. The authorization is commonly done with Role-Based Access Control (RBAC). Following diagram shows these authentication and authorization request handling flow of API server.

Role-Based Access Control(RBAC)

If you have a small team and small cluster setup(e.g consisting of only a few nodes) in your organization, you might not have a systematic approach to handle the authorization yet. Perhaps you even granted everyone on your team cluster admin permissions to keep management simple. But not every user needs unrestricted ability to create, modify, and delete resources. As the number of cluster nodes, applications, and team members increases, you’ll want to limit the resources your team members and applications can access, as well as the actions they can take.

RBAC framework in Kubernetes allows you to do just that. For example, it can help to ensure that developers only deploy certain apps to a given namespace or that your infrastructure management teams have view-only access for monitoring tasks. Basically, RBAC defines policies for restricting and controlling user access to resources of a system by using roles attached to users.

User Accounts vs. Service Accounts

In Kubernetes, RBAC permissions/policies can be used to define the access rights of human users(or groups of human users). Kubernetes identifies human users as User Accounts. However, RBAC policies can also govern the behavior of software resources, which Kubernetes identifies as Service Accounts. A Service Account provides an identity for a process that runs in a pod. Service accounts are not User Accounts. User Accounts are used by Administrators and Developers etc, to access the cluster and do some dev work or maintenance. Service Accounts are used by applications and processes to authenticate as they talk to the ApiServer. And these Service Accounts can be restricted by way of Kubernetes RBAC. This allows you to authenticate and restrict access and what that process/application can do.

Every namespace has a default Service Account. And every pod created without specifying a Service Account gets assigned the default Service Account (and it’s token mounted to it as a secret) though it has very few permissions. Therefore, if you want to give more permissions to an application, or want custom control, you’ll want to create a Service Account for your app or process.

Role vs ClusterRole

RBAC authorizations can define permissions/policies that can be limited within a namespace or the entire cluster. To do this, you can define a set of permission is called a Role, which is defined within a namespace. If you want a role that is cluster-wide, this is defined as a ClusterRole. Basically, ClusterRoles and Roles define the actions a user can perform within a cluster or namespace, respectively. Kubernetes allows you to configure custom roles or use default user-facing roles(e.g Cluster Admin, Admin, Edit, View).

RoleBinding vs ClusterRoleBinding

You can assign Roles and ClusterRoles to Kubernetes subjects (e.g users, groups, or service accounts). Roles can be assign to subjects(e.g users, groups, or service accounts) with RoleBindings and ClusterRoles can be assigned to subjects(e.g users, groups, or service accounts) with ClusterRoleBindings. In this post I’m discussing about handling Kubernetes RBAC policies with assigning Roles and Cluster Roles to Service Accounts via RoleBindings and ClusterRoleBindings. There are two main types of permissions handling, 1) Handling RBAC policies in namespace-wide and 2) Handling RBAC policies in cluster-wide.

1. Namespace-Wide RBAC Policies

First I have tested the functionality of namespace-wide RBAC policies which assigns Service Account permissions to namespace via Role and RoleBinding. For that I have created namespace, Services Account, define namespace policies with Role and assigned those policies to Service Account via RoleBinding.

1.1. Create Namespace

First I have checked the RBAC enabled in the Kubernets cluster. Then created a namespace(rahasak).

1.2. Create Service Account

Following is the way to create Service Account. I have assigned this Service Account into previously created rahasak namespace.

Service account has a token. The one I just created is named, rahasak-serviceaccount-token-vntdr. This token is stored as a Kubernetes secret and can be read as a secret. This token is what you’ll use to authenticate your third-party app to the Kubernetes ApiServer.

1.3. Create Role

Following is the way to create Role with different permissions. This Role defines the actions that can be performed(get, watch, list) for the resources pods only in the rahasak namespace.

1.4. Create RoleBinding

This Role can be assigned to Service Account via RoleBinding. So that Service Account can only list, get, watch pods in the rahasak namespace.

1.5. Test Permissions

To test the permissions that assigned to the Service Account, I have used a custom pod with kubectl command inside. It available bibinwilson/docker-kubectl Docker image. I have created a pod with this Docker image and assigned the rahasak-serviceaccount to it. So the pod should only allows to do the permissions specified in the Role(e.g list, get, watch pods in the rahasak namespace). I have deployed this pod, connected to the pod via kubectl exec and check if has the privileges we mentioned in the Role.

2. Cluster-Wide RBAC Policies

Second I have tested the cluster wide RBAC policies which assigning cluster wide Service Account permissions via ClusterRole and ClusterRoleBinding. For that I have created namespace, Services Account, define cluster policies with ClusterRole and assigned those policies to Service Account via ClusterRoleBinding.

2.1. Create Namespace

I have created a different namespace called bassa(previously created namespace, rahasak) for this scenario.

2.2 Create Service Account

Following is the way to create Service Account. I have assigned this Service Account into bassa namespace.

2.3. Create ClusterRole

Following is the way to create ClusterRole with different permissions. This Role defines the actions that can be performed(get, watch, list) for the resources pods. The namespace of the ClusterRole is omitted since ClsterRoles are not namespaced.

2.4. Create ClusterRoleBinding

This ClusterRole can be assigned to Service Account via ClusterRoleBinding. So that Service Account can list, get, watch pods in the cluster(all namespaces).

2.5. Test Permissions

Similar to previous scenario, to test the permissions that assigned to the Service Account, I have used a custom pod with kubectl command inside. It available bibinwilson/docker-kubectl Docker image. I have created a pod with this Docker image and assigned the bassa-serviceaccount to it. So the pod should allows to do the permissions specified in the ClusterRole(e.g list, get, watch pods in the all namespaces in the cluster). I have deployed this pod, connected to the pod via kubectl exec and check if has the privileges we mentioned in the ClusterRole.

Reference

  1. https://octopus.com/blog/k8s-rbac-roles-and-bindings
  2. https://devopscube.com/create-kubernetes-role/
  3. https://about.gitlab.com/blog/2018/08/07/understanding-kubernestes-rbac/#:~:text=RBAC%20vs%20ABAC&text=A%20fundamental%20building%20block%20of,to%20make%20authorization%20policy%20changes.
  4. https://learnk8s.io/rbac-kubernetes
  5. https://sysdig.com/learn-cloud-native/kubernetes-security/kubernetes-rbac/
  6. https://dzone.com/articles/using-rbac-with-service-accounts-in-kubernetes
  7. https://travis.media/kubernetes-service-accounts-complete-guide-for-beginners/
  8. https://goteleport.com/blog/kubernetes-rbac-tips/

--

--