Browse Source

docs: update DEP 4600 (ID-JAG) based on review feedback

Signed-off-by: kanywst <niwatakuma@icloud.com>
pull/4600/head
kanywst 6 days ago
parent
commit
6e578ceba8
  1. 76
      docs/enhancements/id-jag-2026-03-02#4600.md

76
docs/enhancements/id-jag-2026-03-02#4600.md

@ -123,8 +123,10 @@ sequenceDiagram
Clients can request ID-JAG tokens from Dex's `/token` endpoint by specifying
`requested_token_type=urn:ietf:params:oauth:token-type:id-jag` in a
Token Exchange request. ID-JAG support is gated behind a feature flag
(`enableIDJAG`) and disabled by default.
Token Exchange request. ID-JAG support is enabled by adding
`urn:ietf:params:oauth:token-type:id-jag` to `oauth2.tokenExchange.tokenTypes`.
When not listed, requests with this `requested_token_type` are rejected,
ensuring no change in behavior for existing deployments.
The request parameters (extending existing Token Exchange):
@ -152,25 +154,58 @@ The response:
- `issued_token_type`: `urn:ietf:params:oauth:token-type:id-jag`
- `token_type`: `N_A` (this is not an OAuth access token)
- `expires_in`: lifetime in seconds (default: 300, configurable independently of ID token
lifetime via `idJAGTokensValidFor`)
lifetime via `expiry.idJAGTokens`)
- `scope`: OPTIONAL if the issued scope is identical to the requested scope; REQUIRED
otherwise. Per Section 4.3.2 of the specification, policy evaluation at the IdP may
result in different scopes being issued than were requested.
ID-JAG policy configuration:
Complete configuration example:
```yaml
tokenExchange:
enableIDJAG: true # default: false; feature flag for ID-JAG support
idJAGTokensValidFor: "5m" # default: 5m; independent of idTokensValidFor
idJAGPolicies:
- clientID: "wiki-app"
oauth2:
grantTypes:
- authorization_code
- urn:ietf:params:oauth:grant-type:token-exchange
tokenExchange:
# List of token types enabled for exchange. Adding id-jag enables ID-JAG support.
# Omitting it (default) disables ID-JAG without affecting other token exchange flows.
# SAML2 (urn:ietf:params:oauth:token-type:saml2) may be added in a future release.
tokenTypes:
- urn:ietf:params:oauth:token-type:id_token
- urn:ietf:params:oauth:token-type:id-jag
expiry:
idTokens: "24h"
idJAGTokens: "5m" # default: 5m; independent of idTokens
staticClients:
- id: wiki-app
name: "Wiki Application"
secret: "wiki-secret"
redirectURIs:
- "https://wiki.example/callback"
# Per-client ID-JAG policy. Clients without this section cannot obtain ID-JAG tokens
# (default-deny). Only audiences and scopes listed here may be requested.
idJAGPolicies:
allowedAudiences:
- "https://chat.example/"
- "https://calendar.example/"
allowedScopes:
- "chat.read"
- "calendar.read"
- id: supermarket-app
name: "Supermarket Application"
secret: "supermarket-secret"
redirectURIs:
- "https://supermarket.example/callback"
idJAGPolicies:
allowedAudiences:
- "https://grocery.store.1/"
- "https://grocery.store.2/"
allowedScopes:
- "eat.bananas"
- "eat.apples"
```
### Implementation Details/Notes/Constraints
@ -179,14 +214,18 @@ tokenExchange:
per Section 3 of the specification (header `typ: "oauth-id-jag+jwt"`, claims including
`iss`, `sub`, `aud`, `client_id`, `jti`, `exp`, `iat`).
- A new config-based policy evaluator controls which clients can request ID-JAGs for which
audiences, with a default-deny posture when policies are configured.
- Per-client `idJAGPolicies` in `staticClients` control which audiences and scopes a
given client may request in an ID-JAG. Clients without `idJAGPolicies` are denied
by default. Dynamically registered clients are currently unsupported for ID-JAG policies;
support via DB-stored policies or CEL expressions (#4601) is deferred to a future release.
- OIDC discovery is extended with `id_jag_signing_alg_values_supported` per Section 6.
- OIDC discovery is extended with `identity_chaining_requested_token_types_supported` per
Section 6 of the specification. When ID-JAG is enabled, Dex includes
`urn:ietf:params:oauth:token-type:id-jag` in this metadata property.
- ID-JAG support is gated behind the `enableIDJAG` feature flag. When disabled (default),
requests with `requested_token_type=urn:ietf:params:oauth:token-type:id-jag` are
rejected, ensuring no change in behavior for existing deployments.
- ID-JAG support is enabled by listing `urn:ietf:params:oauth:token-type:id-jag` in
`oauth2.tokenExchange.tokenTypes`. When not listed (default), requests are rejected,
ensuring no change in behavior for existing deployments.
### Risks and Mitigations
@ -198,11 +237,14 @@ tokenExchange:
- **Replay attack risk**: Server-side `jti` tracking is deferred, so a stolen ID-JAG
can be replayed within its 5-minute lifetime. Short `expires_in` is the only Dex-side
mitigation; Resource Authorization Servers should implement `jti` caching independently.
- **Public client misuse**: Per Section 7.1 of the specification, ID-JAG SHOULD only be
used by confidential clients. Public clients should use the standard authorization code
flow with interactive user consent at the Resource Authorization Server. Dex will enforce
this by rejecting ID-JAG requests from public clients (clients without a secret).
- **Breaking changes**: None. This is purely additive to the existing
Token Exchange implementation. The `audience` parameter is newly introduced
(not previously used in the implementation despite DEP #2812's original proposal),
and `connector_id` already exists. The feature flag ensures existing deployments
are unaffected.
and `connector_id` already exists.
### Alternatives

Loading…
Cancel
Save