Kubernetes RBAC — Update default ClusterRoles without editing them

Sumanth Reddy
3 min readJan 9, 2022

Kubernetes RBAC helps us control access to various resources on the cluster. The RBAC API declares four kinds of Kubernetes object: Role, ClusterRole, RoleBinding and ClusterRoleBinding. In simpler terms, the concept of RBAC is as follows

  1. There are multiple actions which can be performed on various resources like GET, POST, WATCH, LIST, PATCH etc.
  2. You group all the actions on resources which can be performed for easier management. These are Role and ClusterRole.
  3. You now assign these grouped permissions to Users using RoleBinding and ClusterRoleBinding.

Role and RoleBinding are at namespace level, ClusterRole and ClusterRoleBinding are at cluster level.

There are also default ClusterRoles created by Kubernetes out of the box. You can find them at https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles. Listing them here for ease

  • cluster-admin Allows super-user access to perform any action on any resource
  • admin — Full admin access, intended to be granted within a namespace
  • edit — Edit access except for editing RBAC
  • view — Allows view for most of objects

Now this is all good in theory, but real time use cases are always different. In my case the team wanted the access as below —

  1. Basic access — Full view plus rudimentary edit access to resources like deleting pods, exec’ing to pods, editing HPA etc. at namespace level.
  2. Edit access — Edit access to all resources at namespace level.

Now this mean i can’t just use View ClusterRole for #1 because we needed few edit accesses as well. Another way is maintaining our own list of View + edit accesses as another ClusterRole. This felt redundant and need to update ClusterRole for new CRD’s every now and then. This is where the Aggregated ClusterRoles come to help. Quoting from doc

You can aggregate several ClusterRoles into one combined ClusterRole. A controller, running as part of the cluster control plane, watches for ClusterRole objects with an aggregationRule set. The aggregationRule defines a label selector that the controller uses to match other ClusterRole objects that should be combined into the rules field of this one.

So in layman terms, we can maintain multiple separate ClusterRoles and bubble/aggregate them to other cluster roles without editing them directly.

We maintain just the extra rules in our own ClusterRole.

This is same as just any other ordinary ClusterRole but with one exception of the label

rbac.authorization.k8s.io/aggregate-to-view: "true"

Now when we check the main View ClusterRole we can find that our rules are automatically aggregated into it dynamically 😱😍

The magic here is done by aggregationRule in the ClusterRole. The controller watches the ClusterRoles and merges the rules from other ClusterRoles which has the label defined, and in our case:

rbac.authorization.k8s.io/aggregate-to-view: true

NOTE — This method aggregates the rules to default View ClusterRole which might be used by third party serviceaccounts and others. Use with caution.

--

--