| Internet-Draft | OpenID Authentication Token | July 2026 |
| Fletcher | Expires 22 January 2027 | [Page] |
This document defines the OpenID Authentication Token: a proof-of-possession token that a Relying Party obtains by exchanging an OpenID Connect ID Token at an OpenID Provider's token endpoint using OAuth 2.0 Token Exchange (RFC 8693). The resulting OpenID Authentication Token preserves the authentication session state and the cryptographic key binding of the source ID Token, while being explicitly scoped to one or more designated audiences and minimized to prevent the over-sharing of identity claims. It provides a standard mechanism for a Relying Party to convey a verifiable, audience-scoped assertion of an end-user's authentication event to another Relying Party without reusing, and thereby over-disclosing, the original ID Token.¶
This note is to be removed before publishing as an RFC.¶
The latest revision of this draft can be found at https://gffletch.github.io/openid_authn_token/draft-openid-authn-token-protocol.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-openid-authn-token-protocol/.¶
Source for this draft and an issue tracker can be found at https://github.com/gffletch/openid_authn_token.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 22 January 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
OpenID Connect [OpenID.Core] defines the ID Token, a JSON Web Token (JWT)
[RFC7519] that a Relying Party (RP) receives at the end of an authentication
flow as an assertion that the end-user was authenticated. The ID Token is
audience-restricted to the RP that requested it (via the aud claim) and
typically carries a rich set of identity claims describing the end-user.¶
There is growing demand for an RP to convey the fact of an end-user's authentication to a second RP -- for example, when a front-end application needs a back-end service, or a partner service, to independently trust that a particular authentication event occurred. Today this is often accomplished by forwarding the original ID Token. This practice has two significant problems:¶
Audience confusion. The forwarded ID Token's aud claim names the
original RP, not the recipient. A conforming recipient cannot treat itself
as the intended audience, and non-conforming acceptance invites token
confusion and replay attacks.¶
Over-sharing of claims. The ID Token carries whatever identity claims were released to the original RP. Forwarding it discloses all of those claims to the recipient, regardless of whether the recipient needs, or is authorized to receive, them.¶
[OpenID.KeyBinding] strengthens the ID Token by binding it to a
proof-of-possession key (a cnf claim [RFC7519]), transforming it from a
bearer token into a holder-of-key token using DPoP [RFC9449]. However, that
specification anticipates sharing the (now key-bound) ID Token itself, and so
inherits the audience-confusion and over-sharing problems described above.¶
This document defines the OpenID Authentication Token (OAT) and the OpenID Authentication Token Protocol (OATP) to address these problems. An OAT is minted by the OpenID Provider (OP) through an OAuth 2.0 Token Exchange [RFC8693] in which the source ID Token is presented as the subject token. The resulting OAT:¶
is signed by the OP using the same signing keys used for its ID Tokens, so it is verifiable exactly as an ID Token is;¶
preserves the authentication session state (sid), auth_time, acr,
and amr of the source ID Token;¶
preserves the cnf key binding of the source ID Token, so that the
Requesting Client can reuse a single proof-of-possession key when presenting
the OAT to a recipient;¶
is explicitly scoped, via its aud claim, to one or more designated Target
Relying Parties; and¶
contains only the claims that the OP's audience-specific policy permits, minimizing disclosure.¶
The OAT thereby provides an equivalent, key-bound mechanism to [OpenID.KeyBinding] for sharing an authentication assertion, while retaining clear audience guidance and preventing the over-sharing of claims.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
This document uses the terms defined in OAuth 2.0 [RFC6749], OAuth 2.0 Token Exchange [RFC8693], OpenID Connect Core [OpenID.Core], and DPoP [RFC9449]. In addition, the following terms are defined:¶
A JWT, signed by the OpenID Provider, that asserts an end-user authentication event to one or more designated Target Relying Parties. It is obtained through the token exchange defined in this document.¶
The Relying Party that holds a source ID Token and presents it to the OP's
token endpoint to obtain an OpenID Authentication Token. The Requesting
Client authenticates to the token endpoint as an OAuth client and holds the
private key referenced by the source ID Token's cnf claim.¶
A party designated as an audience of the OpenID Authentication Token. It consumes and validates the OAT. A Target Relying Party MAY, but need not, be a registered client of the OP.¶
The ID Token presented as the subject token of the token exchange. It SHOULD be key-bound as defined in [OpenID.KeyBinding].¶
An OpenID Authentication Token is a signed JWT [RFC7519] [RFC7515]. Its
JOSE header MUST include a typ (type) header parameter with the value
authn+jwt (see Section 8.2), which distinguishes it from an ID Token and
from an access token and prevents cross-protocol substitution.¶
An OAT MUST contain the following claims:¶
issREQUIRED. The Issuer Identifier of the OP. It MUST be identical to the iss
claim of the Source ID Token.¶
subREQUIRED. The subject identifier. Its value is determined by the OP's audience-specific policy (see Section 3.2).¶
audREQUIRED. An array of one or more Target Relying Party identifiers to which the OAT is scoped. Even when a single audience is present, using the array form is RECOMMENDED for consistency.¶
expREQUIRED. Expiration time. An OAT SHOULD be short-lived.¶
iatREQUIRED. Time at which the OAT was issued.¶
auth_timeREQUIRED. The auth_time value from the Source ID Token, conveying the time
of the original authentication event. It MUST NOT be updated by the exchange.¶
cnfREQUIRED. A confirmation claim [RFC7800] binding the OAT to a
proof-of-possession key. It MUST contain a single jkt member whose value is
the base64url-encoded JWK SHA-256 Thumbprint [RFC7638] of the key that the
Requesting Client proved possession of, via a DPoP proof, on the token
exchange request. The provenance of that key depends on whether the Source ID
Token is itself key-bound (see Section 3.3).¶
An OAT SHOULD contain the following claims when they are present in the Source ID Token, preserving the authentication session state:¶
sidThe Session ID from the Source ID Token, tying the OAT to the OP session so that session lifecycle events (for example, logout) can be reflected.¶
acrThe Authentication Context Class Reference from the Source ID Token.¶
amrThe Authentication Methods References from the Source ID Token.¶
An OAT MAY contain the following claims:¶
nbfThe time before which the OAT MUST NOT be accepted.¶
jtiA unique identifier for the OAT, to support replay detection.¶
azpThe Authorized Party. When present, its value is the client identifier of the Requesting Client.¶
actAn actor claim, as defined in Section 4.1 of [RFC8693], whose sub member
identifies the Requesting Client that obtained and presents the OAT. Its use
is RECOMMENDED so that a Target Relying Party can determine which party
mediated the assertion.¶
Any additional identity claims are included only as permitted by the OP's audience-specific policy (see Section 4.4).¶
An OAT MUST NOT be used as an OAuth 2.0 access token, and MUST NOT be accepted by a protected resource in place of an access token.¶
The value of the sub claim in an OAT is deployment- and audience-dependent.
An OP MAY issue a public subject identifier (the same value as the Source ID
Token's sub) or a pairwise (audience-scoped) subject identifier, according to
its policy and the registration of each Target Relying Party.¶
When multiple audiences are requested in a single exchange (see
Section 4.1), the OP MUST issue a single OAT containing a single sub
value that is valid for all of the requested audiences. If the OP's policy
would require different sub values for different requested audiences -- for
example, because the requested audiences belong to different pairwise
identifier sectors -- the OP MUST NOT issue an OAT and MUST instead return an
error as described in Section 4.5.¶
An OAT is always key-bound. The binding is established by a single, uniform
mechanism: the Requesting Client presents a DPoP proof [RFC9449] on the token
exchange request, and the OP sets the OAT's cnf claim to the JWK Thumbprint
([RFC7638], expressed as jkt) of the key demonstrated by that proof. The
same key is later used by the Requesting Client to demonstrate proof of
possession when it presents the OAT to a Target Relying Party
(Section 5).¶
The provenance of the binding key differs depending on whether the Source ID
Token is itself key-bound, but the mechanism and the resulting cnf form do
not:¶
Key-bound Source ID Token. When the Source ID Token is key-bound as
defined in [OpenID.KeyBinding] and therefore carries a cnf claim, the
DPoP proof key on the exchange MUST be the key bound by that cnf claim. The
OP MUST verify that the proof key's thumbprint matches the Source ID Token's
bound key before issuing the OAT. The Requesting Client thus reuses the single
key it already holds, minimizing key management, and the OP obtains proof that
the Requesting Client legitimately holds the Source ID Token's bound key.¶
Bearer (non-key-bound) Source ID Token. When the Source ID Token has no
cnf claim, the Requesting Client presents a DPoP proof using a key of its
own choosing (for example, a stable client key or a fresh per-share key). The
OP binds the OAT to that key. This lets a Requesting Client obtain a key-bound
OAT even from a bearer Source ID Token; the associated trust considerations
are described in Section 7.¶
In both cases the OP normalizes the OAT cnf to the jkt (thumbprint) form
regardless of how the Source ID Token expressed its own cnf; the full public
key is carried in the DPoP proof at presentation and need not be embedded in
the OAT. This keeps the trust model aligned with [OpenID.KeyBinding]: the
Requesting Client is the authenticating component that proves possession, and
the Target Relying Party is the consuming component that requires such proof.¶
A Target Relying Party MUST NOT trust an OAT bearing a cnf claim without a
corresponding, successfully verified proof of possession (see
Section 5).¶
An OpenID Authentication Token is obtained by an OAuth 2.0 Token Exchange [RFC8693] at the OP's token endpoint.¶
The Requesting Client makes a token exchange request to the token endpoint. In addition to authenticating as an OAuth client, the request uses the following parameters:¶
grant_typeREQUIRED. MUST be urn:ietf:params:oauth:grant-type:token-exchange.¶
subject_tokenREQUIRED. The Source ID Token.¶
subject_token_typeREQUIRED. MUST be urn:ietf:params:oauth:token-type:id_token.¶
requested_token_typeREQUIRED. MUST be urn:openid:params:token-type:authn-token
(Section 8.1).¶
audienceREQUIRED. One or more identifiers of the Target Relying Parties for which the
OAT is requested. Multiple audiences MAY be requested by including the
audience parameter multiple times, subject to the constraint in
Section 3.2.¶
resourceOPTIONAL. One or more absolute URIs, as defined in Section 2.1 of [RFC8693], further indicating the target service(s) at which the OAT is intended to be used.¶
scopeOPTIONAL. The requested scope. Used, together with the claims parameter, by
the Requesting Client to indicate the identity claims it wishes the OAT to
contain (see Section 4.4).¶
claimsOPTIONAL. A JSON object, as defined in Section 5.5 of [OpenID.Core], requesting specific claims to be included in the OAT. The OP remains authoritative over which claims are released.¶
The Requesting Client MUST include a DPoP proof JWT, as defined in Section 4 of [RFC9449], in the DPoP header field of the token request. The OAT is bound
to the key demonstrated by this proof (Section 3.3). When the Source ID
Token is key-bound, the proof MUST be made with the key bound by the Source ID
Token's cnf claim; otherwise the Requesting Client MAY use a key of its own
choosing. The OP MUST verify the DPoP proof as described in
Section 4.2.¶
The following is a non-normative example of a token request (line breaks and indentation within the body are for display purposes only):¶
POST /token HTTP/1.1 Host: op.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2Iiwia... grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange &subject_token=eyJhbGciOiJSUzI1NiIsInR5cCI6ImRwb3AraWRfdG9rZW4i... &subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aid_token &requested_token_type=urn%3Aopenid%3Aparams%3Atoken-type%3Aauthn-token &audience=https%3A%2F%2Frp-b.example.org &scope=openid¶
Upon receiving a token exchange request as defined above, the OP MUST, in addition to its normal client authentication and token exchange processing:¶
Validate the Source ID Token per Section 3.1.3.7 of [OpenID.Core],
including its signature, issuer, expiration, and integrity. The aud of the
Source ID Token identifies the Requesting Client's original client
registration; the OP MUST confirm that the authenticated Requesting Client
is authorized to exchange that ID Token.¶
Verify the DPoP proof in the DPoP header field per Section 5 of [RFC9449]. If the DPoP proof is missing or fails this verification, the OP
MUST reject the request with an invalid_dpop_proof error.¶
If the Source ID Token contains a cnf claim, additionally confirm that the
JWK Thumbprint [RFC7638] of the proof's key equals the thumbprint of the
key bound by that cnf claim. If the proof is valid but its key does not
match, the OP MUST reject the request with an invalid_key_binding error
(Section 4.5).¶
Determine, for each requested audience (and any resource), whether the
Requesting Client is authorized to obtain an OAT for that Target Relying
Party. If any requested audience is not permitted, the OP MUST return an
invalid_target error.¶
Determine the sub value per Section 3.2. If a single sub
value cannot satisfy all requested audiences, return an invalid_target
error.¶
Determine the set of identity claims to include per Section 4.4.¶
Mint the OAT, copying iss, auth_time, and (when present) sid,
acr, and amr from the Source ID Token, setting aud to the requested
audience(s), setting cnf to { "jkt": <thumbprint of the DPoP proof key> }
(Section 3.3), and signing it with the OP's signing key.¶
The response is an OAuth 2.0 Token Exchange response as defined in Section 2.2 of [RFC8693]. The OAT is returned in the access_token response parameter (as
required by that specification for the issued token), and the
issued_token_type parameter MUST be urn:openid:params:token-type:authn-token.¶
Because the OAT is not an OAuth 2.0 access token, the token_type response
parameter MUST be N_A as described in Section 2.2.1 of [RFC8693].¶
The following is a non-normative example response:¶
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token": "eyJ0eXAiOiJhdXRobitqd3QiLCJhbGciOiJSUzI1NiJ9...",
"issued_token_type": "urn:openid:params:token-type:authn-token",
"token_type": "N_A",
"expires_in": 300
}
¶
The following is the non-normative, decoded payload of the OAT from the
response above. The cnf claim carries the jkt thumbprint of the key the
Requesting Client proved possession of on the exchange request.¶
{
"iss": "https://op.example.com",
"sub": "Z5O3upPC88QrAjx00dis",
"aud": ["https://rp-b.example.org"],
"exp": 1749825900,
"iat": 1749825600,
"auth_time": 1749820000,
"sid": "08a5019c-17e1-4977-8f42-65a12843ea02",
"acr": "urn:mace:incommon:iap:silver",
"amr": ["pwd", "otp"],
"azp": "s6BhdRkqt3",
"act": { "sub": "s6BhdRkqt3" },
"cnf": {
"jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
}
}
¶
The Requesting Client MAY request identity claims to be included in the OAT
using the scope and claims parameters. The OP is authoritative over the
claims that are actually released. The OP MUST apply its audience-specific
policy and MAY remove any requested claim that the applicable Target Relying
Party is not authorized to receive.¶
To prevent over-sharing, an OP SHOULD default to releasing only the
authentication and session claims defined in Section 3.1 (namely iss,
sub, aud, exp, iat, auth_time, and, when present, sid,
acr, amr, and cnf), including additional identity claims only when they
are both requested and permitted by policy. An OAT MUST NOT contain any claim
that the OP's audience-specific policy does not permit for every audience named
in the aud claim.¶
Errors are returned as defined in Section 2.2.2 of [RFC8693] and Section 5.2 of [RFC6749]. In addition to the error codes defined there, this document relies on the following:¶
invalid_targetThe requested audience or resource is unknown, is not permitted for the Requesting Client, or cannot be satisfied by a single subject identifier across all requested audiences (see Section 3.2).¶
invalid_dpop_proofAs defined in Section 7 of [RFC9449]; returned when the required DPoP proof
is missing or is not a valid DPoP proof (for example, a malformed proof, an
invalid signature, a stale iat, or a replayed jti). This code does not
cover the case in which a valid proof is made with the wrong key; see
invalid_key_binding.¶
invalid_key_bindingThe DPoP proof is itself valid, but the Source ID Token is key-bound and the
JWK Thumbprint of the proof key does not match the key bound by the Source ID
Token's cnf claim (Section 4.2). This is a non-retryable
condition: presenting the same request with a freshly generated proof over
the same key will not succeed. This code is registered by this document
(Section 8.3).¶
The mechanism by which the Requesting Client conveys the OAT to a Target
Relying Party is out of scope of this document, mirroring
[OpenID.KeyBinding]. Regardless of the transport, the OAT MUST be presented
together with a proof of possession of the key identified by its cnf claim; a
DPoP proof [RFC9449] is RECOMMENDED for this purpose. The Requesting Client is
the party that demonstrates this proof of possession, using the same key it
proved possession of on the token exchange request (Section 3.3).¶
A Target Relying Party consuming an OAT MUST:¶
Validate the OAT as a JWT [RFC7519] [RFC7515]: verify the signature
using the OP's published signing keys, and reject the token if the JOSE
header typ is not authn+jwt.¶
Verify that the iss claim is the expected OP.¶
Verify that its own identifier is present in the aud claim.¶
Verify the exp (and nbf, if present) claims.¶
Verify the accompanying proof of possession and confirm that the JWK
Thumbprint of the proof's key equals the OAT's cnf jkt value. The Target
Relying Party MUST NOT trust an OAT in the absence of such proof.¶
Not treat the OAT as an OAuth 2.0 access token, and not present it to any protected resource in place of an access token.¶
An OP that supports this specification SHOULD advertise the fact in its metadata document [OpenID.Discovery] [RFC8414] using the following:¶
authn_token_endpointOPTIONAL. The URL of the token endpoint at which OpenID Authentication Tokens
may be obtained. When absent, the OP's token_endpoint is used.¶
authn_token_signing_alg_values_supportedOPTIONAL. A JSON array of the JWS signing algorithms supported for signing OpenID Authentication Tokens.¶
An OP that supports this specification MUST include
urn:openid:params:token-type:authn-token in the token types it supports for
the requested_token_type parameter, and SHOULD indicate its support for
token exchange and DPoP through the corresponding metadata parameters defined
in [RFC8693] and [RFC9449].¶
The OAT is always bound, via its cnf claim, to a key held by the Requesting
Client rather than by the Target Relying Party. The Requesting Client therefore
acts as the authenticating component that proves possession; the Target Relying
Party relies on that proof rather than performing proof of possession itself.
Deployments MUST ensure that the Requesting Client's private key is protected
commensurate with the sensitivity of the authentication assertions it can mint
OATs for. As recommended by [OpenID.KeyBinding], a distinct key pair per
Requesting Client instance SHOULD be used to avoid token confusion; a
Requesting Client MAY additionally use a fresh per-share key when binding an OAT
from a bearer Source ID Token.¶
When the Source ID Token is key-bound, requiring the exchange DPoP proof to be made with the bound key ensures that only a party actually holding that key can obtain an OAT; a stolen bearer copy of a key-bound ID Token cannot be exchanged.¶
When the Source ID Token is a bearer token, this protection is absent: the security of the exchange rests on the confidentiality of the Source ID Token together with the Requesting Client's authentication to the token endpoint. Because token exchange requires the Requesting Client to authenticate as an OAuth client, a stolen bearer Source ID Token alone -- without the client's credentials -- still cannot be exchanged for an OAT. Nonetheless, minting an OAT from a bearer Source ID Token is strictly weaker than from a key-bound one: whichever key the (authenticated) client presents becomes the OAT's bound key. OPs SHOULD prefer key-bound Source ID Tokens, SHOULD require them for security-sensitive audiences, and MAY refuse by policy to mint OATs from bearer Source ID Tokens.¶
The OAT's aud claim names the Target Relying Party rather than the Requesting
Client, giving a conforming Target Relying Party a clear basis to accept the
token. The distinct typ value authn+jwt prevents an OAT from being
substituted for an ID Token, an access token, or a DPoP-bound ID Token
([OpenID.KeyBinding]). Target Relying Parties MUST strictly enforce the
aud, iss, and typ checks in Section 5.¶
By defaulting to authentication and session claims and applying
audience-specific policy, the OAT limits disclosure of identity claims to what
each Target Relying Party is authorized to receive. Where cross-RP correlation
is a concern, OPs SHOULD issue pairwise subject identifiers per
Section 3.2. Because a single OAT carries a single sub value,
naming multiple audiences with incompatible pairwise sectors is rejected rather
than silently collapsing them to a shared identifier.¶
The auth_time in an OAT describes the original authentication
event. Preserving sid allows an OAT's validity to be
tied to the OP session so that logout or session termination can be reflected;
OPs and Target Relying Parties MAY integrate OAT lifecycle with existing
session management and revocation mechanisms.¶
The Source ID Token's nonce claim is not carried into the OAT. The nonce
is a request-response correlator between the Requesting Client and the OP;
no recipient of the OAT issued it or can validate it for its intended purpose.¶
The token type identifier urn:openid:params:token-type:authn-token, used as
the value of the requested_token_type and issued_token_type parameters,
resides in the urn:openid:params URN sub-namespace managed by the OpenID
Foundation rather than the IANA "OAuth URI" registry. It is defined here
following the conventions for OAuth token type identifiers in Section 4.1 of [RFC8693]. This document requests no IANA action for this identifier; the
OpenID Foundation is the change controller.¶
This document requests registration of the following media type in the "Media
Types" registry, for use as the value of the typ JOSE header parameter and,
where applicable, the Content-Type of an OpenID Authentication Token.¶
application¶
authn+jwt¶
N/A¶
N/A¶
binary; a JWT is a series of base64url-encoded values with period separators.¶
See Section 11 of [RFC7519] and the Security Considerations of this document.¶
OpenID Foundation¶
This document requests registration of the following error code in the "OAuth Extensions Error Registry" established by [RFC6749].¶
This document requests registration of the metadata parameters
authn_token_endpoint and authn_token_signing_alg_values_supported in the
"OpenID Connect Discovery 1.0" / "OAuth Authorization Server Metadata"
registries, with this document as the specification document and the OpenID
Foundation as the change controller.¶
The author thanks the contributors to OpenID Connect Key Binding [OpenID.KeyBinding], on which the key-binding model of this document is based, and the authors of OAuth 2.0 Token Exchange [RFC8693] and DPoP [RFC9449].¶