API Security
This document outlines critical security patterns and best practices for developing secure APIs in the DeployStack Backend. Following these guidelines ensures consistent security behavior and prevents common vulnerabilities.Overview
Security in API development requires careful consideration of the order in which validation and authorization occur. The DeployStack Backend uses Fastify’s hook system to implement security controls, and understanding the proper hook usage is crucial for maintaining security.The Critical Security Pattern: Authorization Before Validation
The Problem
A common security anti-pattern occurs when authorization checks happen after input validation. This can lead to:- Information Disclosure: Unauthorized users receive validation errors instead of proper 403 Forbidden responses
- Inconsistent Error Responses: Some endpoints return 400 (validation errors) while others return 403 (authorization errors)
- Security Through Obscurity Violation: API structure and validation rules are leaked to unauthorized users
Real-World Example
Consider this test failure that led to the discovery of this pattern:Fastify Hook Execution Order
Understanding Fastify’s hook execution order is essential for proper security implementation:Key Security Principle
Authorization must happen inpreValidation
to ensure it runs before schema validation.
Correct Implementation Patterns
✅ Secure Pattern: preValidation for Authorization
❌ Insecure Pattern: preHandler for Authorization
Security Implications
With Incorrect Pattern (preHandler)
With Correct Pattern (preValidation)
Authorization Middleware Usage
Available Middleware Functions
The DeployStack Backend provides several authorization middleware functions:Dual Authentication Support
For endpoints that support both web users (cookies) and CLI users (OAuth2 Bearer tokens), use the dual authentication middleware:Satellite Authentication
For endpoints that need to authenticate DeployStack Satellite instances, use the satellite authentication middleware. Satellites use API key-based authentication with argon2 hash verification.Satellite Authentication Flow
The satellite authentication middleware performs these steps:- Bearer Token Extraction: Extracts API key from Authorization header
- Database Lookup: Retrieves all satellite records from database
- Hash Verification: Uses argon2.verify() to validate API key against stored hashes
- Context Setting: Sets satellite information on request object for route handlers
Satellite Context Object
When satellite authentication succeeds, the middleware setsrequest.satellite
with:
Security Considerations
- API Key Storage: Satellite API keys are stored as argon2 hashes in the database
- Key Generation: 32-byte cryptographically secure random keys (base64url encoded)
- Key Rotation: New API key generated on each satellite registration
- Scope Isolation: Satellites can only access their own resources and endpoints
Registration Token Authentication
For satellite registration security, the system uses specialized JWT-based registration tokens that follow a different security model than regular user authentication.Registration Token Middleware
ThevalidateRegistrationToken()
middleware (located in src/middleware/registrationTokenMiddleware.ts
) provides secure satellite registration through:
- JWT Validation: Cryptographically signed tokens with HMAC-SHA256
- Single-Use Enforcement: Tokens consumed after successful registration
- Scope Validation: Global vs team token verification
- Security Event Logging: Failed attempts monitored and logged
Token Format and Usage
Registration tokens follow specific prefixes:deploystack_satellite_global_
for DeployStack-operated satellitesdeploystack_satellite_team_
for customer-deployed team satellites
Bearer deploystack_satellite_*
Error Response Pattern
Unlike regular authentication errors, registration token failures provide specific instructions:Usage Context
Registration token authentication is exclusively used for the/api/satellites/register
endpoint. It should not be used for regular API endpoints, which use the standard authentication methods above.
Team-Aware Permission System
For endpoints that operate within team contexts (e.g.,/teams/:teamId/resource
), use the team-aware permission middleware:
How Team-Aware Permissions Work
TherequireTeamPermission()
middleware performs these security checks in order:
- Authentication Check: Verifies user is logged in
- Team ID Extraction: Gets team ID from URL params (
:teamId
) or custom function - Global Admin Bypass: Global admins can access any team’s resources
- Team Membership: Verifies user belongs to the specified team
- Team Role Lookup: Gets user’s role within that team (
team_admin
orteam_user
) - Permission Check: Verifies the team role has the required permission
Team Permission Security Model
Error Responses for Team Permissions
Team-aware endpoints return specific error messages:Permission-Based Authorization (Recommended)
Permission-based authorization is the preferred approach for most endpoints as it provides:- Granular Control: Fine-grained access control per feature
- Scalability: Easy to add new permissions without role changes
- Flexibility: Users can have different permission combinations
- Maintainability: Clear separation between authentication and authorization
Current Permission Structure
The system includes these MCP-related permissions:Permission Assignment by Role
Correct Usage Examples
Error Response Consistency
Proper Error Response Structure
All authorization errors should follow this structure:Response Status Code Guidelines
- 401 Unauthorized: User is not authenticated (no valid session)
- 403 Forbidden: User is authenticated but lacks required permissions
- 400 Bad Request: Input validation failed (only for authorized users)
Testing Security Properly
Test Authorization Before Validation
Advanced Security Patterns
Multiple Authorization Checks
For complex authorization requirements:Conditional Authorization
Security Checklist
Before deploying any protected endpoint, verify:- Authorization uses
preValidation
, notpreHandler
- Unauthorized users get 401/403, never validation errors
- Tests verify proper status codes for unauthorized access
- Error responses don’t leak sensitive information
- Schema validation only runs for authorized users
- Documentation reflects security requirements
Related Documentation
- API Documentation Generation - General API development patterns
- Authentication System - User authentication implementation
- Role-Based Access Control - Permission system details