Skip to content

Conversation

@hf
Copy link
Contributor

@hf hf commented Oct 17, 2025

Introduces v2 of a refresh token algorithm.

Goals

  1. Smaller disk size. A common complaint with the refresh_tokens table is that it's huge and difficult to clean up without impacting IO performance.
  2. Lighter on replication. A lot of active users cause a lot of on-wire traffic for replication.
  3. Easier to debug and analyze. Refresh tokens are not transparent, and a recursive self-relationship is not easy to debug with difficult edge cases that are not local in time.

Configuration Options

Config Meaning
GOTRUE_SECURITY_REFRESH_TOKEN_ALGORITHM_VERSION 0 or 1 for regular tokens, 2 for new tokens. This currently only applies on new sessions. Old sessions use old implementation.
GOTRUE_SECURITY_REFRESH_TOKEN_ALLOW_REUSE not secure, but allows any v2 refresh token to always be reused.

Implementation

Refresh tokens now encode the session ID + counter value, which is then signed by a per-session HMAC key. By comparing the state in the session and the counter in the refresh token, we can identify whether a refresh token is being used properly or it's being reused. We can also identify what type of reuse is going on.

If the refresh token counter is the previous refresh token, it means the client failed to save the last response. This is always allowed.

If the refresh token counter is older than the previous refresh token, then it's being reused. Reuse is allowed only if the client is refreshing the same session within the GOTRUE_SECURITY_REFRESH_TOKEN_REUSE_INTERVAL.

To ensure a non-synchronized client synchronizes to the correct refresh token state, the session's refresh token counter is incremented only on valid refresh token use.

Please check the massive suite of tests (>700 LOC) which exercise every possible combination to ensure correctness of the algorithm. The coverage here is above 95% (of the lines that can be covered).

Observability and Debuging

Requests that create a session and refresh a session will now receive these response headers:

Header Meaning
sb-auth-user-id the user to which the session belongs
sb-auth-session-id the newly created or refreshed session
sb-auth-refresh-token-counter (v2 only) the refresh token's counter that is being returned
sb-auth-refresh-token-prefix (v1 only) the first 5 characters of the refresh token being returned
sb-auth-refresh-token-reuse-cause (v2 only) a comma separated list explaining what type of reuse was detected
sb-auth-refresh-token-rotation (v2 only) if the session is being terminated due to detected malicious refresh token reuse

@hf hf force-pushed the hf/new-rt branch 4 times, most recently from 2cabb9f to fdcf9ab Compare October 22, 2025 15:19
@hf hf marked this pull request as ready for review October 22, 2025 15:22
@hf hf requested a review from a team as a code owner October 22, 2025 15:22
@coveralls
Copy link

coveralls commented Oct 23, 2025

Pull Request Test Coverage Report for Build 18907392822

Details

  • 374 of 442 (84.62%) changed or added relevant lines in 8 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+0.5%) to 68.012%

Changes Missing Coverage Covered Lines Changed/Added Lines %
internal/api/oauthserver/handlers.go 0 2 0.0%
internal/api/token_refresh.go 16 18 88.89%
internal/models/refresh_token.go 28 34 82.35%
internal/models/sessions.go 25 35 71.43%
internal/models/user.go 27 43 62.79%
internal/tokens/service.go 182 214 85.05%
Files with Coverage Reduction New Missed Lines %
internal/tokens/service.go 1 81.42%
Totals Coverage Status
Change from base Build 18906175758: 0.5%
Covered Lines: 13786
Relevant Lines: 20270

💛 - Coveralls

Copy link
Contributor

@issuedat issuedat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work 👏 Some great test coverage too! Left a few comments but nothing majorly blocking on my end.

@hf hf enabled auto-merge (squash) October 29, 2025 13:32
@hf hf merged commit dea5b8e into master Oct 29, 2025
7 checks passed
@hf hf deleted the hf/new-rt branch October 29, 2025 14:06
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.

6 participants