Skip to main content

OAuth Protected Authorization
draft-hardt-oauth-protected-authorization-00

Document Type Active Internet-Draft (individual)
Authors Dick Hardt , Sam Goto
Last updated 2026-07-04
Replaces draft-hardt-httpbis-redirect-headers
RFC stream (None)
Intended RFC status (None)
Formats
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-hardt-oauth-protected-authorization-00
Web Authorization Protocol                                      D. Hardt
Internet-Draft                                                     Hellō
Intended status: Standards Track                                 S. Goto
Expires: 5 January 2027                                           Google
                                                             4 July 2026

                     OAuth Protected Authorization
              draft-hardt-oauth-protected-authorization-00

Abstract

   This document defines browser support for protecting OAuth 2.0
   authorization requests and authorization responses during redirect-
   based authorization flows.  A single Structured Field header field,
   OAuth-Authorization, is set by the OAuth client in the redirect
   response that sends the browser to the authorization server, and by
   the authorization server in the redirect response that returns the
   browser to the OAuth client.  In both cases the browser augments the
   header with the attested origin of the redirecting party and delivers
   it to the redirect destination.  The mechanism provides security for
   the authorization request: the authorization server receives a
   browser-attested, tamper-evident statement of which origin initiated
   the request.  The mechanism provides security and privacy for the
   authorization response: the authorization code is delivered in the
   browser-protected header instead of the redirect URI, and never
   appears in a URL, eliminating its exposure through browser history,
   server logs, Referer headers, analytics systems, and URL sharing.
   The header is generated, validated, and delivered by the browser, and
   is inaccessible to scripts, service workers, and browser extensions.
   Existing OAuth deployments continue to function unchanged; the
   protections activate only when the OAuth client, browser, and
   authorization server all support them.

Discussion Venues

   _Note: This section is to be removed before publishing as an RFC._

   Source for this draft and an issue tracker can be found at
   https://github.com/dickhardt/oauth-protected-authorization
   (https://github.com/dickhardt/oauth-protected-authorization).

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

Hardt & Goto             Expires 5 January 2027                 [Page 1]
Internet-Draft           Protected Authorization               July 2026

   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 5 January 2027.

Copyright Notice

   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.

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   4
     1.1.  Goals . . . . . . . . . . . . . . . . . . . . . . . . . .   5
     1.2.  Non-Goals . . . . . . . . . . . . . . . . . . . . . . . .   5
     1.3.  Browser Enforcement Precondition  . . . . . . . . . . . .   6
   2.  Conventions and Terminology . . . . . . . . . . . . . . . . .   6
   3.  Protocol Overview . . . . . . . . . . . . . . . . . . . . . .   7
   4.  The OAuth-Authorization Header Field  . . . . . . . . . . . .   7
     4.1.  query . . . . . . . . . . . . . . . . . . . . . . . . . .   8
     4.2.  origin  . . . . . . . . . . . . . . . . . . . . . . . . .   8
     4.3.  path  . . . . . . . . . . . . . . . . . . . . . . . . . .   8
   5.  Authorization Request . . . . . . . . . . . . . . . . . . . .   8
     5.1.  Client Behavior . . . . . . . . . . . . . . . . . . . . .   9
     5.2.  Authorization Server Behavior . . . . . . . . . . . . . .   9
   6.  Authorization Response  . . . . . . . . . . . . . . . . . . .  10
     6.1.  Authorization Server Behavior . . . . . . . . . . . . . .  10
     6.2.  Client Behavior . . . . . . . . . . . . . . . . . . . . .  11
   7.  Path Validation . . . . . . . . . . . . . . . . . . . . . . .  12
   8.  Browser Processing Model  . . . . . . . . . . . . . . . . . .  12
   9.  Deployment Considerations . . . . . . . . . . . . . . . . . .  14
     9.1.  Incremental Adoption  . . . . . . . . . . . . . . . . . .  14

Hardt & Goto             Expires 5 January 2027                 [Page 2]
Internet-Draft           Protected Authorization               July 2026

     9.2.  Dual Transmission of Request Parameters . . . . . . . . .  14
     9.3.  Single-Page Applications  . . . . . . . . . . . . . . . .  14
     9.4.  Header Sizes  . . . . . . . . . . . . . . . . . . . . . .  15
   10. Security Considerations . . . . . . . . . . . . . . . . . . .  15
     10.1.  Dependence on Browser Enforcement  . . . . . . . . . . .  15
     10.2.  Downgrade  . . . . . . . . . . . . . . . . . . . . . . .  15
     10.3.  Cross-Context Delivery . . . . . . . . . . . . . . . . .  15
     10.4.  What Is and Is Not Protected . . . . . . . . . . . . . .  16
     10.5.  Server-Side Handling . . . . . . . . . . . . . . . . . .  16
     10.6.  Relationship to Existing Mechanisms  . . . . . . . . . .  17
   11. Privacy Considerations  . . . . . . . . . . . . . . . . . . .  17
     11.1.  Authorization Request Privacy  . . . . . . . . . . . . .  17
     11.2.  Authorization Response Privacy . . . . . . . . . . . . .  17
     11.3.  No New Cross-Site Information Flow . . . . . . . . . . .  17
     11.4.  Origin and Path Disclosure . . . . . . . . . . . . . . .  18
     11.5.  User Transparency  . . . . . . . . . . . . . . . . . . .  18
   12. IANA Considerations . . . . . . . . . . . . . . . . . . . . .  18
     12.1.  OAuth-Authorization Header Field . . . . . . . . . . . .  18
   13. Implementation Status . . . . . . . . . . . . . . . . . . . .  18
   14. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . .  19
   15. References  . . . . . . . . . . . . . . . . . . . . . . . . .  19
     15.1.  Normative References . . . . . . . . . . . . . . . . . .  19
     15.2.  Informative References . . . . . . . . . . . . . . . . .  19
   Appendix A.  Example: Authorization Code Flow Before and After  .  20
     A.1.  Without This Mechanism (Current OAuth)  . . . . . . . . .  20
     A.2.  With This Mechanism . . . . . . . . . . . . . . . . . . .  21
   Appendix B.  Design Rationale . . . . . . . . . . . . . . . . . .  22
     B.1.  Why OAuth-Specific Rather Than Generic Redirect
            Headers  . . . . . . . . . . . . . . . . . . . . . . . .  22
     B.2.  Why a Single Header Field . . . . . . . . . . . . . . . .  22
     B.3.  Why Not Cryptographic Protection of Parameters  . . . . .  22
     B.4.  Why Not Move to the Back Channel  . . . . . . . . . . . .  23
     B.5.  Why the Authorization Request Parameters Stay in the
            URL  . . . . . . . . . . . . . . . . . . . . . . . . . .  23
     B.6.  Why a Structured Field Dictionary Wrapping a Query
            String . . . . . . . . . . . . . . . . . . . . . . . . .  23
     B.7.  Why Redirect Responses Only (Why Not form_post) . . . . .  23
     B.8.  Why the AS Rejects on Query Mismatch, Rather Than the
            Browser Dropping the Header  . . . . . . . . . . . . . .  24
     B.9.  Why Not a Sec-Prefixed Name . . . . . . . . . . . . . . .  24
     B.10. Why Not a response_mode Value . . . . . . . . . . . . . .  24
     B.11. Why the Authorization Response Is Not Readable by
            JavaScript . . . . . . . . . . . . . . . . . . . . . . .  24
     B.12. Why Native Application Flows Are Out of Scope . . . . . .  24
     B.13. Why Browser-Attested Origin When iss Exists . . . . . . .  25
   Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  25

Hardt & Goto             Expires 5 January 2027                 [Page 3]
Internet-Draft           Protected Authorization               July 2026

1.  Introduction

   OAuth 2.0 [RFC6749] redirect-based authorization flows carry protocol
   parameters in URLs.  The critical parameter is the *authorization
   code*: it is a credential, exchangeable for tokens.  When the
   authorization server redirects back to the OAuth client with
   ?code=...&state=... in the redirect URI, that credential is written
   into browser history, web server access logs, proxy and load balancer
   logs, and analytics systems; it leaks through Referer headers to
   third-party resources loaded by the callback page; and it can be
   disclosed through URL sharing, screenshots, and copy/paste.  The
   OAuth 2.0 Security Best Current Practice [RFC9700] documents these
   leakage vectors and prescribes mitigations that limit the damage of a
   leaked code (PKCE [RFC7636], one-time use, short lifetimes), but the
   code is still exposed.

   A second, related weakness is that the authorization server has no
   reliable way to know which web origin sent the user.  The Referer
   header may be trimmed, stripped, or rewritten, and everything else in
   the authorization request is claimed by the requester rather than
   attested by anyone.

   This document defines browser behavior and a single Structured Field
   [RFC9651] header field, OAuth-Authorization, used on both legs of the
   flow:

   *  For the *authorization request*, the OAuth client sets the header
      in the redirect response that sends the browser to the
      authorization server.  The browser delivers it with the
      navigation, adding a browser-attested origin (and optionally a
      browser-validated path) identifying where the navigation actually
      came from.  Its presence also signals to the authorization server
      that the browser and OAuth client support protected authorization
      responses.

   *  For the *authorization response*, the authorization server sets
      the header in the redirect response that returns the browser to
      the OAuth client, placing the authorization response parameters in
      the header instead of the redirect URI.  The browser delivers it,
      exactly once, to the redirect URI, adding a browser-attested
      origin identifying the authorization server.

   The browser performs the same processing in both cases (Section 8);
   which OAuth message the header carries is determined by the endpoint
   that receives it.

   The mechanism provides *security for the authorization request, and
   security and privacy for the authorization response*:

Hardt & Goto             Expires 5 January 2027                 [Page 4]
Internet-Draft           Protected Authorization               July 2026

   *  The authorization request parameters remain in the request URI,
      unchanged, so existing authorization servers continue to work.
      The header adds origin attestation, tamper evidence, and a
      capability signal.  This is security without privacy: the OAuth
      client cannot know whether a given user's browser supports this
      mechanism, so the parameters never leave the URL.

   *  The authorization response parameters, above all the authorization
      code, exist only in the protected header and never appear in any
      URL.  The authorization server sends them this way only after the
      header's arrival with the authorization request has proven that
      the browser and OAuth client support it.

   Existing deployments continue to function unchanged, and adoption is
   deliberately inexpensive: for most clients, support arrives as an
   update to the OAuth library they already use, with no new endpoints,
   no keys, and no change to how authorization parameters are
   constructed or parsed (Section 9).

1.1.  Goals

   1.  Provide an explicit browser signal that a navigation is an OAuth
       authorization request.
   2.  Provide a protected, browser-mediated delivery mechanism for
       OAuth authorization responses.
   3.  Preserve complete compatibility with existing OAuth deployments
       and parameter processing.

   This mechanism complements PKCE [RFC7636], PAR [RFC9126], iss
   identification [RFC9207], and JARM [JARM].  It does not replace any
   of them.

1.2.  Non-Goals

   *  This is not a back-channel protocol.  Protocols that move the
      authorization exchange out of the front channel entirely (such as
      PAR [RFC9126] for the request, or the AAuth protocol
      [I-D.hardt-oauth-aauth-protocol] for the full authorization
      exchange) provide stronger confidentiality with different
      deployment costs.  See Appendix B.4.
   *  This is not a generic HTTP redirect mechanism.  It is
      intentionally specific to OAuth authorization flows.  See
      Appendix B.1.
   *  This mechanism does not protect against a compromised or non-
      conforming browser, a malicious authorization server, or a
      malicious OAuth client.
   *  Native application flows [RFC8252] are out of scope.  See
      Appendix B.12.

Hardt & Goto             Expires 5 January 2027                 [Page 5]
Internet-Draft           Protected Authorization               July 2026

1.3.  Browser Enforcement Precondition

   The security properties defined in this document are provided by
   browser behavior, not by the header name or value.  The header MUST
   be inaccessible to page JavaScript, to fetch() and XMLHttpRequest, to
   service workers, and to browser extensions (Section 8). *A browser
   that cannot enforce all of the protections in Section 8 (for example,
   because its extension APIs expose all request headers) MUST NOT
   implement this mechanism.* In that case the flow degrades safely to
   standard OAuth: no header is generated, and the authorization server
   responds with parameters in the redirect URI as it does today.

2.  Conventions and Terminology

   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 "authorization request", "authorization
   response", "authorization server" (AS), "client", and "redirect URI"
   as defined by OAuth 2.0 [RFC6749], and "origin" as defined by
   [RFC6454].

   *Client*: in this document, "client" always means the OAuth client as
   defined by [RFC6749], the application requesting authorization.  The
   HTTP client performing navigations is always referred to as "the
   browser".

   *Browser*: a user agent performing top-level navigations on behalf of
   a user.

   *Redirecting server / redirecting URL*: the server, and the URL, from
   which a redirect response was received.  The browser attests the
   origin (and optionally a path prefix) of the redirecting URL, which
   is well defined even when the redirect is the first response in a
   navigation (e.g., a login URL that immediately returns a redirect).

   *Authorization request and response* always refer to the OAuth
   messages [RFC6749], never to HTTP requests and responses.  At each
   redirect hop, the OAuth-Authorization header field appears in two
   HTTP messages: the redirecting server sets it in the redirect
   _response_, and the browser delivers it as a header field of the
   subsequent HTTP _request_ to the redirect destination.  This document
   always states which HTTP message is meant.

Hardt & Goto             Expires 5 January 2027                 [Page 6]
Internet-Draft           Protected Authorization               July 2026

3.  Protocol Overview

   The flow is standard OAuth; the additions introduced by this
   specification are marked *(new)*:

   1.  The client constructs a normal authorization request URI and
       returns a redirect response (302 or 303) to the browser. *(new)*
       The redirect response also carries an OAuth-Authorization header
       whose query member is the same serialized query string that
       appears in the authorization request URI.
   2.  *(new)* The browser recognizes the header, adds the browser-
       attested origin member (and path if claimed and valid), and
       delivers it as a header field of the HTTP request to the
       authorization server.  The request URI is unchanged.
   3.  The AS processes the authorization request from the URI as it
       does today. *(new)* If the OAuth-Authorization header is present,
       the AS verifies the query member matches the request URI query,
       and now knows (a) the browser-attested origin of the client and
       (b) that the browser and client support protected authorization
       responses.
   4.  The AS authenticates the user and obtains authorization, using
       any number of internal redirects or pages; the header plays no
       role in these intermediate steps.
   5.  The AS returns a redirect response to the registered redirect
       URI. *(new)* Instead of placing the authorization response
       parameters in the redirect URI query, the AS places them in the
       query member of an OAuth-Authorization header.  The redirect URI
       carries no response parameters.
   6.  *(new)* The browser adds the browser-attested origin of the AS
       and delivers the header, exactly once, as a header field of the
       HTTP request to the redirect URI.
   7.  *(new)* The client reads the authorization response parameters
       from the header's query member, using the same parsing it uses
       for URL query strings today, and verifies the browser-attested
       origin is the expected AS.

   If any party does not support the mechanism, the header is simply
   absent and the flow proceeds as standard OAuth.

4.  The OAuth-Authorization Header Field

   OAuth-Authorization is a Structured Field Dictionary [RFC9651] with
   three members, all Strings: query, origin, and path.  The redirecting
   server sets the header in a redirect response; the browser validates
   and augments it, and delivers it as a header field of the subsequent
   HTTP request to the redirect destination (Section 8).

Hardt & Goto             Expires 5 January 2027                 [Page 7]
Internet-Draft           Protected Authorization               July 2026

   A recipient determines which OAuth message the header carries from
   its own role: an authorization endpoint receives authorization
   requests; a redirect URI receives authorization responses.  Delivery
   to the wrong context fails closed (Section 10.3).

4.1.  query

   Set by the redirecting server; relayed by the browser without
   inspection or modification.

   The query member carries the OAuth parameters, using the same
   serialization as a URL query string, so recipients parse it with the
   code they already use for URLs today:

   *  In an *authorization request* (Section 5), the client sets query
      to the query component of the authorization request URI, byte-
      identical to it.
   *  In an *authorization response* (Section 6), the AS sets query to
      the serialized authorization response parameters that would
      otherwise appear in the redirect URI query.

4.2.  origin

   Set only by the browser: the ASCII serialization [RFC6454] of the
   redirecting URL's origin.  Servers MUST NOT set origin; the browser
   removes any server-set value before setting its own.  A receiving
   party can therefore rely on origin unconditionally: it cannot be set,
   suppressed, or modified by web content or by any server.

4.3.  path

   Claimed by the redirecting server; validated, and set or removed, by
   the browser.

   The redirecting server MAY include a path member as a claim about the
   path prefix of the redirecting URL; the value MUST begin and end with
   /. The browser delivers the member only if the redirecting URL's path
   begins with the claimed value, and removes it otherwise (Section 7).
   A receiving party can therefore rely on a delivered path
   unconditionally: the browser only delivers claims it has verified.

5.  Authorization Request

Hardt & Goto             Expires 5 January 2027                 [Page 8]
Internet-Draft           Protected Authorization               July 2026

5.1.  Client Behavior

   The client constructs the authorization request URI exactly as it
   does today; all authorization request parameters remain in the URI
   query for compatibility.  In the redirect response (302 or 303) that
   sends the browser to the authorization server, the client
   additionally sets the header:

 HTTP/1.1 303 See Other
 Location: https://as.example/authorize?client_id=abc&response_type=code
     &redirect_uri=https%3A%2F%2Fapp.example%2Fportal%2Fcb&state=123
     &code_challenge=E9Melhoa...&code_challenge_method=S256
 OAuth-Authorization: query="client_id=abc&response_type=code
     &redirect_uri=https%3A%2F%2Fapp.example%2Fportal%2Fcb&state=123
     &code_challenge=E9Melhoa...&code_challenge_method=S256",
     path="/portal/"

   (Line breaks in the examples are for readability only.)

   The query member MUST be byte-identical to the query component of the
   Location URI.  The client MAY include a path claim (Section 7).

   The browser processes the header per Section 8 and delivers it with
   the navigation:

   GET /authorize?client_id=abc&response_type=code&redirect_uri=...
       &state=123&code_challenge=...&code_challenge_method=S256 HTTP/1.1
   Host: as.example
   OAuth-Authorization: query="client_id=abc&response_type=code
       &redirect_uri=...&state=123&code_challenge=...
       &code_challenge_method=S256",
       origin="https://app.example", path="/portal/"

   Note that the browser does NOT compare the query member with the
   Location URI query.  Dropping the header on a mismatch would allow an
   attacker able to tamper with the URI to silently downgrade the flow
   to unprotected behavior; instead the header is always delivered and
   the authorization server detects tampering (Section 5.2).

5.2.  Authorization Server Behavior

   The AS processes the authorization request from the request URI query
   exactly as it does today.  Deployments that do not implement this
   specification require no changes.

   An AS that implements this specification and receives an OAuth-
   Authorization header with an authorization request:

Hardt & Goto             Expires 5 January 2027                 [Page 9]
Internet-Draft           Protected Authorization               July 2026

   1.  MUST verify that the query member is byte-identical to the query
       component of the request URI, and reject the authorization
       request with an error if they differ.  A mismatch indicates
       tampering or a defective client and MUST NOT be silently ignored.
   2.  SHOULD verify that the origin member is consistent with the
       client's registered redirect_uri values (e.g., that the
       registered redirect URIs for the presented client_id belong to
       the attested origin), and reject the request otherwise.  Unlike
       the Referer header, origin is browser-attested: it cannot be set,
       suppressed, or modified by web content.
   3.  MAY use a validated path member to discriminate between multiple
       clients registered on the same origin under different path
       prefixes.
   4.  MUST return the authorization response using the OAuth-
       Authorization header as defined in Section 6.  The header's
       arrival with the authorization request is the capability signal:
       it can only have arrived via a supporting browser from a
       supporting client.

   On this leg the header provides origin attestation and tamper
   evidence; it does not provide confidentiality.  The authorization
   request parameters remain visible in the URL, as they are today.

6.  Authorization Response

6.1.  Authorization Server Behavior

   An AS whose authorization request arrived bearing the OAuth-
   Authorization header MUST deliver the authorization response in the
   header, and MUST NOT include response parameters in the redirect URI:

   HTTP/1.1 303 See Other
   Location: https://app.example/portal/cb
   OAuth-Authorization: query="code=SplxlOBeZQQYbYS6WxSbIA
       &state=123&iss=https%3A%2F%2Fas.example"

   The AS delivers error responses through the same header, for
   consistency: once support is established, every authorization
   response, success or error, arrives through the same channel, giving
   the client a single processing path.  (Keeping error details out of
   URLs and logs is a secondary benefit.)

   HTTP/1.1 303 See Other
   Location: https://app.example/portal/cb
   OAuth-Authorization: query="error=access_denied&state=123
       &iss=https%3A%2F%2Fas.example"

   The AS MAY include a path claim (Section 7).

Hardt & Goto             Expires 5 January 2027                [Page 10]
Internet-Draft           Protected Authorization               July 2026

   An AS MUST NOT include an OAuth-Authorization header in its response
   redirect unless the corresponding authorization request arrived
   bearing the header: without that signal there is no evidence the
   browser will deliver the header or that the client will read it.

   The browser processes the header per Section 8 and delivers it with
   the navigation, exactly once, to the redirect URI only:

   GET /portal/cb HTTP/1.1
   Host: app.example
   OAuth-Authorization: query="code=SplxlOBeZQQYbYS6WxSbIA
       &state=123&iss=https%3A%2F%2Fas.example",
       origin="https://as.example"

6.2.  Client Behavior

   A client that receives an OAuth-Authorization header at its redirect
   URI:

   1.  MUST obtain the authorization response parameters by parsing the
       query member as a URL query string, and MUST ignore any query
       parameters present in the request URI.
   2.  MUST verify that the origin member matches the origin of the
       authorization server it sent the corresponding authorization
       request to, and reject the response otherwise.  This browser-
       attested check complements the iss parameter [RFC9207] and is
       stronger: iss is asserted by whichever server sent the response.
   3.  Processes the parameters (including state verification and the
       token request with PKCE) exactly as it does for URL-delivered
       responses today.

   A client that receives authorization response parameters in the URL
   (because the user's browser, or the AS, does not support this
   mechanism) processes them as it does today.  A client can never
   require the header: URL delivery may simply mean an unsupporting
   browser (see Section 10.2).

   Because the header is delivered only once, clients MUST complete
   processing (or persist what they need) on first delivery; a reload of
   the redirect URI carries neither the header nor any parameters.  Note
   that this also means an authorization code can no longer be replayed
   out of browser history: there is nothing in the URL or the history
   entry to replay.

Hardt & Goto             Expires 5 January 2027                [Page 11]
Internet-Draft           Protected Authorization               July 2026

7.  Path Validation

   Multiple clients may share an origin, separated by path prefix (e.g.,
   https://host.example/app1/ and https://host.example/app2/).  The
   origin alone cannot discriminate between them.  The path member
   allows the receiving party to know which path prefix within the
   origin the redirect actually came from.

   The path member is a claim made by the redirecting server and
   validated by the browser:

   1.  The redirecting server includes path in its header with a value
       that MUST begin and end with / (e.g., path="/app1/").
   2.  The browser checks whether the path component of the redirecting
       URL begins with the claimed value.
   3.  If it does, the browser includes the path member in the delivered
       header.
   4.  If it does not, the browser removes the path member and delivers
       the header without it.

   The trailing / requirement ensures prefix matching occurs on path-
   segment boundaries (/app1/ does not match /app1evil/x).

   The redirecting server cannot lie about its path: the browser only
   delivers a path claim it has verified.  A receiving party that
   requires path discrimination treats an absent path member accordingly
   (e.g., an AS that registered a client with a path-scoped redirect URI
   SHOULD reject a request whose validated path is absent or
   inconsistent with the registration).

8.  Browser Processing Model

   This is fundamentally a browser behavior specification: the security
   properties of the OAuth-Authorization header field are created
   entirely by the browser processing rules in this section.  The
   browser acts as a trusted protocol participant, a role it already
   plays for every OAuth flow today by enforcing TLS, cookie isolation,
   redirect handling, and origin boundaries.  This section makes that
   role explicit.

   *Recognition.* The browser processes the header when, and only when,
   it appears in a 302 or 303 response to a top-level navigation.  No
   URL heuristics are used.  The header is ignored (and stripped) in all
   other contexts: subresource requests, fetch/XHR responses, embedded
   frames, and non-redirect responses.

Hardt & Goto             Expires 5 January 2027                [Page 12]
Internet-Draft           Protected Authorization               July 2026

   *Identical processing on both legs.* The browser applies the same
   rules whether the redirecting server is a client sending an
   authorization request or an AS returning an authorization response.
   The browser does not parse or interpret the query member; in
   particular, it does not compare it with the Location URI
   (Appendix B.8).

   *Single hop, stateless.* The header is relayed exactly one hop: from
   the redirect response in which the redirecting server set it, to the
   HTTP request for the Location URI, and no further.  The browser keeps
   no state about an OAuth flow across hops; if an intermediate
   destination redirects again, that response must itself set the header
   for the browser to relay it.  Any transient state used to relay the
   header is destroyed after delivery.

   *Browser-generated members.* The browser removes any origin member
   set by a server and sets it itself; the browser validates any server-
   claimed path member and delivers it only if valid.  Receiving parties
   can therefore rely on origin and path unconditionally.

   *Protection requirements.* The browser MUST ensure that:

   *  Web content cannot set this header field on any request: it MUST
      be treated as a forbidden header name in the sense of Fetch
      [FETCH].
   *  JavaScript cannot read this header field from any request or
      response, including via fetch(), XMLHttpRequest, performance and
      reporting APIs, or any other API.
   *  Service workers cannot observe or modify this header field, on
      either the redirect responses that carry it or the requests that
      deliver it, including via navigation preload.
   *  Browser extensions cannot read, modify, inject, suppress, or
      replay this header field, regardless of the permissions the
      extension holds.
   *  The header field is processed only for top-level navigations,
      delivered only to the Location destination of the redirect that
      carried it, delivered at most once, and never persisted.

   These protections are intentionally stronger than those of Sec--
   prefixed header fields, which today remain readable by extensions and
   service workers.  A browser that cannot enforce every requirement in
   this list MUST NOT implement this mechanism (see Section 10.1).

Hardt & Goto             Expires 5 January 2027                [Page 13]
Internet-Draft           Protected Authorization               July 2026

   *Standards coordination.* The processing model in this section (the
   forbidden header name, service worker opacity, and navigation
   integration) requires a normative change to the WHATWG Fetch standard
   [FETCH].  A Fetch pull request defining this processing model is a
   deliverable of this work; this document defines the OAuth protocol
   semantics that rely on it.

9.  Deployment Considerations

9.1.  Incremental Adoption

   No coordination between parties is required.  Each party adds support
   independently, in any order:

   *  *Clients* add the OAuth-Authorization header to the redirect
      responses they already send, keeping all parameters in the URL,
      and read authorization responses from the header when present,
      falling back to URL parameters when it is not.  This is a library
      update.
   *  *Browsers* implement the processing model in Section 8.
   *  *Authorization servers* verify and use the header when it arrives
      with an authorization request, and switch the authorization
      response to the header, whose arrival proves the whole path
      supports it.

   Until all three parties support the mechanism, every flow proceeds
   exactly as standard OAuth.  There is no flag day and no breakage for
   any non-supporting party.

9.2.  Dual Transmission of Request Parameters

   Clients send the authorization request parameters in both the URL and
   the header on every request, indefinitely: a client cannot know
   whether any given user's browser supports this mechanism, and this
   specification deliberately defines no discovery mechanism.  This is
   why the authorization request gains security but not privacy
   (Section 11.1), and why the authorization response, which is sent in
   the header only when support is proven, gains both.

9.3.  Single-Page Applications

   The authorization response is delivered to the server at the redirect
   URI; it is, by design, not readable by JavaScript (Appendix B.11).
   SPAs that process authorization codes in front-end code continue to
   work exactly as they do today (they will not receive the header
   because they do not send it from a server-issued redirect response).
   SPAs that adopt a backend-for-frontend gain the protections of this
   specification.

Hardt & Goto             Expires 5 January 2027                [Page 14]
Internet-Draft           Protected Authorization               July 2026

9.4.  Header Sizes

   Authorization code responses are small (typically well under 1 KB).
   Deployments that layer large response payloads into the query member,
   such as JARM [JARM] response JWTs, should be aware of intermediary
   header size limits, commonly 8 to 16 KB.

10.  Security Considerations

10.1.  Dependence on Browser Enforcement

   Everything in this specification depends on the browser protections
   in Section 8.  If extensions, service workers, or page script can
   observe or forge the header, the mechanism provides no security
   benefit over URL parameters and MUST NOT be implemented.  This is the
   central deployment requirement of this specification and is
   intentionally stated bluntly: the security properties are defined by
   browser behavior, and exist only where the browser provides them.

   This specification assumes an honest, conforming browser.  It cannot
   protect against a compromised or malicious browser, browser bugs that
   fail to enforce the processing model, or debugging tools operating
   with the user's authority.  Servers SHOULD treat anomalous origin
   values as potential indicators of a non-conforming implementation.

10.2.  Downgrade

   An attacker who prevents the mechanism from operating (for example,
   by interfering with a non-protected portion of the flow) obtains at
   most today's OAuth: parameters in URLs, with all [RFC9700]
   mitigations (PKCE, state, one-time short-lived codes, exact redirect
   URI matching) still in force.  A client cannot distinguish "the
   user's browser does not support this" from "support was stripped",
   and therefore can never hard-require the header; this residual
   downgrade is accepted and is exactly the status quo.  The browser is
   stateless across the flow (Section 8), so it cannot mark a callback
   as "should have been protected"; a future extension could revisit
   this if browsers ever maintain per-flow state.

   Query tampering, by contrast, is not a downgrade vector: the browser
   always delivers the header with the authorization request, and the AS
   rejects on mismatch (Section 5.2).

10.3.  Cross-Context Delivery

   A single header field name means a header could in principle reach a
   party expecting the other OAuth message.  Both directions fail
   closed:

Hardt & Goto             Expires 5 January 2027                [Page 15]
Internet-Draft           Protected Authorization               July 2026

   *  An authorization endpoint that receives a header whose query
      member is not byte-identical to the request URI query rejects the
      request (Section 5.2); a header carrying authorization response
      parameters never matches an authorization request URI.
   *  A client that receives a header at its redirect URI verifies the
      browser-attested origin is its expected AS (Section 6).  A header
      minted by any other party, including an attacker's site issuing a
      redirect to the client's redirect URI, carries the attacker's
      origin and is rejected.  Web content and extensions cannot forge
      the header at all (Section 8).

10.4.  What Is and Is Not Protected

   Protected: the authorization code, and the other authorization
   response parameters, never appear in URLs, eliminating exposure via
   browser history, web server and proxy logs, Referer headers,
   analytics and crash reporting, URL sharing, screenshots, and copy/
   paste; and both parties receive a browser-attested origin for the
   other side of each redirect.

   Not protected: parameters in transit (TLS remains REQUIRED for every
   HTTP request and response carrying the header); the authorization
   request parameters, which remain in the URL by design; the parties
   themselves (a malicious AS or client is out of scope); and injection
   of an attacker's _legitimate_ authorization response at a client
   (authorization code injection), for which PKCE remains REQUIRED.

10.5.  Server-Side Handling

   When carrying an authorization response, the query member contains
   the authorization code and MUST be treated with the confidentiality
   of an Authorization header: excluded or redacted in access logs,
   application logs, and telemetry.  Because the same field name is used
   on both legs, the simple deployment rule is to treat OAuth-
   Authorization as sensitive everywhere.  Moving parameters out of URLs
   removes them from _default_ URL logging; header logging is a
   configuration choice that servers MUST make deliberately.

   Receiving parties MUST parse the header as a Structured Field
   [RFC9651] and reject malformed values.  An HTTP request or response
   carrying more than one instance of the header field is invalid;
   recipients MUST ignore the header field entirely in that case, and
   browsers MUST NOT relay duplicated instances.

Hardt & Goto             Expires 5 January 2027                [Page 16]
Internet-Draft           Protected Authorization               July 2026

10.6.  Relationship to Existing Mechanisms

   This mechanism supplements and does not relax any existing
   requirement: redirect URI registration and exact matching, state (or
   equivalent CSRF protection), PKCE [RFC7636], and the mitigations of
   [RFC9700] all continue to apply.  The origin member provides a
   browser-attested complement to iss [RFC9207] for mix-up defense, and
   browser-attested client origin strengthens the AS's ability to detect
   requests initiated from unexpected origins, supplementing rather than
   replacing redirect URI validation.

11.  Privacy Considerations

11.1.  Authorization Request Privacy

   Authorization request parameters remain in the URL indefinitely
   (Section 9) and remain exposed exactly as they are today.  This is
   explicitly a non-goal: authorization request parameters (client_id,
   redirect_uri, state, code_challenge) are not secrets.  Deployments
   that need request confidentiality should use PAR [RFC9126].

11.2.  Authorization Response Privacy

   Authorization response parameters never appear in URLs, browser
   history, Referer headers, or default logs, and the header is
   invisible to page JavaScript, embedded third parties, service
   workers, and extensions.  The header is delivered once and never
   persisted.

11.3.  No New Cross-Site Information Flow

   This mechanism activates only on OAuth authorization navigations:
   flows that by design already convey the client's identity to the AS
   (client_id, redirect_uri) in the URL.  The browser-attested origin
   gives the AS nothing it does not already receive; it makes an
   existing claim reliable rather than adding a new one.  On the return
   leg, the AS origin delivered to the client identifies a party the
   client chose and already knows.  The header is invisible to all third
   parties, so it cannot be used as a side channel between origins.
   What remains true, and is unchanged by this specification, is that
   front-channel OAuth inherently reveals to the AS that a user is
   authorizing a given client; only back-channel protocols such as
   [I-D.hardt-oauth-aauth-protocol] change that.

Hardt & Goto             Expires 5 January 2027                [Page 17]
Internet-Draft           Protected Authorization               July 2026

11.4.  Origin and Path Disclosure

   The origin member is a reliable equivalent of a scheme-plus-host
   Referer, and a validated path member discloses a path prefix, but
   only to the party the redirect was addressed to, which in OAuth
   already knows the counterparty.  Unlike Referer, these members cannot
   be stripped by the user without the flow degrading to URL parameters
   (which disclose strictly more).  This trade-off, favoring reliable
   counterparty verification over origin hiding, is appropriate only
   where mutual knowledge of the parties is expected, as it is in OAuth;
   it is one of the reasons this mechanism is OAuth-specific rather than
   generic (Appendix B.1).

11.5.  User Transparency

   Users cannot inspect or modify the header in-page (unlike URL
   parameters).  Browsers SHOULD surface it in developer tools, read-
   only, while maintaining all protections in Section 8.

12.  IANA Considerations

   This document registers one header field in the "Hypertext Transfer
   Protocol (HTTP) Field Name Registry" defined in [RFC9110].

12.1.  OAuth-Authorization Header Field

   Field name: OAuth-Authorization

   Status: permanent

   Structured Type: Dictionary

   Reference: [this document]

13.  Implementation Status

   *Note to RFC Editor: Please remove this section before publication.*

   Specification status: Exploratory draft.  This document replaces
   draft-hardt-httpbis-redirect-headers, refocused on the OAuth use case
   following IETF 125 feedback.

   Browser support: not yet implemented; requires the Fetch processing
   model in Section 8.

   Server and client support: reference implementations needed; adoption
   is a library update for both.

Hardt & Goto             Expires 5 January 2027                [Page 18]
Internet-Draft           Protected Authorization               July 2026

14.  Acknowledgments

   The authors would like to thank early reviewers for their valuable
   feedback and insights that helped shape this proposal: Jonas Primbs,
   Warren Parad.  This document was refocused on the OAuth use case in
   response to feedback from the HTTPBIS working group at IETF 125, in
   particular from Martin Thomson, Justin Richer, David Waite, Mike
   Bishop, Li Ruochen, and Yaroslav Rosomakho.

15.  References

15.1.  Normative References

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <https://www.rfc-editor.org/info/rfc2119>.

   [RFC6454]  Barth, A., "The Web Origin Concept", RFC 6454,
              DOI 10.17487/RFC6454, December 2011,
              <https://www.rfc-editor.org/info/rfc6454>.

   [RFC6749]  Hardt, D., Ed., "The OAuth 2.0 Authorization Framework",
              RFC 6749, DOI 10.17487/RFC6749, October 2012,
              <https://www.rfc-editor.org/info/rfc6749>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              May 2017, <https://www.rfc-editor.org/info/rfc8174>.

   [RFC9110]  Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
              Ed., "HTTP Semantics", STD 97, RFC 9110,
              DOI 10.17487/RFC9110, June 2022,
              <https://www.rfc-editor.org/info/rfc9110>.

   [RFC9651]  Nottingham, M. and P. Kamp, "Structured Field Values for
              HTTP", RFC 9651, DOI 10.17487/RFC9651, September 2024,
              <https://www.rfc-editor.org/info/rfc9651>.

   [RFC9700]  Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett,
              "Best Current Practice for OAuth 2.0 Security", BCP 240,
              RFC 9700, DOI 10.17487/RFC9700, January 2025,
              <https://www.rfc-editor.org/info/rfc9700>.

15.2.  Informative References

   [FETCH]    WHATWG, "Fetch Living Standard", 2026,
              <https://fetch.spec.whatwg.org/>.

Hardt & Goto             Expires 5 January 2027                [Page 19]
Internet-Draft           Protected Authorization               July 2026

   [I-D.hardt-oauth-aauth-protocol]
              Hardt, D., "AAuth Protocol", Work in Progress, Internet-
              Draft, draft-hardt-oauth-aauth-protocol-08, 24 June 2026,
              <https://datatracker.ietf.org/doc/html/draft-hardt-oauth-
              aauth-protocol-08>.

   [JARM]     Lodderstedt, T. and B. Campbell, "JWT Secured
              Authorization Response Mode for OAuth 2.0 (JARM)",
              November 2022,
              <https://openid.net/specs/oauth-v2-jarm.html>.

   [RFC7636]  Sakimura, N., Ed., Bradley, J., and N. Agarwal, "Proof Key
              for Code Exchange by OAuth Public Clients", RFC 7636,
              DOI 10.17487/RFC7636, September 2015,
              <https://www.rfc-editor.org/info/rfc7636>.

   [RFC8252]  Denniss, W. and J. Bradley, "OAuth 2.0 for Native Apps",
              BCP 212, RFC 8252, DOI 10.17487/RFC8252, October 2017,
              <https://www.rfc-editor.org/info/rfc8252>.

   [RFC9126]  Lodderstedt, T., Campbell, B., Sakimura, N., Tonge, D.,
              and F. Skokan, "OAuth 2.0 Pushed Authorization Requests",
              RFC 9126, DOI 10.17487/RFC9126, September 2021,
              <https://www.rfc-editor.org/info/rfc9126>.

   [RFC9207]  Meyer zu Selhausen, K. and D. Fett, "OAuth 2.0
              Authorization Server Issuer Identification", RFC 9207,
              DOI 10.17487/RFC9207, March 2022,
              <https://www.rfc-editor.org/info/rfc9207>.

Appendix A.  Example: Authorization Code Flow Before and After

A.1.  Without This Mechanism (Current OAuth)

   Client redirects to the AS:

 HTTP/1.1 303 See Other
 Location: https://as.example/authorize?client_id=abc&response_type=code
     &redirect_uri=https%3A%2F%2Fapp.example%2Fportal%2Fcb&state=123
     &code_challenge=E9Melhoa...&code_challenge_method=S256

   The AS has only the unreliable Referer header to know where the user
   came from.  After authorization, the AS redirects back:

   HTTP/1.1 303 See Other
   Location: https://app.example/portal/cb?code=SplxlOBeZQQYbYS6WxSbIA
       &state=123&iss=https%3A%2F%2Fas.example

Hardt & Goto             Expires 5 January 2027                [Page 20]
Internet-Draft           Protected Authorization               July 2026

   The authorization code is now in the URL: recorded in browser
   history, in the client's access logs and any intermediary's logs,
   sent in the Referer header to any third-party resource the callback
   page loads, and available to be shared, screenshotted, or pasted.

A.2.  With This Mechanism

   Client redirects to the AS; the URL is identical to today, plus the
   header:

 HTTP/1.1 303 See Other
 Location: https://as.example/authorize?client_id=abc&response_type=code
     &redirect_uri=https%3A%2F%2Fapp.example%2Fportal%2Fcb&state=123
     &code_challenge=E9Melhoa...&code_challenge_method=S256
 OAuth-Authorization: query="client_id=abc&response_type=code
     &redirect_uri=https%3A%2F%2Fapp.example%2Fportal%2Fcb&state=123
     &code_challenge=E9Melhoa...&code_challenge_method=S256",
     path="/portal/"

   The redirecting URL is https://app.example/portal/login, so the
   browser validates the /portal/ path claim, attests the origin, and
   delivers:

   GET /authorize?client_id=abc&response_type=code&redirect_uri=...
       &state=123&code_challenge=...&code_challenge_method=S256 HTTP/1.1
   Host: as.example
   OAuth-Authorization: query="client_id=abc&response_type=code
       &redirect_uri=...&state=123&code_challenge=...
       &code_challenge_method=S256",
       origin="https://app.example", path="/portal/"

   The AS verifies the query member matches the URL, verifies
   https://app.example is consistent with the registered redirect URI
   for client_id=abc, and, knowing the browser and client support
   protected authorization responses, returns the response in the header
   with a clean redirect URI:

   HTTP/1.1 303 See Other
   Location: https://app.example/portal/cb
   OAuth-Authorization: query="code=SplxlOBeZQQYbYS6WxSbIA
       &state=123&iss=https%3A%2F%2Fas.example"

   The browser attests the AS origin and delivers, once:

Hardt & Goto             Expires 5 January 2027                [Page 21]
Internet-Draft           Protected Authorization               July 2026

   GET /portal/cb HTTP/1.1
   Host: app.example
   OAuth-Authorization: query="code=SplxlOBeZQQYbYS6WxSbIA
       &state=123&iss=https%3A%2F%2Fas.example",
       origin="https://as.example"

   The client verifies origin is its expected AS, parses the query
   member with its existing query-string parser, verifies state, and
   exchanges the code (with its PKCE verifier).  The authorization code
   never appeared in any URL: nothing in browser history, nothing in
   URL-based logs, nothing in Referer headers, nothing to share or
   replay.

Appendix B.  Design Rationale

B.1.  Why OAuth-Specific Rather Than Generic Redirect Headers

   A generic redirect-header mechanism gives the browser no way to know
   when protections apply, no defined trust model, and a broad new
   surface for navigation tracking.  Scoping to OAuth lets the browser
   recognize exactly one flow shape, attach exactly the metadata that
   flow needs, and constrain the mechanism to navigations that already
   carry cross-site identifiers by design.

B.2.  Why a Single Header Field

   The browser's processing is identical on both legs of the flow, so
   one header field name means one processing rule, one forbidden header
   name in Fetch, and one IANA registration.  Separate "request" and
   "response" names would also invite conflating the OAuth message
   direction with the HTTP message direction: the header appears in an
   HTTP response and then an HTTP request on _each_ leg.  The receiving
   endpoint's role already determines which OAuth message the header
   carries, and delivery to the wrong context fails closed
   (Section 10.3).

B.3.  Why Not Cryptographic Protection of Parameters

   The exposure this document addresses is at the endpoints, not on the
   channel: TLS already protects parameters in transit.  An encrypted or
   signed response (JARM [JARM]) placed in a URL is still a URL: still
   written to history, still in access logs, still sent in Referer
   headers, still shareable.  Cryptographic protection also requires key
   distribution between every client and AS pair, and no cryptographic
   scheme can attest a client's _web origin_: only the user agent knows
   which origin actually initiated a navigation.  The mechanisms
   compose: a JARM response can be carried in the header's query member,
   gaining URL-freedom on top of its integrity properties.

Hardt & Goto             Expires 5 January 2027                [Page 22]
Internet-Draft           Protected Authorization               July 2026

B.4.  Why Not Move to the Back Channel

   Not putting sensitive parameters in the front channel at all is the
   strongest protection, and it is a different protocol.  PAR [RFC9126]
   moves the authorization request to the back channel; the AAuth
   protocol [I-D.hardt-oauth-aauth-protocol] moves the entire
   authorization exchange to authenticated back-channel HTTP.  Those
   approaches carry different deployment costs: new endpoints, client
   authentication, and protocol changes on both sides.  This
   specification exists for the enormous installed base of redirect-
   based OAuth deployments, which can adopt it as a library update with
   no new endpoints, no keys, and no change to how authorization
   parameters are constructed or parsed.

B.5.  Why the Authorization Request Parameters Stay in the URL

   Compatibility, permanently.  The authorization request URI is
   processed by every existing AS with no changes, and the client can
   never know whether the user's browser supports this mechanism, so it
   always sends both (Section 9).  The query member on this leg is not
   for confidentiality (authorization request parameters are not
   secrets) but provides a canonical copy bound to browser-attested
   origin metadata, a tamper check (Section 5.2), and the capability
   signal that unlocks the protected authorization response.

B.6.  Why a Structured Field Dictionary Wrapping a Query String

   The outer Structured Field [RFC9651] layer gives the browser a well-
   defined, extensible place for the members it owns (origin, path)
   without colliding with the OAuth parameter namespace.  The OAuth
   parameters themselves stay query-string encoded inside the query
   member, so every implementation parses them with the same code path
   it uses for URLs today: no new parameter encoding, and no dual-parser
   inconsistency bugs.

B.7.  Why Redirect Responses Only (Why Not form_post)

   This mechanism applies exclusively to redirect responses.  The
   form_post response mode places parameters in the document as form
   fields, where they are visible to page JavaScript and extensions no
   matter what the browser does with headers; there is nothing there for
   the browser to protect.  Redirects are also what the overwhelming
   majority of deployments use, and extending them is a library change
   rather than an infrastructure change.

Hardt & Goto             Expires 5 January 2027                [Page 23]
Internet-Draft           Protected Authorization               July 2026

B.8.  Why the AS Rejects on Query Mismatch, Rather Than the Browser
      Dropping the Header

   If the browser dropped the header when the query member disagreed
   with the URL, an attacker able to modify the URL query could make the
   header vanish, silently downgrading the flow to unprotected URL
   parameters.  Instead the browser always delivers the header, and the
   AS treats a mismatch as an error (Section 5.2).  Tampering becomes a
   visible failure rather than a silent downgrade.

B.9.  Why Not a Sec-Prefixed Name

   The Sec- prefix means only that web content cannot _set_ a header;
   extensions and service workers can still read Sec- request headers
   today.  The protections required here are strictly stronger
   (Section 8) and are defined by normative browser behavior plus
   forbidden-header-name registration in Fetch.  A Sec- prefix would
   understate the guarantee being made, and would break the symmetry of
   the same header field flowing from a redirect response into the
   browser's subsequent HTTP request.

B.10.  Why Not a response_mode Value

   The protected authorization response is functionally a new response
   mode, but it is negotiated by demonstrated browser capability (the
   header's arrival with the authorization request) rather than
   requested by the client.  A response_mode parameter would allow a
   client to request behavior the user's browser may not support, which
   cannot work.  In-band capability signaling is the only reliable
   negotiation.

B.11.  Why the Authorization Response Is Not Readable by JavaScript

   Deliberate.  [RFC9700] and current browser-based-app guidance steer
   authorization codes away from script-accessible surfaces, where they
   are exposed to XSS, injected third-party code, and extensions.
   Delivering the authorization response only to the server at the
   redirect URI enforces that guidance structurally.

B.12.  Why Native Application Flows Are Out of Scope

   The header cannot survive the custom-scheme or app-link handoff from
   the system browser back to a native app: the operating system
   delivers a URL, not headers.  The threat model also differs:
   dedicated system authentication sessions do not run page JavaScript
   or extensions in the same way.  Native flows continue to use their
   existing mechanisms (with PKCE, per [RFC8252]).

Hardt & Goto             Expires 5 January 2027                [Page 24]
Internet-Draft           Protected Authorization               July 2026

B.13.  Why Browser-Attested Origin When iss Exists

   The iss parameter [RFC9207] is asserted by whichever server sends the
   response; in the mix-up scenarios it targets, the client must trust
   the asserter.  The origin member is attested by the browser and
   cannot be set or influenced by any server.  The two compose: iss
   travels unchanged inside the query member, and the client
   additionally gets an unforgeable statement of which origin the
   response actually came from.

Authors' Addresses

   Dick Hardt
   Hellō
   Email: dick.hardt@gmail.com

   Sam Goto
   Google
   Email: goto@google.com

Hardt & Goto             Expires 5 January 2027                [Page 25]