# Issue #28 Implementation Summary: "When authentication is enabled, login should be forced" ## Overview This document summarizes the implementation of Issue #28, which addresses the security gap where authentication was not properly enforced when enabled. The changes ensure that when authentication is enabled, only explicitly public endpoints are accessible without authentication. ## Changes Made ### 1. Tightened Default Public Paths **File**: `src/auth_middleware.cpp` **Changes**: - Modified `initializeDefaultPaths()` to only include truly essential endpoints as public by default - Reduced default public paths from 7 endpoints to just 2: - `/api/health` - Health check endpoint - `/api/status` - Basic server status - Moved model discovery endpoints from public paths to user paths: - `/api/models`, `/api/models/types`, `/api/models/directories` - `/api/samplers`, `/api/schedulers`, `/api/parameters` **Security Impact**: Prevents unauthorized access to model information and system capabilities when authentication is enabled. ### 2. Enhanced Authentication Logic **File**: `src/auth_middleware.cpp` **Changes**: - Modified `requiresAuthentication()` to follow an "authentication-first" approach - Added explicit check for authentication disabled status first - When authentication is enabled, only paths explicitly in `publicPaths` are accessible without authentication - All other paths require authentication when auth is enabled **Before**: ```cpp bool AuthMiddleware::requiresAuthentication(const std::string& path) const { // Check if path is public if (pathMatchesPattern(path, m_config.publicPaths)) { return false; } // If authentication is enabled (not NONE), then all paths except public ones require authentication return !isAuthenticationDisabled(); } ``` **After**: ```cpp bool AuthMiddleware::requiresAuthentication(const std::string& path) const { // First check if authentication is completely disabled if (isAuthenticationDisabled()) { return false; } // Authentication is enabled, check if path is explicitly public if (pathMatchesPattern(path, m_config.publicPaths)) { return false; } // All other paths require authentication when auth is enabled return true; } ``` ### 3. Configurable Public Paths **Files**: - `include/server_config.h` - `src/auth_middleware.cpp` - `src/main.cpp` **Changes**: - Added `customPublicPaths` field to `AuthConfig` structure - Added `--public-paths` command line option - Implemented parsing of comma-separated public paths with automatic trimming and prefix handling - Added help documentation for the new option **Usage Examples**: ```bash # Default behavior (only health and status are public) ./stable-diffusion-rest --models-dir /data/SD_MODELS --auth jwt # Custom public paths ./stable-diffusion-rest --models-dir /data/SD_MODELS --auth jwt --public-paths "/api/health,/api/status,/api/models" # Make all endpoints public (not recommended for production) ./stable-diffusion-rest --models-dir /data/SD_MODELS --auth jwt --public-paths "/" ``` ### 4. Protected Endpoint Updates **File**: `src/server.cpp` **Changes**: - Updated all model discovery endpoints to use authentication middleware: - `/api/samplers`, `/api/schedulers`, `/api/parameters` - `/api/models`, `/api/models/types`, `/api/models/directories` - `/api/models/stats` - Updated queue endpoints to require authentication: - `/api/queue/status`, `/api/queue/job/{id}` **Security Impact**: Ensures all potentially sensitive endpoints require authentication when auth is enabled. ### 5. Documentation **File**: `AUTHENTICATION_SECURITY_GUIDE.md` **Changes**: - Created comprehensive security guide explaining the authentication changes - Documented default secure configuration - Provided migration guide for existing deployments - Included best practices and troubleshooting information - Added examples for different deployment scenarios ### 6. Unit Tests **Files**: - `test_auth_security_simple.cpp` - `src/CMakeLists.txt` **Changes**: - Created comprehensive test suite covering all authentication scenarios - Added build configuration for the new test executable - Tests cover: - Default public paths behavior - Custom public paths configuration - Authentication method consistency - Protected endpoint verification - Edge cases and error conditions ## Security Improvements ### Before Implementation - When authentication was enabled, many endpoints remained publicly accessible - Model discovery, system information, and utility endpoints were exposed without authentication - No way to customize which endpoints should be public - Inconsistent authentication enforcement across different auth methods ### After Implementation - **Secure by Default**: Only essential health/status endpoints are public when auth is enabled - **Explicit Control**: Administrators can customize public paths via command line - **Consistent Enforcement**: All auth methods properly enforce authentication requirements - **Comprehensive Protection**: All sensitive endpoints require authentication when enabled ## Migration Guide ### For Existing Deployments 1. **Review Client Applications**: Check if any applications rely on previously public endpoints 2. **Update Authentication**: Ensure client applications handle authentication properly 3. **Configure Public Paths**: Use `--public-paths` if needed to maintain compatibility 4. **Test Thoroughly**: Verify all endpoints behave as expected ### Example Migration Scenarios #### Scenario 1: Public API Documentation ```bash ./stable-diffusion-rest --models-dir /data/SD_MODELS --auth jwt --public-paths "/api/health,/api/status,/api/docs,/api/openapi.json" ``` #### Scenario 2: Internal Monitoring ```bash ./stable-diffusion-rest --models-dir /data/SD_MODELS --auth jwt --public-paths "/api/health,/api/status,/api/queue/status" ``` #### Scenario 3: Development Environment ```bash ./stable-diffusion-rest --models-dir /data/SD_MODELS --auth jwt --public-paths "/api/health,/api/status,/api/models,/api/samplers" ``` ## Testing ### Building and Running Tests ```bash # Configure build with tests enabled cmake -DBUILD_AUTH_SECURITY_TEST=ON .. # Build the test cmake --build . --target test_auth_security_simple # Run the tests ./build/bin/test_auth_security_simple ``` ### Test Coverage The test suite covers: - ✅ Default public paths when auth is disabled - ✅ Default public paths when auth is enabled - ✅ Custom public paths configuration - ✅ Path parsing with spaces and auto-prefixing - ✅ Model discovery endpoint protection - ✅ Generation endpoint protection - ✅ Queue endpoint protection - ✅ Authentication method consistency - ✅ Optional authentication scenarios ## Command Line Options ### New Option - `--public-paths `: Comma-separated list of public paths that don't require authentication - Default: `/api/health,/api/status` when auth is enabled - Example: `--public-paths "/api/health,/api/status,/api/models"` ### Updated Help Text ``` Authentication Options: --auth Authentication method (none, jwt, api-key, unix, pam, optional) --auth-method Authentication method (alias for --auth) --jwt-secret JWT secret key (auto-generated if not provided) --jwt-expiration JWT token expiration time (default: 60) --enable-guest-access Allow unauthenticated guest access --pam-service-name PAM service name (default: stable-diffusion-rest) --auth-data-dir Directory for authentication data (default: ./auth) --public-paths Comma-separated list of public paths (default: /api/health,/api/status) ``` ## Best Practices 1. **Principle of Least Privilege**: Only make endpoints public that are absolutely necessary 2. **Regular Security Reviews**: Periodically review your authentication configuration 3. **Monitor Access**: Log and monitor authentication attempts 4. **Use Strong Authentication**: Prefer JWT or PAM over simpler methods 5. **Secure Communication**: Always use HTTPS in production 6. **Token Management**: Implement proper token expiration and refresh mechanisms ## Conclusion The implementation of Issue #28 significantly improves the security posture of the stable-diffusion.cpp-rest server by ensuring that when authentication is enabled, login is truly forced and only explicitly configured endpoints remain publicly accessible. The changes provide administrators with fine-grained control over public endpoints while maintaining a secure default configuration. The implementation is backward compatible through the `--public-paths` configuration option, allowing existing deployments to migrate at their own pace while immediately benefiting from the improved security defaults.