ADR: Per-User API Keys for Multi-Tenant SaaS Support#7
Conversation
Proposes architecture for multi-tenant SaaS support where each user gets their own scoped API key instead of sharing a single key. Key points: - Per-user API keys scoped to only that user's data - API key generated on OAuth completion - Backward compatible with existing single API key mode - Enables secure Laravel/SaaS integration Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This comment was marked as outdated.
This comment was marked as outdated.
Major changes based on review bot analysis: Security Fixes: - Replace URL-based API key delivery with two-step code exchange - Remove user ID from key prefix to prevent enumeration attacks - Add rate limiting as Phase 1 (was future enhancement) Architecture Clarifications: - Extend existing APIKey model instead of adding User fields - Document relationship between service-level and user-scoped keys - Clarify self-hosted vs SaaS deployment modes Implementation Improvements: - Reorder phases: Database → OAuth → Auth → Key Management → Admin - Add comprehensive testing phase with security tests - Add key revocation endpoint (separate from regeneration) - Document webhook authentication strategy Documentation: - Add detailed OAuth flow sequence diagram - Answer all open questions from review - Add security considerations section - Include rate limit response headers Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1-4 of ADR-001 implementation:
Database & Models:
- Extended APIKey model with user_id FK, rate limiting fields
- Added TempAuthCode model for secure OAuth code exchange
- Created Alembic migration for new columns and tables
- Added relationship between User and APIKey models
API Key Generation:
- New api_keys.py utility with secure key generation
- SHA-256 hashing with constant-time comparison
- Rate limiting logic with sliding window
Secure OAuth Flow (Two-Step Code Exchange):
- New /api/v1/oauth/start endpoint for SaaS clients
- OAuth callback generates temp code, not API key
- /api/v1/oauth/exchange for server-to-server key retrieval
- Temp codes expire in 5 minutes, single-use
Per-User Authentication Guard:
- New per_user_api_key_guard with rate limit enforcement
- User-scoped keys can only access their own data
- Service-level keys (user_id=NULL) have full access
- Rate limit headers in responses (X-RateLimit-*)
Key Management Endpoints:
- POST /users/{id}/api-key/regenerate
- POST /users/{id}/api-key/revoke
- GET /users/{id}/api-key/info
- GET /users/{id}/status
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The CSRF config was excluding paths that don't exist (/api/v1/...). Updated to exclude the actual paths: - /oauth/ - OAuth endpoints for SaaS (callback, exchange, start) - /users/ - API routes that use API key auth, not sessions Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
@claude please rereview |
|
Claude finished @StuMason's task in 2m 0s —— View job Re-review Complete: Per-User API KeysI've completed a comprehensive re-review of this PR. Overall, the implementation is well-architected and production-ready with strong security foundations. Here's my detailed analysis: ✅ Strengths1. Excellent ADR Documentation
2. Solid Security Design
3. Clean Database Schema
4. Backward Compatibility
|
| Phase | Status | Notes |
|---|---|---|
| Phase 1: Database & Rate Limiting | ✅ Complete | Migration, models, rate limiting implemented |
| Phase 2: OAuth Integration | ✅ Complete | Temp codes, exchange endpoint working |
| Phase 3: Authentication Guard | Guard implemented but not applied to data endpoints | |
| Phase 4: Key Management | ✅ Complete | Regenerate, revoke, status endpoints present |
| Phase 5: Admin Dashboard | ❓ Unknown | Not reviewed in this PR |
| Phase 6: Testing | ❌ Missing | No test files in changeset |
| Phase 7: Documentation | ✅ Complete | Excellent ADR |
🎯 Summary & Recommendation
Overall Assessment: This is high-quality work with strong architectural foundations. The ADR is exemplary, the security design is sound, and the code is clean.
Critical Path to Merge:
- ✅ MUST FIX: Apply
per_user_api_key_guardto data/sleep routers ⚠️ SHOULD FIX: Remove duplicate key generation inauth.py⚠️ SHOULD FIX: Add rate limit headers to responses- 📝 NICE TO HAVE: Add integration tests
- 📝 NICE TO HAVE: Document OAuth state storage limitation
Verdict: Approve after addressing item #1 (critical guard replacement). Items #2-3 can be follow-up PRs if needed, but #1 is essential for the security model to work correctly.
CRITICAL: Replace api_key_guard with per_user_api_key_guard on all user data routers (data, sleep, sync) to enforce: - Per-user access restrictions (user keys can only access own data) - Rate limiting on all endpoints - Proper key validation Also removes legacy generate_api_key() function from auth.py that was superseded by core/api_keys.py implementation. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Summary
This PR proposes an architecture decision for implementing per-user API keys to support multi-tenant SaaS deployments.
Problem
Currently, a single API key grants access to ALL users' data. If compromised in a SaaS context, it's a total data breach.
Solution
Each user gets their own API key, scoped to only their data:
Key Changes Proposed
api_key_hash,api_key_prefixcolumns to User modelTest plan
🤖 Generated with Claude Code