Custom Policy Provider SPI

I’m trying to extend my Keycloak server (or even Keycloak itself) with a custom authorization policy – any chance someone did a similar thing already?

Basically, I’d like to create a custom policy that a user can create, edit, delete from the admin console, with custom fields, rules, evaluation, etc.

I looked into how e.g. RolePolicyProvider is set up and tried doing the same, by setting up a custom Java SPI with a custom PolicyProvider and PolicyProviderFactory - and I managed to deploy the provider, having Keycloak display it.

image

But if I try creating it, Keycloak prompts me with an error “Page not found…”
image

Which I’d expect, as I haven’t defined the fields, form ie. a template yet – but I can’t even find relevant info on how to actually do this.

Are there any docs on how to do this? Has anyone tried doing something similar?

I was faced with the same issue. I created the Policy using the API:

curl --location --request POST 'http://localhost:8080/auth/admin/realms/myrealm/clients/1d7fe657-0184-4449-afe1-44146776c6b9/authz/resource-server/policy' \
--header 'Authorization: Bearer eyJ...' \
--header 'Content-Type: application/json' \
--data-raw '{"name":"My custom policy","type":"myCustomPolicyType"}'

Hi @cristiandmt ,

Could you please share some samples regarding this …?

This is a sample custom policy SPI. It validates only that the username starts with keycloak. GitHub - xjkwak/keycloak-custom-policy-spi: Example about creating a Custom Policy SPI in Keycloak

1 Like

I got the same “page not found” issue.
Has anyone a solution for this?

Hi Cristian,
I downloaded and installed keycloak-custom-policy-spi. I see “Custom Policy” in the drop-down, but when I click it I am getting the same “Page Not Found” issue.

Yeah, I didn’t work on create the form for administering the new policy. That’s why I created the policy without UI by using the endpoint:

curl --location --request POST 'http://localhost:8080/auth/admin/realms/myrealm/clients/1d7fe657-0184-4449-afe1-44146776c6b9/authz/resource-server/policy' \
--header 'Authorization: Bearer eyJ...' \
--header 'Content-Type: application/json' \
--data-raw '{"name":"My custom policy","type":"myCustomPolicyType"}'

Do you have guidelines on how to create a form?

Hi @ertu ,
No I don’t. But you could review the code of the existing policies: keycloak/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy at main · keycloak/keycloak · GitHub

@ertu unfortunately there is no guide on this. I looked into how the existing forms are created, and that’s internal within Keycloak - but it looks like there’s no easy way.

Still, if anyone else comes up with a solution, please share it here!

Actually, I managed to replace the existing RolePolicyProvider. I just copied the code(2 source files) from keycloak github, added my stuff, build the jar and deployed as a new role policy provider.
In the source code I only made sure that the factory is taking my policy provider.
But now I am stuck with getting the scopes of the permission.

I implemented it similar to @cristiandmt but now during the rpt request, we are facing an issue :

PERMISSION_TOKEN_ERROR\norg.keycloak.services.CorsErrorResponseException: HTTP 500 Internal Server Error\n\tat org.keycloak.keycloak-services@17.0.1//org.keycloak.authorization.authorization.AuthorizationTokenService.authorize(AuthorizationTokenService.java:255

can someone assist ?

Hi @ertu, have you added the custom policy successfully in keycloak?

Yes, it was added by overwriting the default Role Policy Provider.

Can you please share your code, I am getting difficulty in getting the template for the custom policy, could you please help in it?

I took 2 files from Github:
RolePolicyProvider.java
RolePolicyProviderFactory.java
I changed the package name to package com.xxx.keycloak.policy.provider;

I made this change to RolePolicyProviderFactory.java:
private RolePolicyProvider provider = new RolePolicyProvider(this::toRepresentation);
was replaced with:
private RolePolicyProvider provider = new com.xxx.keycloak.policy.provider.RolePolicyProvider(
this::toRepresentation);

In the RolePolicyProvider.java file I actually made the changes I needed. So whatever you are up to change it here.

Hope this helps!

Actually I have taken the sample code of cristiandmt and made its jar and deployed it, it is showing in UI in policies list but when I am clicking it, it is showing page error, have you made the template for your custom policy. Also, have you uploaded the jar of these two files?

Do you mean with template the form?
I did not create a template. That is the beauty of the solution: I am overwriting the existent template.
Of course, uploaded and using it.
Uploaded with copying the jar file to “/opt/keycloak/providers” and run “kc.sh build”.

Thanks @ertu, will try it.

@ertu I am getting these errors, could you please help? Do I have to add other classes as well for their reference?