Before diving into Kubernetes, let's take discuss how you'd grant access to resources.
For example, how would you authorize access to apps?
The simplest idea is to assign permissions to users.
Mo is an admin and can do anything.
Alice is a dev and has read-only access.
This authorization system works but has a limitation: you have to re-assign permissions every time you add users.
And worse, all permissions are duplicated.
If you have to remove write access to all users, you have to edit all of them.
What's the alternative?
Instead of assigning permissions to users directly, you could assign them to a generic profile.
Let's create a profile "admin" and assign all the permissions.
And you could have a "dev" with read-only.
Finally, you could assign those generic profiles to users.
Mo is the "admin" and Alice a "dev".
If there's a new dev joining the team, you can assign the "dev" profile again.
Those profiles are usually called Roles.
And that's how you have Role-Based Access Control (RBAC).
Now that we've discussed how to grant permissions, it's time to look at the resources.
What are you giving access to?
Example: you can list Pods, but not Secrets.
Or: you can use the default namespace, but not kube-system.
What about users?
In Kubernetes, Roles can be assigned to external users (humans!) or bots (applications inside the cluster).
You can also have groups that are a mix of both.
So let's recap:
- You have users (humans, bots, groups).
- You create roles to grant permissions to the API endpoints.
- You link roles to users.
The last step is called binding, and it's usually done through another object called RoleBinding that links identities to roles.
There's one thing to remember, though.
Roles and RoleBindings are created in a namespace, and they grant access to resources in the current namespace.
What happens when you want to grant access to global resources, such as Nodes or Persistent Volumes?
It'd be great if there were a way to define a profile as global instead of being scoped to a namespace.
Well, you just invented the ClusterRole — a global role that applies to the entire cluster.
To link an identity to a global role, we use a ClusterRoleBinding.
What happens when you link a "standard" ClusterRole to a RoleBinding?
Is it even possible?
The user will have all the permissions from the ClusterRole but scoped in the current namespace of the RoleBinding.
Lastly a few useful kubectl commands that I find helpful:
- User-impersonation with "kubectl --as=jenkins".
- Verifying API access with "kubectl auth can-i ".
You can also combine them.
This thread is a very short summary of Arthur's article on the @learnk8s blog: https://learnk8s.io/rbac-kubernetes.
If you want to dig deeper into Kubernetes and RBAC, make sure to check it out.
And finally, if you've enjoyed this short post, you might also like the Kubernetes workshops that we run at Learnk8s or this collection of past Twitter threads https://twitter.com/danielepolencic/status/1298543151901155330.
Until next time!