A glance of Kubernetes Role-Based-Access-Control (RBAC)

RBAC

1. Metaphor

  • Service Account (SA): "Cheedge" is a worker (identity card).

  • Role/ClusterRole: "Read-Only access to check each bank safe box" (permissions/authorization).

  • RoleBinding/ClusterRoleBinding: The contract that grants this guy permission to access the bank safe box.

So according to above, this guy can access the bank safe box every day, but Read-Only...

2. Define and Use it

After clear the basic meaning for these concepts, let's see a simple example to control create, delete, get, and list operations to cm in the pod:

Scenario:

Grant a service account the ability to create, delete, get, and list ConfigMaps in the default namespace.

1. Create the Role:

Define permissions (get, list, create, delete cm in the default namespace).

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: configmap-manager
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["create", "delete", "get", "list"]

2. Create the Service Account:

Represents the identity of the pod.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: configmap-sa
  namespace: default

3. Create the RoleBinding:

Grant the service account the configmap-manager role.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: configmap-binding
  namespace: default
subjects:
- kind: ServiceAccount
  name: configmap-sa
  namespace: default
roleRef:
  kind: Role
  name: configmap-manager
  apiGroup: rbac.authorization.k8s.io

4. Verify the Setup:

Deploy a pod that uses the service account and test the permissions:

apiVersion: v1
kind: Pod
metadata:
  name: configmap-tester
  namespace: default
spec:
  serviceAccountName: configmap-sa
  containers:
  - name: tester
    image: bitnami/kubectl
    command: ["sleep", "3600"]

Then, exec into the pod and try commands:

kubectl exec -it configmap-tester -- /bin/sh
kubectl create configmap test-config --from-literal=version=1
kubectl get configmaps
kubectl delete configmap test-config

The service account will only be able to perform the actions allowed by the role.

And if we remove create operation in the cm, by edit the role. Then we check again, we will found

$ kubectl create configmap test-config --from-literal=version=1
error: failed to create configmap: configmaps is forbidden: User "system:serviceaccount:default:configmap-sa" cannot create resource "configmaps" in API group "" in the namespace "default"

here, we can see the message said, the sa cannot create the cm.

5. use auth can-i for varification

We can also use kubectl auth can-i command for a quick look of if or not we can DO with the RESOURCE.

kubectl auth can-i VERB RESOURCE --as=[USER|SA] -n NAMESPACE
# eg.
$ k auth can-i create deploy --as=system:serviceaccount:ns1:view-sa -n ns1
yes
$ k auth can-i create deploy --as=new_user -n ns2
no

More Details

There are more details maybe trival but it's better to be clear.

1. Roles ONLY Control Kubernetes Resources

  • Role/ClusterRole is About API Access:

    • Kubernetes Roles and ClusterRoles are specifically designed to manage access to Kubernetes API resources. They do not extend to controlling non-Kubernetes resources, such as files, directories, or system processes.

    • These permissions don't "automatically do anything" unless something in the pod uses them, like kubectl, a Kubernetes SDK (e.g., client-go for Go), or another tool that interacts with the Kubernetes API.

This means if you run a busybox pod with a ServiceAccount that has API permissions, the pod WON'T be able to do anything with those permissions (unless you explicitly install and use tools like kubectl or write a script/application that makes API calls).

2. About User

We can also use rolebinding (or clusterrolebinding) to bind role with user:

kubectl create rolebinding admin-binding \
  --clusterrole=admin \
  --user=user1 \
  --user=user2 \
  --group=group1 \
  --namespace=default

3. Role vs. ClusterRole

  • Use Roles: When you need permissions limited to a specific namespace. This is safer and more restrictive.

  • Use ClusterRoles: When you need permissions across the entire cluster (e.g., managing nodes or resources in multiple namespaces).

Best Practices:

  • Use Roles wherever possible to minimize scope and potential risk.

  • Use ClusterRoles sparingly and only for tasks requiring cluster-wide permissions.

In reality, Roles are more common in multi-tenant clusters, where namespaces isolate workloads. ClusterRoles are used for administrative tasks or by operators that need to manage resources across namespaces.

4. Comparison with Cloud Concepts

KubernetesAWSAzure
Service AccountIAM Role/Instance ProfileManaged Identity
RoleIAM PolicyAzure Role Definition
ClusterRoleIAM Policy (with global permissions)Azure Role Definition (global)
RoleBindingIAM Role Assignment (specific resource)Role Assignment (specific resource)
ClusterRoleBindingIAM Role Assignment (global scope)Role Assignment (global scope)

Key Difference:

  • AWS and Azure combine the concepts of authentication and authorization into a single entity (e.g., IAM Role/Managed Identity), whereas Kubernetes separates them (service account for authentication, role for authorization).