Skip to content

Adds ID-JAG JWT Bearer grant support (draft-ietf-oauth-identity-assertion-authz-grant-03) - #301

Open
aditya-okta wants to merge 2 commits into
go-oauth2:masterfrom
aditya-okta:feature/id-jag-grant
Open

Adds ID-JAG JWT Bearer grant support (draft-ietf-oauth-identity-assertion-authz-grant-03)#301
aditya-okta wants to merge 2 commits into
go-oauth2:masterfrom
aditya-okta:feature/id-jag-grant

Conversation

@aditya-okta

@aditya-okta aditya-okta commented Jun 29, 2026

Copy link
Copy Markdown

feat: implement Identity Assertion Authorization Grant (ID-JAG) — RFC 7523


Implements the Identity Assertion JWT Authorization Grant per draft-ietf-oauth-identity-assertion-authz-grant-03 (https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant/),
allowing this server to act as a Resource Authorization Server that accepts ID-JAG assertions from trusted external IdPs and issues scoped access tokens.

What's new

Grant registration (const.go)

  • Adds JWTBearer grant type constant (urn:ietf:params:oauth:grant-type:jwt-bearer)

Assertion validation (server/idjag.go)

  • Two-pass JWT validation: unverified parse for header dispatch only (typ, alg, kid), then full signature verification before any claim is trusted
  • Enforces typ: oauth-id-jag+jwt, asymmetric-only alg allowlist (RS256, ES256, PS256), trusted issuer allowlist, aud/client_id/jti/exp/iat checks
  • Clock skew (IDJAGClockSkew, default 60s) applied to exp, nbf, and iat
  • Optional replay protection via pluggable AssertionReplayStore
  • Reference OIDC discovery key resolver (NewOIDCIssuerKeyResolver) — stdlib only, no new dependencies

Grant handler (server/server.go)

  • handleIDJAGGrant: fail-closed config validation, public client guard with boot-time warning, optional IDJAGAuthorizationHandler policy hook for scope/resource narrowing

Replay store (store_replay.go)

  • AssertionReplayStore interface (additive — existing TokenStore implementations unaffected)
  • NewMemoryAssertionReplayStore() in-memory reference implementation

Config (server/config.go, manage/config.go, manage/manager.go)

  • 7 new Config fields: TrustedIDJAGIssuers, IDJAGAudience, IDJAGClockSkew, IDJAGAllowPublicClients, IDJAGIssuerKeyResolver, IDJAGAuthorizationHandler, IDJAGReplayStore
  • DefaultJWTBearerTokenCfg: 2h access token, no refresh token (per spec §4.4.3)
  • SetGrantTypeCfg for operator override

Error mapping (errors/)

  • ErrInsufficientUserAuthentication (insufficient_user_authentication, HTTP 400) per §8.2
  • Correct codes throughout: malformed assertion → ErrInvalidRequest; grant not in AllowedGrantTypes → ErrUnsupportedGrantType

Tests

  • server/idjag_test.go — 14 cases covering type confusion, algorithm confusion, untrusted issuer, audience mismatch, client_id binding, clock skew, missing claims, replay
  • store_replay_test.go — 4 cases covering first store, duplicate rejection, post-expiry reuse, context cancellation

Covers the three fixes: non-200 responses in
NewOIDCIssuerKeyResolver now return errors assertion is stored in tgr.Assertion to avoid
Request nil dereference, and parseECPublicKey rejects off-curve points early.
@aditya-okta

Copy link
Copy Markdown
Author

@LyricTian, can you please take a look at this PR ?

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