RFsole - Fotolia

Be selective with Kubernetes RBAC permissions

Kubernetes RBAC has some vital best practices that save IT teams frustration and consternation. This brief tutorial takes you through new role creation to permissions management.

Role-based access control is an authorization mechanism used to restrict and control user access to a resource or system based on default or custom-defined roles. Admins can secure IT containerized environments with more granular control using this approach, but they need to follow certain processes so they don't inadvertently create an unwieldy system.

All Kubernetes RBAC role authorization decisions in a cluster are driven by the rbac.authorization.k8s.io API group. As a best practice, always enable RBAC roles in the cluster to ensure projects -- and the organization as a whole -- are more compliant to security best practices.

Kubernetes RBAC best practices to follow in an implementation include the following:

  • Enforce least privilege. By default, all access is denied when RBAC is enabled. IT admins define user permissions at a more granular level. Only grant users their necessary permissions; any unnecessary and elevated permissions increase security risk and attack surface. For example, cluster administrator-level permissions should not be extended to all IT staff.
  • Continuously adjust the RBAC strategy. RBAC isn't self-sustaining -- IT teams can't set up RBAC rules and roles and walk away. Take a slow approach to RBAC testing and validation. Implement RBAC in phases; understand what works for your enterprise or team if a satisfactory state isn't achievable. Set an interval after which to reevaluate the operational state and analyze the environment continuously for any gaps or areas of improvement as the project or organization grows -- for example, the cleanup, or removal, of old user accounts that should be terminated.
  • Reuse roles and don't create too many. Do not create Kubernetes RBAC roles to cater to individual user requirements: This increases risk and attack surface, which defeats the purpose of RBAC permissions. RBAC is not user-based access control -- its job role-based, so roles should be reusable and bind groups of users to the same set of RBAC permissions. RBAC roles reduce administrative effort and improve role assignment efficiency to existing -- and properly vetted -- roles.

Roles, ClusterRoles, RoleBindings, ClusterRoleBindings and Subjects

There are three main components to the Kubernetes RBAC model:

  1. Role and ClusterRole. These are a set of permissions that define the different types of permissions. Roles set permissions on a namespace level, whereas ClusterRoles define cluster-level permission, or for all namespaces present in the ecosystem.
  2. RoleBinding and ClusterRoleBinding. These components are a "species" list of subjects and their corresponding role assignments. RoleBindings bind roles; ClusterRoles manage the namespace level; and ClusterRoleBindings bind a ClusterRole to all the namespaces.
  3. Subjects. Users, groups and service accounts are called subjects in RBAC rules.

Before we can understand how IT admins implement RBAC components in Kubernetes, let's create a user account in a test environment. Although we use an X.509 certificate for this mini tutorial, we could have used a ServiceAccount. But, for the sake of simplicity, we will work with a normal user account.

Create a Kubernetes user account with a certificate

Create a user account, newemployee, and run the following openssl command to create a private key:

openssl genrsa -out newemployee.key 2048

Next, create a Certificate Signing Request (CSR) with the newemployee username we just created:

openssl req -new -key newemployee.key -out newemployee.csr -subj "/CN=newemployee"
Generate an RSA private key to create a new user account
Figure 1. Generate RSA private key

Sign the CSR with Kubernetes CA (Certificate Authority); note that, because I'm using Minikube, my cluster certificate and key are under the ~/minikube/ folder. This setup creates a user certificate newemployee.crt, which is valid for 365 days.

openssl x509 -req -in newemployee.csr -CA ~/.minikube/ca.crt -CAkey ~/.minikube/ca.key -CAcreateserial -out newemployee.crt -days 365

Now create users inside the Kubernetes cluster with the certificate:

kubectl config set-credentials newemployee --client-certificate=newemployee.crt --client-key=newemployee.key

We can also validate the new user quickly via the following command:

kubectl config view -o jsonpath='{.users[*].name}'
New user account, newemployee
Figure 2. Validate the new user account

Now we a have a new user (Subject) in Kubernetes, and can create a Role and assign it to the user (RoleBinding).

Creating a Role and RoleBinding to the user account

Let's create a new namespace and deploy a simple Nginx server as pods in the new namespace:

kubectl create namespace webserver
kubectl create deployment my-nginx --image nginx --namespace webserver
Create a namespace with an Nginx server deployed as a set of Kubernetes pods.
Figure 3. Create a namespace.

Copy the following YAML configuration and save it to a file named roles.yaml: This file defines a role to only perform the list operation on the Nginx pods. This role binds to the newemployee user created in the above section.

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: list-pods
rules:
 - apiGroups: ["*"]
   resources: ["pods"]
   verbs: ["list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: newemployee-list-pods
subjects:
 - apiGroup: ""
   kind: User
   name: newemployee
roleRef:
 apiGroup: ""
 kind: Role
 name: list-pods

Save this file. Then apply this configuration to the namespace with the kubectl apply -f .\role.yaml --namespace webserver command.

Use the YAML configuration file to apply the configuration to the namespace.
Figure 4. Apply the YAML configuration

Pass the username to the --user parameter of kubectl get pods command, which lists the pods running within the namespace. The command will fail if we try to perform any other operation, such as delete, which returns a "forbidden" error. As per the RBAC model enforced in this tutorial, the user newemployee is unauthorized to perform a delete operation.

kubectl get pods --namespace webserver --user newemployee
kubectl delete pod <name of your pod> --namespace webserver --user newemployee
The newemployee account is not authorized to perform other commands, and an attempt returns a forbidden error.
Figure 5. Unauthorized operation error result

Privilege escalation

IT teams will encounter many use cases wherein a user needs escalated privileges. Let's extend this example and grant both list and delete permissions to this user.

Save the following file as role.yaml -- and note that delete is included in the list of the user's approved operations.

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: list-pods
rules:
 - apiGroups: ["*"]
   resources: ["pods"]
   verbs: ["list","delete"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: newemployee-list-pods
subjects:
 - apiGroup: ""
   kind: User
   name: newemployee
roleRef:
 apiGroup: ""
 kind: Role
 name: list-pods

Reapply this configuration.

kubectl apply -f .\role.yaml --namespace webserver
kubectl delete pod <name of your pod> --namespace webserver --user newemployee

The newemployee user role is now authorized to delete the pods in the namespace.

Apply new permissions for additional operations.
Figure 6. Grant newemployee role additional permissions

Next Steps

Adopt a zero-trust framework for a safer IT ecosystem

Dig Deeper on Containers and virtualization

Software Quality
App Architecture
Cloud Computing
SearchAWS
TheServerSide.com
Data Center
Close