How are Keycloak roles managed?
Asked Answered
M

2

53

Keycloak is a great tool, but it lacks proper documentation.

So we have Realm.roles, Client.roles and User.roles

How do there 3 work together when accessing an application using a specific client?

Sincerely,

Multifold answered 15/12, 2017 at 18:1 Comment(0)
K
97

In KeyCloak we have those 3 roles:

  1. Realm Role
  2. Client Role
  3. Composite Role

There are no User Roles in KeyCloak. You most likely confused that with User Role Mapping, which is basically mapping a role (realm, client, or composite) to the specific user

In order to find out how these roles actually work, let's first take a look at a simple Realm model I created. As you can see in picture below, every Realm has one or multiple Clients. And every Client can have multiple Users attached to it.

enter image description here

Now from this it should be easy to conclude how role mappings work.

Realm Role: It is a global role, belonging to that specific realm. You can access it from any client and map to any user. Ex Role: 'Global Admin, Admin'

Client Role: It is a role which belongs only to that specific client. You cannot access that role from a different client. You can only map it to the Users from that client. Ex Roles: 'Employee, Customer'

Composite Role: It is a role that has one or more roles (realm or client ones) associated to it.

Kalisz answered 17/12, 2017 at 17:55 Comment(6)
Thank you, not I am even more confused... How do scopes play in the picture? Are Client roles increasing realm roles or restricting them? What if I have a client for webapp, and a client for mobile, both sharing the same client role?Multifold
Since you already know, KeyCloak community is not so big, therefore, as far as I know, there are no best practices for that case. You can either create a global (realm level) role, and easily access it from both clients, or you can create two identical roles in each client. Depending on your project scale, pick from what suits you best.Kalisz
Thank you, I got it - once again keycloak documentation is really weak in the area. I finally understood how the client can "filter" user roles based on a scope. From your comment, I also leaned the roleId could be "replicated" across multiple clients.Multifold
@Kalisz I have a question, In my project which is java based I want to allow users to view database data as per his/her role. Ofcourse with the help of spring security I can check the role according to user's role but it is possible to handle things on database levels?Translation
Hi @Gurinder, Have you found any configurations or technique to applying keycloak roles at database level?Anatomical
Users are associated with the realm, not with the clients in that realm.Scrooge
B
24

IMO there are some inaccuracies in this thread; hopefully, my answer will help clarify them.

In the Keycloak book titled "Keycloak - Identity and Access Management for Modern Applications: Harness the power of Keycloak, OpenID Connect, and OAuth 2.0 protocols to secure applications" written by two of the core developers, one can read the following:

Keycloak has two categories of roles: realm and client roles.

As the names suggest, realm roles are defined at the realm level, whereas client roles are associated with a given client. Semantically, a realm role represents a user role within the whole organization (i.e., represented by the realm). Client roles represent a "role" that is only meaningful within that client.

Let us use a concrete example: We have a Realm A (representing a company) that contains three clients named account, webapp1, and webapp2; the first client is deployed by default with Keycloak (KC), whereas the remaining are specific to our imaginary organization.

There are two types of users that can use our web apps: regular and admin users. Those can be represented by the roles user and admin, respectively. Since those roles span across our realm clients while retaining their meaning, they are good candidates to be realm roles. So, in KC we would create them as realm roles, and eventually assign them to the users, accordingly. In the access token, those roles would be shown as follows:

"realm_access": {
   "roles": [
     "admin",
     "regular"
 ]
}

If one creates a new user in KC, and then under the tab Role Mappings checks the user roles:

(new UI)

enter image description here

(old UI)

enter image description here

One can see that the user will be assigned the (account) client roles manage-account, managed-account-links, and view-profile. Those roles are only meaningful for that client; they are meaningless for our web apps, for example. Therefore, those are good examples of client roles because their meaning is tightly-coupled with a specific client (i.e., account). In the access token, those roles would be shown as follows:

"resource_access": {
   "account": [
     "roles": [
       "manage-account",
       "managed-account-links",
       "view-profile"
    ]
  ]
}

Let us now imagine that users can pay for a premium account on each of our web apps. To signal to our apps if a user has (or does not) a premium account, we created the role premium.

Should the role premium be a realm role or a client role? Since a user can have a premium account in one web app without necessarily having to have one on the other, we should make premium a client role. So for each client, we would have a separate role named 'premium'. Even though the role name is the same, the meaning changes according to the client. A premium in webapp1 does not mean that the user has a premium in webapp2 and vise-versa.

The access token could look like the following:

"resource_access": {
   "webapp1": [
     "roles": [
       "premium",
       ...
    ]
   "webapp2": [
     "roles": [
       ....
    ]
  ]
}

Each app can easily navigate through the JWT and verify if the user has a premium account associated with that app.

If we now change the requirements so that a user can only have one single global premium account that gives access to all features in all of our web apps in the Realm A, then the role premium should become a realm role because it would now have a global meaning that is transversal to the clients within Realm A.

Composite Roles

From the official Keycloak documentation, one can read:

A composite role is a role that can be associated with other roles.

So if we have a role A composed of role B, whenever we assign role A to a user, role B is also automatically assigned to that user. However, if we instead just assign role B, then role A will not be automatically assigned. This is because role A is composed of role B and not the other way around.

Returning to our example, the role admin could be composed by the realm role regular and the client roles premium from both webapp1 and webapp2.

Special case (Service Account Roles)

Typically, roles are explicitly assigned to users; however, in KC it is also possible to "assign roles to a client" as long as that client has the Client Credentials Grant enabled (or Service account or Service accounts roles using KC terminology).

(new UI)

enter image description here

(old UI)

enter image description here

In reality, KC creates an implicit user and associates it to that client, so in the end the roles are implicitly assigned to this user.

Bellringer answered 29/12, 2022 at 23:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.