4

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

Jonas Gröger
  • 1,558
  • 2
  • 21
  • 35

1 Answers1

3

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

Dominik
  • 2,801
  • 2
  • 33
  • 45
  • 1
    Hey Dominik, this works for a single client. I have thousands of clients and each of them has a publicKey specific to that client. I did not state that in my question above (implicit knowledge) – Jonas Gröger May 22 '21 at 21:37
  • 1
    Hey Jonas, so as far as I can tell (there still is some implicit knowledge) you'd go best by creating a keycloak extension and implement a custom protocol mapper. See the acc. Answer here for details: https://stackoverflow.com/questions/53089776/keycloak-add-extra-claims-from-database-external-source-with-custom-protocol-m (i am at my smartphone right now). – Dominik May 23 '21 at 12:09
  • Thats what I thought. I don't think I can go by just installing Keycloak and be done with it. Something must be developed / installed aswell. – Jonas Gröger May 23 '21 at 13:48