Update JWT Claims with custom metadata at a later point after sign-in

Hi all

I have been evaluating Keycloak as our identity and access management component and have been quite impressed with all its capabilities.

The only thing that I have been struggling to find out is how to update JWT claims with custom metadata and force refresh them at a later point after the sign-in process.

Some context:

  • We run a (soft) multi-tenant app that has an organization id in each table to scope the data.
  • We have several react frontends and react-native mobile apps connecting to the backend.

Desired flow:

  1. User logs in over Keycloak OIDC at the URL app.domain.com
  2. After a successful login, the user is shown a list of organizations that he/she is part of
  3. The user select the organization that he/she wants to access
  4. Issue: At this point an updated JWT is sent to the frontend with the organization id, user role in the selected business, Hasura headers for the selected business, etc.
  5. With each subsequent API request the organization id and the role is extracted to scope permissions on the database

At step 4 I am facing issues on how to update the OIDC JWT claims and request a new token in the frontend.

Would appreciate any help on this topic!

Point 3. could be a part of the authentication process. With this aproach you would need to write a simple custom authenticator (maybe even script authenticator would be enought for that task) which could present a user with a list of organizations and store the chosen one in a user attribute. The attribute can be further used in claims mapping (e.g. in a script mapper). Point 4. wouldn’t be necessary then.

Did you succeed with it at the end? I have the exact same problem in front of me. Thanks!

First, it’s recommended to manage token lifecycle on the backend instead of the frontend to avoid storing tokens in the browser, which poses a risk.

If you choose to maintain the current setup, here’s how you can achieve it:

  1. Create a client for your frontend application, and a client for each organization.

  2. Create corresponding roles for each organization, and assign these roles to the corresponding users

  3. Create a dedicated scope under “client scope” for each organization (e.g., org1).
    Then for each scope, add a scope on the corresponding roles (third tab on the settings of a client scope).

  4. Under the settings of the frontend app, go to client scope and add these client scopes to the frontend client as optional scopes.

  5. In your frontend application, where you display the list of organizations, for each organization, add a link to initiate the OAuth flow, and specify the name of the organization created as a client scope (step 3) in the scope parameter.

The resulting access token will contain the roles of the current user under the organization provided as a scope, and also the name of this organization in the audience.

Also make sure to disable the full scope allowed setting for the frontend application.

Please note that you can implement this also on the backend side by adding a BFF with and south agent that will handle all the flows.

Hope that will help.