Kubernetes: Authorization Part2- RBAC

Claire Lee
7 min readMar 27, 2023

--

Kubernetes resources can be classified as either namespaced or non-namespaced. You can use the kubectl api-resources command to obtain a list of resources available in the Kubernetes API, along with their namespace scope. To grant permissions to entities within a namespace, you can use Role. To grant permissions that span across the entire cluster, you can use ClusterRole. After defining these roles, you can bind them to specific entities using RoleBinding for Role and ClusterRoleBinding for ClusterRole.

Kubernetes: Authorization Part2- RBAC

Namespaced vs. Non-namespaced Resources

Kubernetes resources can be divided into two categories: namespaced and non-namespaced.

namespaced vs. non-namespaced resources

Namespaced resources are scoped to a specific namespace, which is a logical partition within a cluster that organizes and isolates resources. Each namespaced resource is unique within its namespace. Even though multiple resources in different namespaces may have the same name, they are separate and distinct resources with their own configurations and associated resources. For example, you could have two Pods with the name “web” in two different namespaces “production” and “staging”. Despite the same name, each pod is distinct and has its own configuration and associated resources in its respective namespace.

Non-namespaced resources are cluster-wide, meaning they are not bound to a particular namespace. Each non-namespaced resource is unique across the entire cluster. For example, the Node resource is non-namespaced. Each Kubernetes cluster has a set of nodes that are used to host and run containers. Since nodes are non-namespaced, there can only be one instance of each node resource in the entire cluster.

Kubectl api-resources command

The kubectl api-resources command provides information about resources available in the Kubernetes API, including whether they are namespaced or not.

$ kubectl api-resources

The “NAMESPACED” column in the output indicates whether a resource is namespaced or not. If it’s “true”, the resource is namespaced, and if it’s “false”, it’s non-namespaced.

Part of namespaced resources:

NAME                      SHORTNAMES   APIVERSION                     NAMESPACED   KIND
configmaps cm v1 true ConfigMap
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
pods po v1 true Pod
secrets v1 true Secret
serviceaccounts sa v1 true ServiceAccount
services svc v1 true Service
daemonsets ds apps/v1 true DaemonSet
deployments deploy apps/v1 true Deployment
replicasets rs apps/v1 true ReplicaSet
statefulsets sts apps/v1 true StatefulSet
rolebindings rbac.authorization.k8s.io/v1 true RoleBinding
roles rbac.authorization.k8s.io/v1 true Role

Part of non-namespaced resources:

NAME                     SHORTNAMES   APIVERSION                     NAMESPACED   KIND
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumes pv v1 false PersistentVolume
clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
storageclasses sc storage.k8s.io/v1 false StorageClass

RBAC

In Kubernetes, Role and ClusterRole are used to define a set of permissions that can be granted to entities (such as users, groups, or service accounts) within a namespace or across the entire cluster, respectively. On the other hand, RoleBinding and ClusterroleBinding are used to bind these roles to specific entities.

RBAC

Role and RoleBinding(namespaced scope)

A Role is a set of permissions defined within a namespace that can be granted to entities within that namespace. For example, a role might allow a user to create or update pods within a namespace. A RoleBinding is used to bind a role to one or more entities, such as a user, group, or service account.

However, there may be scenarios where you need to define permissions for resources across multiple namespaces or for the entire cluster. In such cases, using a Role is not sufficient.

ClusterRole and ClusterRoleBinding(cluster-wide scope)

A ClusterRole is similar to a Role, but is defined at the cluster level, meaning it applies to all namespaces within the cluster. For example, a Clusterrole might allow a user to view all pods in the cluster. A ClusterRoleBinding is used to bind a clusterrole to an entity, such as a user, group, or service account, across all namespaces in the cluster.

Short Name

There are no short names for Role, RoleBinding, ClusterRole, and ClusterRoleBinding resources.

RBAC with YAML

Role and RoleBinding

role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: <role_name>
namespace: <namespace_name>
rules:
- apiGroups: ["<group_name>"] # "" for the core API group
resources: ["<namespaced_resource>"]
verbs: ["<verb1>", "<verb2>", ..., "<verbN>"]

If you are unfamiliar with apiGroups, consider reviewing “the Kubernetes documentation on Core and Named API Groups“.

role-binding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: <rolebinding_name>
# The namespace of the RoleBinding determines where the permissions are granted.
# This only grants permissions within the "<namespace_name>" namespace.
namespace: <namespace_name>
subjects:
- kind: <User or Group or ServiceAccount>
name: <user_name or group_name or service_account_name>
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: <role_name>
apiGroup: rbac.authorization.k8s.io

example:

# developer-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev
name: developer
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "create"]

# developer-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-rolebinding
namespace: dev
subjects:
- kind: User
name: dev-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io

You can use resourceNames field to specify the name of the resource that the Role applies to.

role-specify-resource-name.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: <role_name>
namespace: <namespace_name>
rules:
- apiGroups: ["<group_name>"] # "" for the core API group
resources: ["<namespaced_resource>"]
resourceNames: ["<resource_name1>", "<resource_name2>", ..., "<resource_nameN>"]
verbs: ["<verb1>", "<verb2>", ..., "<verbN>"]

ClusterRole and ClusterRoleBinding

cluster-role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: <cluster_role_name>
# "namespace" omitted since ClusterRoles are not namespaced
rules:
- apiGroups: ["<group_name>"] # "" for the core API group
resources: ["<resource>"]
verbs: ["<verb1>", "<verb2>", ..., "<verbN>"]

cluster-role-binding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: <cluster_role_binding_name>
subjects:
- kind: <User or Group or ServiceAccount>
name: <user_name or group_name or service_account_name>
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: <cluster_role_name>
apiGroup: rbac.authorization.k8s.io

example:

# admin-cluster-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: admin-cluster-role
rules:
- apiGroups: [""]
resources: ["pods", "services", "deployments"]
verbs: ["get", "list", "watch", "update", "create"]

# admin-cluster-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-cluster-role-binding
subjects:
- kind: User
name: admin-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: admin-cluster-role
apiGroup: rbac.authorization.k8s.io

You can add a resourceNames field to specify the name of the resource that the ClusterRole applies to.

cluster-role-with-resource-name.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: <clusterrole_name>
# "namespace" omitted since ClusterRoles are not namespaced
rules:
- apiGroups: ["<group_name>"] # "" for the core API group
resources: ["<resource>"]
resourceNames: ["<resource_name1>", "<resource_name2>", ..., "<resource_nameN>"]
verbs: ["<verb1>", "<verb2>", ..., "<verbN>"]

Commands

commands
  1. Create a new Role in the specified namespace, granting the specified verbs on the specified resources.
$ kubectl create role <role-name> 
--verb=<verb>
--resource=<resource>
--namespace=<namespace>

2. Create a new RoleBinding in the specified namespace, binding the specified Role to the specified user.

$ kubectl create rolebinding <rolebinding-name> 
--role=<role-name>
--user=<user-name>
--namespace=<namespace>

3. Create a new ClusterRole, granting the specified verbs on the specified resources across the entire cluster.

$ kubectl create clusterrole <clusterrole-name> 
--verb=<verb>
--resource=<resource>

4. Create a new ClusterRoleBinding, binding the specified ClusterRole to the specified user across the entire cluster.

$ kubectl create clusterrolebinding <clusterrolebinding-name> 
--clusterrole=<clusterrole-name>
--user=<user-name>

5. Check if the current user has the required permissions to perform a specific action on a particular resource within a specific namespace.

$ kubectl auth can-i <verb> <resource> --namespace <namespace_name>

6. Check if a user, group, or service account has the required permissions to perform a specific action on a particular resource within a specific namespace.

  • User
$ kubectl auth can-i <verb> <resource> --namespace <namespace_name> 
--as <user-name>
  • Group
$ kubectl auth can-i <verb> <resource> --namespace <namespace_name> 
--as-group <group-name>
  • Service account
$ kubectl auth can-i <verb> <resource> --namespace <namespace_name> 
--as system:serviceaccount:<namespace>:<service-account-name>

Return a“yes” or “no” answer, indicating whether the user has the necessary permissions.

--

--