fix(auth): revoke OAuth sessions on logout - #418
Merged
Conversation
- Add RFC 7009 token revocation support - Revoke superseded grants after re-authentication - Delete local credentials even when revocation fails
Contributor
Author
|
Stack: wyattjoh/oauth-revoke-on-logout Part of a stacked-prs chain. Do not merge manually. |
rafa-thayto
approved these changes
Aug 17, 2026
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
clerk auth logoutpreviously deleted the stored OAuth session locally and never told the authorization server, so the refresh token stayed redeemable until its natural expiry — the local delete was a false reassurance on shared machines, CI runners, and any host the user no longer trusts. The same gap applied toclerk auth loginwhen re-authenticating over a live session: a new grant was minted while the old one stayed valid.Both paths now call the OAuth 2.0 Token Revocation endpoint (RFC 7009) at
/oauth/token/revoke, which the instance advertises asrevocation_endpointin its discovery document and which accepts a public client presenting only itsclient_id. Logout revokes the stored refresh token and then deletes locally in afinally, so the local delete is never skippable. Re-authentication captures the outgoing refresh token before the browser flow and revokes it only after the replacement is stored, so an abandoned or failed flow leaves the original session intact rather than stranding the user with no credentials.Revocation is best-effort throughout: the caller is already discarding the credentials, so a network failure or a server error is logged under
--verboseand never blocks logout or re-authentication. Per RFC 7009 §2.2 the endpoint also answers200for a token it does not recognise, so an already-expired session is indistinguishable from a successful revocation. A refresh that has already failed withinvalid_grantskips revocation entirely, since that grant is spent server-side and there is nothing left to revoke.Test plan
bun run format:check,bun run lint,bun run typecheckbun run test— 2607 pass, 0 failtoken+client_idreceives200, and that omittingclient_idreceives400 invalid_requestauth logout --verbose, confirmed thePOST /oauth/token/revokerequest, then confirmed the captured token was rejected withinvalid_grantauth login -y, confirmed a different session was stored, that the old grant was rejected withinvalid_grant, and that the revoke request was issued only after the replacement was written to the keyring