Understanding RBAC in Kubernetes
Understand how RBAC (Role Based Access Control) works in Kubernetes. Implement RBAC and make sure things are working as expected.

RBAC overview
RBAC or Role Based Access Control is one way of implementing access control in Kubernetes. It can be scoped either to a 'specific namespace' or extended to the 'whole cluster'.
Namespace scoped RBAC
The RBAC rules are scoped to a specific Kubernetes namespace and apply only for resources belonging to that namespace. We use this for instance when we want to give a user or service account permissions to do something on some resources only inside a specific namespace. To implement namespace scoped RBAC, we use the Role and RoleBinding resources.
The Role and RoleBinding resources have to be created inside the namespace we want to limit access control in.
The Role resource defines the permissions. For instance, the permission to list pods. The RoleBinding resource associates the permissions to a user, a group or a service account. The associated user, group or service account will then be granted the permissions defined inside the Role resource and therefore be authorized to perform the associated actions only inside a specific namespace.
Cluster scoped RBAC
The RBAC rules are not limited to specific namespaces and apply to the whole Kubernetes cluster. We use this for instance when we want to give a user, a group or a service account, permissions to do something on some resources (namespacable or not) accross the entire cluster. To implement cluster scoped RBAC, we use the ClusterRole and ClusterRoleBinding resources.
The ClusterRole resource defines the permissions. For instance, the permission to list pods. The ClusterRoleBinding resource associates the permissions to a user, a group or a service account. The associated user, group or service account will then be granted the permissions defined inside the ClusterRole resource and therefore be authorized to perform the associated actions at the cluster level.
Implementing RBAC
Role or ClusterRole resources
Here is a sample Role or ClusterRole resource manifest:
kind: Role # or ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: podsReader
namespace: mynamespace # only for Role resource
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
This sample can be used to create a Role or ClusterRole resource by simply setting the appropriate 'kind' (Role or ClusterRole) and not using the 'metadata.namespace' field for the ClusterRole resource as that resource can't be put into namespaces.
The 'rules' section is the most interesting one because that's where we define the permissions. We need the following elements to define the permissions:
- apiGroups: a list of API groups of the resources we want to set access control for, for instance 'apps', 'batch', etc. Next paragraph describes how to easily find this information for specific resources
- resources: a list of resources types we want to set access control for ('deployments', 'secrets', 'pods', etc.)
- verbs: actions that can be performed on the resources. The list of available verbs, their descriptions and the HTTP verbs equivalent is available here.
How to identify K8s resources API groups
To show a list of 'resources' supported by our Kubernetes cluster and the associated 'apiGroups', we can use the 'kubectl api-resources' command. Here is an example:
$ kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
(...)
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
pods po v1 true Pod
(...)
controllerrevisions apps/v1 true ControllerRevision
daemonsets ds apps/v1 true DaemonSet
deployments deploy apps/v1 true Deployment
replicasets rs apps/v1 true ReplicaSet
statefulsets sts apps/v1 true StatefulSet
(...)
The 'NAME' column indicates the name of the resources supported by our Kubernetes cluster. The 'APIVERSION' column is composed of the 'apiGroups' followed by a version after the slash separator. For the 'deployments' resource for instance, the 'apiGroups' value is 'apps'.
For some of the resources, the 'APIVERSION' does not include their 'apiGroups'. This is the case for instance for the 'pods' resource. This means that the resource belong to the 'core' API group and the value to use for 'apiGroups' in our Role/ClusterRole resources definition is ""
, as shown in the previous Role/ClusterRole sample resource manifest.
RoleBinding or ClusterRoleBinding resources
Here is a sample RoleBinding or ClusterRoleBinding resource manifest:
kind: RoleBinding # or ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: podsReader
namespace: mynamespace # only for RoleBinding resource
subjects:
- kind: ServiceAccount # or User or Group
name: myserviceaccount
namespace: mynamespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role # or ClusterRole
name: podsReader
This sample can be used to create a RoleBinding or ClusterRoleBinding resource by simply setting the appropriate 'kind' (RoleBinding or ClusterRoleBinding) and not using the 'metadata.namespace' field for the ClusterRoleBinding resource as that resource can't be put into namespaces.
It associates an existing Role or ClusterRole resource to an existing service account, in order to grant the service account, permissions defined inside the Role or ClusterRole resource.
Here is an explanation of the contents of the 'subjects' and 'roleRef' fields:
- subjects: defines the subject(s) on which to bound a specific Role or ClusterRole resource
kind
: the type of the subject. Can be 'User', 'Group' or 'ServiceAccount'name
: the name of the subject (a User name, Group name or ServiceAccount name)namespace
: the namespace where to find the subject (only for ServiceAccount Kind)
- roleRef: the Role or ClusterRole that will be bound to the subject
apiGroup
: most of the timerbac.authorization.k8s.io
kind
: the type of the role reference. Can be 'Role' or 'ClusterRole'name
: the name of the 'Role' or 'ClusterRole' that will be bound to the subject
Testing RBAC using impersonation
Once we have configured RBAC to authorize access to specific Kubernetes resources for some users, groups or service accounts, the next thing to do is to test that everything is working as expected.
Having a way to do so whithout asking users to perform specific actions or setting up pods with specific service accounts to verify the access is more convenient. This is where Kubernetes impersonation feature comes in.
Thanks to Kubernetes impersonation feature, we can take the identity of another user, a group or a service account to perform specific actions (list pods inside a specific namespace for instance) and therefore make sure RBAC rules are properly configured.
The user we perform actions as can be a real user from an identity provider system (GCP IAM user for instance) or a non existing/virtual one. The user taking the identity of another user (real or fake/virtual user), a group or a service account, first have to be authorized to do so with a ClusterRole and the associated ClusterRoleBinding as follows:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: impersonation
rules:
- apiGroups: [""] # the core API group
resources: ["user"] # or group or serviceaccount
# Users, groups or serviceaccount name(s)
resourceNames: ["user-to-impersonate@mycompany.com"]
verbs: ["impersonate"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: impersonation
subjects:
- kind: User # or Group or ServiceAccount
name: user-that-impersonate@mycompany.com
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: impersonation
User and group resources, most of the time are custom resources available only when we use Managed Kubernetes service from Cloud Providers like GCP, AWS... and correspond to users and groups available inside the IAM (Identity and Access Management) service they provide for users, groups and services access management.
The previous sample manifest allows the user identified by the 'user-that-impersonate@mycompany.com' email address to take the identity of the user identified by the 'user-to-impersonate@mycompany.com' email address. We can use the same sample manifest to also authorize impersonation of a group or a service account.
Then, 'user-that-impersonate@mycompany.com' can configure RBAC rules for 'user-to-impersonate@mycompany.com' and test the configuration by taking the identity of 'user-to-impersonate@mycompany.com' using the following 'kubectl' commands:
# Run a Kubectl command as another user (--as) or group (--as-group)
$ kubectl --as user-to-impersonate@mycompany.com get pods -n frontend
# Test if a specific Kubectl command will work... without actually running it
kubectl auth can-i get pods -n frontend
# Test if a specific Kubectl command will work for a specific user,
# without actually running it
kubectl auth can-i get pods -n frontend --as user-to-impersonate@mycompany.com
That's all. We now have the essentials knowledge required to understand, implement and test RBAC rules in Kubernetes.