Skip to content

2.4.0-rc.4

Pre-release
Pre-release

Choose a tag to compare

@lakhansamani lakhansamani released this 21 Jul 15:15
3b35919

Highlights

OAuth 2.1 authorization-server hardening for MCP (#693, closes #516) — Authorizer's /oauth/token and /authorize now support what the current MCP authorization spec actually asks of an AS, scoped against the real spec text rather than an older draft.

  • Refresh-token reuse detection (OAuth 2.1 §6.1 / RFC 9700 §4.14.2), scoped to the specific compromised token's rotation lineage (family_id) rather than the whole user — replaying one retired token can no longer force-log-out a user's other sessions. Includes a short grace window so a benign multi-tab/retry double-refresh doesn't self-revoke, and a guard against a transient session-store lookup blip being mistaken for a breach.
  • RFC 8707 resource indicators on the primary authorization_code flow (/authorize + /oauth/token), binding the issued access token's aud to the target resource server — previously only available on the token-exchange/delegation path.
  • GET /.well-known/oauth-authorization-server (RFC 8414) metadata alias.
  • New opt-in --oauth2-1-strict flag (default off, zero behavior change unless enabled): rejects the implicit grant and all front-channel-token response_type hybrids, and requires PKCE S256 over plain.
  • RFC 7591 Dynamic Client Registration and RFC 9728 Protected Resource Metadata deliberately not added — the current MCP spec downgrades DCR to optional, and RFC 9728 is the MCP resource server's responsibility, not the authorization server's (see examples/with-mcp).

SCIM group provisioning → OpenFGA roles → SAML group assertions (#694, closes #692 and the pending piece of #512) — bridges SCIM directory sync, fine-grained authorization, and SAML SSO, previously three disconnected features.

  • SCIM Groups (/scim/v2/Groups, full CRUD + PATCH) across all 13 storage backends — the PATCH parser handles real-world Okta/Entra deviations from the RFC, not just the RFC's own examples.
  • Group membership and group→role bindings live as OpenFGA tuples (group:<org>/<id>#member, role:<org>/<name>#assignee), reusing the engine's existing userset-as-subject support.
  • The SAML Identity Provider (from 2.4.0-rc.3) can now assert group membership as a SAML attribute, and inbound org SSO/SAML logins project FGA-derived roles into the JWT roles claim — both gated by a two-layer cross-tenant containment check (FGA object namespace + the authoritative row) so a group/role in one org can never leak into another org's assertion or token.
  • displayName matching is case-insensitive and Unicode-consistent across all 6 database engines (SQL/Arango/Couchbase/Cassandra/DynamoDB/Mongo agree on the same fold, rather than each engine's own native, mutually-inconsistent case folding).

Also new in the examples repo: with-a2a-agent-card, a spec-conformant A2A (Agent2Agent) v1.0 Agent Card backed by Authorizer as the OAuth2 authorization server.

Both features went through multiple rounds of independent adversarial security review (family-scoped revocation redesign, cross-tenant containment verification, storage-provider-specific correctness passes) before merge.

This is a release candidate (pre-release). Run make test-all-db cross-DB validation before promoting to a stable release.