Skip to content

feat(auth0-server-js): add loginWithCustomTokenExchange and customTokenExchange methods#176

Open
cschetan77 wants to merge 3 commits into
feature/support-act-claimfrom
feat/custom-token-exchange
Open

feat(auth0-server-js): add loginWithCustomTokenExchange and customTokenExchange methods#176
cschetan77 wants to merge 3 commits into
feature/support-act-claimfrom
feat/custom-token-exchange

Conversation

@cschetan77
Copy link
Copy Markdown

@cschetan77 cschetan77 commented May 25, 2026

Description

Adds first-class Custom Token Exchange (CTE) support to ServerClient in auth0-server-js, building on the actor token and act claim foundation added to auth0-auth-js.

  • loginWithCustomTokenExchange(options, storeOptions?): exchanges a custom external token (e.g. a Google ID token, a legacy system token) for Auth0 tokens and persists the result as a user session in the StateStore. Equivalent to completing an interactive login flow, but without a browser redirect. Calls stateStore.set with removeIfExists: true to prevent session fixation. Returns Promise<LoginWithCustomTokenExchangeResult>, surfacing authorizationDetails from the token response for callers using RAR (authorization_details in extra).
  • customTokenExchange(options, storeOptions?): performs the same RFC 8693 token exchange but returns the raw TokenResponse without touching the StateStore. Designed for delegation and impersonation flows where downstream tokens are needed but no session should be created or modified.
  • LoginWithCustomTokenExchangeOptions and CustomTokenExchangeOptions type aliases in types.ts, both derived from ExchangeProfileOptions in auth0-auth-js. This keeps the types consistent across the monorepo and inherits actorToken, actorTokenType, and all other exchange options automatically. Also added LoginWithCustomTokenExchangeResult interface to types.ts

Both methods follow the same domain resolution and AuthClient routing pattern used by loginBackchannel, supporting both static domain and resolver mode configurations.

The return of Promise<LoginWithCustomTokenExchangeResult> containing authorizationDetails is kept in consistent with completeInteractiveLogin and loginBackchannel methods. Though the case for returning it is narrow.

Testing

Unit tests

  • loginWithCustomTokenExchange - should persist session after successful exchange
  • loginWithCustomTokenExchange - should use "default" audience when none provided
  • loginWithCustomTokenExchange - should persist domain on session
  • loginWithCustomTokenExchange - should call stateStore.set with removeIfExists=true (session fixation)
  • loginWithCustomTokenExchange - should throw when exchange fails
  • loginWithCustomTokenExchange - should return authorizationDetails when RAR was used
  • loginWithCustomTokenExchange - should resolve domain via resolver function
  • customTokenExchange - should return token response without persisting session
  • customTokenExchange - should throw when exchange fails

Checklist

  • I have added documentation for new/changed functionality in this PR or in auth0.com/docs
  • All active GitHub checks for tests, formatting, and security are passing
  • The correct base branch is being used, if not the default branch

@cschetan77 cschetan77 force-pushed the feat/custom-token-exchange branch from bd5cc6f to 12cfbca Compare June 2, 2026 08:02
@cschetan77 cschetan77 force-pushed the feature/support-act-claim branch from 77b32f4 to 1ef94d5 Compare June 3, 2026 11:45
@cschetan77 cschetan77 force-pushed the feat/custom-token-exchange branch from ba61a9a to 97b20dc Compare June 3, 2026 11:49
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.

1 participant