@changa, I've rewritten my answer based on our discussion. Hope this helps!
Let me first clarify some key areas before I answer. My main focus on the answer that you've linked was really on how to play around the Evaluate
tool and I didn't really dive too deeply into some of the concepts - so let's do that :)
In Keycloak, you'll encounter Client and Authorization Scopes. For a formal definition of these terms please check out the Core Concepts and Terms in the Server Administration Guide, but simply put:
Client Scopes are scopes which are granted to clients when they are requested via the scope
parameter (once the resource owner permits it). Note that there's also the concept of Default Client Scope
but I've chosen to keep things simple. Furthermore, you can leverage protocol and role scope mappers to tailor what claims and assertions are present in the access token.
Authorization Scopes on the other hand are granted to clients after successful evaluation of the policies against a protected resource. These scopes are not granted to clients based on user consent.
The key differences between the two is really when and how a client obtains these scopes. To help you visualize all of this, here's a scenario:
A renowned martial artist called Bob
authenticates via Keycloak
Bob
get presented with a consent screen where he is asked to share his name, his fighting style and his age.
Bob
chooses to give access to his name and fighting style but he declines to share his age.
When we inspect the token now, we would see the following (completely made up) entries for the scope
attribute of the access token: name
and fighting_style
.
Additionally, let's assume that we've set up a couple of protocol mappers (e.g. User Attribute Mapper Type - there are a ton) to display the values for full name and fighting style via the following token claims: fighter_name
and martial_arts
when the two Client Scopes
above are present in the access token. In addition to two previously mentioned scopes, we would also see something like fighter_name: Robert Richards
and martial_arts: Freestyle Karate
when examining the access token.
- Side Note: Given the length of this answer, I've decided to skip this topic but please check out this awesome video at around the 7 minute mark along with the associated GitHub Project for more information. The README is pretty good.
Additionally, let's assume that Bob
is mapped to a realm role called Contestant
and a client role of Fighter
and we did place any restrictions in Keycloak when it comes to sharing this info. So in addition to all the things mentioned above, we would see that information inside the token as well.
- Needless to say, this is an oversimplification on my part as I'm simply setting up the stage for demo. purposes and there's much more information inside the access token.
Bob
doesn't like how the tournament bracket is laid out as he's eager to fight the world champ as soon as possible, so he attempts to change his placement by sending a request against tournament/tekken6/bracket/{id}
. This resource is associated with the scope bracket:modify
. Additionally, there is a permission which associates the resource in question with a role based policy named Referee Role Required
. If Bob
were a Referee
then he would be granted the bracket:modify
scope but since he isn't, then he is denied that scope.
- I've barely touched the surface when it comes to the inner workings of the Authorization process in Keycloak. For more information, check out this practical guide. You can do some pretty cool stuff with UMA.
Ok, so that's enough theory. Let's set up our environment to demo all of this. I'm using the following:
- A realm called
demo
- A client called
my-demo-client
- A client scope called
client_roles
- 2 users -
paul
and law
- Two realms level roles -
Admin
and Reader
- Two client level roles -
demo-admin
and demo-reader
Please note that I will using Keycloak 12.0.4 and I will skip almost all the basic setup instructions. I will only share the relevant bits. If you're not sure how to set this all up, please check out the Getting Started Guide or this answer. The answer contains steps for version 8 but the differences are very minor as far as I could tell.
Associating Users And Roles
In order to associate paul
with the Admin
, Reader
, bank-admin
and bank-reader
roles, please do the following:
- Click on
Users
> View all users
> Click on the ID
value for paul
> Click on Role Mappings
> Under Realm Roles
move Admin
and Reader
under Assigned Roles
> Select my-demo-client
under the Client Roles
select box and move demo-admin
and demo-reader
under Assigned Roles
like so

- As for
law
we'll just associate him with Reader
and bank-reader
.
Associating a client scope with a client
Create a Client Scope by:
- Clicking on the
Client Scopes
link on the left > Click on Create
> Enter custom-client-scope
for the Name
field and Hit Save. It should look like this

- Click on
Clients
on the left > Select the my-demo-client
> Click on the Client Scopes
tab at the top > and let's just move it to Assigned Default Client Scopes
for convenience.
Inspecting the Access Token
We can easily generate an access token for our setup via Keycloak to see what it looks like. In order to do so:
Click on Evaluate
tab under Client Scopes
.
Select paul
as the user
Click on the blue Evaluate
button
Click on Generated Access Token
. While inspecting the token, look for:
resource_access
to see client level roles associated with paul
realm_access
to see paul
's realm level roles
scope
to see the Client Scope
that we created called custom-client-scope

If you generate a token for law
, you would see less roles when compared to paul
.
Obtaining a Scope After Policy Evaluation
Continuing with our setup:
- I've created an
account/{id}
resource with two Authorization Scopes
called account:read
and account:modify
like so

- Additionally, I've created two role based policies called
Only Reader Role Policy
and Only Admin Role Policy
where the former requires the Reader
realm role while the latter requires the Admin
realm role. Here's an example for reference.

Note that you can further enhance that policy at the client level if you wish but to keep things simple, I chose not to do so.
Furthermore, I've created two scoped based permissions called Read Account Scope Permission
and Modify Account Scope Permission
.
The Read Account Scope Permission
will grant the account:read
Authorization Scope
if the user is either an Admin
or a Reader
. One key thing to notice here is the the Decision Strategy has to be set to Affirmative
in order to achieve this behavior.

Modify Account Permission
on the other hand grants the account:modify
Authorization Scope
to users with the Admin
role.

- Now, if you choose the evaluate the user
paul
(remember he is both Admin
and Reader
) against the Account Resource
, he will be granted both the account:read
and account:modify
Authorization Scopes
. Let's see if this true. Here's our Evaluate
screen and notice that I did not associate any roles with paul
since this was already done via the Users
> Role Mappings
tab

- And here are the results of that evaluation as predicted

- Here is the evaluation result for
law
. Since he's not an Admin
he'll be denied the account:modify
scope but he'll be granted the account:read
scope.

- And finally, we can further confirm this by click on
Show Authorization Data
which shows the permissions inside the access token for law

Hopefully this helps you see where each piece of the puzzle fits in your architecture. Cheers!