Skip to main content

Availability

Available from Tyk 5.15.0.

Introduction

Microsoft Entra ID solves delegated, on-behalf-of authentication with its On-Behalf-Of (OBO) flow. Entra rejects the RFC 8693 token exchange grant outright, failing with unsupported_grant_type (AADSTS70003), so Entra cannot be configured as a standard token exchange provider. On the wire, OBO is the standard RFC 7523 JWT bearer grant plus a small number of Microsoft conventions, each of which maps onto existing token exchange configuration: the grantType: jwt-bearer provider setting, customParams, and the defaultTarget audience and scopes fields. Token exchange runs under the OAuth 2.0 (External IdP) security scheme.

Prerequisites

Before configuring token exchange against Entra, you need:
  • An Entra app registration for the middle-tier API, which is the application Tyk Gateway authenticates as when it calls the downstream API on the caller’s behalf.
  • That app registration’s Application (client) ID.
  • Either a client secret, or a certificate uploaded to Tyk Gateway’s certificate store if you want to authenticate with private_key_jwt instead of a shared secret.
  • The downstream API’s exposed scopes, as they appear on the app registration’s Expose an API page (for example Orders.Read).

Configure the Provider

Set grantType: jwt-bearer on the provider and point it at your tenant’s Entra endpoints:
A few fields are worth calling out:
  • clientAuth.method: client_secret_post is the simplest path. For production, Microsoft recommends certificate-based authentication: set method: private_key_jwt and certId to a certificate already uploaded to Tyk Gateway’s certificate store instead of clientSecret. See Client Authentication for the private_key_jwt fields and its RSA-only constraint.
  • customParams.requested_token_use: on_behalf_of is Entra’s OBO switch. Any IdP-specific form parameter travels through customParams the same way.
  • defaultTarget.audience and defaultTarget.scopes are the same fields RFC 8693 providers use. Under jwt-bearer, Tyk Gateway renders them into the wire request differently, see Scope Rendering.

The Request Entra Receives

Given the configuration above, Tyk Gateway sends:
This is the request described in Microsoft’s On-Behalf-Of flow documentation.

Requesting All Consented Permissions

To request every permission your application has been statically granted on an API, rather than naming scopes individually, write the fully-qualified .default scope directly:
Because this scope already contains a /, Tyk’s scope rendering rule passes it through verbatim instead of prefixing it with audience/.

Scope Grammar Constraints

Entra allows only one downstream resource per token request, and rejects a request that mixes .default with named permissions. Tyk Gateway does not validate Entra’s scope grammar. A configuration that violates one of these rules fails at runtime with an AADSTS error, for example AADSTS70011, reported through the idp_error outcome. Check the structured logs for the relayed error code and description.

Conditional Access and Step-Up Authentication

If the downstream API sits behind a Conditional Access policy or requires MFA, Entra responds to the exchange with interaction_required. Tyk’s step-up authentication relay is always active for the jwt-bearer grant and needs no configuration. It returns a 401 challenge to the original caller instead of failing the exchange, so an MSAL-based (or similar) client can complete the step-up and retry.

Multi-Tenant Applications

If your API serves users from multiple Entra tenants and you cannot enumerate every tenant ID up front, use a regex: issuer entry and a claim variable in tokenEndpoint instead of listing each tenant explicitly:
See Multi-Tenant Issuer Matching for how the regex: prefix and the $tyk_context.jwt_claims_tid token endpoint variable work.
A regex: issuer entry controls which provider a token is routed to, not which tenants are trusted. Trust is decided by the JWT authentication scheme’s allowedIssuers list. Pairing a permissive regex: entry with an empty or permissive allowedIssuers accepts any Entra tenant, so set allowedIssuers deliberately to the tenants you want to trust.