Keycloak in Docker #4 – How to define user privileges and roles

featured image

Keycloak offers a wide variety of methods for defining user permissions and roles. We can configure privileges across a realm or a specific client application. In addition, we can combine permissions by assigning users to groups or creating composite roles.

Prerequsities

User roles in Keycloak

Role is an abstraction that helps to incorporate access details and privileges into a convenient concept. Thanks to this, we can easily assign a set of permissions to users, user groups or more complex roles.

Keycloak roles are defined in a dedicated namespace so that all users with the same roles have identical permissions in that namespace. In other words, realm-level roles are a global namespace for a given realm, while client roles are namespaces intended for specific applications.

In summary, we can manage user permissions in Keycloak with:

  • Realm roles,
  • Client roles,
  • Groups,
  • Composite roles.

What’s more, we can combine these approaches to fine-tune permission management.

Master realm roles

Master is a unique realm that is available by default to allow admins to control other realms. Here we can create multiple super users who will be able to manage all or only selected realms. The documentation specifies two default realm-level roles for master: admin and create-realm:

Users with the admin role are super users and have full access to manage any realm on the server. Users with the create-realm role are allowed to create new realms. They will be granted full access to any new realm they create.

https://www.keycloak.org/docs/16.0/server_admin/#global-roles

Master views other realms as clients with the -realm suffix appended to their names. Consequently, in our example Keycloak server, the Example-Realm-realm is listed among the clients of the master realm:

keycloak realms in the master realm

Furthermore, we can check the role mappings for our default admin account:

roles assigned to a default admin account in Keycloak

Additionally, we can find more details and specifications of the experimental features in the Master realm access control section of the Keycloak documentation.

Realm roles

We need to select Example-Realm to view all roles available in it. In addition to the default offline_access and uma_authorization roles, we can see a role that I created specifically for this realm – user:

user role list for a Keycloak realm

In order to see users associated with a given role, click the role name and go to the Users in Role tab:

users with a specific role

The roles defined within a realm will be effective across all its clients. As a result, we can use them to provide more coarse-grained access control.

Client roles

In Keycloak, each client gets its own role namespace to hold user roles. Roles defined in one client are invisible to other clients. First, we’re going to create a sample application for our realm:

creating client

Then, we can select the Roles tab and click the Add Role button to create the employee role. Finally, we can see all roles assigned to that particular client, just like on the screenshot below:

user roles in a client  defined in Keycloak

Now we can assign this role to users. Keep in mind that this role is only effective for that particular client. It won’t be added to the realm namespace by default, nor will it be visible for other clients.

To see users with a specific role, click the role name and select the Users in Role tab. In addition, we can also preview what client roles will be included in the access token for a given user. Go to Clients → Client Scopes → Evaluate, select a user, click the Evaluate button and go to the Generated Access Token tab, as shown on the screenshot below:

example access token containing client roles

The client roles are listed in the resource_access section of the token.

Groups

We can manage a common set of user privileges and role mappings by assigning them to Keycloak groups.

Group hierarchy and role inheritance

In order to simplify user management, we can utilize privilege inheritance. According to the hierarchy described in the documentation:

A group can have multiple subgroups but a group can have only one parent. Subgroups inherit the attributes and role mappings from their parent. Users inherit the attributes and role mappings from their parent as well.


If you have a parent group and a child group, and a user that belongs only to the child group, the user in the child group inherits the attributes and role mappings of both the parent group and the child group.

https://www.keycloak.org/docs/16.0/server_admin/#proc-managing-groups_server_administration_guide

Let’s explore this concept on a practical example. As an illustration, I want to assign privileges to users according to the following scheme:

Role management example

First, I’m going to create all the roles (publish-release, manage-issue, etc.). For this example, I am creating realm-level roles.

Second, I’m going to create groups and subgroups in the Keycloak groups management view. As a result, I have the structure shown in the screenshot below:

user group hierarchy

Then we can assign our roles to the created groups. To do this, edit a group, go to the Role Mappings tab, select the roles from the Available Roles list and click Add selected. In the screenshot below, you can see the role mapping for the dev-ops group:

assigning roles to a group

Finally, I’m going to assign one of the realm users, carlo, to the dev-ops group:

adding user to a Keycloak group

When we examine his role mappings, we see that his effective roles include not only those directly related to the dev-ops group (manage-issue, publish-release, schedule-downtime), but also those assigned to the development group (create-feature-branch, create-merge-request):

effective roles for a group member

Moreover, the only role I have manually assigned to him is user. Therefore, this is the only role I can manually remove from his role mappings. To remove roles that he has acquired through membership in a specific group, we need to remove him from that group.

Combining realm and client level roles

Earlier in this article, I created a client-level role – the employee role. I can assign this role to all members of the development group:

assigning client role to realm group

As a result, members will have realm-level roles recognized by all clients (e.g. create-feature-branch) and a client-level role (employee) visible only to the example-client application. We can see the result in the effective roles mappings for carlo:

client and realm level roles for a user

Composite roles

Both realm and client-level roles can be marked as Composite. Thanks to this, we can assign them additional roles. In other words, a service with a composite role obtains all the roles associated with that composite. It’s important to realise that we shouldn’t overuse composites as recursive inheritance can lead to convoluted mappings.

Let’s create a client-level role – admin-service, mark it as a composite role and associate it with the backup-database and crawl-pages roles:

creating a composite role

Consequently, by assigning the admin-service role to an application, we also grant it all associated roles. As we can see, we can easily assign a complex set of permissions to services and applications.

Groups vs composite roles

The functions provided by the groups and the composite roles overlap and we technically can achieve the same goal with each of them. However, we should manage users with the former and applications with the latter. As we can read in the docs:

Composite Roles are similar to Groups as they provide the same functionality. The difference between them is conceptual. Composite roles apply the permission model to a set of services and applications. Use composite roles to manage applications and services.

Groups focus on collections of users and their roles in an organization. Use groups to manage users.

https://www.keycloak.org/docs/16.0/server_admin/#con-comparing-groups-roles_server_administration_guide

In addition, in the keycloak-dev mailing list archives from 2015 we can read:

So, keycloak composite roles would be a way to organise rights for a set of applications. (…) Conversely, a keycloak group would provide a way to organize a set of users. (…) Really, in Keycloak with composite roles, you can have a role act as a group. So, while groups and roles are logically the same adding the concept of a group though provides distinction and clarity without overloading the concept of a composite.

https://lists.jboss.org/pipermail/keycloak-dev/2015-November/005735.html

Exporting Keycloak realm with user roles

Keycloak Admin console supports exporting realms. The following example shows how to save a realm with the groups, roles and its clients that we’ve created so far.

First, select the Export option from the menu and check the Export groups and roles and Export clients checkboxes:

exporting keycloak realm with user roles, groups and clients

You’ll get the realm-export.json file that you can save on your machine. Inside you’ll find the roles for Example-Realm and example-client:

If you don’t want to lose these roles when you delete the keycloak containers and their associated volumes, replace the realm-export.json file assigned to the following volume in the docker-compose-keycloak.yml file:

However, we won’t be able to include users in the file created from the Admin console export. Therefore, if you need to export users as well, follow directions provided in the Keycloak in Docker #5 – How to export a realm with users and secrets post or Importing and exporting the database section of the documentation.

If you want to keep the default users and still export realm from the Admin console, just copy the users array from the default-users.json file to your new realm-export.json file.

Read more on user roles in Keycloak

Photo by Mikhail Nilov from Pexels

One thought on “Keycloak in Docker #4 – How to define user privileges and roles

Leave a Reply

Your email address will not be published.