Skip to content

feat: add actor token support for Custom Token Exchange impersonation & delegation#1595

Merged
subhankarmaiti merged 10 commits into
masterfrom
feat/custom-token-exchange-actor-token
Jul 27, 2026
Merged

feat: add actor token support for Custom Token Exchange impersonation & delegation#1595
subhankarmaiti merged 10 commits into
masterfrom
feat/custom-token-exchange-actor-token

Conversation

@subhankarmaiti

@subhankarmaiti subhankarmaiti commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

This PR adds support for delegation and impersonation in Custom Token Exchange flows, following RFC 8693 OAuth 2.0 Token Exchange.

You can now pass an actorToken (and its actorTokenType) to customTokenExchange to indicate the acting party in a delegation or impersonation scenario. When present, the issued tokens carry the act claim, which is now exposed on the user profile.

Supported on web, iOS, and Android.

  const credentials = await auth0.customTokenExchange({
    subjectToken: 'external-subject-token',                                                       
    subjectTokenType: 'urn:acme:legacy-token',
    actorToken: 'acting-party-token',                                                             
    actorTokenType: 'urn:ietf:params:oauth:token-type:id_token',                                
  });                                    

  // The acting-party claim is available on the decoded user profile:
  const user = auth0.auth.userInfo... // or via parseIdToken / useAuth0().user                    
  console.log(user.act); // { sub: '...', act: { ... } } for delegation chains    

Summary by CodeRabbit

  • New Features
    • Added delegation/impersonation support to RFC 8693 custom token exchange using optional actorToken/actorTokenType across web, iOS, and Android.
    • Exposed acting party details via the returned user’s act claim (including nested delegation).
    • Updated the sample apps to collect and use actor token inputs.
  • Bug Fixes
    • Added stricter early validation for token type and actor-token parameter pairing.
    • Improved native error handling to preserve specific Auth0 error codes.
  • Documentation
    • Documented “Delegation & Impersonation (Actor Token)” behavior and constraints.
  • Tests
    • Added/expanded tests for act preservation and actor-token validation/forwarding.

@subhankarmaiti
subhankarmaiti requested a review from a team as a code owner July 15, 2026 07:20
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Custom token exchange now supports paired actor-token parameters across web, JavaScript, Android, and iOS paths. Validation prevents incomplete pairs, native requests construct actor tokens, user profiles expose act, and documentation and tests cover the new behavior.

Changes

Actor token custom exchange

Layer / File(s) Summary
Contracts and paired-parameter validation
src/types/parameters.ts, src/types/common.ts, src/specs/NativeA0Auth0.ts, src/platforms/native/bridge/INativeBridge.ts, src/core/utils/..., src/core/models/__tests__/Auth0User.spec.ts
Public contracts include actor-token fields and the optional act claim; shared validation rejects incomplete pairs and validates token-type URIs, with corresponding tests.
Web exchange wiring
src/platforms/web/adapters/...
The web adapter validates actor parameters, conditionally sends actor_token and actor_token_type, and handles responses without refresh tokens.
Native bridge and platform wiring
src/platforms/native/..., android/..., ios/...
Actor-token values are validated and forwarded through native bridges, converted into Android and iOS actor-token objects, and covered by bridge tests that preserve native error codes.
Example flow and documentation
example/src/..., EXAMPLES.md
The example apps expose subject-only and actor-token exchanges, while documentation describes setup, claims, and exchange constraints.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant Auth0Client
  participant WebOrNativeBridge
  participant Auth0
  App->>Auth0Client: customTokenExchange(actorToken, actorTokenType)
  Auth0Client->>Auth0Client: validate paired parameters
  Auth0Client->>WebOrNativeBridge: forward actor-token parameters
  WebOrNativeBridge->>Auth0: exchange subject and actor tokens
Loading

Suggested reviewers: pmathew92

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: actor token support for Custom Token Exchange delegation and impersonation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/custom-token-exchange-actor-token

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread ios/NativeBridge.swift Outdated
Comment thread ios/NativeBridge.swift Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/core/utils/__tests__/validation.spec.ts (1)

24-33: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use Jest's built-in error matching.

The manual try/catch/throw pattern can be simplified into a single concise assertion using Jest's .toThrow() combined with expect.objectContaining().

♻️ Proposed fix
-  it('should throw with the invalid_actor_token_parameters code', () => {
-    try {
-      validateActorTokenParameters(undefined, 'urn:token-type');
-      throw new Error('Expected validateActorTokenParameters to throw');
-    } catch (e) {
-      expect(e).toBeInstanceOf(AuthError);
-      expect((e as AuthError).code).toBe('invalid_actor_token_parameters');
-    }
-  });
+  it('should throw with the invalid_actor_token_parameters code', () => {
+    expect(() => validateActorTokenParameters(undefined, 'urn:token-type')).toThrow(
+      expect.objectContaining({ code: 'invalid_actor_token_parameters' })
+    );
+  });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/utils/__tests__/validation.spec.ts` around lines 24 - 33, Replace
the manual try/catch and fallback throw in the validation test with Jest’s
built-in error assertion around validateActorTokenParameters, using toThrow with
expect.objectContaining to verify the AuthError instance and
invalid_actor_token_parameters code.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/platforms/native/adapters/__tests__/NativeAuth0Client.spec.ts`:
- Around line 281-283: Remove the any casts from both customTokenExchange
assertions in src/platforms/native/adapters/__tests__/NativeAuth0Client.spec.ts
at lines 281-283 and 306-308, using the typed mock function directly or
jest.mocked(mockBridgeInstance.customTokenExchange). In
src/platforms/native/bridge/__tests__/NativeBridgeManager.spec.ts at lines
442-444, replace the any cast with an unknown-to-specific-type cast such as
Credentials, using the correct return type for the test.

In `@src/platforms/web/adapters/WebAuth0Client.ts`:
- Around line 265-266: Update the conditional property spreads in the
WebAuth0Client request payload to check actorToken and actorTokenType against
undefined rather than truthiness, ensuring empty-string values are included
consistently with validateActorTokenParameters and the paired fields are sent
together.

In `@src/types/common.ts`:
- Line 156: Update the act property in the relevant type definition to use
Record<string, unknown> instead of Record<string, any>, preserving its optional
nested actor-claim structure.

---

Nitpick comments:
In `@src/core/utils/__tests__/validation.spec.ts`:
- Around line 24-33: Replace the manual try/catch and fallback throw in the
validation test with Jest’s built-in error assertion around
validateActorTokenParameters, using toThrow with expect.objectContaining to
verify the AuthError instance and invalid_actor_token_parameters code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5e711f4b-b1ab-4117-804c-e1a9302fbd32

📥 Commits

Reviewing files that changed from the base of the PR and between 60d8ec7 and cc85b4e.

📒 Files selected for processing (16)
  • EXAMPLES.md
  • android/src/main/java/com/auth0/react/A0Auth0Module.kt
  • ios/NativeBridge.swift
  • src/core/models/__tests__/Auth0User.spec.ts
  • src/core/utils/__tests__/validation.spec.ts
  • src/core/utils/validation.ts
  • src/platforms/native/adapters/NativeAuth0Client.ts
  • src/platforms/native/adapters/__tests__/NativeAuth0Client.spec.ts
  • src/platforms/native/bridge/INativeBridge.ts
  • src/platforms/native/bridge/NativeBridgeManager.ts
  • src/platforms/native/bridge/__tests__/NativeBridgeManager.spec.ts
  • src/platforms/web/adapters/WebAuth0Client.ts
  • src/platforms/web/adapters/__tests__/WebAuth0Client.spec.ts
  • src/specs/NativeA0Auth0.ts
  • src/types/common.ts
  • src/types/parameters.ts

Comment thread src/platforms/native/adapters/__tests__/NativeAuth0Client.spec.ts Outdated
Comment thread src/platforms/web/adapters/WebAuth0Client.ts Outdated
Comment thread src/types/common.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@example/src/screens/class-based/ClassApiTests.tsx`:
- Around line 238-253: Update the custom token exchange button’s disabled
condition in the actor-enabled test to also require actorTokenType, alongside
subjectToken, subjectTokenType, and actorToken. Keep the existing runTest and
customTokenExchange behavior unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4a615615-4f7a-496a-bdba-9e1eae0ec5cb

📥 Commits

Reviewing files that changed from the base of the PR and between cc85b4e and 447a97e.

📒 Files selected for processing (9)
  • example/src/navigation/ClassDemoNavigator.tsx
  • example/src/screens/class-based/ClassApiTests.tsx
  • example/src/screens/class-based/ClassProfile.tsx
  • ios/A0Auth0.mm
  • ios/NativeBridge.swift
  • src/platforms/native/adapters/__tests__/NativeAuth0Client.spec.ts
  • src/platforms/native/bridge/__tests__/NativeBridgeManager.spec.ts
  • src/platforms/web/adapters/WebAuth0Client.ts
  • src/types/common.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/platforms/web/adapters/WebAuth0Client.ts
  • src/types/common.ts
  • src/platforms/native/adapters/tests/NativeAuth0Client.spec.ts
  • src/platforms/native/bridge/tests/NativeBridgeManager.spec.ts

Comment thread example/src/screens/class-based/ClassApiTests.tsx
NandanPrabhu
NandanPrabhu previously approved these changes Jul 16, 2026
Comment thread src/platforms/native/bridge/NativeBridgeManager.ts
Comment thread src/core/utils/validation.ts Outdated
Comment thread src/core/utils/validation.ts
Comment thread src/platforms/web/adapters/__tests__/WebAuth0Client.spec.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/utils/validation.ts`:
- Around line 82-85: Normalize actor values to undefined when they are empty or
whitespace-only before the exchange boundary, rather than forwarding the
original truthy strings. Update validateActorTokenParameters and the
WebAuth0Client.customTokenExchange/native forwarding paths to reuse the
normalized values, and add an adapter-level regression test covering
whitespace-only inputs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5231cf93-a909-486c-8537-51867f1c92d7

📥 Commits

Reviewing files that changed from the base of the PR and between da4a95b and 094e18c.

📒 Files selected for processing (7)
  • src/core/utils/__tests__/validation.spec.ts
  • src/core/utils/validation.ts
  • src/platforms/native/adapters/NativeAuth0Client.ts
  • src/platforms/native/bridge/NativeBridgeManager.ts
  • src/platforms/native/bridge/__tests__/NativeBridgeManager.spec.ts
  • src/platforms/web/adapters/WebAuth0Client.ts
  • src/platforms/web/adapters/__tests__/WebAuth0Client.spec.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/platforms/native/adapters/NativeAuth0Client.ts
  • src/platforms/web/adapters/tests/WebAuth0Client.spec.ts
  • src/platforms/web/adapters/WebAuth0Client.ts
  • src/platforms/native/bridge/NativeBridgeManager.ts
  • src/platforms/native/bridge/tests/NativeBridgeManager.spec.ts
  • src/core/utils/tests/validation.spec.ts

Comment thread src/core/utils/validation.ts
Comment thread EXAMPLES.md Outdated
console.log(user.act); // The acting party claim
```

> ⚠️ **Refresh token suppression**: When an actor token is present, Auth0 will **not** issue a refresh token, regardless of whether `offline_access` is in the requested scope. `credentials.refreshToken` will be `undefined` in this case.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since there's no refresh token in this flow, it's worth adding what that means downstream: a later refresh-token grant can't re-issue the tokens, so the act claim can't be re-emitted either and the acting party is effectively fixed at exchange time. That consequence is the part developers tend to get surprised by, more than the missing token itself.

Comment thread EXAMPLES.md
Comment thread EXAMPLES.md Outdated
Comment thread EXAMPLES.md Outdated

@kishore7snehil kishore7snehil left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@subhankarmaiti
subhankarmaiti merged commit 639e629 into master Jul 27, 2026
5 checks passed
@subhankarmaiti
subhankarmaiti deleted the feat/custom-token-exchange-actor-token branch July 27, 2026 12:36
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.

3 participants