Skip to content

fix(auth): revoke OAuth sessions on logout - #418

Merged
wyattjoh merged 1 commit into
mainfrom
wyattjoh/oauth-revoke-on-logout
Aug 17, 2026
Merged

fix(auth): revoke OAuth sessions on logout#418
wyattjoh merged 1 commit into
mainfrom
wyattjoh/oauth-revoke-on-logout

Conversation

@wyattjoh

@wyattjoh wyattjoh commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

clerk auth logout previously 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 to clerk auth login when 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 as revocation_endpoint in its discovery document and which accepts a public client presenting only its client_id. Logout revokes the stored refresh token and then deletes locally in a finally, 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 --verbose and never blocks logout or re-authentication. Per RFC 7009 §2.2 the endpoint also answers 200 for a token it does not recognise, so an already-expired session is indistinguishable from a successful revocation. A refresh that has already failed with invalid_grant skips 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 typecheck
  • bun run test — 2607 pass, 0 fail
  • Verified against the live endpoint that a public client sending only token + client_id receives 200, and that omitting client_id receives 400 invalid_request
  • Manual, logout: captured a freshly issued refresh token without redeeming it, ran auth logout --verbose, confirmed the POST /oauth/token/revoke request, then confirmed the captured token was rejected with invalid_grant
  • Manual, re-authentication: captured the outgoing refresh token without redeeming it, completed auth login -y, confirmed a different session was stored, that the old grant was rejected with invalid_grant, and that the revoke request was issued only after the replacement was written to the keyring

- Add RFC 7009 token revocation support
- Revoke superseded grants after re-authentication
- Delete local credentials even when revocation fails
@wyattjoh

Copy link
Copy Markdown
Contributor Author

Stack: wyattjoh/oauth-revoke-on-logout

Part of a stacked-prs chain. Do not merge manually.

@wyattjoh
wyattjoh requested a review from rafa-thayto August 17, 2026 18:37
@wyattjoh
wyattjoh merged commit 1e65b68 into main Aug 17, 2026
8 of 9 checks passed
@wyattjoh
wyattjoh deleted the wyattjoh/oauth-revoke-on-logout branch August 17, 2026 18:40
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.

2 participants