API Security Model
Overview
Section titled “Overview”The middleware has been updated to implement a more secure and specific authentication model for API routes. Instead of blanket-skipping authentication for all API routes, we now categorize them and require appropriate guards. Unknown API routes now enforce authentication by default for security.
🔒 Security Categories
Section titled “🔒 Security Categories”1. Public API Routes (No Authentication Required)
Section titled “1. Public API Routes (No Authentication Required)”/api/health- Health checks for monitoring/api/contact- Contact form submissions
2. Admin API Routes (Require Admin Authentication)
Section titled “2. Admin API Routes (Require Admin Authentication)”/api/admin/*- All admin operations/api/cache/*- Cache management operations/api/maintenance/*- System maintenance operations/api/debug/*- Debugging endpoints/api/tests/*- Testing endpoints
3. Protected API Routes (Require Regular Authentication)
Section titled “3. Protected API Routes (Require Regular Authentication)”/api/auth/*- Authentication operations/api/erp/*- ERP-related operations/api/orders/*- Order management/api/extracted-orders/*- Extracted order operations/api/pdf-documents/*- PDF document operations/api/support/*- Support operations/api/trigger/webhooks- Webhook endpoints
4. Unknown API Routes (Default to Authentication Required) ⚠️ SECURITY ENFORCED
Section titled “4. Unknown API Routes (Default to Authentication Required) ⚠️ SECURITY ENFORCED”- Any new API routes not explicitly categorized WILL REQUIRE AUTHENTICATION
- Returns HTTP 401 Unauthorized if no valid user session is found
- Prevents unauthorized access to potentially sensitive endpoints
- Security by default - no accidental exposure of new endpoints
🛡️ Required Implementation
Section titled “🛡️ Required Implementation”For Admin Routes
Section titled “For Admin Routes”All admin API endpoints MUST call requireAdmin(locals, request) at the start of their handler:
class AdminHandler extends BaseAPIHandler { async GET({ locals, request }: any): Promise<Response> { return this.handleRequest(async () => { // REQUIRED: Check authentication and admin permissions const { userId } = await this.requireAdmin(locals, request);
// Your handler logic here... // userId is guaranteed to be valid and belong to an admin }); }}For Protected Routes
Section titled “For Protected Routes”All protected API endpoints MUST call requireAuth(locals, request) at the start of their handler:
class ProtectedHandler extends BaseAPIHandler { async POST({ locals, request }: any): Promise<Response> { return this.handleRequest(async () => { // REQUIRED: Check authentication const { userId } = await this.requireAuth(locals, request);
// Your handler logic here... // userId is guaranteed to be valid }); }}For Public Routes
Section titled “For Public Routes”Public API endpoints don’t need authentication guards, but should still use proper input validation and rate limiting.
🚨 NEW: Default Authentication Enforcement
Section titled “🚨 NEW: Default Authentication Enforcement”Unknown API Route Behavior
Section titled “Unknown API Route Behavior”When a request is made to an uncategorized API route:
- Middleware attempts authentication using
getUserFromSession(request) - If authentication succeeds: User is attached to
context.locals.userand request proceeds - If authentication fails or no user: HTTP 401 Unauthorized is returned immediately
- Request never reaches the handler - security is enforced at the middleware level
Example 401 Response
Section titled “Example 401 Response”{ "error": "Unauthorized", "message": "Authentication required for this endpoint", "code": "AUTHENTICATION_REQUIRED"}Security Benefits
Section titled “Security Benefits”- No accidental exposure of new endpoints
- Consistent authentication across all unknown routes
- Immediate rejection of unauthorized requests
- Clear error messages for debugging
🔍 Current Status Check
Section titled “🔍 Current Status Check”✅ Already Implemented (Good)
Section titled “✅ Already Implemented (Good)”/api/admin/system-stats.ts- UsesrequireAdmin/api/admin/rate-limiting.ts- UsesrequireAdmin/api/admin/unblock-ip.ts- UsesrequireAdmin/api/cache/flush.ts- UsesrequireAdmin/api/cache/stats.ts- UsesrequireAdmin
⚠️ Need to Check/Update
Section titled “⚠️ Need to Check/Update”/api/maintenance/*- Verify admin guards/api/debug/*- Verify admin guards/api/tests/*- Verify admin guards/api/auth/*- Verify auth guards/api/erp/*- Verify auth guards/api/orders/*- Verify auth guards/api/extracted-orders/*- Verify auth guards/api/pdf-documents/*- Verify auth guards/api/support/*- Verify auth guards
🚨 Security Implications
Section titled “🚨 Security Implications”Before (Insecure)
Section titled “Before (Insecure)”- All API routes skipped authentication in middleware
- Individual handlers had to remember to implement guards
- Risk of forgetting to add
requireAuthorrequireAdmin - Potential for unauthorized access to sensitive operations
- Unknown routes could proceed unauthenticated
After (Secure)
Section titled “After (Secure)”- Middleware categorizes routes and requires authentication where appropriate
- Individual handlers still need guards, but middleware provides a safety net
- Unknown routes default to requiring authentication
- Immediate 401 rejection for unauthorized requests to unknown routes
- Clear separation between public, protected, and admin endpoints
- Security by default - no accidental exposure
📋 Implementation Checklist
Section titled “📋 Implementation Checklist”- Verify all
/api/admin/*endpoints userequireAdmin(locals, request) - Verify all
/api/cache/*endpoints userequireAdmin(locals, request) - Verify all
/api/maintenance/*endpoints userequireAdmin(locals, request) - Verify all
/api/debug/*endpoints userequireAdmin(locals, request) - Verify all
/api/tests/*endpoints userequireAdmin(locals, request) - Verify all
/api/auth/*endpoints userequireAuth(locals, request) - Verify all
/api/erp/*endpoints userequireAuth(locals, request) - Verify all
/api/orders/*endpoints userequireAuth(locals, request) - Verify all
/api/extracted-orders/*endpoints userequireAuth(locals, request) - Verify all
/api/pdf-documents/*endpoints userequireAuth(locals, request) - Verify all
/api/support/*endpoints userequireAuth(locals, request) - Test that public routes (
/api/health,/api/contact) work without authentication - Test that protected routes reject unauthenticated requests
- Test that admin routes reject non-admin users
- Test that unknown API routes return 401 Unauthorized ⚠️ NEW
🔧 Adding New API Routes
Section titled “🔧 Adding New API Routes”When adding new API routes:
- Determine the security category (public, protected, or admin)
- Add the route to the appropriate array in
middleware.ts - Implement the appropriate guard in your handler
- Test authentication requirements work as expected
Example: Adding a New Admin Route
Section titled “Example: Adding a New Admin Route”// In middleware.ts, add to adminApiRoutes:const adminApiRoutes = [ '/api/admin', '/api/cache', '/api/maintenance', '/api/debug', '/api/tests', '/api/admin/new-feature', // Add your new route here];
// In your handler:class NewFeatureHandler extends BaseAPIHandler { async POST({ locals, request }: any): Promise<Response> { return this.handleRequest(async () => { const { userId } = await this.requireAdmin(locals, request); // Your handler logic here... }); }}⚠️ Important Security Note
Section titled “⚠️ Important Security Note”If you forget to add a new route to the appropriate category array, the middleware will automatically enforce authentication and return 401 for unauthorized requests. This provides a security safety net but means you should always categorize your routes properly.
🚀 Benefits
Section titled “🚀 Benefits”- Improved Security - No more accidentally forgetting authentication
- Clear Categorization - Easy to understand which routes need what level of auth
- Defense in Depth - Middleware + handler guards provide multiple security layers
- Maintainable - Clear patterns for implementing new secure endpoints
- Production Ready - Prevents the authentication failures that were causing app crashes
- Security by Default - Unknown routes automatically require authentication
- Immediate Rejection - Unauthorized requests to unknown routes get 401 immediately