Skip to content

OAuth2 OP readiness M1: Revocation foundation and storage hygiene #1250

Closed
8 of 8 issues completed
Closed

Description

@gtema

Milestone 1 of the OAuth2/OIDC provider production-readiness roadmap (audit: doc/src/contributor/oauth2-production-readiness.md, findings F-A1..A5, F-D1, F-F1, F-F2).

Why this milestone first

The OP currently has no revocation surface beyond emergency signing-key rotation:

  • No RFC 7009 /revoke; the only way a refresh family ends is reuse detection (crates/core/src/oauth2_session/service.rs:336-345).
  • Refresh families reset expires_at on every rotation with no absolute lifetime and never re-check the user (service.rs:299-300, crates/keystone/src/api/v4/oauth2/token.rs:820-950). A disabled or deleted user keeps refreshing indefinitely, contrary to ADR 0026 §13 "Revocation Semantics Parity".
  • Storage has no index by user_id, client_id, or domain_id (crates/oauth2-session-driver-raft/src/lib.rs:44-70), so "revoke everything for user X" is a full scan.
  • Client DELETE does not revoke refresh families despite the admin guide saying so (crates/core/src/oauth2_client/service.rs:182-191).
  • Abandoned pre-auth sessions, codes, device grants, and refresh tokens are never deleted: expiry is enforced lazily on read only and there is no session janitor (service.rs:147,240,289,393,411,464). GET /authorize is an unauthenticated Raft write per request.
  • Cross-client refresh presentation rotates the victim's family leaf before the ownership check (token.rs:880 vs :908).

Exit criteria

  • An operator can revoke all OP sessions for a user, client, or domain via API and keystone-manage.
  • A user disable/delete or password change ends that user's OP refresh families within one access-token lifetime.
  • /revoke (RFC 7009) is served and advertised in discovery.
  • Raft key count stays flat under a loop of abandoned GET /authorize requests.
  • A foreign client presenting a stolen refresh token cannot spend it.

Sub-issues carry the individual steps. client_credentials can be promoted to GA once this milestone closes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    • Status
      Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions