Implement Token Exchange External To Internal In Keycloak.
According to Keycloak Documentation, there are multiple token exchange flows available for the OAuth 2.0 Token Exchange specification.
Implement Token Exchange External To Internal In Keycloak.
According to Keycloak Documentation, there are multiple token exchange flows available for the OAuth 2.0 Token Exchange specification.
Use Case
Suppose you have an external Identity Provider (IDP) such as Google Cloud or Microsoft Azure AD. A user authenticates using SSO, and the frontend receives an external access token. The frontend then sends that token to your backend or directly to Keycloak, where it is exchanged for an internal Keycloak token.
In this guide, I will use Google as the external IDP, but the same approach works for other providers as well. I have implemented this setup as POC for my client with minimal configuration changes.
Go to google cloud, add new project or select existing one.

Google Cloud Dashboard
Go to Credentials section

Click on add credentials and add new Oauth Client Id.

Add Client and keep for testing purpose don’t add authorized origin but in prod you must restrict origins. I will be using postman to obtain access token so thats why I have added its callback url.

On same Screen click on OAuth Consent Screen.

Add your details in the opened page after clicking above highlighted link.

Go to Data Section and add required scopes. I have added email,openid and profile scopes. You can add more if you want.

Now move to Keycloak Official Website.
I am using the binary distribution, but you can use Docker or any deployment method you prefer.
Before starting Keycloak, you must enable:
- Token Exchange
- Fine-grained admin permissions v1
The v1 is important; otherwise, some required options will not appear in the admin console.
Go to the bin directory and run:
export KC_FEATURES=token-exchange,admin-fine-grained-authz:v1
Run below command to start the keycloak.
./kc.sh start-dev
If starts, then perfect if you face something like below error because of Java version.

Then you would have to add JVM argument use below command.
./kc.sh start-dev -Dnet.bytebuddy.experimental=true
Now go to http://localhost:8080 add client of type OPEN ID Connect. Follow from screenshots pasted below.

Enable:
- Client Authentication
- Authorization

For development purposes, you can temporarily use * in root URLs, web origins, and redirect URLs. Avoid this in production.
Go client and enable permissions.

On the same screen, click token exchange.

Save and go to client details now.

Click create policy and add policy for the client .


Go back to the the permissions section of your client and assign him the policy.

Add your client id, secret, choose first broker login and save.


Enable permissions.

Assign token exchange policy.


Set up the postman for oauth 2, retrieve your google access token. copy access token will be used in keycloak request to exchange for keycloak local token.

You can replace your access token with google or idp of your choice which allows the token exchange.
curl --location 'http://localhost:8080/realms/your-realm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=client' \
--data-urlencode 'client_secret=secret' \
--data-urlencode 'subject_token=token' \
--data-urlencode 'subject_issuer=google' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
--data-urlencode 'subject_token_type=urn:ietf:params:oauth:token-type:access_token'

I hope this helps.
Thanks
메타데이터
- post_id
- a574b31eea7b
- slug
- implement-token-exchange-external-to-internal-in-keycloak-a574b31eea7b
- url
- https://medium.com/@nabeeltariqbhatti/implement-token-exchange-external-to-internal-in-keycloak-a574b31eea7b
- canonical_url
- https://medium.com/@nabeeltariqbhatti/implement-token-exchange-external-to-internal-in-keycloak-a574b31eea7b
- author_url
- https://medium.com/@nabeeltariqbhatti
- status
- ok
- fetched_at
- 2026-08-01 13:20:37