My poor laptop with:
i5-82500U CPU @ 1.6Ghz
8 GB Ram
Docker compose with Keycloak + PostgreSQL
Experiment was to test whether Keycloak can scale to our requirements of fine-grained access control.
To at least be familiar with terminology of resource
, resource's scope
, permission
, policy
in the context of Authorization
We'll model a Pokemon as resource
, and the different read/write access of its different sections of data as scope
E.g. Pokemon-1
as a resource
, and location-read
as a scope
under this resource
.
Total number of
resource
= number of PokemonTotal number of
scope
= number of Pokemon x 2 (access, i.e. read & write) x number of data sections.
We have modelled the "permissions" (not to be confused with Keycloak's permission
) of our data, but how do we control who have these "permissions"? This is done through the use of permission
and policy
.
Best introduced with an example.
To assign any user with the realm role VIRTUAL_TEAM_1
to have access to Pokemon-1
's location-read
.
We have to
- Create a role-based
policy
to allow any user with the roleVIRTUAL_TEAM_1
. - Create a scope-based
permission
that specifies the specificresource
(i.e.Pokemon-1
), and itsscope
(i.e.location-read
), and select thepolicy
we created in the previous step.
If we want to allow VIRTUAL_TEAM_2
to also have the same access, all we need to do is to associate the VRITUAL_TEAM_2 policy
with the scope-based permission
created. Note that the decision_strategy
for this permission have to be set as affirmative
Because we have to create a
permission
for eachscope
xresource
to specify who can access thescope
of a particularresource
(e.g.Pokemon-1
'slocation-read
):The total number of
permission
= number ofresource
xscope
= number of Pokemon x 2 (access, i.e. read & write) x number of data sectionsand..
The total number of
policy
= Number ofVIRTUAL_TEAM
roles (or however we want to group our users, because there are other kinds of policies e.g. user-based policy).
With the data model in mind,
I created:
- 270,000 Pokemons (
resource
), and for each resource, 14 read/write data section (scope
).- Hence, there are 3,780,000
resource,scope
pair
- Hence, there are 3,780,000
- 6 VIRTUAL_TEAM role-based
policy
- For each
resource-scope
pair, apermission
that associates all 6 VIRTUAL_TEAMpolicy
- Hence, there are 3,780,000
permission
- Internally, the database have to store the
permission
topolicy
mapping, this results in a table with slightly over 18,000,000 records
- Hence, there are 3,780,000
Using a user alice
with VIRTUAL_TEAM_1
role
- Get a token first
$ ALICE_TOKEN=$(curl -L -X POST 'http://localhost:8080/auth/realms/master/protocol/openid-connect/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=pokemon-db' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_secret=1821e008-13c5-430d-959e-06c890c687e4' \
--data-urlencode 'scope=openid' \
--data-urlencode 'username=alice' \
--data-urlencode 'password=P@ssw0rd123' | jq -r .access_token)
- Query for the
scopes
of a particularresource
that she has access to
$ curl http://localhost:8080/auth/realms/master/protocol/openid-connect/token \
-H "Authorization: Bearer "$ALICE_TOKEN \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "audience=pokemon-db" --data "permission=Pokemon-1" --data "response_mode=permissions"
[{"scopes":["location-read"],"rsid":"cc78b064-8096-4bd7-8f0f-76600ce2f8cb","rsname":"Pokemon-1"}]
took 42s on the first query, and <50ms on subsequent queries. This is likely due to caching. If we try to remove some form of caching by modifying a permission and firing a subsequent query that relies on that permission, the query takes around 2s.
Loading of specific fields under the Authorization tab under Client hangs (or maybe it just takes a looooong time).
Examples include:
- List of
resource
that have a particularscope
- Most probably due to the fact that many
resource
have the samescope
- Most probably due to the fact that many
- List of
permission
that are dependent on a particularpolicy
- Most probably due to the fact that many
permission
have the samepolicy
- Most probably due to the fact that many
- Evaluate tab, where we can test and evaluate policies given a user, roles
- Most probably because the UI tries to fetch all
permission
on allresource
(even though we may only specify a particular resource)
- Most probably because the UI tries to fetch all