Skip to content

fix(models): exclude oauth client sessions from mfa step-up invalidation (#2801) - #2802

Merged
cemalkilic merged 4 commits into
supabase:masterfrom
melcheikh:fix/preserve-oauth-sessions-on-mfa-invalidation
Nov 3, 2026
Merged

cemalkilic merged 4 commits into
supabase:masterfrom
melcheikh:fix/preserve-oauth-sessions-on-mfa-invalidation

Conversation

@melcheikh

Copy link
Copy Markdown
Contributor

What kind of change does this PR introduce?

Bug fix.

What is the current behavior?

Closes #2801.

When a user completes an MFA verification (verifyTOTPFactor, verifyPhoneFactor, verifyWebAuthnFactor, or RecoveryCodesVerify), GoTrue calls models.InvalidateSessionsWithAALLessThan(tx, user.ID, models.AAL2.String()).

The function executes:

DELETE FROM sessions WHERE user_id = ? AND aal < ?

Because OAuth 2.1 client sessions are issued at AAL1 and cannot step up to AAL2, any MFA verification by the user deletes all sessions issued to third-party OAuth clients. Subsequent refresh attempts by those clients fail with refresh_token_not_found.

What is the new behavior?

InvalidateSessionsWithAALLessThan now excludes sessions associated with an OAuth client:

DELETE FROM sessions WHERE user_id = ? AND aal < ? AND oauth_client_id IS NULL

OAuth client session lifecycles remain managed by consent revocation via RevokeOAuthSessions.

Additional context

Added unit test TestInvalidateSessionsWithAALLessThan_PreservesOAuthSessions in internal/models/sessions_test.go. The test asserts that:

  1. Standard browser AAL1 sessions are invalidated on step-up.
  2. OAuth client sessions (oauth_client_id present) are preserved.
  3. Higher-assurance AAL2 sessions are preserved.

@melcheikh
melcheikh requested a review from a team as a code owner September 14, 2026 04:32
@lemiffe

lemiffe commented Oct 22, 2026

Copy link
Copy Markdown

This also affects us, would be great to have it merged.
In our scenario we have an MCP session (aal1), and when a two factor code is verified (when I log onto my account in my app), Supabase Auth deletes the aal1 sessions ending my MCP session.

@dulacp

dulacp commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

@cemalkilic are you still working on this repo? or can you please route us to another maintainer.

We hit that too in production, active MCP sessions have their token being revoked when the user performs an MFA challenge.

@cemalkilic

Copy link
Copy Markdown
Contributor

Thanks a lot for the fix and the thorough test, @melcheikh, and sorry it sat for so long.

I also checked the query plan: the delete still goes through the user_id index and the new oauth_client_id IS NULL condition is only a filter on that user's few rows, so there should be performance impact.

@cemalkilic
cemalkilic merged commit ae468ca into supabase:master Nov 3, 2026
4 checks passed
@melcheikh

Copy link
Copy Markdown
Contributor Author

Thanks @cemalkilic, and thanks for checking the query plan!
On the MCP side of the OAuth server I've also opened #2894 (RFC 8707 resource indicators) and #2895 (Client ID Metadata Documents). Happy to adapt them to your plans for GA, and to help with the AAL / OAuth token endpoint work you mentioned (#2877) if that's useful.

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.

OAuth 2.1 server: MFA verification deletes OAuth client sessions (InvalidateSessionsWithAALLessThan does not exclude oauth_client_id)

4 participants