Keycloak Javascript policy deployment

April 19, 2023 

Introduction

This article tries to include everything you need to know about Keycloak Javascript policy deployment. By Javascript policies I mean authorization policies of Javascript type attached to Keycloak clients that have authorization enabled. If you don't know what Keycloak authorization services are, you are probably in the wrong place.

While the process of creating and deploying the JAR files is pretty well documented, it is not altogether clear for the uninitiated how the policies are shown in Keycloak.

Some history first

In Keycloak versions prior to 7.0.1 you could create Javascript-based authorization policies using the Admin Console for your Keycloak clients. That of course required that the client had authorization enabled. In subsequent Keycloak versions you had to enable this feature separately. There were two ways to do this:

  • Pass -Dkeycloak.profile.feature.upload_scripts=enabled option on startup
  • Add feature.upload_scripts=enabled to $KEYCLOAK_HOME/configuration/profile.properties.

The script upload feature which you could use to create Javascript policies in the Admin Console was later removed from Keycloak for security reasons. The new and better way to deploy Javascript policies is to distribute them to Keycloak as JAR files.

Keycloak Javascript policy deployment with a JAR file

You can create JAR files with Javascript policies easily. You need two things:

  1. The Javascript file(s) you want to use as policies
  2. A metadata file

Start by creating a directory with the following layout:

.
├── META-INF
│   └── keycloak-scripts.json
└── policy.js

The policy.js is the actual policy you want to deploy. The filename has no special meaning, so you could as well use foobar.js if you wanted. Here is a trivial example:

$evaluation.grant();

The keycloak-scripts.json file contains metadata related to the policy:

{
    "policies": [
        {
            "name": "MyPolicy",
            "fileName": "policy.js",
            "description": "My Policy"
        }
    ]
}

Multiple policies can be present in a single JAR file. You can also distribute mappers and authenticators alongside with policies, but that's outside of the scope of this article.

You can create a JAR file with either "jar" or "zip". On Linux you would do the following:

$ zip -r policy.jar META-INF/ policy.js 
  adding: META-INF/ (stored 0%)
  adding: META-INF/keycloak-scripts.json (deflated 39%)
  adding: policy.js (stored 0%)

The archive contents should look like this:

$ zipinfo policy.jar 
Archive:  policy.jar
Zip file size: 665 bytes, number of entries: 3
drwxr-xr-x  3.0 unx        0 bx stor 23-Apr-18 10:52 META-INF/
-rw-r--r--  3.0 unx      208 tx defN 23-Apr-18 10:52 META-INF/keycloak-scripts.json
-rwxr-xr-x  3.0 unx       21 tx stor 23-Apr-18 10:52 policy.js
3 files, 229 bytes uncompressed, 147 bytes compressed:  35.8%

So, the Javascript file, policy.js, at the root level and keycloak-scripts.json under META-INF.

Deploying the JAR file

If you are using non-Quarkus versions of Keycloak you can just drop the JAR file to the auto-deployment directory (e.g. /opt/keycloak/standalone/deployments) and should get deployed. On Quarkus versions of Keycloak you'd put the JAR file into $KEYCLOAK_HOME/providers and run kc.sh build.

Checking if the deployment was successful

Typically you can check systemd unit status or Keycloak logs to see if the deployment was successful. The best way, though, is to use the "Server Info" page:

  1. Login as Keycloak admin user
  2. Click on the user menu
  3. Select "Server Info"
  4. Click on the "Provider" tab
  5. Navigate to the "Policy" section
  6. Check if your policy (e.g. "script-policy.js") is present

The final and conclusive test is to attach the policy to a Keycloak client which has authorization enabled.

How to attach the policies to a Keycloak client

This is the part that nobody really bothered documenting so it took me off guard. The authorization policies you could upload from the Admin Console were already of the "Javascript type". Policies that are deployed using JAR files actually become their own policy type. For example, given the JAR file above you should find a new policy of type "MyPolicy" under the Keycloak client's authorization policies dropdown menu. You can attach the same policy to the same client multiple times if you want, as long as you use a different policy name.

Samuli Seppänen
Samuli Seppänen
Author archive
menucross-circle