perf(git): replace per-request token decryption with indexed hash lookup#279
perf(git): replace per-request token decryption with indexed hash lookup#279jaredglaser wants to merge 1 commit into
Conversation
Git HTTP auth loaded every git_tokens row and JWE-decrypted each one on every request before comparing. Migration 024 adds a token_hash column (SHA-256 hex of the raw token) with a unique index, token creation now writes the hash, and auth does a single indexed lookup plus timingSafeEqual, mirroring the sessions pattern. Rows created before the migration have a NULL hash; those fall back to the legacy decrypt-and-compare scan and get their hash backfilled on a successful match so the next request takes the fast path. Token matching moved to src/lib/git/git-token-auth.ts with injected repo and decrypt dependencies so it is unit-testable outside the route. Closes #243 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 35 minutes and 58 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (8)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Git HTTP auth (
src/routes/api/git.$.ts) loaded everygit_tokensrow and JWE-decrypted each one on every request before the timing-safe compare, making auth O(n) in token count with a JWE decrypt per row.024_git_token_hash.sqladds atoken_hashcolumn (SHA-256 hex of the raw token) with a unique index.createGitTokennow writes the hash at creation (hashGitTokeninsrc/lib/git/git-token-auth.ts).token_hashplustimingSafeEqual, mirroring the sessions pattern insrc/lib/auth/session-manager.ts. A length guard preventstimingSafeEqualfrom throwing on a malformed stored hash.WHERE token_hash IS NULL), and the hash is backfilled on a successful match so the next request takes the fast path. Keyring and JWE decrypt load lazily, so the fast path never touches them.src/lib/git/git-token-auth.tswith injected repo and decrypt dependencies so it is unit-testable outside the route file.findAllEncrypted(sole caller was the route) becamefindLegacyEncrypted; addedfindByTokenHashandsetTokenHash.Migration numbering note: open PRs #276 and #278 also claim 024, so renumbering this migration on rebase is expected.
Testing
bun run typecheckclean.bun test --isolate src/lib/git/__tests__/git-token-auth.test.ts(8 pass): fast path skips legacy scan and decryption, legacy match backfills the hash, malformed stored hash falls through without throwing, all-decrypt-failure logging, fire-and-forget backfill failure does not throw.bun test --isolate src/lib/database/repositories/__tests__/git-token-repository.test.ts(17 pass): create insertstoken_hash,findByTokenHash,findLegacyEncryptedfilters NULL-hash rows,setTokenHash.bun test --isolate src/data/__tests__/git-tokens.functions.test.ts(8 pass): created token stores the SHA-256 hash of the raw token.Closes #243
🤖 Generated with Claude Code