feat(auth-jwt-substrate): JWT session machinery, middleware, revocation#20
Merged
Conversation
themightychris
added a commit
that referenced
this pull request
May 16, 2026
npm install -w apps/api jose
JWT primitives (issue/verify for access, refresh, claim-pending tokens), cookie helpers, in-memory revocation store + gitsheets persistence, session metadata in private bucket, session middleware (onRequest hook), requireAuth guards, and auth routes (me, refresh, logout, sessions, sessions/:jti/revoke, OAuth stubs returning 501). Also updates rate-limit plugin to use account-based keys when request.session.person is set (300/min reads, 30/min writes per account), and extends the private store interface with readBlob/writeBlob for non-record arbitrary blob storage.
Tests cover all 12 validation criteria from the plan: - mintSessionFor issues valid access + refresh JWTs - cfp_claim token rejected by verifyAccess (scope enforcement) - GET /api/auth/me anonymous and authenticated paths - Expired access JWT → anonymous (not 401) - POST /api/auth/refresh: no-cookie, expired, revoked, and valid cases - POST /api/auth/logout: cookie clearing and subsequent-me-returns-anonymous - GET /api/auth/sessions: 401 unauthenticated, session list with current:true - POST /api/auth/sessions/:jti/revoke: 409 and 404 cases - OAuth stubs return 501 oauth_not_yet_wired - Account-based rate limit keys separate from IP bucket
5a555dd to
653e3fb
Compare
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
specs/behaviors/authorization.mdandspecs/api/auth.mdrequest.session(person, accountLevel, personId, jti) viaonRequesthookGET /api/auth/me,POST /api/auth/refresh,POST /api/auth/logout,GET /api/auth/sessions,POST /api/auth/sessions/:jti/revoke/api/auth/github/start,/api/auth/github/callback) return501 oauth_not_yet_wiredfor the github-oauth plan to implementSet<jti>(O(1) hot path) + persistedrevocationsgitsheet (survives restarts); periodic sweeper clears expired recordssession-metadata.json— never in the public commit logreadBlob/writeBlobfor non-record arbitrary storageTest plan
mintSessionFor(personId)issues valid access + refresh JWTs that the verifier acceptscfp_claimtoken not accepted byverifyAccess(scope enforcement)GET /api/auth/mewith validcfp_sessionreturns person + accountLevelGET /api/auth/mewith no cookie returns{person:null, accountLevel:'anonymous'}200POST /api/auth/refreshwith valid refresh JWT returns new pair; old jti revokedPOST /api/auth/refreshwith revoked refresh JWT → 401refresh_token_revokedPOST /api/auth/logoutclears cookies; subsequent/api/auth/mereturns anonymousGET /api/auth/sessionslists non-revoked sessions; current markedcurrent:truePOST /api/auth/sessions/:jti/revokewith current session → 409cannot_revoke_current_sessionPOST /api/auth/sessions/:jti/revokewith unknown jti → 404oauth_not_yet_wired🤖 Generated with Claude Code