External-to-Internal Token Exchange Best Practices in v26.x: JWT Authorization Grant and Entra ID aud Claim

Hello,

We are seeking guidance on the recommended approach for External-to-Internal Token Exchange in Keycloak v26.6.5.

Our Scenario

  • Architecture: Our application is embedded in an iframe by a third-party application.
  • Domains: The host application and our application reside on different domains.
  • Identity: The host application authenticates users via its own OIDC Identity Provider (IdP).Our application uses Keycloak.
  • Goal: We need to exchange the host application’s Access Token (External) for a Keycloak Access Token (Internal) to authorize API calls from our frontend/backend.

Current Implementation Plan

Based on the documentation for JWT Authorization Grant (RFC 7523) and Identity Chaining, we plan to:

  1. Send the external token to a custom backend endpoint in our application.
  2. The backend performs a grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer request to Keycloak’s token endpoint, using the external token as the assertion.
  3. Keycloak validates the assertion against a configured Identity Provider and issues an internal token.

Questions:

  1. Does this align with the current “best practice” for cross-domain identity chaining in Keycloak 26.x ?
  2. Since this involves an iframe, are there specific recommendations for managing the session (e.g., avoiding the deprecated check-sso iframe approach in favor of this grant)?

The Entra ID aud Claim Issue

While testing with Microsoft Entra ID (v2.0 tokens), we’ve encountered a known limitation: Entra ID v2.0 access tokens do not allow customizing the aud (audience) claim, it is strictly set to the Application ID.

However, Keycloak’s JWT Authorization Grant strictly expects the aud to match either the Keycloak Issuer URL or the Token Endpoint URL (per RFC 7523).

  1. Is there a configuration in Keycloak 26.x to relax this validation or map a custom expected audience for a specific IdP?
  2. If not, is there a plan to support a “Google-style” deviation where the aud can match the Client ID instead?

We would appreciate any insights or corrections to our approach.