In one line: a client uses OAuth Token Exchange to get a short-lived, IdP-signed grant (the ID-JAG) for a Resource Authorization Server that already trusts the same IdP for SSO, then redeems it with the JWT Bearer grant for an access token without sending the user through a consent redirect.
What this is
When one application needs a user's data at another application, it normally starts an interactive OAuth flow that the IdP both apps use for SSO never sees (Section 1). This draft defines Cross-App Access (XAA), where the shared IdP brokers that access instead. The client presents its Identity Assertion (an OpenID Connect ID Token or SAML 2.0 assertion) or, optionally, an IdP Refresh Token to the IdP's token endpoint using Token Exchange (RFC 8693). The IdP returns an Identity Assertion JWT Authorization Grant (ID-JAG): a JWT with typ oauth-id-jag+jwt whose audience is the Resource Authorization Server (Section 3). The client redeems it at the Resource Authorization Server as an RFC 7523 JWT bearer grant. The Resource Authorization Server stays the issuer of access tokens and applies its own local policy to what it grants (Section 1). The draft is a profile of the Identity Chaining draft and is a Standards Track WG document in the OAuth working group (datatracker states: Active, I-D Exists, WG Document).
How it works
Diagram
sequenceDiagram
participant C as Client
participant I as IdP Authorization Server
participant R as Resource Authorization Server
participant S as Resource Server
C->>I: User SSO (OpenID Connect or SAML)
I-->>C: ID Token or SAML assertion, optional Refresh Token
C->>I: Token Exchange (subject_token, audience, resource, scope, client authentication)
I-->>C: ID-JAG (issued_token_type id-jag, token_type N_A)
C->>R: JWT bearer grant with the ID-JAG as assertion
R-->>C: Access token
C->>S: API request with access token- The user signs in to the Client at the IdP using OpenID Connect or SAML; the Client gets an Identity Assertion and optionally a Refresh Token (Section 4.2).
- The Client sends a Token Exchange request to the IdP with
requested_token_type=urn:ietf:params:oauth:token-type:id-jag, exactly oneaudience(the Resource Authorization Server), a recommendedresource, optionalscopeorauthorization_details, and the subject token (Section 4.3). - The IdP MUST authenticate the Client, validate the subject token, check policy, and return a signed ID-JAG in the
access_tokenfield of the response (Sections 4.3.3 and 4.3.4). - The Client posts the ID-JAG to the Resource Authorization Server's token endpoint as
urn:ietf:params:oauth:grant-type:jwt-bearer(orjwt-dpopfor a DPoP-bound ID-JAG), normally authenticating with its registered credentials; a sender-constrained ID-JAG may be redeemed without client authentication (Section 4.4). - The Resource Authorization Server validates
typ,iss, signature,aud,client_id, tenant,cnf, and the resource, scope and authorization details, and then issues an access token (Section 4.4.1). - The Client calls the Resource Server with the access token. The Resource Server trusts only the Resource Authorization Server, not the IdP (Section 2.1).
Use cases
- Enterprise SaaS-to-SaaS integration: a SaaS app obtains an access token to a third-party SaaS API for a user without an interactive consent flow, with the enterprise IdP deciding which client may reach which application (Appendix A.1).
- Customer identity (CIAM): a first-party customer application invokes third-party developer SaaS components for the signed-in customer, with the CIAM platform acting as the IdP (Appendix A.2).
- Email and calendaring clients: a client with no pre-registered OAuth client at the IdP or the Resource Authorization Server identifies itself with a Client ID Metadata Document and authenticates with a private key, for example using private_key_jwt (Appendix A.3).
- AI agent calling external tools: the agent discovers the tool's authorization server through Protected Resource Metadata, checks for the
id-jaggrant profile, tries the silent ID-JAG path first, and otherwise falls back to an interactive authorization code flow (Appendix A.4). - SAML-based SSO deployments: a client that uses SAML for SSO swaps its assertion for an IdP Refresh Token, then uses that token as the subject token to get ID-JAGs (Section 4.5).
Why This Matters Now
- Trigger: the top OAuth WG deep-dive candidate after triage, whose note (in
tracks/oauth-wg/data/normalized/candidates.json) cites broad normative changes. Comparing the texts shows that most of those changes (client authentication at the IdP, a single audience, mTLS binding, new metadata) landed in -05. -06 changed the IdP error code for a failed subject token. - Source evidence: the announcement on the OAuth list says the diff looks big but mostly tightens wording based on feedback from many new implementations, and that the flow and overall design have not changed. It calls out the IdP authenticating the Client, a single audience,
invalid_requestreplacinginvalid_grantfor failed subject tokens, key-bound ID-JAGs replacing client authentication at the Resource Authorization Server, mTLS as a second binding option,id_jag_signing_alg_values_supported, and a new Privacy Considerations section. - Expected impact: implementers of the IdP side of Token Exchange need to re-check error handling and client authentication. Resource Authorization Server implementers need to re-check the client-authentication alternative, the
cnfhandling, tenant checks and resource governance checks. The draft expires on 4 May 2027 (Status of This Memo), and the author says remaining open issues are to be discussed at IETF 127.
What Changed
- Spec/document change summary: the -05 to -06 diff (https://author-tools.ietf.org/iddiff?url1=draft-ietf-oauth-identity-assertion-authz-grant-05&url2=draft-ietf-oauth-identity-assertion-authz-grant-06) shows two substantive edits. The IdP error for a subject token that fails validation changes from
invalid_granttoinvalid_request, "as required by Section 2.2.2 of RFC 8693", and the Client is told it can get a new subject token and retry (Section 4.3.4.3). The draft also explains whyaccess_deniedis used instead ofinvalid_targetwhen the Client or End-User is not authorized for the target: so that the Client can tell a forbidden target from an unrecognized one. The rest of that diff is dates, version strings and Document History lines. - The Document History in -06 lists a long set of items under -05. The -04 and -05 texts show that the IdP client-authentication rule with
invalid_clientand the single-audience rule (Section 4.3.3), mTLS binding (Section 9.11.2),id_jag_signing_alg_values_supported(Section 7.1) and Privacy Considerations (Section 10) are absent from -04 and present in -05. -06 only adds the missing history lines. -05 was posted on 30 October 2026, and -06 on 31 October 2026 with 80 pages (Datatracker history, linked under Sources). spec-notes.md attributes each change to its revision. - Section 4.3.3 requires the IdP to reject a request without client authentication with
invalid_client. Section 4.4 requires the Resource Authorization Server to reject a request with neither client authentication nor a sender-constrained ID-JAG withinvalid_client. - Section 3 makes RS256 mandatory to implement for both the IdP and the Resource Authorization Server, and says Resource Authorization Servers SHOULD also support ES256. Section 7.1 says that if
id_jag_signing_alg_values_supportedis present it MUST include RS256. - Compatibility or migration concerns: an IdP that returns
invalid_grantfor a bad subject token is no longer conformant with -06 and clients that key retry logic oninvalid_grantat the Token Exchange step may need to handleinvalid_request. At the Resource Authorization Server,invalid_grantis still the code for ID-JAG validation failures (Section 4.4.3), so the same client must distinguish the two endpoints. The announcement asks implementers of the Token Exchange step to check their error handling. Deployments that rely on a client being unauthenticated at the IdP, or that send more than oneaudience, are no longer conformant.
Technical Analysis
- Threat model implications:
- Subject tokens are high-value (Section 9.2): one subject token can be exchanged for ID-JAGs to many Resource Authorization Servers, so the draft says deployments should not rely on client authentication alone, should keep client keys in a separate protection domain, and should consider sender-constraining and rotating Refresh Tokens.
- Metadata and discovery attacks (Sections 9.5 and 9.6): a client that skips the RFC 8414 issuer check, or the RFC 9728 resource check, can be steered to an attacker's authorization server, which then relays the ID-JAG and the client's credentials. The draft names the issuer check as the primary defence and lists three further mitigations: the
resourcevalue in the ID-JAG, the IdP governance check, and sender-constraining. - Token confusion (Section 4.3.3): the IdP must confirm the subject token is of the stated type and was issued for that purpose, reject access tokens, ID-JAGs and client assertions presented as Identity Assertions, and reject a
typthat names another token type. Because ID Tokens have no explicittyp, the draft allows deployment-specific ways to identify them. - Audience binding: the Resource Authorization Server must check that
audis its own issuer (a string or a one-element array) and must checkclient_idagainst the authenticated client (Section 4.4.1). - Identity trust (Section 9.8):
sub_id.issuermust never establish trust in the ID-JAG issuer, and a Resource Authorization Server that resolves users byemailoraud_subis relying on the issuer tenant's administrators. - Disclosure (Sections 9.9 and 10): the ID-JAG is visible to the Client, so a pairwise
sub,sub_idoraud_subis disclosed to it and can be linked across Resource Authorization Servers. Error descriptions SHOULD NOT reveal, for example, license status.
- Protocol flow implications:
- Token Exchange response quirks: the grant is returned in
access_tokenwithtoken_typeN_A(Section 4.3.4). - Resource handling:
resourceis a single string or a non-empty array of unique strings in the claim and is compared with Simple String Comparison (Sections 3.1 and 4.3). The IdP may grant a subset but must copy each granted identifier exactly as sent. - Refresh tokens at the Resource Authorization Server: the Resource Authorization Server SHOULD NOT return one, and clients may resubmit the ID-JAG until it expires unless the server limits
expor tracksjti(Section 4.4.4). - Sender constraining (Section 9.11): DPoP puts
jktincnfand requires thejwt-dpopgrant type; mTLS putsx5t#S256incnf. An IdP SHOULD NOT bind to both. Clients SHOULD inspect the ID-JAG for the expectedcnfbecause the response does not say whether binding happened, which guards against silent downgrade. - Client authentication alternatives: the Resource Authorization Server SHOULD require client authentication, but a sender-constrained ID-JAG from an unauthenticated client may be accepted, and then the
cnfproof takes the place of theclient_idcheck (Sections 4.4, 4.4.1 and 9.1). - Tenancy (claims in Section 3, rules in Sections 6.1, 6.2 and 6.4, rejection in Section 4.4.1): two separate claims.
tenant, defined by OpenID Enterprise, names the issuer's tenant; a multi-tenant issuer must include it, and the Resource Authorization Server must trustissandtenanttogether.aud_tenant, registered by this draft, names the Resource Authorization Server's tenant, andaud+aud_tenant+aud_submust be unique there. The Resource Authorization Server must reject the ID-JAG withinvalid_grantif it cannot determine the recipient tenant unambiguously.
- Token Exchange response quirks: the grant is returned in
- Interop concerns:
- Client ID mapping (Section 5.1): the IdP must know the client's identifier at the Resource Authorization Server by an out-of-band record, or clients can use Client ID Metadata Documents as a shared namespace.
- Subject identifier mapping (Section 5.2):
subis chosen for the Resource Authorization Server, so it can differ from thesubin the Client's own ID Token. The samesubmust be used for a given End-User and Resource Authorization Server regardless of which Client asks. - SAML NameID (Section 3.2):
sub_idwith formatsaml-nameidforbids transient NameIDs, requires comparing every member the Resource Authorization Server uses (includingsp_name_qualifier), and does not cover deployments that resolve users by an attribute outside<Subject>. - Key discovery: the IdP SHOULD publish its signing key at
jwks_uriin metadata located per RFC 8414, with an OpenID Discovery fallback allowed for the Resource Authorization Server (Section 7.1). - Dependencies on other drafts: the Identity Chaining draft (version 17 is cited) and the DPoP grant draft (version 02 is cited) are Work in Progress, so changes in them can affect this profile.
Open Questions
- Section 9.3 still contains a "TBD" about requesting the ID-JAG in the authorization request when stepping up authentication, to save a round trip. The draft says nothing on how
insufficient_user_authenticationinteracts with the newinvalid_requestrule for the subject token. - Section 4.3.3 and Section 9.10 leave
actor_tokenand theactclaim without normative processing, and say only that future extensions may define them. The draft does not say how a Resource Authorization Server should treat anactclaim it receives. - The announcement does not list the "remaining open issues" for IETF 127. Open issues in the working group repository cover resource handling (#141, #142), access token lifetime (#145), multi-tenancy (#109, #129), DPoP nonces (#106) and the gateway topology conflict with the Section 4.3.3 audience check (#114).
- Section 4.3.4.3 says an expired or revoked Refresh Token subject token yields
invalid_request. This matches RFC 8693 Section 2.2.2, which requiresinvalid_requestwhenever asubject_tokenis invalid. RFC 6749 Section 5.2 usesinvalid_grantfor an invalid refresh token, but only in a refresh grant. Here the Refresh Token arrives as a Token Exchangesubject_token, so RFC 8693 governs. A client that also refreshes tokens directly has to expectinvalid_grantthere andinvalid_requestat Token Exchange. - Section 4.3.3 makes the IdP resource-governance check a SHOULD while Section 9.5 relies on that check as one defence. Section 4.3.3 also says how the IdP learns which resources a Resource Authorization Server governs is out of scope.
- Section 4.4.4 allows reuse of an ID-JAG for new access tokens but leaves one-time use to Resource Authorization Server policy via
jti. The draft does not give a shared rule, so behaviour may differ between servers. - Section 7.2 lets a Resource Authorization Server advertise
authorization_grant_profiles_supportedbut Section 9.7 forbids it from disclosing issuer allow lists, so a client has no standard way to learn in advance whether a given issuer will be accepted beyond the optional protected discovery mechanism. - Section 4.3.4.3 lists
invalid_request,access_deniedandinvalid_targetas profiled IdP codes, while Section 4.3.3 also requiresinvalid_client. Section 4.4.3 says it profiles "the following two codes" yet Sections 4.4 and 4.4.1 also useinvalid_client. Whether a complete error table is wanted is unclear.
Experiments
- Lab 1: Stand up a test IdP token endpoint that accepts the ID-JAG Token Exchange and send it five bad requests, then compare the responses with what -06 specifies and with what existing libraries return: no client authentication (
invalid_client, Section 4.3.3); twoaudiencevalues (invalid_request, Section 4.3.3); an access token assubject_token(Section 4.3.3 forbids accepting it but names no code;invalid_requestis inferred from Section 4.3.4.3, which profiles subject-token validation failures with it); an expired ID Token (invalid_request, Section 4.3.4.3); and an ID Token whoseaudis a different client (invalid_requestfor an audience mismatch, Section 4.3.4.3). - Lab 2: Take one valid ID-JAG and present it to a Resource Authorization Server with mutations that Section 4.4.1 says must fail with
invalid_grant(Section 4.4.3): wrongtyp,audthat does not identify this server, aclient_idthat does not match the authenticated client, aresourcethe server does not govern, a missingtenantfrom a multi-tenant issuer, and acnfbinding that does not verify. Then present an unmodified ID-JAG for an End-User the server does not entitle, and one whose resources are all rejected by local policy; both should returnaccess_denied(Sections 4.4.1 and 4.4.3). Record any server that mixes up the two codes. - Lab 3: Request a DPoP-bound and an mTLS-bound ID-JAG and redeem each at the Resource Authorization Server. With the matching key or certificate it succeeds, using the
jwt-dpopgrant type for DPoP (Sections 4.4 and 9.11.1.2.1). With a different key or certificate it fails withinvalid_grant(Sections 9.11.1.2.1 and 9.11.2.2). With no DPoP proof or no client certificate it also fails withinvalid_grant(Sections 9.11.1.2.2 and 9.11.2.2). Then redeem an unbound ID-JAG without client authentication: that isinvalid_client, while a sender-constrained ID-JAG without client authentication may be accepted (Section 4.4).
Sources
- https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant/06/
- https://mailarchive.ietf.org/arch/msg/oauth/-3eHjZkoYNz0qDpviERKkheVDbI/
- https://mailarchive.ietf.org/arch/msg/oauth/h4Zk-3zySe6CD3fuxoaHst4scH8/
- https://mailarchive.ietf.org/arch/msg/oauth/0cWcjyFw5Dg4iOH5Zf02P5sVTrg/
- https://github.com/oauth-wg/oauth-identity-assertion-authz-grant
- https://github.com/oauth-wg/oauth-identity-assertion-authz-grant/issues
- https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant/history/
- https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-04.txt
- https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-05.txt
- https://author-tools.ietf.org/iddiff?url1=draft-ietf-oauth-identity-assertion-authz-grant-05&url2=draft-ietf-oauth-identity-assertion-authz-grant-06
- https://www.rfc-editor.org/rfc/rfc8693#section-2.2.2
- https://www.rfc-editor.org/rfc/rfc6749#section-5.2