How to specify client-specific custom attribute in access token

3.1k views Asked by At

I have a Keycloak setup and I'm using the client_credential flow to create access tokens for thousands of back-ends.

I would like to include another custom field in the access token, so next to exp etc., I'd like to have a field publicKey. This field is specific and unique for each of the clients.

Is that possible using Keycloak?

EDIT: Clarified that I have many back-ends and each of them has a specific and unique publicKey

1

There are 1 answers

3
Dominik On

I assume you have a hard-coded value inside the claim publicKey. If so, this will suffice: You create a custom scope who issues the token. So assuming you have a Client Backend, which wants to exchange a user token for a serviceaccount-token to reach out to a downstream service client_credentials_service, and this serviceaccount-token should have the publicKey attribute inside, here's one way you could do it:

  1. In your realm, create and save a new Scope under Client Scopesin admin UI. client scopes example

  2. Go to Client Scopes -> publicKeyScope -> Mappers -> create and create a new hardcoded claim, example below: hard coded mappers example

  3. Open your client client_credentials_service and switch to tab Client Scopes client example

Here you could add your new scope either as default or as optional scope to your client. optional means, in the request you make to kcs token endpoint to obtain a token via client_credentials flow, you have to add the scope=publicKeyScope param. e.g. like this:

curl --location --request POST 'http://localhost:8080/auth/realms/yourRealm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=client_credentials_service' \
--data-urlencode 'client_secret=your-secret' \
--data-urlencode 'scope=email publicKeyScope' \
--data-urlencode 'grant_type=client_credentials'

When it's added as default, you don't have to explicitly add the desired scope to the request.

As long as you're not adding this scope (or the corresponding mapping) to another client, only your client_credentials_service token obtained via client credentials flow will include this claim.

Example for resulting token: token result example