Skip to content

feat(customTokenExchange): promote actor_token, organization, requested_token_type to first-class options#834

Merged
cschetan77 merged 3 commits into
masterfrom
feat/cte-enhancements
Jul 1, 2026
Merged

feat(customTokenExchange): promote actor_token, organization, requested_token_type to first-class options#834
cschetan77 merged 3 commits into
masterfrom
feat/cte-enhancements

Conversation

@cschetan77

@cschetan77 cschetan77 commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Changes

lib/context.js

  • Promote actor_token, actor_token_type, requested_token_type, and organization from extra passthrough to named first-class options on req.oidc.customTokenExchange()
  • Add all four to PARAM_DENYLISTactor_token/actor_token_type must be paired and validated together; organization affects tenant context and must be explicit; requested_token_type has a dedicated field to make intent clear
  • Validate that actor_token_type is required when actor_token is provided, throwing HTTP 400 before hitting the network
  • Add validateSubjectToken() — fails fast on common mistakes before hitting the network: blank/whitespace-only values, leading/trailing whitespace, and accidental Bearer prefix
  • Validate that organization is not blank when provided
  • Add extractActClaim() helper that extracts the act claim from delegation exchange responses — checks id_token claims first (via openid-client's claims() helper), falls back to decoding the JWT access token for M2M flows, silently skips opaque tokens
  • Attach act claim to the returned result when actor_token was provided

index.d.ts

  • Add ActClaim interface ({ sub: string; [key: string]: unknown })
  • Add actor_token, actor_token_type, requested_token_type, organization to CustomTokenExchangeOptions
  • Add act?: ActClaim to TokenExchangeResponse
  • Update extra type to accept string[] values

Updated usage

// Delegation / impersonation
const tokenSet = await req.oidc.customTokenExchange({
  actor_token: agentAccessToken,
  actor_token_type: 'urn:acme:agent-token',
  audience: 'https://api.example.com',
});
console.log(tokenSet.act); // { sub: '<agent-sub>' }

// Targeted downstream API with org context
const tokenSet = await req.oidc.customTokenExchange({
  audience: 'https://inventory.example.com',
  scope: 'read:stock',
  organization: 'org_abc123',
  requested_token_type: 'urn:ietf:params:oauth:token-type:jwt',
});

Unit tests updated

  • Migrated organization test from extra to first-class option
  • Replaced old catch-all extra actor test with dedicated first-class tests for actor_token/actor_token_type and requested_token_type
  • Added validation tests: actor_token without actor_token_type → HTTP 400, blank organization → HTTP 400
  • Added subject_token validation tests: whitespace, Bearer prefix
  • Added act claim extraction tests: extracted when actor_token provided, absent when it is not

Test plan

  • npm test — all 320 tests pass, no regressions
  • All 20 customTokenExchange tests pass including 9 new/updated cases

@cschetan77 cschetan77 requested a review from a team as a code owner June 23, 2026 08:20
…ed_token_type to first-class options

- Promote `actor_token`, `actor_token_type`, `requested_token_type`, and
  `organization` from `extra` passthrough to named first-class options on
  `customTokenExchange`, consistent with the CTE implementation in
  `@auth0/auth0-auth-js` and `@auth0/auth0-server-js`
- Add all four to `PARAM_DENYLIST` so they cannot be accidentally double-set
  via `extra` (actor_token/type must be paired and validated together;
  organization affects tenant context and must be explicit)
- Validate that `actor_token_type` is required when `actor_token` is provided,
  throwing HTTP 400 before hitting the network
- Extract and expose the `act` claim on the response for delegation flows:
  checks `id_token` claims first (via openid-client's `claims()` helper),
  falls back to decoding the JWT access token, silently skips opaque tokens
- Add `ActClaim` interface and `act` field to `TokenExchangeResponse` in
  `index.d.ts`; update `extra` type to accept `string[]` values
- Update unit tests: migrate existing actor/organization tests to first-class
  options, add coverage for `requested_token_type`, `actor_token_type`
  validation, and `act` claim extraction
@cschetan77 cschetan77 force-pushed the feat/cte-enhancements branch from 38ac829 to 39d6552 Compare July 1, 2026 07:09
@cschetan77 cschetan77 merged commit f48ca0e into master Jul 1, 2026
16 of 18 checks passed
@cschetan77 cschetan77 deleted the feat/cte-enhancements branch July 1, 2026 11:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants