features.resourceIndicators
RFC8707 - Resource Indicators for OAuth 2.0
Specifies whether Resource Indicator capabilities shall be enabled. When enabled, the authorization server shall support the resource parameter at the authorization and token endpoints to enable issuing Access Tokens for specific Resource Servers (APIs) with enhanced audience control and scope management.
The authorization server implements the following resource indicator processing rules:
- Multiple resource parameters may be present during Authorization Code Flow, Device Authorization Grant, and Backchannel Authentication Requests, but only a single audience for an Access Token is permitted.
- Authorization and Authentication Requests that result in an Access Token being issued by the Authorization Endpoint MUST only contain a single resource (or one MUST be resolved using the
defaultResourcehelper). - Client Credentials grant MUST only contain a single resource parameter.
- During Authorization Code / Refresh Token / Device Code / Backchannel Authentication Request exchanges, if the exchanged code/token does not include the
'openid'scope and only has a single resource then the resource parameter may be omitted - an Access Token for the single resource is returned. - During Authorization Code / Refresh Token / Device Code / Backchannel Authentication Request exchanges, if the exchanged code/token does not include the
'openid'scope and has multiple resources then the resource parameter MUST be provided (or one MUST be resolved using thedefaultResourcehelper). An Access Token for the provided/resolved resource is returned. - (with userinfo endpoint enabled and useGrantedResource helper returning falsy) During Authorization Code / Refresh Token / Device Code exchanges, if the exchanged code/token includes the
'openid'scope and no resource parameter is present - an Access Token for the UserInfo Endpoint is returned. - (with userinfo endpoint enabled and useGrantedResource helper returning truthy) During Authorization Code / Refresh Token / Device Code exchanges, even if the exchanged code/token includes the
'openid'scope and only has a single resource then the resource parameter may be omitted - an Access Token for the single resource is returned. - (with userinfo endpoint disabled) During Authorization Code / Refresh Token / Device Code exchanges, if the exchanged code/token includes the
'openid'scope and only has a single resource then the resource parameter may be omitted - an Access Token for the single resource is returned. - Issued Access Tokens shall always only contain scopes that are defined on the respective Resource Server (returned from
features.resourceIndicators.getResourceServerInfo).
default value:
{ defaultResource: [AsyncFunction: defaultResource], // see expanded details below enabled: true, getResourceServerInfo: [AsyncFunction: getResourceServerInfo], // see expanded details below useGrantedResource: [AsyncFunction: useGrantedResource] // see expanded details below}(Click to expand) features.resourceIndicators options details
defaultResource
Section titled “defaultResource”Specifies a helper function that shall be invoked to determine the default resource indicator for a request when none is provided by the client during the authorization request or when multiple resources are provided/resolved and only a single one is required during an Access Token Request. This function enables authorization server policy-based resource selection according to deployment requirements.
oneOf, when present, contains the candidate resource indicators. Leaving that array unresolved causes a request that requires one target to fail with invalid_target.
default value:
async function defaultResource( _ctx: KoaContextWithOIDC, _client: Client, oneOf?: readonly string[] | undefined,): Promise<string | readonly string[] | undefined> { if (oneOf) return oneOf; return undefined;}getResourceServerInfo
Section titled “getResourceServerInfo”Specifies a helper function that shall be invoked to load information about a Resource Server (API) and determine whether the client is authorized to request scopes for that particular resource. This function enables resource-specific scope validation and Access Token configuration according to authorization server policy.
A returned accessTokenTTL must be a positive safe integer number of seconds. Fractional, non-finite, non-positive, and unsafe integer values are rejected.
Reject unauthorized resource indicators with errors.InvalidTarget.
recommendation: Only allow client’s pre-registered resource values. To pre-register these you shall use the extraClientMetadata configuration option to define a custom metadata and use that to implement your policy using this function.
default value:
async function getResourceServerInfo( ctx: KoaContextWithOIDC, resourceIndicator: string, client: Client,): Promise<ResourceServer> { /* implementation required */ }Example: (Click to expand) Resource Server Definition.
{ // REQUIRED // available scope values (space-delimited string) scope: string, // OPTIONAL // "aud" (Audience) value to use // Default is the resource indicator value will be used as token audience audience?: string, // OPTIONAL // Issued Token TTL as a positive safe integer number of seconds // Default is - see `ttl` configuration accessTokenTTL?: number, // Issued Token Format // Default is - opaque accessTokenFormat?: 'opaque' | 'jwt', // JWT Access Token Format (when accessTokenFormat is 'jwt') // Default is `{ sign: { alg: 'RS256' }, encrypt: false }` // Tokens may be signed, signed and then encrypted, or just encrypted JWTs. jwt?: { // Tokens will be signed sign?: | { alg?: string, // 'PS256' | 'PS384' | 'PS512' | 'ES256' | 'ES384' | 'ES512' | 'Ed25519' | 'RS256' | 'RS384' | 'RS512' | 'EdDSA' | 'ML-DSA-44' | 'ML-DSA-65' | 'ML-DSA-87' kid?: string, // OPTIONAL `kid` to aid in signing key selection } | { alg: string, // 'HS256' | 'HS384' | 'HS512' key: CryptoKey | KeyObject | Buffer, // shared symmetric secret to sign the JWT token with kid?: string, // OPTIONAL `kid` JOSE Header Parameter to put in the token's JWS Header }, // Tokens will be encrypted encrypt?: { alg: string, // 'dir' | 'RSA-OAEP' | 'RSA-OAEP-256' | 'RSA-OAEP-384' | 'RSA-OAEP-512' | 'ECDH-ES' | 'ECDH-ES+A128KW' | 'ECDH-ES+A192KW' | 'ECDH-ES+A256KW' | 'A128KW' | 'A192KW' | 'A256KW' | 'A128GCMKW' | 'A192GCMKW' | 'A256GCMKW' enc: string, // 'A128CBC-HS256' | 'A128GCM' | 'A192CBC-HS384' | 'A192GCM' | 'A256CBC-HS512' | 'A256GCM' key: CryptoKey | KeyObject | Buffer, // public key or shared symmetric secret to encrypt the JWT token with kid?: string, // OPTIONAL `kid` JOSE Header Parameter to put in the token's JWE Header } }}Example: (Click to expand) Resource Server (API) with two scopes, an expected audience value, an Access Token TTL and a JWT Access Token Format.
{ scope: 'api:read api:write', audience: 'resource-server-audience-value', accessTokenTTL: 2 * 60 * 60, // 2 hours accessTokenFormat: 'jwt', jwt: { sign: { alg: 'ES256' }, },}Example: (Click to expand) Resource Server (API) with two scopes and a symmetrically encrypted JWT Access Token Format.
{ scope: 'api:read api:write', accessTokenFormat: 'jwt', jwt: { sign: false, encrypt: { alg: 'dir', enc: 'A128CBC-HS256', key: Buffer.from('f40dd9591646bebcb9c32aed02f5e610c2d15e1d38cde0c1fe14a55cf6bfe2d9', 'hex') }, }}useGrantedResource
Section titled “useGrantedResource”Specifies a helper function that shall be invoked to determine whether an already granted resource indicator should be used without being explicitly requested by the client during the Token Endpoint request. This function enables flexible resource selection policies for token issuance operations.
true permits the already granted resource to be selected when the request omits resource; false does not.
recommendation: Use return true when it’s allowed for a client to skip providing the “resource” parameter at the Token Endpoint.
recommendation: Use return false (default) when it’s required for a client to explicitly provide a “resource” parameter at the Token Endpoint or when other indication dictates an Access Token for the UserInfo Endpoint should be returned.
default value:
async function useGrantedResource( _ctx: KoaContextWithOIDC, _source: | AuthorizationCode | RefreshToken | DeviceCode | BackchannelAuthenticationRequest | PreAuthorizedCode,): Promise<boolean> { return false;}