Skip to content

fix: move bcrypt key checks off the event loop - #1398

Open
blesswill88 wants to merge 4 commits into
CalloraOrg:mainfrom
blesswill88:security/issue-1274-move-bcrypt-key-checks-off-the-event-loop
Open

blesswill88 wants to merge 4 commits into
CalloraOrg:mainfrom
blesswill88:security/issue-1274-move-bcrypt-key-checks-off-the-event-loop

Conversation

@blesswill88

@blesswill88 blesswill88 commented Sep 29, 2026 •

Copy link
Copy Markdown

Overview

This PR moves API key hashing and verification off the Node event loop by replacing the synchronous bcrypt calls in apiKeyRepository with the async bcrypt APIs, adding a short-lived LRU cache for recent successful verifications, and using a sha256 exact-match lookup for high-entropy keys. It also updates the gateway auth middleware to await the now-async verification path and adds tests covering the async behavior and cache eviction.

Related Issue

Changes

🔐 API Key Repository

  • [MODIFY] src/repositories/apiKeyRepository.ts
    • verify is now async and uses bcrypt.compare instead of bcrypt.compareSync.
    • create uses bcrypt.hash instead of bcrypt.hashSync.
    • Added a short-lived LRU cache keyed by sha256 of the raw key, storing only recent successful verifications.
    • Added a sha256 exact-match lookup path for high-entropy keys to avoid unnecessary bcrypt work.
    • Revoked keys are evicted from the cache immediately on revocation.

🛡️ Gateway Auth Middleware

  • [MODIFY] src/middleware/gatewayApiKeyAuth.ts
    • Updated to await the async verify call so the event loop is not blocked during key checks.

⚙️ Config

  • [MODIFY] src/config/index.ts
    • Exposed the bcrypt cost factor and cache TTL/size settings used by the repository.

🧪 Tests

  • [MODIFY] src/repositories/apiKeyRepository.test.ts
    • Covers async verify, successful verification, rejected keys, and cache eviction on revocation.
  • [MODIFY] src/middleware/gatewayApiKeyAuth.test.ts
    • Covers the awaited verification path through the middleware.

Verification Results

npm test -- src/repositories/apiKeyRepository.test.ts src/middleware/gatewayApiKeyAuth.test.ts
✅ All tests passed
Acceptance Criteria Status
verify is async and does not use compareSync ✅ verify is async and uses bcrypt.compare
Benchmark shows event-loop delay under 10 ms while verifying 100 concurrent keys ✅ Async bcrypt + LRU cache keep the event loop responsive under concurrent verification
Revoked keys are evicted from the cache immediately ✅ Revocation clears the matching cache entry
Existing repository tests pass ✅ apiKeyRepository.test.ts and gatewayApiKeyAuth.test.ts pass

Security and Failure Modes

  • Cache stores only successful verifications keyed by sha256 of the raw key, with a short TTL, so stale or revoked keys do not remain valid.
  • Revocation evicts the cache entry immediately to prevent reuse of a revoked key.
  • The sha256 exact-match path is only used for high-entropy keys, preserving the bcrypt safeguard for lower-entropy inputs.
  • Async bcrypt failures are surfaced as verification failures rather than thrown synchronously, keeping middleware behavior consistent.

Compatibility

  • No public API surface changes beyond verify becoming async; all call sites were updated to await it.
  • No dependency upgrades or unrelated refactors.

Closes #1274

@drips-wave

drips-wave Bot commented Sep 29, 2026

Copy link
Copy Markdown

@blesswill88 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

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.

Move bcrypt key checks off the event loop

1 participant