Skip to content

Conversation

@wangsijie
Copy link
Contributor

@wangsijie wangsijie commented Dec 24, 2025

Summary

This PR implements access token exchange for service-to-service delegation using the standard RFC 8693 token type.

Key Changes:

  1. Use standard urn:ietf:params:oauth:token-type:access_token for receiving access tokens in token exchange

    • Supports both opaque and JWT access tokens
    • JWT tokens are verified using the issuer's JWK set
    • Opaque tokens are looked up via oidc-provider's AccessToken.find()
  2. Add new urn:logto:token-type:impersonation_token for explicit impersonation token handling

    • Migrates the old subject token type to this new explicit type
    • Legacy tokens starting with sub_ prefix are still supported for backward compatibility
  3. Token validation order (for access_token type):

    1. If token starts with sub_ prefix → treat as legacy impersonation token (backward compatibility)
    2. Try to find as opaque access token via oidc-provider
    3. Fallback to JWT verification using the issuer's JWK set
  4. Access tokens are not consumption-tracked - the same token can be exchanged multiple times (e.g., by different services)

  5. Feature is guarded by isDevFeaturesEnabled flag

Files Changed:

  • types.ts: Updated token type enum, added ImpersonationToken type
  • account.ts: Refactored validation logic to support opaque/JWT tokens with backward compatibility
  • index.ts: Updated to pass AccessToken class and JWT verification options
  • index.test.ts: Updated tests for new validation flow
  • access-token-exchange.test.ts: Integration tests for access token exchange

Test plan

  • Unit tests for access token exchange (opaque, JWT, and legacy impersonation tokens)
  • Integration tests for token exchange using standard access token type
  • Backward compatibility tests for sub_ prefixed tokens
  • CI should run tests automatically

…delegation

Add support for exchanging JWT access tokens as subject tokens in the token exchange grant.
This enables service-to-service delegation where a service can exchange a user's JWT access
token for a new token with different permissions.

Key changes:
- Add new subject_token_type: urn:ietf:params:oauth:token-type:jwt
- Verify JWT tokens using the issuer's JWK set
- JWT tokens are not consumption-tracked (can be reused multiple times)
- Feature is guarded by isDevFeaturesEnabled flag
@github-actions github-actions bot added the feature Cool stuff label Dec 24, 2025
@github-actions
Copy link

github-actions bot commented Dec 24, 2025

COMPARE TO master

Total Size Diff ⚠️ 📈 +22.37 KB

Diff by File
Name Diff
.changeset/kind-eels-march.md 📈 +907 Bytes
packages/core/src/oidc/grants/token-exchange/account.ts 📈 +4.24 KB
packages/core/src/oidc/grants/token-exchange/index.test.ts 📈 +7.75 KB
packages/core/src/oidc/grants/token-exchange/index.ts 📈 +167 Bytes
packages/core/src/oidc/grants/token-exchange/types.ts 📈 +689 Bytes
packages/integration-tests/src/tests/api/oidc/token-exchange/access-token-exchange.test.ts 📈 +6.32 KB
packages/integration-tests/src/tests/api/oidc/token-exchange/actor-token.test.ts 📈 +5.6 KB
packages/integration-tests/src/tests/api/oidc/token-exchange/index.test.ts 📈 +3.26 KB

@github-actions github-actions bot added size/xl and removed size/xl labels Dec 24, 2025
- Replace positional arguments with a single object parameter
- Pass specific jwtVerificationOptions instead of entire envSet
- Rename 'type' to 'subjectTokenType' for clarity
@github-actions github-actions bot added size/xl and removed size/xl labels Dec 25, 2025
@wangsijie wangsijie marked this pull request as ready for review December 25, 2025 06:47
@github-actions github-actions bot added size/xl and removed size/xl labels Dec 25, 2025
@github-actions github-actions bot added size/xl and removed size/xl labels Dec 25, 2025
- Use `urn:ietf:params:oauth:token-type:access_token` for both opaque and JWT tokens
- Add `urn:logto:token-type:impersonation_token` for explicit impersonation token handling
- Support backward compatibility: tokens starting with `sub_` are treated as impersonation tokens
- Token validation order: legacy impersonation → opaque (via AccessToken.find) → JWT verification
- Rename integration test file to reflect broader access token support
@github-actions github-actions bot added size/xl and removed size/xl labels Dec 30, 2025
@wangsijie wangsijie changed the title feat(core): support JWT access token exchange for service-to-service delegation feat(core): support access token exchange for service-to-service delegation Dec 30, 2025
@github-actions github-actions bot added size/xl and removed size/xl labels Dec 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

3 participants