Pushed Authorization Requests
Overview
Section titled “Overview”Pushed Authorization Requests (PAR, RFC 9126) allow the client to send authorization parameters to the authorization server via a back-channel POST request, instead of including them in the authorization URL query string. This provides:
- Parameter confidentiality — Authorization parameters are not exposed in the browser address bar or HTTP referer headers
- Request integrity — Parameters cannot be tampered with during the redirect
- Large parameter support — No URL length limitations
- Required by FAPI 2.0 — Mandatory for financial-grade API compliance
The PAR API is available at client.par.
How PAR Works
Section titled “How PAR Works”sequenceDiagram
participant App
participant SDK
participant AS as Auth Server
App->>SDK: Login
SDK->>AS: POST /par (all params)
AS->>SDK: request_uri
SDK-->>AS: Redirect with request_uri only
- The SDK sends all authorization parameters to the PAR endpoint via POST
- The server returns a
request_uri(an opaque reference to the stored parameters) - The authorization URL contains only the
request_uriandclient_id— no sensitive parameters
Checking Availability
Section titled “Checking Availability”// Check if PAR endpoint is availableconst available = await client.par.isAvailable();
// Check if the server requires PARconst required = await client.par.isRequired();Pushing Authorization Parameters
Section titled “Pushing Authorization Parameters”Send authorization parameters to the PAR endpoint:
const parResult = await client.par.push({ redirectUri: 'https://myapp.com/callback', scope: 'openid profile email',});
console.log(parResult.requestUri); // urn:ietf:params:oauth:request_uri:...console.log(parResult.expiresAt); // Epoch secondsPARResult
Section titled “PARResult”| Property | Type | Description |
|---|---|---|
requestUri | string | Opaque reference to the stored authorization request |
expiresAt | number | When the request URI expires (epoch seconds) |
Building the Authorization URL
Section titled “Building the Authorization URL”After pushing, build the authorization URL with just the request_uri:
const url = await client.par.buildAuthorizationUrl(parResult.requestUri);
// Redirect the userwindow.location.href = url;The generated URL contains only client_id and request_uri — all other parameters are stored server-side.
Complete Flow
Section titled “Complete Flow”// 1. Push parametersconst parResult = await client.par.push({ redirectUri: 'https://myapp.com/callback', scope: 'openid profile email',});
// 2. Build URL with request_uriconst url = await client.par.buildAuthorizationUrl(parResult.requestUri);
// 3. Redirectwindow.location.href = url;
// 4. Handle callback (same as standard Authorization Code Flow)const tokens = await client.handleCallback(window.location.href);API Reference
Section titled “API Reference”Push Options
Section titled “Push Options”The push() method accepts the same options as buildAuthorizationUrl():
| Parameter | Type | Default | Description |
|---|---|---|---|
redirectUri | string | Required | Redirect URI |
scope | string | 'openid profile' | Requested scopes |
responseType | 'code' | 'none' | 'code' | Response type |
prompt | string | — | Prompt behavior |
loginHint | string | — | Login hint |
maxAge | number | — | Maximum authentication age in seconds |
acrValues | string | — | Authentication context |
resource | string | string[] | — | Resource indicator |
audience | string | — | Target audience |
extraParams | Record<string, string> | — | Additional parameters |
Error Handling
Section titled “Error Handling”| Error Code | Description | Recovery |
|---|---|---|
par_error | PAR request failed | Check parameters, retry |
par_required | Server requires PAR but it wasn’t used | Use usePar: true or call par.push() |
no_par_endpoint | PAR endpoint not found in discovery | Server doesn’t support PAR |
try { const parResult = await client.par.push({ redirectUri: 'https://myapp.com/callback', });} catch (error) { if (error.code === 'no_par_endpoint') { // Fall back to standard authorization URL const { url } = await client.buildAuthorizationUrl({ redirectUri: 'https://myapp.com/callback', }); window.location.href = url; }}References
Section titled “References”- RFC 9126 — OAuth 2.0 Pushed Authorization Requests
- PAR feature overview — Server-side PAR documentation
Next Steps
Section titled “Next Steps”- JAR & JARM — Signed authorization requests and responses
- DPoP — Bind tokens to cryptographic keys
- Authorization Code Flow — Standard login flow