From e032e321d6e65f987374e6ea7248507bec0d218c Mon Sep 17 00:00:00 2001
From: AJ Ancheta <7781450+ancheetah@users.noreply.github.com>
Date: Thu, 5 Nov 2026 14:18:43 -0500
Subject: [PATCH] feat(oidc-client): add RAR support [SDKS-5435]
---
.changeset/big-kids-smash.md | 7 ++
e2e/oidc-app/src/index.html | 2 +
e2e/oidc-app/src/par/main.ts | 46 +--------
e2e/oidc-app/src/rar-par/index.html | 61 ++++++++++++
e2e/oidc-app/src/rar-par/main.ts | 52 ++++++++++
e2e/oidc-app/src/rar/index.html | 28 ++++++
e2e/oidc-app/src/rar/main.ts | 31 ++++++
e2e/oidc-app/src/utils/journey-login.ts | 53 ++++++++++
e2e/oidc-suites/src/par.spec.ts | 4 +-
packages/oidc-client/README.md | 99 ++++++++++++++++++-
.../src/lib/authorize.request.micros.ts | 3 +
packages/oidc-client/src/lib/client.store.ts | 19 +++-
.../oidc/src/lib/authorize.utils.ts | 20 +++-
packages/sdk-types/src/lib/authorize.types.ts | 31 +++++-
packages/sdk-types/src/lib/config.types.ts | 9 +-
15 files changed, 413 insertions(+), 52 deletions(-)
create mode 100644 .changeset/big-kids-smash.md
create mode 100644 e2e/oidc-app/src/rar-par/index.html
create mode 100644 e2e/oidc-app/src/rar-par/main.ts
create mode 100644 e2e/oidc-app/src/rar/index.html
create mode 100644 e2e/oidc-app/src/rar/main.ts
create mode 100644 e2e/oidc-app/src/utils/journey-login.ts
diff --git a/.changeset/big-kids-smash.md b/.changeset/big-kids-smash.md
new file mode 100644
index 00000000000..7e11344480c
--- /dev/null
+++ b/.changeset/big-kids-smash.md
@@ -0,0 +1,7 @@
+---
+'@forgerock/oidc-client': minor
+'@forgerock/sdk-oidc': minor
+'@forgerock/sdk-types': minor
+---
+
+Added RAR support through `authorizationDetails` parameter in OIDC config. Works with or without PAR.
diff --git a/e2e/oidc-app/src/index.html b/e2e/oidc-app/src/index.html
index dcc720ee3b0..c0fd57ee6a7 100644
--- a/e2e/oidc-app/src/index.html
+++ b/e2e/oidc-app/src/index.html
@@ -13,6 +13,8 @@
OIDC Client E2E Test Index | Ping Identity JavaScript SDK
Ping AM
Ping One
PAR (Pushed Authorization Request)
+ RAR (Rich Authorization Request)
+ RAR with PAR
diff --git a/e2e/oidc-app/src/par/main.ts b/e2e/oidc-app/src/par/main.ts
index 46ec6b3e367..ce5664181a8 100644
--- a/e2e/oidc-app/src/par/main.ts
+++ b/e2e/oidc-app/src/par/main.ts
@@ -6,13 +6,11 @@
* of the MIT license. See the LICENSE file for details.
*
*/
+import { runLoginJourney } from '../utils/journey-login.js';
import { oidcApp } from '../utils/oidc-app.js';
-const AM_BASE = 'https://openam-sdks.forgeblocks.com/am';
-const REALM = 'alpha';
-
const urlParams = new URLSearchParams(window.location.search);
-const wellknown = urlParams.get('wellknown');
+const AM_BASE = 'https://openam-sdks.forgeblocks.com/am';
const config = {
clientId: 'ParClient',
@@ -20,51 +18,15 @@ const config = {
scope: 'openid profile email',
par: true,
serverConfig: {
- wellknown:
- wellknown ||
- 'https://openam-sdks.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration',
+ wellknown: `${AM_BASE}/oauth2/alpha/.well-known/openid-configuration`,
},
};
-// Run journey Login to establish an AM session before background PAR auth
-async function runLoginJourney(username: string, password: string): Promise {
- const authenticateUrl = `${AM_BASE}/json/realms/root/realms/${REALM}/authenticate?authIndexType=service&authIndexValue=Login`;
-
- // Step 1: start the journey
- const initRes = await fetch(authenticateUrl, {
- method: 'POST',
- credentials: 'include',
- headers: { 'Content-Type': 'application/json', 'Accept-API-Version': 'resource=2.1' },
- body: '{}',
- });
- const initJson = await initRes.json();
-
- if (initJson.successUrl) return; // already authenticated
-
- // Fill NameCallback + PasswordCallback
- for (const cb of initJson.callbacks ?? []) {
- if (cb.type === 'NameCallback') cb.input[0].value = username;
- if (cb.type === 'PasswordCallback') cb.input[0].value = password;
- }
-
- // Step 2: submit credentials
- const submitRes = await fetch(authenticateUrl, {
- method: 'POST',
- credentials: 'include',
- headers: { 'Content-Type': 'application/json', 'Accept-API-Version': 'resource=2.1' },
- body: JSON.stringify(initJson),
- });
- const submitJson = await submitRes.json();
-
- if (!submitJson.tokenId && !submitJson.successUrl) {
- throw new Error(submitJson.message || 'Login failed');
- }
-}
-
const journeyForm = document.getElementById('journey-form') as HTMLFormElement;
const journeyStatus = document.getElementById('journey-status') as HTMLParagraphElement;
const backgroundBtn = document.getElementById('login-background') as HTMLButtonElement;
+// Run journey Login to establish an AM session before background PAR auth
journeyForm.addEventListener('submit', async (e) => {
e.preventDefault();
const username = (document.getElementById('username') as HTMLInputElement).value;
diff --git a/e2e/oidc-app/src/rar-par/index.html b/e2e/oidc-app/src/rar-par/index.html
new file mode 100644
index 00000000000..58a2fc055d7
--- /dev/null
+++ b/e2e/oidc-app/src/rar-par/index.html
@@ -0,0 +1,61 @@
+
+
+
+
+
+ E2E Test | Ping Identity JavaScript SDK
+
+
+
+
+
+
Home
+
OIDC App | RAR (Rich Authorization Request) + PAR Login
+
+ Client: rar — RAR enabled. authorization_details are
+ serialized and sent in the authorize url or PAR POST body.
+
+
+
Step 1: Establish AM Session (Journey: Login)
+
+ Background PAR + RAR auth requires an existing AM session. Log in via the Login journey
+ first.
+
+
+
+
+
Step 2: RAR OAuth
+
+
+
+
+
+
+
+
+
Start Over
+
+
+
+
diff --git a/e2e/oidc-app/src/rar-par/main.ts b/e2e/oidc-app/src/rar-par/main.ts
new file mode 100644
index 00000000000..6898093d846
--- /dev/null
+++ b/e2e/oidc-app/src/rar-par/main.ts
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright (c) 2026 Ping Identity Corporation. All right reserved.
+ *
+ * This software may be modified and distributed under the terms
+ * of the MIT license. See the LICENSE file for details.
+ *
+ */
+import { runLoginJourney } from '../utils/journey-login.js';
+import { oidcApp } from '../utils/oidc-app.js';
+
+const urlParams = new URLSearchParams(window.location.search);
+const AM_BASE = 'https://openam-stoyan.forgeblocks.com/am';
+
+const config = {
+ clientId: 'rar',
+ redirectUri: 'http://localhost:8443/rar-par/',
+ scope: 'openid profile email',
+ serverConfig: {
+ wellknown: `${AM_BASE}/oauth2/alpha/.well-known/openid-configuration`,
+ },
+ par: true,
+ authorizationDetails: [
+ {
+ type: 'account_information',
+ actions: ['list_accounts', 'read_balances'],
+ locations: ['https://example.com/accounts'],
+ datatypes: ['balances'],
+ },
+ ],
+};
+
+const journeyForm = document.getElementById('journey-form') as HTMLFormElement;
+const journeyStatus = document.getElementById('journey-status') as HTMLParagraphElement;
+const backgroundBtn = document.getElementById('login-background') as HTMLButtonElement;
+
+// Run journey Login to establish an AM session before background auth
+journeyForm.addEventListener('submit', async (e) => {
+ e.preventDefault();
+ const username = (document.getElementById('username') as HTMLInputElement).value;
+ const password = (document.getElementById('password') as HTMLInputElement).value;
+ journeyStatus.textContent = 'Logging in…';
+ try {
+ await runLoginJourney(username, password, AM_BASE);
+ journeyStatus.textContent = '✓ Session established — background login now available.';
+ backgroundBtn.disabled = false;
+ } catch (err) {
+ journeyStatus.textContent = `✗ ${err instanceof Error ? err.message : 'Login failed'}`;
+ }
+});
+
+oidcApp({ config, urlParams });
diff --git a/e2e/oidc-app/src/rar/index.html b/e2e/oidc-app/src/rar/index.html
new file mode 100644
index 00000000000..2f344b1eeff
--- /dev/null
+++ b/e2e/oidc-app/src/rar/index.html
@@ -0,0 +1,28 @@
+
+
+
+ E2E Test | Ping Identity JavaScript SDK
+
+
+
+
+
+
Home
+
OIDC App | RAR Login
+
+
+
+
+
+
+
+
+
Start Over
+
+
+
+
diff --git a/e2e/oidc-app/src/rar/main.ts b/e2e/oidc-app/src/rar/main.ts
new file mode 100644
index 00000000000..59fc4de962a
--- /dev/null
+++ b/e2e/oidc-app/src/rar/main.ts
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright (c) 2026 Ping Identity Corporation. All right reserved.
+ *
+ * This software may be modified and distributed under the terms
+ * of the MIT license. See the LICENSE file for details.
+ *
+ */
+import { oidcApp } from '../utils/oidc-app.js';
+
+const urlParams = new URLSearchParams(window.location.search);
+
+const config = {
+ clientId: 'rar',
+ redirectUri: 'http://localhost:8443/rar/',
+ scope: 'openid profile email',
+ serverConfig: {
+ wellknown:
+ 'https://openam-stoyan.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration',
+ },
+ authorizationDetails: [
+ {
+ type: 'account_information',
+ actions: ['list_accounts', 'read_balances'],
+ locations: ['https://example.com/accounts'],
+ datatypes: ['balances'],
+ },
+ ],
+};
+
+oidcApp({ config, urlParams });
diff --git a/e2e/oidc-app/src/utils/journey-login.ts b/e2e/oidc-app/src/utils/journey-login.ts
new file mode 100644
index 00000000000..6dc6059e006
--- /dev/null
+++ b/e2e/oidc-app/src/utils/journey-login.ts
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright (c) 2026 Ping Identity Corporation. All right reserved.
+ *
+ * This software may be modified and distributed under the terms
+ * of the MIT license. See the LICENSE file for details.
+ *
+ */
+const urlParams = new URLSearchParams(window.location.search);
+const journeyParam = urlParams.get('journey');
+
+const AM_BASE = 'https://openam-sdks.forgeblocks.com/am';
+const REALM = 'alpha';
+const JOURNEY = journeyParam || 'Login';
+
+// Run journey Login to establish an AM session before background auth
+export async function runLoginJourney(
+ username: string,
+ password: string,
+ amBase?: string,
+): Promise {
+ const authenticateUrl = `${amBase || AM_BASE}/json/realms/root/realms/${REALM}/authenticate?authIndexType=service&authIndexValue=${JOURNEY}`;
+
+ // Step 1: start the journey
+ const initRes = await fetch(authenticateUrl, {
+ method: 'POST',
+ credentials: 'include',
+ headers: { 'Content-Type': 'application/json', 'Accept-API-Version': 'resource=2.1' },
+ body: '{}',
+ });
+ const initJson = await initRes.json();
+
+ if (initJson.successUrl) return; // already authenticated
+
+ // Fill NameCallback + PasswordCallback
+ for (const cb of initJson.callbacks ?? []) {
+ if (cb.type === 'NameCallback') cb.input[0].value = username;
+ if (cb.type === 'PasswordCallback') cb.input[0].value = password;
+ }
+
+ // Step 2: submit credentials
+ const submitRes = await fetch(authenticateUrl, {
+ method: 'POST',
+ credentials: 'include',
+ headers: { 'Content-Type': 'application/json', 'Accept-API-Version': 'resource=2.1' },
+ body: JSON.stringify(initJson),
+ });
+ const submitJson = await submitRes.json();
+
+ if (!submitJson.tokenId && !submitJson.successUrl) {
+ throw new Error(submitJson.message || 'Login failed');
+ }
+}
diff --git a/e2e/oidc-suites/src/par.spec.ts b/e2e/oidc-suites/src/par.spec.ts
index 8d618d449da..a73a6896dee 100644
--- a/e2e/oidc-suites/src/par.spec.ts
+++ b/e2e/oidc-suites/src/par.spec.ts
@@ -11,7 +11,9 @@ import { expect, test } from '@playwright/test';
import { asyncEvents } from './utils/async-events.js';
import { pingAmPassword, pingAmUsername } from './utils/demo-users.js';
-async function loginJourney(page, username: string, password: string) {
+import type { Page } from '@playwright/test';
+
+async function loginJourney(page: Page, username: string, password: string) {
await page.getByLabel('User Name').fill(username);
await page.getByLabel('Password').fill(password);
await page.getByRole('button', { name: 'Login (Journey)' }).click();
diff --git a/packages/oidc-client/README.md b/packages/oidc-client/README.md
index 4119d84729e..cc276ef20f8 100644
--- a/packages/oidc-client/README.md
+++ b/packages/oidc-client/README.md
@@ -18,6 +18,8 @@ The oidc module follows the [OIDC](https://openid.net/specs/openid-connect-core-
- [Redirect-Based Login](#redirect-based-login-authorizeurl)
- [Background Authorization](#background-authorization-authorizebackground)
- [Automatic Token Renewal](#automatic-token-renewal)
+ - [Pushed Authorization Requests (PAR)](#pushed-authorization-requests-par)
+ - [Rich Authorization Requests (RAR)](#rich-authorization-requests-rar)
- [Error Handling](#error-handling)
## Installation
@@ -57,7 +59,10 @@ The `oidc()` initialization function accepts the following configuration:
- **scope** (required) - Space-separated list of requested scopes (e.g., `'openid profile email'`)
- **storage** (optional) - Storage configuration for tokens (defaults to localStorage)
- **timeout** (optional) - Request timeout in milliseconds
-- **additionalParameters** (optional) - Additional parameters to include in authorization requests
+- **par** (optional) - Use Pushed Authorization Requests (PAR) for the authorization flow; omitted auto-detects from the server's well-known configuration (see [Pushed Authorization Requests (PAR)](#pushed-authorization-requests-par))
+- **authorizationDetails** (optional) - Use Rich Authorization Requests (RAR) for the authorization flow. See [Rich Authorization Requests (RAR)](#rich-authorization-requests-rar).
+
+See `OidcConfig` interface for the full list of options.
## Quick Start
@@ -330,6 +335,98 @@ if ('error' in tokens) {
}
```
+### Pushed Authorization Requests (PAR)
+
+The client supports [Pushed Authorization Requests](https://datatracker.ietf.org/doc/html/rfc9126) (PAR, RFC 9126), an OAuth 2.0 extension that hardens the authorization flow.
+
+In a standard flow, all authorization parameters (`redirect_uri`, `scope`, PKCE `code_challenge`, `state`, and so on) are packed into the authorize URL and pass through the browser. With PAR, the client first POSTs those parameters directly to the server's PAR endpoint, receives a short-lived `request_uri`, and then sends the browser to the authorization endpoint with only `client_id` and `request_uri` in the URL:
+
+**Enabling PAR**
+
+PAR is enabled with the `par` configuration option:
+
+```js
+const config = {
+ serverConfig: { wellknown: 'https://example.com/.well-known/openid-configuration' },
+ clientId: 'example-client-id',
+ redirectUri: 'https://example-app/redirect-uri',
+ scope: 'openid profile email',
+ par: true,
+};
+```
+
+How it resolves:
+
+- `par: true` — always use PAR
+- `par: false` — never use PAR; OIDC Client initialization fails if the server's well-known configuration advertises `require_pushed_authorization_requests: true`
+- `par` omitted — PAR is used automatically when the server requires it, otherwise the standard flow is used
+
+Both `authorize.url()` and `authorize.background()` respect this setting. The `request_uri` is single-use and short-lived (typically 30–90 seconds), so the authorize navigation must complete before it expires.
+
+### Rich Authorization Requests (RAR)
+
+The client supports [Rich Authorization Requests](https://datatracker.ietf.org/doc/html/rfc9396) (RAR, RFC 9396), an OAuth 2.0 extension that lets the client request fine-grained, transaction-specific authorization instead of just scopes. Details are sent as the `authorization_details` request parameter — a JSON array describing _what_ the client wants to do rather than a coarse scope string.
+
+Each detail object has a `type` string defined by the authorization server, plus the standard fields `locations`, `actions`, `datatypes`, and `privileges`. Type-specific fields the SDK doesn't model go in `additionalFields`, whose entries are flattened onto the object before the request is sent.
+
+**Declaring authorization details**
+
+Details can be set at initialization, so they apply to every authorization request the client makes:
+
+```js
+const config = {
+ serverConfig: { wellknown: 'https://example.com/.well-known/openid-configuration' },
+ clientId: 'example-client-id',
+ redirectUri: 'https://example-app/redirect-uri',
+ scope: 'openid profile email',
+ authorizationDetails: [
+ {
+ type: 'payment_initiation',
+ actions: ['initiate', 'status'],
+ locations: ['https://example.com/payments'],
+ instructedAmount: { currency: 'EUR', amount: '123.50' },
+ creditorName: 'Merchant A',
+ },
+ ],
+};
+```
+
+Type-specific fields like `instructedAmount` and `creditorName` can be passed through `additionalFields`:
+
+```js
+const config = {
+ // ...other options
+ authorizationDetails: [
+ {
+ type: 'payment_initiation',
+ actions: ['initiate', 'status'],
+ locations: ['https://example.com/payments'],
+ additionalFields: {
+ instructedAmount: { currency: 'EUR', amount: '123.50' },
+ creditorName: 'Merchant A',
+ },
+ },
+ ],
+};
+```
+
+Authorization details can alternatively be supplied per call, which overrides the OIDC Client configuration for that request:
+
+```js
+const authResponse = await oidcClient.authorize.background({
+ authorizationDetails: [
+ {
+ type: 'account_information',
+ actions: ['list', 'read'],
+ locations: ['https://example.com/accounts'],
+ datatypes: ['balances', 'transactions'],
+ },
+ ],
+});
+```
+
+Details are serialized to JSON for the `authorization_details` parameter and are included in both the standard flow and the pushed (PAR) request body. Server support for RAR is required; consult your authorization server's documentation for the detail `type` values and fields it accepts.
+
### Error Handling
The library uses a consistent error handling pattern. All methods return either a success response or an error object. Check if the response contains an `error` property:
diff --git a/packages/oidc-client/src/lib/authorize.request.micros.ts b/packages/oidc-client/src/lib/authorize.request.micros.ts
index 53098144839..0bdc6caa26a 100644
--- a/packages/oidc-client/src/lib/authorize.request.micros.ts
+++ b/packages/oidc-client/src/lib/authorize.request.micros.ts
@@ -100,6 +100,9 @@ export const buildParBodyµ = (
redirectUri: config.redirectUri,
scope: config.scope || 'openid',
responseType: config.responseType || 'code',
+ ...(config.authorizationDetails !== undefined && {
+ authorizationDetails: config.authorizationDetails,
+ }),
...parBodyOptions,
challenge,
state,
diff --git a/packages/oidc-client/src/lib/client.store.ts b/packages/oidc-client/src/lib/client.store.ts
index e971a35ea7d..af9fb9d84ca 100644
--- a/packages/oidc-client/src/lib/client.store.ts
+++ b/packages/oidc-client/src/lib/client.store.ts
@@ -175,6 +175,9 @@ export async function oidc({
redirectUri: config.redirectUri,
scope: config.scope || 'openid',
responseType: config.responseType || 'code',
+ ...(config.authorizationDetails !== undefined && {
+ authorizationDetails: config.authorizationDetails,
+ }),
...(config.loginHint !== undefined && { loginHint: config.loginHint }),
...(config.nonce !== undefined && { nonce: config.nonce }),
...(config.display !== undefined && { display: config.display }),
@@ -213,7 +216,13 @@ export async function oidc({
config,
log,
store,
- { ...(options ?? ({} as GetAuthorizationUrlOptions)), prompt: 'none' as const },
+ {
+ ...(config.authorizationDetails !== undefined && {
+ authorizationDetails: config.authorizationDetails,
+ }),
+ ...(options ?? ({} as GetAuthorizationUrlOptions)),
+ prompt: 'none' as const,
+ },
useParFlow,
),
);
@@ -335,7 +344,13 @@ export async function oidc({
config,
log,
store,
- { ...(authorizeOptions ?? ({} as GetAuthorizationUrlOptions)), prompt: 'none' as const },
+ {
+ ...(config.authorizationDetails !== undefined && {
+ authorizationDetails: config.authorizationDetails,
+ }),
+ ...(authorizeOptions ?? ({} as GetAuthorizationUrlOptions)),
+ prompt: 'none' as const,
+ },
useParFlow,
).pipe(
Micro.flatMap((response): Micro.Micro => {
diff --git a/packages/sdk-effects/oidc/src/lib/authorize.utils.ts b/packages/sdk-effects/oidc/src/lib/authorize.utils.ts
index 204749334d0..604644eb152 100644
--- a/packages/sdk-effects/oidc/src/lib/authorize.utils.ts
+++ b/packages/sdk-effects/oidc/src/lib/authorize.utils.ts
@@ -4,8 +4,21 @@
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
+import type { AuthorizationDetail, GetAuthorizationUrlOptions } from '@forgerock/sdk-types';
-import type { GetAuthorizationUrlOptions } from '@forgerock/sdk-types';
+/**
+ * Serializes RAR {@link AuthorizationDetail} objects to a JSON string for the
+ * `authorization_details` request parameter. Each detail's `additionalFields`
+ * is flattened onto the detail; entries in `additionalFields` that shadow a
+ * modeled property are overridden by the modeled entry.
+ */
+export function serializeRarAuthDetails(authDetails: AuthorizationDetail[]): string {
+ const flattenedDetails = authDetails.map((detail) => {
+ const { additionalFields, ...knownAuthDetails } = detail;
+ return { ...additionalFields, ...knownAuthDetails };
+ });
+ return JSON.stringify(flattenedDetails);
+}
/**
* Builds URLSearchParams for an OAuth2/OIDC authorization request.
@@ -35,5 +48,10 @@ export function buildAuthorizeParams(
if (options.uiLocales) params.set('ui_locales', options.uiLocales);
if (options.acrValues) params.set('acr_values', options.acrValues);
+ if (options.authorizationDetails?.length) {
+ const serializedAuthDetails = serializeRarAuthDetails(options.authorizationDetails);
+ params.set('authorization_details', serializedAuthDetails);
+ }
+
return params;
}
diff --git a/packages/sdk-types/src/lib/authorize.types.ts b/packages/sdk-types/src/lib/authorize.types.ts
index 014273d67f5..0a183459314 100644
--- a/packages/sdk-types/src/lib/authorize.types.ts
+++ b/packages/sdk-types/src/lib/authorize.types.ts
@@ -19,21 +19,23 @@ export type AuthPromptValue = (typeof AUTH_PROMPT_VALUES)[number];
/**
* Options for the authorization URL
+ *
+ * These four properties clientid, scope, responseType and redirectUri are required
+ * when using this type, which are not required when defining Config.
+ *
* @param clientId The client ID of the application
* @param redirectUri The redirect URI of the application
* @param responseType The response type of the authorization request
* @param scope The scope of the authorization request
*/
export interface GetAuthorizationUrlOptions extends LegacyConfigOptions {
- /**
- * These four properties clientid, scope, responseType and redirectUri are required
- * when using this type, which are not required when defining Config.
- */
clientId: string;
scope: string;
redirectUri: string;
responseType: ResponseType;
responseMode?: 'fragment' | 'form_post' | 'pi.flow' | 'query';
+ /** Authorization details for Rich Authorization Requests (RAR) */
+ authorizationDetails?: AuthorizationDetail[];
login?: 'redirect' | 'embedded';
state?: string;
verifier?: string;
@@ -56,3 +58,24 @@ export interface GenerateAndStoreAuthUrlValues extends GetAuthorizationUrlOption
clientId: string;
prefix?: string;
}
+
+/**
+ * A single object for the `authorization_details` request parameter as
+ * defined by RFC 9396 (Rich Authorization Requests). Type-specific fields
+ * not modeled below can be added to the catch-all `additionalFields` parameter,
+ * whose entries are flattened onto the object before sending the request.
+ */
+export interface AuthorizationDetail {
+ /** The type of authorization details as defined by the authorization server */
+ type: string;
+ /** Locations this authorization applies to */
+ locations?: string[];
+ /** Actions this authorization applies to */
+ actions?: string[];
+ /** Data types this authorization applies to */
+ datatypes?: string[];
+ /** Privileges this authorization applies to */
+ privileges?: string[];
+ /** Catch-all for type-specific fields not modeled above (e.g. `instructedAmount` for `payment_initiation`) */
+ additionalFields?: Record;
+}
diff --git a/packages/sdk-types/src/lib/config.types.ts b/packages/sdk-types/src/lib/config.types.ts
index ce2d9e84695..eb63a888bf2 100644
--- a/packages/sdk-types/src/lib/config.types.ts
+++ b/packages/sdk-types/src/lib/config.types.ts
@@ -4,7 +4,12 @@
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
-import type { AuthDisplayValue, AuthPromptValue, ResponseType } from './authorize.types.js';
+import type {
+ AuthDisplayValue,
+ AuthorizationDetail,
+ AuthPromptValue,
+ ResponseType,
+} from './authorize.types.js';
import type { AsyncLegacyConfigOptions } from './legacy-config.types.js';
import type { CustomStorageObject } from './tokens.types.js';
@@ -27,6 +32,8 @@ export interface OidcConfig extends AsyncLegacyConfigOptions {
responseType?: ResponseType;
/** Use Pushed Authorization Requests (PAR) for the authorization flow. */
par?: boolean;
+ /** Authorization details for Rich Authorization Requests (RAR) */
+ authorizationDetails?: AuthorizationDetail[];
/** URI to redirect to after logout; maps to `post_logout_redirect_uri` in the end-session request. */
signOutRedirectUri?: string;
loginHint?: string;