Security improvements identified for the protect-api-with-api-key branch: - Use short-lived wsToken for WebSocket auth (not session tokens in URLs) - Add AUTOMAKER_HIDE_API_KEY env var to suppress console logging - Add rate limiting to login endpoint (5 attempts/min/IP) - Use timing-safe comparison for API key validation - Make WebSocket tokens single-use 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2.8 KiB
API Security Hardening Design
Date: 2025-12-29 Branch: protect-api-with-api-key Status: Approved
Overview
Security improvements for the API authentication system before merging the PR. These changes harden the existing implementation for production deployment scenarios (local, Docker, internet-exposed).
Fixes to Implement
1. Use Short-Lived wsToken for WebSocket Authentication
Problem: The client currently passes sessionToken in WebSocket URL query parameters. Query params get logged and can leak credentials.
Solution: Update the client to:
- Fetch a wsToken from
/api/auth/tokenbefore each WebSocket connection - Use
wsTokenquery param instead ofsessionToken - Never put session tokens in URLs
Files to modify:
apps/ui/src/lib/http-api-client.ts- UpdateconnectWebSocket()to fetch wsToken first
2. Add Environment Variable to Hide API Key from Logs
Problem: The API key is printed to console on startup, which gets captured by logging systems in production.
Solution: Add AUTOMAKER_HIDE_API_KEY=true env var to suppress the banner.
Files to modify:
apps/server/src/lib/auth.ts- Wrap console.log banner in env var check
3. Add Rate Limiting to Login Endpoint
Problem: No brute force protection on /api/auth/login. Attackers could attempt many API keys.
Solution: Add basic in-memory rate limiting:
- ~5 attempts per minute per IP
- In-memory Map tracking (resets on server restart)
- Return 429 Too Many Requests when exceeded
Files to modify:
apps/server/src/routes/auth/index.ts- Add rate limiting logic to login handler
4. Use Timing-Safe Comparison for API Key
Problem: Using === for API key comparison is vulnerable to timing attacks.
Solution: Use crypto.timingSafeEqual() for constant-time comparison.
Files to modify:
apps/server/src/lib/auth.ts- UpdatevalidateApiKey()function
5. Make WebSocket Tokens Single-Use
Problem: wsTokens can be reused within the 5-minute window. If intercepted, attackers have time to use them.
Solution: Delete the token after first successful validation.
Files to modify:
apps/server/src/lib/auth.ts- UpdatevalidateWsConnectionToken()to delete after use
Implementation Order
- Fix #4 (timing-safe comparison) - Simple, isolated change
- Fix #5 (single-use wsToken) - Simple, isolated change
- Fix #2 (hide API key env var) - Simple, isolated change
- Fix #3 (rate limiting) - Moderate complexity
- Fix #1 (client wsToken usage) - Requires coordination with server
Testing Notes
- Test login with rate limiting (verify 429 after 5 attempts)
- Test WebSocket connection with new wsToken flow
- Test wsToken is invalidated after first use
- Verify
AUTOMAKER_HIDE_API_KEY=truesuppresses banner