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,
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,
In KeyCloak we have those 3 roles:
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.
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.
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)
(old UI)
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)
(old UI)
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.
© 2022 - 2024 — McMap. All rights reserved.