feat(backend): add API key auth middleware for operator-only endpoints - #139
Open
K1NGD4VID wants to merge 6 commits into
Open
feat(backend): add API key auth middleware for operator-only endpoints#139K1NGD4VID wants to merge 6 commits into
K1NGD4VID wants to merge 6 commits into
Conversation
Adds requireAuth middleware that validates X-API-Key header against
OPERATOR_API_KEY env var using crypto.timingSafeEqual to prevent
timing oracle attacks.
Protected routes (require valid X-API-Key):
- POST /api/queues (create)
- POST /api/queues/:id/advance
- POST /api/queues/:id/close
- POST /api/queues/:id/open-enrollment
- POST /api/queues/:id/close-enrollment
- POST /api/escrow/release
- POST /api/escrow/refund
- POST /api/escrow/expire
Unauthenticated routes remain open:
- GET /api/queues, GET /api/queues/:id, GET /api/queues/:id/stats
- POST /api/enrollments, DELETE /api/enrollments
- POST /api/escrow/deposit, GET /api/escrow/:id
- All /public routes
Returns 401 with { error: { message: 'Unauthorized', status: 401 } }
for missing or invalid keys.
Updates existing route tests to include API key header for protected
routes. Adds dedicated auth test file covering valid key, invalid key,
missing key, and no-OPERATOR_API_KEY-configured scenarios.
Closes Stellar-Deejah#50
|
@K1NGD4VID is attempting to deploy a commit to the Deejah Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
- Remove merge conflict markers in escrow/queue route tests
- Fix createApp() call in index.ts (no arguments expected)
- Remove orphaned fn test_expire_position in test.rs
- Mock IntersectionObserver in frontend test setup
- Fix ambiguous findByRole('status') query in accessibility test
- Remove duplicate object keys in enrollment/escrow route tests
- Fix merge conflict markers in escrow route test (release/refund/expire) - Fix escrow deposit auth test with valid 56-char Stellar address - Run cargo fmt on contracts/
- Remove --rm flag from docker run to allow log retrieval on failure - Increase health check retries from 10 to 20 with 3s intervals (60s total) - Add --start-period=10s to Docker HEALTHCHECK for backend startup grace period - Fix HEALTHCHECK to use CommonJS require() instead of ES module import() - Remove duplicate pnpm install line in Dockerfile
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
Adds API key authentication middleware (
requireAuth) to protect operator-only endpoints (queue creation, advancement, closing, escrow release/refund/expire). Previously, any caller with network access could invoke these state-mutating endpoints without any credential.Changes
backend/src/middleware/auth.ts(new)X-API-Keyheader and validates againstOPERATOR_API_KEYenvironment variablecrypto.timingSafeEqualfor constant-time comparison (prevents timing oracle attacks){ error: { message: \Unauthorized\, status: 401 } }for missing/invalid/mismatched keysOPERATOR_API_KEYis not configured (fail-closed)Protected routes
/api/queues/api/queues/:id/advance/api/queues/:id/close/api/queues/:id/open-enrollment/api/queues/:id/close-enrollment/api/escrow/release/api/escrow/refund/api/escrow/expireUnauthenticated routes (unchanged)
GETroutes (queue list, details, stats, escrow lookup)POST /api/enrollments,DELETE /api/enrollmentsPOST /api/escrow/deposit/publicroutesbackend/.env.exampleOPERATOR_API_KEYwith documentation on generating strong keys (openssl rand -base64 32)Configuration key:
crypto.timingSafeEqualNaive
===string comparison short-circuits on the first mismatching character, leaking timing information that lets an attacker brute-force the key character by character over many requests.crypto.timingSafeEqualalways compares every byte of both buffers regardless of where the first difference occurs, making it immune to timing side-channel attacks. Both buffers must be the same length — we compare lengths first (a fast-path rejection that does not leak the content), and only calltimingSafeEqualwhen lengths match.Tests
src/__tests__/routes/auth.route.test.ts— dedicated auth test file covering valid key (201), invalid key (401), missing key (401), no env var configured (401), all protected routes reject without key, and unauthenticated routes remain accessiblequeues.route.test.ts,escrow.route.test.ts,escrowRoutes.test.tsto setOPERATOR_API_KEYand sendX-API-Keyheader on protected routesCloses #50