# ADR-011: Development Authentication Mechanism ## Status Accepted ## Context During Phase 4 development (Web Interface), the team needs to test authentication-protected routes locally. However, IndieLogin.com requires: - A publicly accessible callback URL (HTTPS) - A real domain with valid DNS - External network connectivity This creates friction for local development: - Cannot test protected routes without deploying - Cannot run tests without network access - Cannot develop offline - Slow iteration cycle (deploy to test auth flows) The question: Should we implement a development-only authentication mechanism? ### Requirements for Dev Auth (if implemented) 1. **Must work for local testing** - Allow developers to authenticate locally 2. **Must be easy to use** - Minimal configuration required 3. **Must NEVER exist in production** - Critical security requirement 4. **Must integrate seamlessly** - Work with existing auth module 5. **Must allow protected route testing** - Enable full workflow testing 6. **Must not compromise security** - No backdoors in production code ### Security Criticality This is an extremely sensitive decision. Implemented incorrectly, a dev auth mechanism could: - Create a production authentication bypass - Expose admin functionality to attackers - Violate IndieWeb authentication principles - Undermine the entire security model ## Decision **YES - Implement a development authentication mechanism with strict safeguards** ### Approach: Environment-Based Toggle with Explicit Configuration We will implement a **separate development authentication pathway** that: 1. Only activates when explicitly configured 2. Uses a different route from production auth 3. Clearly indicates development mode 4. Requires explicit opt-in via environment variable 5. Logs prominent warnings when active 6. Cannot coexist with production configuration ### Implementation Design #### Configuration ```bash # Development mode (mutually exclusive) DEV_MODE=true DEV_ADMIN_ME=https://yoursite.com # Identity to simulate # Production mode DEV_MODE=false # or unset ADMIN_ME=https://yoursite.com SITE_URL=https://production.example.com ``` #### Route Structure ```python # Production authentication (always available) GET /admin/login # IndieLogin flow POST /admin/login # Initiate IndieLogin GET /auth/callback # IndieLogin callback POST /admin/logout # Logout # Development authentication (DEV_MODE only) GET /dev/login # Development login form POST /dev/login # Instant login (no external service) ``` #### Dev Auth Flow ```python # /dev/login (GET) def dev_login_form(): # Check DEV_MODE is enabled if not current_app.config.get('DEV_MODE'): abort(404) # Route doesn't exist in production # Render simple form or auto-login return render_template('dev/login.html') # /dev/login (POST) def dev_login(): # Check DEV_MODE is enabled if not current_app.config.get('DEV_MODE'): abort(404) # Get configured dev admin identity me = current_app.config.get('DEV_ADMIN_ME') # Create session directly (bypass IndieLogin) session_token = create_session(me) # Log warning current_app.logger.warning( f"DEV MODE: Created session for {me} without authentication" ) # Set cookie and redirect response = redirect('/admin') response.set_cookie('session', session_token, httponly=True, secure=False) return response ``` #### Safeguards **1. Route Registration Protection** ```python # In app.py or routes module def register_routes(app): # Always register production routes register_production_auth_routes(app) # Only register dev routes if DEV_MODE enabled if app.config.get('DEV_MODE'): app.logger.warning( "=" * 60 + "\n" "WARNING: Development authentication enabled!\n" "This should NEVER be used in production.\n" "Set DEV_MODE=false for production deployments.\n" + "=" * 60 ) register_dev_auth_routes(app) ``` **2. Configuration Validation** ```python def validate_config(app): dev_mode = app.config.get('DEV_MODE', False) if dev_mode: # Require DEV_ADMIN_ME if not app.config.get('DEV_ADMIN_ME'): raise ConfigError("DEV_MODE requires DEV_ADMIN_ME") # Prevent production config in dev mode if app.config.get('SITE_URL', '').startswith('https://'): app.logger.error( "WARNING: DEV_MODE with production SITE_URL detected" ) else: # Require production config if not app.config.get('ADMIN_ME'): raise ConfigError("Production mode requires ADMIN_ME") ``` **3. Visual Indicators** ```html {% if config.DEV_MODE %}
⚠️ DEVELOPMENT MODE - Authentication bypassed
{% endif %} ``` **4. Test Detection** ```python # In tests/conftest.py @pytest.fixture def app(): app = create_app() app.config['DEV_MODE'] = True app.config['DEV_ADMIN_ME'] = 'https://test.example.com' app.config['TESTING'] = True return app ``` ### File Organization ``` starpunk/ ├── auth.py # Production auth functions (unchanged) ├── dev_auth.py # Development auth functions (new) └── routes/ ├── auth.py # Production auth routes └── dev_auth.py # Dev auth routes (conditional registration) templates/ └── dev/ └── login.html # Simple dev login form ``` ## Rationale ### Why Implement Dev Auth? **Development Velocity**: 10/10 - Test protected routes instantly - No deployment required for auth testing - Faster iteration cycle - Enable offline development - Simplify CI/CD testing **Developer Experience**: 10/10 - Remove friction from local development - Make onboarding easier - Enable rapid prototyping - Reduce cognitive load **Testing Benefits**: 10/10 - Test auth flows without network - Deterministic test behavior - Faster test execution - Enable integration tests - Mock external dependencies ### Why This Specific Approach? **Separate Routes** (vs modifying production routes): - Clear separation of concerns - No conditional logic in production code - Easy to audit security - Impossible to accidentally enable in production **Explicit DEV_MODE** (vs detecting localhost): - Explicit is better than implicit - Prevents accidental activation - Clear intent in configuration - Works in any environment **Separate Configuration Variables** (vs reusing ADMIN_ME): - Prevents production config confusion - Makes dev mode obvious - Enables validation logic - Clear intent **Module Separation** (vs mixing in auth.py): - Production auth code stays clean - Easy to review for security - Can exclude from production builds - Clear architectural boundary ## Consequences ### Positive 1. **Faster Development** - Test auth flows without deployment 2. **Better Testing** - Comprehensive test coverage possible 3. **Offline Development** - No network dependency 4. **Simpler Onboarding** - New developers can start immediately 5. **CI/CD Friendly** - Tests run without external services 6. **Clear Separation** - Dev code isolated from production ### Negative 1. **Additional Code** - ~100 lines of dev-specific code 2. **Maintenance Burden** - Another code path to maintain 3. **Potential Misuse** - Could be accidentally enabled 4. **Security Risk** - If misconfigured, creates vulnerability ### Mitigations **For Accidental Activation**: - Startup warnings if DEV_MODE enabled - Configuration validation - Visual indicators in UI - Documentation emphasizing risk **For Security**: - Separate routes (not modifying production) - Explicit configuration required - 404 if DEV_MODE disabled - Logging all dev auth usage - Code review checklist **For Maintenance**: - Keep dev auth code simple - Document clearly - Include in test coverage - Regular security audits ## Alternatives Considered ### 1. No Dev Auth - Always Use IndieLogin (Rejected) **Approach**: Require deployment for auth testing **Pros**: - No security risk - No additional code - Forces realistic testing **Cons**: - Slow development cycle - Cannot test offline - Requires deployment infrastructure - Painful onboarding **Verdict**: Rejected - Too much friction for development --- ### 2. Mock IndieLogin in Tests Only (Rejected) **Approach**: Mock httpx responses in tests, no dev mode **Pros**: - Works for tests - No production risk - Simple implementation **Cons**: - Doesn't help manual testing - Cannot test in browser - Doesn't solve local development - Still requires deployment for UI testing **Verdict**: Rejected - Solves tests but not development workflow --- ### 3. Localhost Detection (Rejected) **Approach**: Auto-enable dev auth if running on localhost **Pros**: - No configuration needed - Automatic **Cons**: - Implicit behavior (dangerous) - Could run production on localhost - Hard to disable - Security through obscurity **Verdict**: Rejected - Too implicit, risky --- ### 4. Special Password (Rejected) **Approach**: Accept a special dev password for local auth **Pros**: - Familiar pattern - Easy to implement **Cons**: - Password in code or config - Could leak to production - Not IndieWeb-compatible - Defeats purpose of IndieLogin **Verdict**: Rejected - Undermines authentication model --- ### 5. Self-Hosted IndieAuth Server (Rejected) **Approach**: Run local IndieAuth server for development **Pros**: - Realistic auth flow - No dev auth code needed - Tests full integration **Cons**: - Complex setup - Additional service to run - Doesn't work offline - Violates simplicity principle **Verdict**: Rejected - Too complex for V1 --- ### 6. Session Injection via CLI (Considered) **Approach**: Command-line tool to create dev sessions directly in DB ```bash python -m starpunk dev-login --me https://test.com ``` **Pros**: - No web routes needed - Very explicit - Hard to misuse - Clean separation **Cons**: - Less convenient than web UI - Doesn't test login flow - Requires DB access - Extra tooling **Verdict**: Good alternative, but web route is more ergonomic --- ### 7. Separate Dev Auth Endpoint with Token (Considered) **Approach**: `/dev/auth?token=SECRET` route with shared secret **Pros**: - Prevents accidental use - Simple implementation - Works in browser **Cons**: - Secret in URL (logs) - Still a backdoor - Not much better than env var **Verdict**: Similar risk profile, less clear ## Implementation Phases ### Phase 1: Core Dev Auth (Phase 4) - Implement dev_auth.py module - Add DEV_MODE configuration - Create /dev/login routes - Add configuration validation - Update documentation ### Phase 2: Developer Experience (Phase 4) - Visual dev mode indicators - Startup warnings - Better error messages - Quick-start guide ### Phase 3: Security Hardening (Before v1.0) - Security audit of dev auth - Penetration testing - Code review checklist - Production deployment guide ## Security Checklist Before v1.0 release: - [ ] DEV_MODE defaults to false - [ ] Production docs emphasize security - [ ] Deployment guide includes check for DEV_MODE=false - [ ] Startup warnings are prominent - [ ] Routes return 404 when DEV_MODE=false - [ ] No way to enable DEV_MODE in production config - [ ] Security audit completed - [ ] Code review of dev auth implementation - [ ] Test that production build doesn't include dev routes - [ ] Documentation warns about risks ## Testing Strategy ### Unit Tests - Test dev auth functions in isolation - Test configuration validation - Test route registration logic - Test DEV_MODE toggle behavior ### Integration Tests - Test full dev auth flow - Test production auth still works - Test DEV_MODE disabled blocks dev routes - Test visual indicators appear ### Security Tests - Test dev routes return 404 in production mode - Test configuration validation catches mistakes - Test cannot enable with production URL - Test logging captures dev auth usage ## Documentation Requirements ### Developer Guide - How to enable DEV_MODE for local development - Clear warnings about production use - Explanation of security model - Troubleshooting guide ### Production Deployment Guide - Checklist to verify DEV_MODE=false - How to validate production configuration - What to check before deployment ### Security Documentation - Threat model for dev auth - Security trade-offs - Mitigation strategies - Incident response if misconfigured ## Success Criteria Dev auth implementation is successful if: 1. ✓ Developers can test protected routes locally 2. ✓ No production deployment needed for auth testing 3. ✓ Tests run without network dependencies 4. ✓ DEV_MODE cannot be accidentally enabled in production 5. ✓ Clear visual/log indicators when active 6. ✓ Production auth code remains unchanged 7. ✓ Security audit passes 8. ✓ Documentation is comprehensive ## References - [ADR-005: IndieLogin Authentication](/home/phil/Projects/starpunk/docs/decisions/ADR-005-indielogin-authentication.md) - [ADR-010: Authentication Module Design](/home/phil/Projects/starpunk/docs/decisions/ADR-010-authentication-module-design.md) - [OWASP Authentication Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html) - [The Twelve-Factor App - Dev/Prod Parity](https://12factor.net/dev-prod-parity) --- **ADR**: 011 **Date**: 2025-11-18 **Status**: Accepted **Decision**: Implement environment-based development authentication with strict safeguards **Impact**: Development workflow, testing, security architecture