Skip to content

Replace argon2id-per-row session lookup with sha256 indexed lookup#60

Merged
jgpruitt merged 1 commit intomainfrom
me0/fix-session-tokens
Apr 28, 2026
Merged

Replace argon2id-per-row session lookup with sha256 indexed lookup#60
jgpruitt merged 1 commit intomainfrom
me0/fix-session-tokens

Conversation

@jgpruitt
Copy link
Copy Markdown
Collaborator

validateSession was scanning every non-expired row in the session table and running argon2id verify against each one until it found a match — ~430ms per request at ~7 sessions today, scaling linearly with total active sessions. Same anti-pattern in getInvitationByToken.

Session and invitation tokens are 256-bit CSPRNG output; their entropy alone defeats offline preimage attacks, so the slow-hash verifier was buying nothing. Switch to a unique-indexed token_hash bytea column storing sha256(rawToken). Each lookup is now a single B-tree probe. Benchmarked at p50 1.1ms / p95 2.2ms with 50 sessions, vs the previous ~3s extrapolated for the same load.

Migration 009 truncates session and invitation tables (raw tokens are unrecoverable from argon2 hashes), drops the token column on both — which cascades the redundant idx_session_token / idx_invitation_token plus the unique-constraint indexes — and adds the new token_hash column with its unique index.

CLI now recognizes UNAUTHORIZED on accounts RPCs, clears the stored session token, and prints "Session expired. Run 'me login' to sign in again." so users aren't stuck repeating 401s.

validateSession was scanning every non-expired row in the session table
and running argon2id verify against each one until it found a match —
~430ms per request at ~7 sessions today, scaling linearly with total
active sessions. Same anti-pattern in getInvitationByToken.

Session and invitation tokens are 256-bit CSPRNG output; their entropy
alone defeats offline preimage attacks, so the slow-hash verifier was
buying nothing. Switch to a unique-indexed token_hash bytea column
storing sha256(rawToken). Each lookup is now a single B-tree probe.
Benchmarked at p50 1.1ms / p95 2.2ms with 50 sessions, vs the previous
~3s extrapolated for the same load.

Migration 009 truncates session and invitation tables (raw tokens are
unrecoverable from argon2 hashes), drops the token column on both —
which cascades the redundant idx_session_token / idx_invitation_token
plus the unique-constraint indexes — and adds the new token_hash
column with its unique index.

CLI now recognizes UNAUTHORIZED on accounts RPCs, clears the stored
session token, and prints "Session expired. Run 'me login' to sign in
again." so users aren't stuck repeating 401s.
@jgpruitt jgpruitt merged commit a0079e2 into main Apr 28, 2026
3 checks passed
@jgpruitt jgpruitt deleted the me0/fix-session-tokens branch April 28, 2026 22:18
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.

1 participant