RFC 9126 — Pushed Authorization Requests — Versola Docs
VersolaVersola/docs
versola.kzGitHub

RFC 9126 — Pushed Authorization Requests

OAuth 2.0 Pushed Authorization Requests (PAR)

Specification: RFC 9126

Pushed Authorization Requests let a client send the authorization request payload directly to the authorization server over an authenticated back-channel call and receive a request_uri in exchange. Only that reference travels through the user agent, so the request cannot be inspected or tampered with in transit and is not limited by URL length.

Pushed Authorization Request Endpoint

  • POST /par — accepts application/x-www-form-urlencoded authorization request parameters
  • Client authentication — same methods as the token endpoint (client_secret_basic, client_secret_post)
  • request_uri parameter rejected in a pushed request
  • Full authorization request validation before any user interaction
  • 405 Method Not Allowed for anything but POST
  • 413 Content Too Large for bodies over 8 KiB
  • 429 Too Many Requests — per-client rate limiting is not implemented
  • request parameter (JAR Request Objects, RFC 9101) — not implemented

client_id is required in the pushed request body and must identify the authenticated client.

Example

POST /par HTTP/1.1
Host: id.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3

response_type=code&client_id=s6BhdRkqt3
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
&scope=openid%20profile&state=af0ifjsldkj
&code_challenge=K2-ltc83acc4h0c9w6ESC_rEMTJ3bww-uCHaoeK1t8U
&code_challenge_method=S256
HTTP/1.1 201 Created
Content-Type: application/json
Cache-Control: no-store

{
  "request_uri": "urn:ietf:params:oauth:request_uri:6esc_11ACC5bwc014ltc14eY22c",
  "expires_in": 60
}

The request_uri reference carries 256 bits of entropy and is valid for 60 seconds by default (configurable via par.request-uri-ttl). Only a keyed hash of the reference is stored, so pushed requests cannot be replayed from a database dump alone.

Authorization Request

  • request_uri parameter at /authorize — replaces the pushed payload in full
  • Bound to the client that pushed it — a mismatching client_id is rejected
  • Single use — the reference is consumed when the authorization request is processed
  • Expired references are rejected

Parameters sent alongside request_uri at the authorization endpoint are ignored; the pushed payload is authoritative.

Error Response

Errors use the token endpoint format from RFC 6749 §5.2. Because a pushed request is processed before any user interaction, validation failures that would normally be redirected back to the client are returned directly in the response body:

HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store

{
  "error": "invalid_request",
  "error_description": "The request_uri parameter must not be provided to the pushed authorization request endpoint"
}

Authorization Server Metadata

  • pushed_authorization_request_endpoint — advertised in the server metadata document
  • require_pushed_authorization_requests — not implemented; PAR is always optional

Client Metadata

  • require_pushed_authorization_requests — not implemented; PAR cannot be mandated per client

Not Implemented

  • Per-authorization-request redirect URIs (RFC 9126 §2.4) — redirect_uri must still exactly match one registered for the client
  • JAR Request Objects (request parameter, RFC 9101)
  • Rate limiting with 429 Too Many Requests