Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@webdeb
Last active October 29, 2022 19:03
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save webdeb/d8a99df9023f01b78e3e8ff580abe10b to your computer and use it in GitHub Desktop.
Save webdeb/d8a99df9023f01b78e3e8ff580abe10b to your computer and use it in GitHub Desktop.
Basic Keycloak Script Mapper to provide Hasura claims

Steps to provide Hasura Claims in Keycloak generated JWT

  1. Create your realm / client
  2. Inside client configuration go to "Mappers"
  3. Click on "Create"
  4. Name it "hasura"
  5. Choose Mapper Type "Script Mapper"
  6. Add following script to demonstrate how it works
/**
 * Available variables: 
 * user - the current user (UserModel)
 * realm - the current realm (RealmModel)
 * token - the current token (TokenModel)
 * userSession - the current userSession (UserSessionModel)
 * keycloakSession - the current keycloakSession (KeycloakSessionModel)
 */


//insert your code here...
var roles = [];
for each (var role in user.getRoleMappings()) roles.push(role.getName());
token.setOtherClaims("https://hasura.io/jwt/claims", {
    "x-hasura-user-id": user.getId(),
    "x-hasura-allowed-roles": Java.to(roles, "java.lang.String[]"),
    "x-hasura-default-role": "user",
});

Thats it, the next step is just to verify your settings

  1. Go to clients -> your-client -> Scopes -> Evaluate
  2. Select an user, and see the generated JWT payload in "Generated Access Token" Tab

Update: Keycloak has a new policy. they disable ScriptMappers by default You have to start the instance with this flag:

-Dkeycloak.profile.feature.upload_scripts=enabled

@webdeb
Copy link
Author

webdeb commented Jan 25, 2021

Now how can we sync our Keycloak users with Hasura.

I would't at all. Just let the user sign-in and use your app, load the user by id, if not found, create the new user.

@lukwil
Copy link

lukwil commented Feb 28, 2021

If someone wants to use composite roles (as I did) and wonders how to do so, here is my working script:

var roles = [];
for each (var role in user.getRoleMappings()) {
    if (role.isComposite()) {
        var composites = role.getComposites();
        var compositeRoleNames = [];
        for each (var composite in composites) {
            compositeRoleNames.push(composite.getName());
        }
        // push all composite role names to roles (equal to modern JS ...compositeNames)
        Array.prototype.push.apply(roles, compositeRoleNames);
    }
    // include role itself, not just possible composites
    roles.push(role.getName());
};

token.setOtherClaims("https://hasura.io/jwt/claims", {
    "x-hasura-user-id": user.getId(),
    "x-hasura-allowed-roles": Java.to(roles, "java.lang.String[]"),
    "x-hasura-default-role": "user",
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment