2.4.0-rc.4
Pre-releaseHighlights
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_codeflow (/authorize+/oauth/token), binding the issued access token'saudto 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-strictflag (default off, zero behavior change unless enabled): rejects the implicit grant and all front-channel-token response_type hybrids, and requires PKCE S256 overplain. - 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
rolesclaim — 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.