Skip to content

ADR 0026 - Token Exchange: OP as STS (RFC 8693, v2) #945

Open
0 of 10 issues completed
Open

Description

@gtema

Umbrella for ADR 0026 §12 "Token Exchange (RFC 8693, v2)". Part of #939.

Goal

Use the RFC 8693 urn:ietf:params:oauth:grant-type:token-exchange grant on POST /v4/oauth2/{domain_id}/token to make the OP a token service (STS) for two strategic uses, and keep the already-shipped Keystone-native path as a frozen, migration-only legacy:

Use Subject token Status
Ingress from external IdPs external IdP JWT, run through the mapping engine #1018
On-behalf-of delegation / audience narrowing the user's token as a service received it (OP JWT, and Fernet/JWS during migration) ADR 0036 §6 (Proposed, not built)
Legacy migration bridge Fernet/JWS token carrying an application-credential chain built; frozen, sunset with Fernet (ADR 0026 §13 Stage 5)

Rationale: ADR 0026 §13 Stage 3 moves machine identities from application credentials to OAuth2Clients, Stage 5 sunsets Fernet, and ADR 0036 supersedes trusts. Investing in new features for Fernet/app-cred/Trust/EC2 subjects would harden something scheduled to disappear. Fixes needed by every subject kind, and defects in the shipped path, are still in scope.

Current state (what is built)

  • Dispatch at crates/keystone/src/api/v4/oauth2/token.rs:329, handler handle_token_exchange_grant (token.rs:961): per-client rate limit, client authentication, requires GrantType::TokenExchange in the client's grant_types, validates subject_token via TokenApi::validate_to_context, signs a native JWT, emits a CADF authenticate event.
  • crates/core/src/oauth2_client/token_exchange.rs: derives DelegationContext::AppCred { project_id } from the authentication chain (security.md I1/I2), enforces same-domain (CrossDomainSubjectToken), keystone_ruleset_version = 0 sentinel.
  • Application credentials only. Trust and EC2 subjects are rejected (UnsupportedDelegation); plain password/token chains are rejected (NotDelegated). This is intentionally not extended (see oauth2: Decide scope of token-exchange subject kinds and revocation #1357).
  • Tests: 5 handler unit tests (token.rs ~2054-2357), 4 core unit tests, 3 raft integration tests (tests/integration/src/oauth2_token_exchange.rs, incl. the cross-domain regression guard).

Work items

Fixes to shipped code and groundwork shared by every subject kind:

Strategic uses:

  • External-IdP subject tokens via the mapping engine → Implement token exchange using the mapping engine #1018 (exit criteria and CI demonstration are defined on that issue; see its comment for the surfaces shared with ADR 0036 §6.4)
  • On-behalf-of exchange → ADR 0036 §6 (implementation issues to be opened once that ADR is accepted)

Demonstration in CI (external-IdP exchange):

Scope, docs and records:

Related

Done when

All sub-issues are closed, ADR 0026 §12/§13 and ADR 0036 §6 agree on supported subject kinds and revocation semantics, the external-IdP exchange is demonstrated against Keycloak and GitHub in CI, and the shipped grant is documented as legacy and covered by a live API test.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    • Status
      Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions