Skip to content

Support RFC 9700-style refresh token rotation grace period with single-successor semantics #1506

@Myks92

Description

@Myks92

Hi maintainers,

I would like to propose first-class support for refresh token rotation with a grace period / overlap window, aligned with RFC 9700 Section 4.14.2.

Problem

Today, the server can rotate refresh tokens and can be configured not to revoke them immediately, but there does not appear to be built-in support for the following server-side behavior:

  • first use of a refresh token issues exactly one successor token pair,
  • repeated use of the old refresh token during a short grace window returns the same already-issued response,
  • reuse of the old refresh token after the grace window fails with invalid_grant,
  • replay after the grace window revokes the active token family.

This matters for:

  • network failures where the client request succeeds but the response is lost,
  • concurrent refresh calls from multiple browser tabs/devices/processes,
  • multi-instance deployments where correctness should not depend on client-side dedupe.

Why this would help

The current extension points are enough for application developers to build this themselves with a custom controller + custom refresh token repository + sidecar state table, but this logic is subtle and easy to get wrong under concurrency.

A built-in solution would make it easier to implement the replay-detection and grace-period behavior recommended by RFC 9700.

Suggested semantics

A possible built-in policy could be:

  1. On first refresh with token R0, issue one new token pair and record successor R1.
  2. For a configurable grace period (for example 30 seconds), repeated use of R0 returns the exact same previously-issued token response instead of minting additional successors.
  3. After the grace period, use of R0 returns invalid_grant.
  4. If R0 is used after the grace window, revoke the active refresh-token family as replay detection.

This is effectively a “single-successor” policy rather than allowing multiple valid rotated refresh tokens during the overlap window.

Possible implementation shape

Even if this is not implemented directly in the core grant logic, it could be useful to expose official hooks or abstractions for:

  • refresh-token family tracking,
  • successor linkage,
  • grace-period expiry,
  • replay response storage/reuse,
  • family-wide revocation on post-grace replay.

Context

There were earlier discussions around not revoking old refresh tokens immediately and around failed delivery of the rotated token response, but RFC 9700 now gives a stronger framing for this class of behavior.

Would you be open to supporting this upstream, either directly or through new extension points?

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions