| Internet-Draft | DTR | June 2026 |
| Jacobsen, et al. | Expires 25 December 2026 | [Page] |
This document defines the Deferred Token Response (DTR) extension
for OAuth 2.1. In existing OAuth grants, the token endpoint either
issues an access token or returns an error.
DTR establishes a generic asynchronous token request mechanism that any
OAuth grant may plug into.
In DTR-aware flows, the authorization server returns a
deferral_code and a polling interval, indicating that the final
token response will be available at a later time.
The client retrieves the eventual response by polling the token
endpoint, or by receiving a callback from the authorization server
when one is configured.¶
This note is to be removed before publishing as an RFC.¶
The latest revision of this draft can be found at https://maxwellgerber.github.io/deferred-token-response/draft-gerber-oauth-deferred-token-response.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-gerber-oauth-deferred-token-response/.¶
Discussion of this document takes place on the Web Authorization Protocol Working Group mailing list (mailto:oauth@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/oauth/. Subscribe at https://www.ietf.org/mailman/listinfo/oauth/.¶
Source for this draft and an issue tracker can be found at https://github.com/maxwellgerber/deferred-token-response.¶
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 25 December 2026.¶
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.¶
Existing OAuth grants assume the authorization server can decide synchronously whether to issue an access token. The Authorization Code Grant (Section 4.1 of [OAUTH-2.1]), Client Credentials Grant (Section 4.2 of [OAUTH-2.1]), and assertion-based grants such as [ID-JAG] all respond to a token request with either a token response or an error response.¶
However, some authorization decisions cannot complete synchronously:¶
Fraud Prevention: Sensitive operations may trigger manual review by parties other than the resource owner.¶
ID Verification: Users may submit copies of physical credentials during onboarding or step-up. Verification by the authorization server (or a third party acting on its behalf) can take hours.¶
Autonomous Agent Authorization: An agent acting on behalf of a user may request access beyond what was provisioned at enrollment, requiring out-of-band approval before the request can be granted.¶
Complex Authorization: Enterprise businesses often manage access controls using governance and administration workflows. Access requests may need to be approved by parties other than the resource owner.¶
In each case, the authorization server today must return an error response, leaving the client without a mechanism to discover when (or whether) the request will eventually be approved.¶
This specification defines a Deferred Token Response, in which the
authorization server returns a deferral_code and a polling
interval in place of an access token.
The deferral_code represents the pending token request
and entitles the client to a final token response when the request
resolves.
The client either polls the token endpoint with the deferral_code,
or receives a callback from the authorization server when a callback
URI is registered.¶
Unlike the Device Authorization Grant [RFC8628], deferral under DTR is initiated by the authorization server, not by the client or the end-user. This allows an authorization server to apply DTR dynamically, based on policy or risk analysis, to a request that began under another grant. The Device Authorization Grant additionally assumes that the same end-user who initiated the flow is the party who will approve it; DTR makes no such assumption, and supports use cases in which a different user, a different system, or no human at all completes the authorization decision.¶
In many of the motivating use cases, the authorization server delegates the actual verification or decision to an external service — an identity verification vendor, a fraud analysis platform, or a governance system. The protocol between the authorization server and any such external provider is out of scope for this specification; only the interface between the client and the authorization server is defined here.¶
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 specification defines the following terms:¶
A unique, opaque, server-generated identifier that represents a
single pending token request. The deferral code is carried
in the deferral_code member of the deferred response
(Section 5.4) and is identified, when
used as a token_type_hint at the revocation endpoint, by the URI
urn:ietf:params:oauth:token-type:deferral-code. The deferral
code is bound to the issuing client and to a sender-constraining
key per Section 10.1, and entitles the bound
party to retrieve the eventual token response.¶
The minimum number of seconds, conveyed in the interval parameter
of the deferred response, that the client MUST wait between two
consecutive polling requests for the same deferral code.¶
An HTTPS URI registered by the client at which it accepts callback notifications from the authorization server when a deferred request resolves.¶
The OAuth grant — for example, the Authorization Code Grant (Section 4.1 of [OAUTH-2.1]), the Client Credentials Grant (Section 4.2 of [OAUTH-2.1]), or Token Exchange ([RFC8693]) — on whose token request the deferred response was returned, and whose successful token response shape is reused when the deferred request eventually resolves.¶
Some grant types utilize multiple authorization server endpoints. For an originating grant whose flow begins at an endpoint other than the token endpoint, the preceding endpoint is the endpoint utilized just before the token endpoint. Examples include the authorization endpoint of the Authorization Code Grant ([OAUTH-2.1]), the device authorization endpoint of [RFC8628], and the authorization challenge endpoint of [FIPA]. A grant that operates entirely at the token endpoint (for example, the Client Credentials Grant) has no preceding endpoint.¶
The Deferred Token Response flow allows an authorization server to defer the issuance of an access token for an arbitrarily long time after the request that would normally produce one.¶
The flow proceeds entirely through the originating grant's existing endpoints. A grant becomes deferred when:¶
The client signals willingness to accept a deferred response by
including deferred among the values of the completion_mode
parameter on the originating grant's token endpoint request.¶
The authorization server elects, on that token endpoint request,
to return a deferred response in place of the normal token
response. The deferred response carries a deferral_code instead
of an access token.¶
The client polls the token endpoint with the deferral_code
until the authorization server returns the final token response, or
optionally receives a callback notification when the request
resolves.¶
For an originating grant with a preceding endpoint — for example, the
authorization endpoint of the Authorization Code Grant of
[OAUTH-2.1], the device authorization endpoint of [RFC8628], or
the authorization challenge endpoint of [FIPA] — the client MAY also
send completion_mode=deferred on the preceding request as an advance
hint.
The hint allows the authorization server to commit to deferral-aware
behavior before the token request — for example, by collecting different
consent, by showing a different verification UX, or by selecting a different
review path.
An authorization server that acts on the hint depends on
the client's intent at the token endpoint matching it; see
Section 4.2. The authorization server returns its grant's
normal response to the preceding request (for example, an
authorization code) regardless of whether the request will be
deferred.¶
+--------+ +-----+ +----------+ | | | | | | | |--(1) Auth Request--------------->| | | | | | (completion_mode=deferred) | | | | | | | |<-(2) Obtain->| End-User | | | | | input | | | |<-(3) Auth Response (code)--------| | | | | | | | +----------+ | |--(4) Token Request-------------->| | | | (code, completion_mode=deferred) | | | |<-(5) Deferred Response-----------| | | | (deferral_code) | | | | | |---------+ | Client | | AS | | | |--(6) Token Request-------------->| | | | | (deferral_code) | | (7) Complete request | |<-Token Response------------------| | | | | | |<--------+ | | ... | | | | | | | |<-(8) Optional Callback-----------| | | | | | | |--(6) Token Request-------------->| | | | (deferral_code) | | | |<-Token Response------------------| | | | | | +--------+ +-----+¶
For a token-endpoint-only grant the flow is the same with steps (1) through (3) collapsed into the initial token request.¶
Once the authorization server has issued a deferral_code, the
remaining flow — polling, callback, eventual token response,
cancellation — is identical regardless of the originating grant.¶
The Deferred Token Response is an opt-in mechanism from the client's
perspective.
An authorization server MUST NOT issue a deferred response to a client
that has not signaled willingness to accept one.
This specification defines the completion_mode request parameter for
that purpose.¶
completion_mode Parameter
completion_modeOPTIONAL. A space-separated list of completion-mode values registered
in the "OAuth Completion Mode Values" registry (Section 12).
Order is not significant, and values MUST NOT be repeated. This
specification defines a single value, deferred: when it is present
in the list, the client signals that it is willing to accept a
deferred response from the authorization server in place of an
immediate token response or error. If the parameter is absent, or is
present but does not include deferred, the client requires
synchronous handling. The authorization server MUST ignore any value
it does not recognize.¶
The client signals opt-in to DTR by including deferred among the
completion_mode values on the originating grant's token endpoint
request.¶
For an originating grant with a preceding endpoint — the authorization
endpoint, the device authorization endpoint of [RFC8628], the
authorization challenge endpoint, or another endpoint introduced by a
future extension — the client MAY additionally send
completion_mode=deferred on that preceding request as an advance hint
to the authorization server. The semantics of the hint are defined in
Section 4.2.¶
Authorization servers that publish Authorization Server Metadata [RFC8414] MUST include the following property to signal support for deferred token responses as described in this specification:¶
deferred_token_response_supportedOPTIONAL. Boolean value specifying whether the the authorization server supports the deferred token response defined in this specification.¶
A client MAY discover authorization server support for this
specification through the deferred_token_response_supported
authorization server metadata parameter (Section 12). A
client MAY send completion_mode=deferred to an authorization server
that does not advertise support; such an authorization server
SHOULD silently ignore the parameter and complete the request synchronously
per its originating grant's rules.¶
For an originating grant with a preceding endpoint, the client MAY
send completion_mode=deferred on that preceding request to inform the
authorization server in advance that the grant may resolve to a
deferred response at the token endpoint. The hint is optional: a
client that omits it on the preceding request can still opt in at the
token endpoint, and the authorization server MUST NOT reject a token
request carrying completion_mode=deferred solely because no hint was
received earlier.¶
Where the authorization request is not sent directly to the
authorization endpoint, completion_mode is conveyed wherever the
request's other authorization parameters are conveyed — for example, in
the request body of a Pushed Authorization Request (PAR) or as a member
of a JWT-secured authorization request object (JAR).¶
An authorization server MAY act on the hint by selecting a deferral-aware path for the originating grant — for example, by collecting different consent from the resource owner, by presenting a different verification UX, by routing the request to a review queue, or by altering its risk-analysis decision. An authorization server that does not use the hint MUST treat the preceding request as it would without DTR; the hint never alters the response shape of the preceding endpoint.¶
A client that has sent completion_mode=deferred on the preceding
request MUST also include deferred among the completion_mode values
on the resulting token request. If the client instead omits deferred
(or omits the parameter) at the token endpoint, the authorization
server MUST reject the request with the error invalid_request.¶
A client that did not send a hint MAY still send
completion_mode=deferred at the token endpoint, and the authorization
server MAY return a deferred response.¶
Polling requests (Section 5.5) are not part of the
originating grant; they continue an already-deferred flow rather than
initiating one and MUST NOT carry the completion_mode parameter.¶
Token endpoint request opting in to DTR (Authorization Code Grant):¶
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW grant_type=authorization_code &code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb &completion_mode=deferred¶
Token endpoint request opting in to DTR (Client Credentials Grant):¶
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW grant_type=client_credentials &scope=profile &completion_mode=deferred¶
The following requests illustrate the optional pre-token hint
(Section 4.2) on grants with a preceding endpoint. A client
that sends a hint is expected to follow up with
completion_mode=deferred on the corresponding token request shown
above.¶
Authorization endpoint hint (Authorization Code Grant of [OAUTH-2.1]):¶
GET /authorize?response_type=code &client_id=s6BhdRkqt3 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb &scope=profile &completion_mode=deferred &state=af0ifjsldkj HTTP/1.1 Host: server.example.com¶
Device authorization endpoint hint (Device Authorization Grant of [RFC8628]):¶
POST /device_authorization HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW scope=profile &completion_mode=deferred¶
Authorization challenge endpoint hint ([FIPA]):¶
POST /authorize-challenge HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW login_hint=%2B1-310-123-4567 &scope=profile &completion_mode=deferred¶
A client that does not wish to poll for the result of a deferred
request MAY register a deferred_client_notification_endpoint
(Section 6.2) at which it accepts callback
notifications from the authorization server.
When the deferred request resolves — successfully, with an error, or by
cancellation — the authorization server sends a callback notification
to that endpoint.¶
A callback notification does not itself convey the token response or
any credential. It indicates that polling the token endpoint with the
deferral_code will now yield a final response.¶
An authorization server MUST NOT initiate a callback notification
before the HTTP response carrying the deferred response that
introduced the deferral_code has been written to the network.
Authorization servers SHOULD additionally delay callbacks for a small
implementation-defined period after that point so that the client can
record the deferral_code before receiving notice of its
resolution.
The authorization server MUST NOT send a callback notification for a
deferral_code that has already expired; the client is informed of
expiration via the expires_in value in the deferred response.¶
The callback is an HTTP POST to the registered
deferred_client_notification_endpoint with the following parameter
encoded in application/json:¶
deferral_codeREQUIRED. The deferral_code of the deferred request that has
resolved.¶
If the client supplied a client_notification_token on the initial
token request that produced this deferral code, the authorization
server MUST authenticate the callback request by including the
client_notification_token as a Bearer credential in the
Authorization header per Section 2.1 of [RFC6750]. The client
MUST validate that the bearer credential equals the
client_notification_token it supplied; on mismatch, the client
MUST respond with HTTP 401 Unauthorized.¶
If the client did not supply a client_notification_token, the
authorization server MUST omit the Authorization header. In that
case the client MUST protect the callback endpoint by some other
means — for example, mutual TLS or network-position assumptions —
and SHOULD treat the callback as advisory until it has confirmed
resolution by polling the token endpoint with the deferral code.¶
The following is a non-normative example with client_notification_token:¶
POST /cb HTTP/1.1
Host: client.example.com
Authorization: Bearer f4oirNBUlM
Content-Type: application/json
{
"deferral_code": "8d67dc78-7faa-4d41-aabd-67707b374255"
}
¶
For valid requests, the client MUST respond with HTTP 204 No Content. The client MUST NOT respond with an HTTP 3xx status code; the authorization server MUST NOT follow redirects.¶
Handling of HTTP error codes in the 4xx and 5xx ranges by the authorization server is out of scope for this specification.¶
Clients receiving a callback notification MUST ignore unrecognized parameters in the callback body.¶
The following Client Metadata parameter is defined by this specification to be used during Client Registration as defined in [RFC7591]:¶
deferred_client_notification_endpointOPTIONAL. URL to which the authorization server sends a notification when a deferred authorization request resolves. If supplied, it MUST be an HTTPS URL. A client that does not register this endpoint retrieves the final token response by polling the token endpoint.¶
A client MAY cancel a pending deferred request to release authorization server resources or because the underlying user intent no longer applies. Cancellation is performed by revoking the deferral code at the authorization server's revocation endpoint per [RFC7009].¶
The client makes an HTTP POST request to the revocation endpoint per
Section 2.1 of [RFC7009], with the following parameters using the
application/x-www-form-urlencoded format:¶
tokenREQUIRED. The deferral code to cancel, exactly as received in the
deferral_code field of the deferred response.¶
token_type_hintRECOMMENDED. Value
urn:ietf:params:oauth:token-type:deferral-code.¶
The client authenticates to the revocation endpoint as required by its registered authentication method per Section 2.4 of [OAUTH-2.1].¶
The following is a non-normative example:¶
POST /revoke HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW token=8d67dc78-7faa-4d41-aabd-67707b374255 &token_type_hint=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Adeferral-code¶
Authorization servers MUST extend the revocation endpoint to accept deferral codes, with the following semantics:¶
If the deferral code is recognized and was issued to the
authenticated client, the authorization server MUST atomically
transition the pending request to a cancelled state, MUST suppress
any pending callback notification for the deferral code where
delivery has not yet been initiated, and MUST cause subsequent
polling requests against the deferral code to return
access_denied per Section 5.6.¶
If the deferral code is unrecognized, was issued to a different authenticated client, or has already been redeemed, cancelled, or expired — the authorization server MUST return HTTP 200 OK without modifying state. Invalid tokens do not cause an error response, per Section 2.2 of [RFC7009].¶
If the deferred request has already resolved successfully and the resulting access token has been delivered to the client, the authorization server MUST NOT revoke that access token as a side effect of revoking the deferral code. The two are independent credentials with independent lifetimes; clients that need to revoke an issued access token MUST do so explicitly per [RFC7009].¶
If the deferred request has resolved successfully but the access
token has not yet been delivered to the client (for example, a
resolution committed between the last poll and the cancellation),
the authorization server MUST treat the deferral code as
redeemed-and-then-cancelled: it MUST NOT issue the access token on
any subsequent polling request and MUST return access_denied instead.¶
The revocation response is governed by Section 2.2 of [RFC7009].¶
After a successful cancellation, the authorization server MAY retain
the deferral code's identifier for the remainder of expires_in to
ensure that subsequent polling requests reliably return
access_denied rather than invalid_grant. Disposal of any data
collected during the deferred request is out of scope for this
specification.¶
To avoid leaking the validity of deferral code identifiers through
response timing, authorization servers SHOULD process revocation
requests in approximately constant time regardless of whether the
supplied token value is recognized. This complements the
indistinguishability of the response codes required by clauses 1 and
2 above.¶
Per Section 2.2 of [RFC7009], the revocation endpoint is idempotent. Clients MAY retry revocation requests on transport failures without risking adverse effects.¶
To allow clients to determine whether the revocation endpoint accepts
deferral codes, this specification registers the authorization server
metadata parameter revocation_endpoint_token_type_values_supported
in Section 12. An authorization server that supports this
specification MUST list
urn:ietf:params:oauth:token-type:deferral-code in this array.¶
Clients SHOULD check that
urn:ietf:params:oauth:token-type:deferral-code is present in
revocation_endpoint_token_type_values_supported before relying on
cancellation. An authorization server that does not advertise support
will return HTTP 200 OK for any revocation request per
Section 2.2 of [RFC7009], which is indistinguishable from a
successful cancellation. Clients that skip this check risk silently
failing to cancel a pending deferred request.¶
A client that has registered a deferred_client_notification_endpoint
SHOULD continue to poll the token endpoint at the rate established by
interval, rather than rely solely on the callback.
Polling provides resilience against lost or delayed callbacks and
limits the impact of a compromised callback endpoint that suppresses
inbound notifications.¶
A client awaiting a deferred request whose expires_in is close to
elapsing MAY send a final polling request slightly before the
expiration, to mitigate the risk of a resolution that occurs too late
to fall within the normal polling schedule.¶
This specification does not define a way to deliver the final token response directly via the callback. Long-running, high-value flows warrant the durability of polling: a single lost push request would otherwise lose the outcome of the entire deferred request.¶
A deferred request may take an arbitrarily long time to resolve. A client that also requires an immediate result — for example, a basic access token or an ID token to render initial user experience — can obtain one by starting a separate, non-deferred grant in parallel, while it continues to poll the deferred request for the final result.¶
How the client obtains the immediate result depends on the originating grant:¶
For the Authorization Code Grant, the client can perform a parallel
OpenID Connect authentication with prompt=none to obtain an ID token
(and, where applicable, an access token) without further user
interaction.¶
For the Client Credentials Grant or [ID-JAG], the client can send an
additional token request that omits the completion_mode parameter
entirely, which the authorization server completes synchronously per the
originating grant's rules.¶
The immediate result and the deferred result are independent: the immediate result reflects what the authorization server can issue synchronously, while the deferred request continues toward the final, possibly higher-assurance, token response. This lets a client proceed with available work immediately rather than blocking on the deferred outcome.¶
When responding to a polling request with authorization_pending, the
authorization server SHOULD include progress information in the
error_description field where appropriate.
Examples include the current step in a multi-step process, the queue
position of the deferred request, or an estimate of remaining
processing time.¶
Authorization servers MUST NOT include personal data, document
identifiers, or any data subject to data-minimization obligations in
the error_description field. Progress information SHOULD be
expressed as opaque step identifiers (for example,
step=document_review) rather than free-form descriptions of user
content.¶
The client MAY surface this information to a human operator if appropriate. Progress information is informational and the client MUST NOT depend on its presence or format.¶
An authorization server may rely on one or more external services to resolve a deferred request — for example, an identity verification vendor, a fraud analysis system, a human review queue, or an enterprise governance platform. This specification does not define or constrain the trust relationship between the authorization server and any such service. From the client's perspective the authorization server remains the sole counterparty: the client has no direct relationship with, and need not be aware of, any external service involved in resolving the deferred request.¶
This section is informative.¶
This specification overlaps in mechanism with OpenID Connect
Client-Initiated Backchannel Authentication (CIBA) [CIBA]: both
issue an opaque identifier (CIBA's auth_req_id, this
specification's deferral code), both define a polling mode governed
by an interval parameter, and both define a callback notification
that signals the client to retrieve the result. The differences are
intentional.¶
Initiation model. CIBA is initiated by the client. DTR is not initiated by a client at all: an existing grant is initiated by its normal means and the authorization server elects to defer the resulting token response. CIBA cannot express deferral of a Client Credentials Grant or a Token Exchange ([RFC8693]) request, because CIBA's initiation inherently requires an end-user; this specification can, because deferral is decided at the token endpoint without regard to the originating grant's initiation pattern.¶
User model. CIBA is a user authentication specification. CIBA
requires the client to identify the user that must be contacted,
using parameters such as login_hint or id_token_hint. CIBA
cannot express situations where the authorization server wishes
to choose the user or system to contact dynamically.¶
This specification builds on the security model of OAuth 2.1 (Section 7 of [OAUTH-2.1]) and the OAuth Security Best Current Practice ([RFC9700]). The considerations in those documents apply. The following considerations are specific to this specification.¶
Deferral codes have lifetimes that may extend for hours or days. Over that window, possession alone confers the right to retrieve the eventual access token. To prevent the substitution attacks this implies, deferral codes are sender-constrained.¶
A client that is a public client per Section 2.1 of [OAUTH-2.1], or
that is using an originating grant whose security profile mandates
DPoP (for example, a profile that adopts [RFC9449] as a
requirement), MUST present a DPoP proof on the initial token request
that yields a deferred response. A confidential client using a strong
client authentication method — for example, mutual TLS per
[RFC8705] or private_key_jwt — MAY omit DPoP. A confidential
client using a weaker client authentication method (client_secret_basic
or client_secret_post) SHOULD bind the deferral code with DPoP.¶
When DPoP is presented on the initial token request, the
authorization server MUST persist the JWK Thumbprint
(Section 6.1 of [RFC9449]) of the proof key. Every subsequent
polling request and revocation request that presents the resulting
deferral code MUST carry a DPoP proof signed by the same key. The
authorization server MUST reject any request whose proof does not
chain to the persisted thumbprint with the error invalid_dpop_proof
(Section 7 of [RFC9449]).¶
When the deferred request resolves and an access token is issued in response to a polling request, the issued access token MUST be DPoP-bound to the same key, consistent with Section 5 of [RFC9449]. A confidential client that did not bind the deferral code with DPoP likewise inherits its originating grant's access-token binding rules unchanged.¶
The callback notification path is not authenticated by DPoP; the post-callback polling request is the moment of redemption and is covered by the rules above.¶
A deferral code is sender-constrained per Section 10.1, inheriting the binding rules of Section 5 of [RFC9449] for refresh tokens. Its threat profile is the same as a refresh token of equivalent lifetime; the considerations of [RFC9449] apply unchanged.¶
The originating grant's credentials — for example, the authorization
code returned to a client that requested response_type=code — are
unaffected by DTR and remain subject to the same protections as in
the non-deferred case (Section 4.1.3 of [OAUTH-2.1],
Section 2.1.1 of [RFC9700]).¶
Misbehaving or compromised clients may poll faster than the announced
interval, consuming authorization server resources.
Authorization servers SHOULD respond to faster-than-interval polling
with slow_down initially and MAY escalate to invalid_request for
clients that persist; a client receiving invalid_request MUST stop
polling for the affected deferral_code.
Authorization servers MAY also impose per-client and per-flow rate
limits independent of the announced interval.¶
The deferred_client_notification_endpoint registered by a client is
an inbound surface from the authorization server. Authorization
servers MUST require that the registered URI is an HTTPS URL.¶
When the client supplies a client_notification_token on the initial
token request, the bearer credential presented in the callback's
Authorization header authenticates the authorization server to the
client (see Section 6.1). Even so, the callback carries
no authorization grant: clients MUST retrieve the resolution by
polling the token endpoint with the deferral code after a callback,
not solely on the basis of having received the callback. Treating the
callback alone as authoritative would allow a denial-of-service
attacker who can cause callbacks to skip polling and miss the actual
authorization decision.¶
A client that does not supply a client_notification_token cannot
authenticate inbound callbacks at the application layer. Such a
client MUST protect the callback endpoint by other means (mutual TLS,
network-position assumptions, or a private network) and MUST treat
any callback as advisory.¶
The authorization server, on every callback, makes an outbound HTTP
request to a client-controlled URL. Without further protections this
would be a server-side request forgery (SSRF) surface: an attacker
who can register a deferred_client_notification_endpoint could
coerce the authorization server into probing internal infrastructure.
The protections below are analogous to the redirect-URI hardening of
Section 4.1 of [RFC9700] and to common SSRF mitigations from
deployed CIBA ([CIBA]) implementations.¶
At registration time, the authorization server SHOULD reject a
deferred_client_notification_endpoint whose hostname resolves to a
private (RFC 6890), loopback, link-local, or unspecified address.
Development and test deployments where such addresses are intentional
are an explicit exception; production deployments SHOULD enforce the
restriction.¶
At delivery time, the authorization server SHOULD re-resolve the hostname and verify that all returned addresses are public (subject to the same exception). To defeat DNS rebinding, the authorization server SHOULD pin the resolved address for the lifetime of the callback connection rather than rely on the resolver's cached entry.¶
The authorization server SHOULD set a finite connect and read timeout on the callback request and SHOULD cap the maximum response body size it is willing to read. The specification already requires the authorization server to ignore any HTTP response body (Section 6.1); the size cap exists to bound resource consumption from a misbehaving or malicious endpoint.¶
The authorization server MUST NOT include the deferral_code, the
client_notification_token, or any other token material in the
callback URL path or query string. The deferral_code is conveyed
in the JSON request body and the client_notification_token, if
present, is conveyed in the Authorization header per
Section 6.1; placing either in the URL would expose the
value to web-server access logs, intermediary proxies, and Referer
headers on any subsequent request the client emits.¶
A client_notification_token is a long-lived shared secret between
the client and the authorization server: it persists from the initial
token request until the deferral code expires or is revoked, which
may be hours or days. Both parties MUST treat it with the storage and
disposal care appropriate to a refresh token of equivalent lifetime
(Section 6 of [RFC9700]). Authorization servers MUST dispose of the
token when the deferral code resolves, expires, or is revoked.
Clients MUST NOT log the token or expose it through error messages.¶
A client_notification_token is bound to a single deferral code.
Clients MUST generate a fresh token for each initial token request
that opts into DTR; reuse across requests collapses the per-request
binding and weakens the protection that the token provides.¶
Deferral codes are designed to allow expires_in values measured in
hours or days. Across that window the resource owner's consent at the
moment of the originating grant may diverge from their state at the
moment of resolution: the owner may have changed credentials, revoked
the client, had their account suspended, or otherwise altered the
preconditions that justified the grant.¶
Before issuing a token in response to a successful polling request,
the authorization server MUST re-evaluate that the resource owner's
consent and the client's authorization remain valid. If consent has
been revoked, the client has been disabled, the resource owner's
session has been terminated, or any precondition of the originating
grant no longer holds, the authorization server MUST return
access_denied per Section 5.6 and MUST NOT
issue an access token. This is the deferred-grant analogue of
Section 4.6 of [RFC9700].¶
A deferral code is a bearer-equivalent credential for the duration
of expires_in. Authorization servers and clients MUST NOT log
deferral code values in plaintext beyond the code's lifetime, and
SHOULD treat them as secrets equivalent to refresh tokens with
respect to log redaction, transport security, and at-rest storage.
Standard web-server access logs that capture POST bodies retain
deferral code values for the entire log retention window;
implementations SHOULD configure their logging stacks to redact the
deferral_code parameter wherever it appears — both as the polling
request parameter and as the response field of deferred responses (see
Section 5.4).¶
Each polling request from a client to the token endpoint is identifiable
to the authorization server via the client's authenticated identity and
the deferral_code.
For long-running deferred requests, the polling pattern itself
(timing, network origin, user-agent of the client) may be observable to
network intermediaries, even though the deferral_code is sent over
TLS.
Clients SHOULD avoid embedding distinguishing information in
client-controlled fields that travel with polling requests.¶
deferral_code
Authorization servers retain deferral_code values, and any
associated context required to complete the deferred request, for the
lifetime indicated by expires_in.
Authorization servers SHOULD retain only the data necessary to complete
the request and to satisfy the cancellation and audit requirements of
this specification, and SHOULD dispose of deferral_code values and
their associated state once the request has resolved or expired.
Disposal of any data collected during the deferred request itself is
out of scope.¶
This section requests registrations in IANA registries as listed below.
Final values for Reference are this RFC once published.¶
This specification requests registration of the following parameter in the IANA "OAuth Parameters" registry:¶
Parameter name: completion_mode¶
Parameter usage location: authorization request, token request¶
Change Controller: IETF¶
Specification Document(s): this specification¶
The value of completion_mode is a space-separated list of values
registered in the "OAuth Completion Mode Values" registry defined below.¶
This specification requests the creation of a new IANA registry titled
"OAuth Completion Mode Values" to hold the values that may appear in the
space-separated completion_mode request parameter.¶
The registry follows the "Specification Required" registration policy [RFC8126]. Each registration comprises:¶
Value: the completion-mode value (a single token containing no spaces).¶
Description: a brief description of the value's meaning.¶
Change Controller: for values registered by the IETF, "IETF"; otherwise the registering party.¶
Specification Document(s): a reference to the document defining the value.¶
This specification registers the following initial value:¶
Value: deferred¶
Description: The client accepts a deferred response (Section 5.4) in place of an immediate token response or error.¶
Change Controller: IETF¶
Specification Document(s): this specification¶
This specification requests registration of the following client metadata definition in the IANA "OAuth Dynamic Client Registration Metadata" registry [RFC7591]:¶
This specification requests registration of the following grant type
in the IANA "OAuth Grant Type" registry, used as the value of the
grant_type parameter on polling token endpoint requests
(Section 5.5):¶
Name: urn:ietf:params:oauth:grant-type:deferred¶
Description: Polling grant type used to retrieve the eventual token response for a deferred authorization request, identified by a deferral code issued in a deferred response per Section 5.4.¶
Change Controller: IETF¶
Specification Document(s): this specification¶
This specification requests registration of the following URIs in the IANA "OAuth URI" registry:¶
URI: urn:ietf:params:oauth:token-type:deferral-code¶
Common Name: Deferral Code¶
Change Controller: IETF¶
Specification Document(s): this specification¶
URI: urn:ietf:params:oauth:grant-type:deferred¶
Common Name: Deferred Token Response Polling Grant¶
Change Controller: IETF¶
Specification Document(s): this specification¶
This section is informative.¶
An online banking application requires the user to authorize a high-risk transaction — for example, a large outbound transfer to a new payee. It is acceptable for the authorization to take from several minutes to a few hours, because the transfer can settle out of band; the user does not need to remain engaged with the application during that time.¶
When the user initiates the transaction, the banking application
sends an authorization request to the bank's authorization server with
completion_mode=deferred. The authorization server's risk-analysis
system
flags the transaction for additional review. The authorization
server returns a deferred response carrying a deferral code.¶
The bank performs additional verification — contacting the user through alternative channels, performing manual review by a fraud analyst, or applying other risk controls. During this time the user is free to close the banking application; on the next session, the client polls the token endpoint with the deferral code and renders the result of the transaction. If the bank registered a callback endpoint, it receives a notification when the result is committed and prompts the user proactively.¶
A user who signed in earlier with a low-assurance method (a stored password, for example) attempts an in-session operation that requires higher assurance — applying for a loan, changing contact details, or unlocking a sensitive feature. The authorization server needs to step up the user's assurance before issuing the token; the step-up may involve biometric verification or document presentation that is not guaranteed to complete instantly.¶
The client sends an authorization request with
completion_mode=deferred. The authorization server determines that
the requested operation
requires step-up, collects the relevant information from the user,
returns a deferred response, and proceeds with the
verification asynchronously. The client renders any unblocked steps
of the user's workflow (form fill, preview, draft persistence) while
polling for the eventual token response. This avoids forcing the
user to wait on a single blocking screen during a verification that
may legitimately take hours.¶
In jurisdictions without widely deployed digital identity, a common identity-verification flow scans a physical document — a passport or driver's license — supplemented by a liveness check (a short video of the end-user matched against the photograph on the document).¶
Most such verifications can be decided automatically. Some require a human operator to inspect the evidence, and that review can take hours. Regulation on automated decision-making in identity verification often makes the human-in-the-loop case mandatory rather than optional.¶
The client sends the originating grant's token request with
completion_mode=deferred. When automated verification suffices, the
authorization server completes synchronously. When it does not, the
authorization server returns a deferred response, queues the
evidence for human review, and notifies the client when the review
completes. The client UX continues immediately for users in the
automated path and degrades gracefully — to "we are reviewing your
documents, you will be notified" — for users in the deferred path,
without requiring two separate authorization flows.¶
An autonomous agent operates on behalf of a human principal under a narrow set of pre-approved scopes. The agent encounters a task that requires authorization beyond what was provisioned at enrollment — for example, executing a purchase above the per-transaction ceiling the principal granted.¶
The agent sends a token request to the authorization server with
completion_mode=deferred. The authorization server, recognizing that
the
requested scope exceeds standing approval, contacts the human
principal out of band — by mobile push, email, or a separate
approval application — and returns a deferred response to the agent.
The agent suspends the affected task and continues with other work.
When the principal approves (or denies) the request out of band, the
authorization server resolves the deferred request; the agent
retrieves the result by polling and either completes the task or
terminates it cleanly.¶
This pattern allows the principal to retain effective oversight without being on the synchronous path of every elevated request.¶
A workforce client requests an access token whose scope corresponds to a sensitive resource — production database access, financial system administration, or PII export — that the enterprise gates through an Identity Governance and Administration (IGA) workflow. The workflow may involve approvals from the requestor's manager, the resource owner, and a security reviewer, and may take from several hours to several business days.¶
The client sends a token request with completion_mode=deferred. The
authorization server, recognizing that the requested scope is under
IGA control, opens a request in the governance system, returns a
deferred response, and notifies the relevant approvers through their
normal channels. The client polls the token endpoint and surfaces
the request as "pending approval" to the requesting user. As
approvers act, the governance system records its decision; on final
approval, the authorization server resolves the deferred request and
the polling client receives the access token. On rejection or
timeout, polling returns access_denied and the client clears the
pending state.¶
This pattern lets the authorization server remain the authoritative issuer of access tokens even when the decision logic lives in a purpose-built governance system, without requiring the client to integrate with the governance system directly.¶
The authors would like to thank the following people for their contributions and reviews of this specification: Karl McGuinness, Mikkel Christensen, Mick Hansen, Vitor Watanabe, Ricardo Pereira¶