Advanced

PAR and JAR — protecting the authorization request

Push authorization requests to the server (RFC 9126) and sign them as JWTs (RFC 9101) for integrity, confidentiality, and early validation.

In a classic OAuth flow, all authorization request parameters travel in the browser’s URL. The user, browser extensions, and malware can read or change them, URLs have length limits, and the authorization server cannot authenticate the client until much later. PAR and JAR address these problems.

Pushed Authorization Requests (PAR, RFC 9126)

The client sends the authorization parameters directly to the server over a back channel, authenticating as it would at the token endpoint. The server returns a short-lived reference.

POST /par HTTP/1.1
Host: login.example.test
Content-Type: application/x-www-form-urlencoded

client_id=budget-app&response_type=code
&redirect_uri=https%3A%2F%2Fbudget.example.test%2Fcb
&scope=openid%20payments.initiate&state=af0ifjsldkj
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJFUzI1NiJ9…
{ "request_uri": "urn:ietf:params:oauth:request_uri:6esc_11ACC5bwc014ltc14eY22c", "expires_in": 60 }

The browser is then redirected with only two parameters:

https://login.example.test/authorize?client_id=budget-app
  &request_uri=urn%3Aietf%3Aparams%3Aoauth%3Arequest_uri%3A6esc_11ACC5bwc014ltc14eY22c

Benefits

  • Integrity and confidentiality: parameters never pass through the browser.
  • Client authentication up front: the server knows the request comes from the genuine client before showing any UI.
  • Early validation: errors such as an invalid redirect URI or scope are returned to the client directly, not shown to the user.
  • No size limit: large requests, such as rich authorization requests, fit comfortably.

Servers advertise pushed_authorization_request_endpoint and can set require_pushed_authorization_requests: true; clients can be registered with the same flag.

JWT-Secured Authorization Requests (JAR, RFC 9101)

JAR packages the authorization parameters in a signed (and optionally encrypted) JWT called a request object:

{
  "iss": "budget-app",
  "aud": "https://login.example.test",
  "response_type": "code",
  "client_id": "budget-app",
  "redirect_uri": "https://budget.example.test/cb",
  "scope": "openid payments.initiate",
  "state": "af0ifjsldkj",
  "nonce": "n-0S6_WzA2Mj",
  "exp": 1792000300
}

The request object can be passed by value (request=<JWT>) or by reference (request_uri). Its header uses typ: oauth-authz-req+jwt. The signature gives non-repudiation: the server can prove which client asked for what.

PAR, JAR, or both?

NeedUse
Keep parameters out of the browser, authenticate the client earlyPAR
Non-repudiable, signed requestJAR
Highest assurance, for example open bankingPAR with a signed request object, as some profiles require

FAPI 2.0 requires PAR for authorization requests; it makes signed request objects optional and specified in its message-signing profile.

Implementation notes

  • request_uri values must be single-use or short-lived and bound to the client that pushed them.
  • Clients still need PKCE and state; PAR protects the request, not the response.
  • Authorization servers must ignore parameters in the front-channel URL that conflict with the pushed request.

References

Knowledge is better when it is shared.Improve this page

Type to search the entire handbook.