# ADR-050: Remove Custom IndieAuth Server ## Status Proposed ## Context StarPunk currently includes a custom IndieAuth authorization server implementation that: - Provides authorization endpoint (`/auth/authorization`) - Provides token issuance endpoint (`/auth/token`) - Manages authorization codes and access tokens - Implements PKCE for security - Stores hashed tokens in the database However, this violates our core philosophy of "every line of code must justify its existence." The custom authorization server adds significant complexity without clear benefit, as users can use external IndieAuth providers like indieauth.com and tokens.indieauth.com. ### Current Architecture Problems 1. **Unnecessary Complexity**: ~500+ lines of authorization/token management code 2. **Security Burden**: We're responsible for secure token generation, storage, and validation 3. **Maintenance Overhead**: Must keep up with IndieAuth spec changes and security updates 4. **Database Bloat**: Two additional tables for codes and tokens 5. **Confusion**: Mixing authorization server and resource server responsibilities ### Proposed Architecture StarPunk should be a pure Micropub server that: - Accepts Bearer tokens in the Authorization header - Verifies tokens with the user's configured token endpoint - Does NOT issue tokens or handle authorization - Uses external providers for all IndieAuth functionality ## Decision Remove all custom IndieAuth authorization server code and rely entirely on external providers. ### What Gets Removed 1. **Python Modules**: - `/home/phil/Projects/starpunk/starpunk/tokens.py` - Entire file - Authorization endpoint code from `/home/phil/Projects/starpunk/starpunk/routes/auth.py` - Token endpoint code from `/home/phil/Projects/starpunk/starpunk/routes/auth.py` 2. **Templates**: - `/home/phil/Projects/starpunk/templates/auth/authorize.html` - Authorization consent UI 3. **Database**: - `authorization_codes` table - `tokens` table - Migration: `/home/phil/Projects/starpunk/migrations/002_secure_tokens_and_authorization_codes.sql` 4. **Tests**: - `/home/phil/Projects/starpunk/tests/test_tokens.py` - `/home/phil/Projects/starpunk/tests/test_routes_authorization.py` - `/home/phil/Projects/starpunk/tests/test_routes_token.py` - `/home/phil/Projects/starpunk/tests/test_auth_pkce.py` ### What Gets Modified 1. **Micropub Token Verification** (`/home/phil/Projects/starpunk/starpunk/micropub.py`): - Replace local token lookup with external token endpoint verification - Use token introspection endpoint to validate tokens 2. **Configuration** (`/home/phil/Projects/starpunk/starpunk/config.py`): - Add `TOKEN_ENDPOINT` setting for external provider - Remove any authorization server settings 3. **HTML Headers** (base template): - Add link tags pointing to external providers - Remove references to local authorization endpoints 4. **Admin Auth** (`/home/phil/Projects/starpunk/starpunk/routes/auth.py`): - Keep IndieLogin.com integration for admin sessions - Remove authorization/token endpoint routes ## Rationale ### Simplicity Score: 10/10 - Removes ~500+ lines of complex security code - Eliminates two database tables - Reduces attack surface - Clearer separation of concerns ### Maintenance Score: 10/10 - No security updates for auth code - No spec compliance to maintain - External providers handle all complexity - Focus on core CMS functionality ### Standards Compliance: Pass - Still fully IndieAuth compliant - Better separation of resource server vs authorization server - Follows IndieWeb principle of using existing infrastructure ### User Impact: Minimal - Users already need to configure their domain - External providers are free and require no registration - Better security (specialized providers) - More flexibility in provider choice ## Implementation Plan ### Phase 1: Remove Authorization Server (Day 1) **Goal**: Remove authorization endpoint and consent UI **Tasks**: 1. Delete `/home/phil/Projects/starpunk/templates/auth/authorize.html` 2. Remove `authorization_endpoint()` from `/home/phil/Projects/starpunk/starpunk/routes/auth.py` 3. Delete `/home/phil/Projects/starpunk/tests/test_routes_authorization.py` 4. Delete `/home/phil/Projects/starpunk/tests/test_auth_pkce.py` 5. Remove PKCE-related functions from auth module 6. Update route tests to not expect /auth/authorization **Verification**: - Server starts without errors - Admin login still works - No references to authorization endpoint in codebase ### Phase 2: Remove Token Issuance (Day 1) **Goal**: Remove token endpoint and generation logic **Tasks**: 1. Remove `token_endpoint()` from `/home/phil/Projects/starpunk/starpunk/routes/auth.py` 2. Delete `/home/phil/Projects/starpunk/tests/test_routes_token.py` 3. Remove token generation functions from `/home/phil/Projects/starpunk/starpunk/tokens.py` 4. Remove authorization code exchange logic **Verification**: - Server starts without errors - No references to token issuance in codebase ### Phase 3: Simplify Database Schema (Day 2) **Goal**: Remove authorization and token tables **Tasks**: 1. Create new migration to drop tables: ```sql -- 003_remove_indieauth_server_tables.sql DROP TABLE IF EXISTS authorization_codes; DROP TABLE IF EXISTS tokens; ``` 2. Remove `/home/phil/Projects/starpunk/migrations/002_secure_tokens_and_authorization_codes.sql` 3. Update schema documentation 4. Run migration on test database **Verification**: - Database migration succeeds - No orphaned foreign keys - Application starts without database errors ### Phase 4: Update Micropub Token Verification (Day 2) **Goal**: Use external token endpoint for verification **New Implementation**: ```python def verify_token(bearer_token: str) -> Optional[Dict[str, Any]]: """ Verify token with external token endpoint Args: bearer_token: Token from Authorization header Returns: Token info if valid, None otherwise """ token_endpoint = current_app.config['TOKEN_ENDPOINT'] try: response = httpx.get( token_endpoint, headers={'Authorization': f'Bearer {bearer_token}'} ) if response.status_code != 200: return None data = response.json() # Verify token is for our user if data.get('me') != current_app.config['ADMIN_ME']: return None # Check scope if 'create' not in data.get('scope', ''): return None return data except Exception: return None ``` **Tasks**: 1. Replace `verify_token()` in `/home/phil/Projects/starpunk/starpunk/micropub.py` 2. Add `TOKEN_ENDPOINT` to config with default `https://tokens.indieauth.com/token` 3. Remove local database token lookup 4. Update Micropub tests to mock external verification **Verification**: - Micropub endpoint accepts valid tokens - Rejects invalid tokens - Proper error responses ### Phase 5: Documentation and Configuration (Day 3) **Goal**: Update all documentation and add discovery headers **Tasks**: 1. Update base template with IndieAuth discovery: ```html ``` 2. Update README with setup instructions 3. Create user guide for configuring external providers 4. Update architecture documentation 5. Update CHANGELOG.md 6. Increment version per versioning strategy **Verification**: - Discovery links present in HTML - Documentation accurate and complete - Version number updated ## Rollback Strategy ### Immediate Rollback If critical issues found during implementation: 1. **Git Revert**: Revert the removal commits 2. **Database Restore**: Re-run migration 002 to recreate tables 3. **Config Restore**: Revert configuration changes 4. **Test Suite**: Run full test suite to verify restoration ### Gradual Rollback If issues found in production: 1. **Feature Flag**: Add config flag to toggle between internal/external auth 2. **Dual Mode**: Support both modes temporarily 3. **Migration Path**: Give users time to switch 4. **Deprecation**: Mark internal auth as deprecated ## Testing Strategy ### Unit Tests to Update - Remove all token generation/validation tests - Update Micropub tests to mock external verification - Keep admin authentication tests ### Integration Tests - Test Micropub with mock external token endpoint - Test admin login flow (unchanged) - Test token rejection scenarios ### Manual Testing Checklist - [ ] Admin can log in via IndieLogin.com - [ ] Micropub accepts valid Bearer tokens - [ ] Micropub rejects invalid tokens - [ ] Micropub rejects tokens with wrong scope - [ ] Discovery links present in HTML - [ ] Documentation explains external provider setup ## Acceptance Criteria ### Must Work 1. Admin authentication via IndieLogin.com 2. Micropub token verification via external endpoint 3. Proper error responses for invalid tokens 4. HTML discovery links for IndieAuth endpoints ### Must Not Exist 1. No authorization endpoint (`/auth/authorization`) 2. No token endpoint (`/auth/token`) 3. No authorization consent UI 4. No token storage in database 5. No PKCE implementation ### Performance Criteria 1. Token verification < 500ms (external API call) 2. Consider caching valid tokens for 5 minutes 3. No database queries for token validation ## Version Impact Per `/home/phil/Projects/starpunk/docs/standards/versioning-strategy.md`: This is a **breaking change** that removes functionality: - Removes authorization server endpoints - Changes token verification method - Requires external provider configuration **Version Change**: 0.4.0 → 0.5.0 (minor version bump for breaking change in 0.x) ## Consequences ### Positive - **Massive Simplification**: ~500+ lines removed - **Better Security**: Specialized providers handle auth - **Less Maintenance**: No security updates needed - **Clearer Architecture**: Pure Micropub server - **Standards Compliant**: Better separation of concerns ### Negative - **External Dependency**: Requires internet connection for token verification - **Latency**: External API calls for each request (mitigate with caching) - **Not Standalone**: Cannot work in isolated environment ### Neutral - **User Configuration**: Users must set up external providers (already required) - **Provider Choice**: Users can choose any IndieAuth provider ## Alternatives Considered ### Keep Internal Auth as Option **Rejected**: Violates simplicity principle, maintains complexity ### Token Caching/Storage **Consider**: Cache validated tokens for performance - Store token hash + expiry in memory/Redis - Reduce external API calls - Implement in Phase 4 if needed ### Offline Mode **Rejected**: Incompatible with external verification - Could allow "trust mode" for development - Not suitable for production ## Migration Path for Existing Users ### For Users with Existing Tokens 1. Tokens become invalid after upgrade 2. Must re-authenticate with external provider 3. Document in upgrade notes ### Configuration Changes ```ini # OLD (remove these) # AUTHORIZATION_ENDPOINT=/auth/authorization # TOKEN_ENDPOINT=/auth/token # NEW (add these) ADMIN_ME=https://user-domain.com TOKEN_ENDPOINT=https://tokens.indieauth.com/token ``` ### User Communication 1. Announce breaking change in release notes 2. Provide migration guide 3. Explain benefits of simplification ## Success Metrics ### Code Metrics - Lines of code removed: ~500+ - Test coverage maintained > 90% - Cyclomatic complexity reduced ### Operational Metrics - Zero security vulnerabilities in auth code (none to maintain) - Token verification latency < 500ms - 100% compatibility with IndieAuth clients ## References - [IndieAuth Spec](https://www.w3.org/TR/indieauth/) - [tokens.indieauth.com](https://tokens.indieauth.com/) - [ADR-021: IndieAuth Provider Strategy](/home/phil/Projects/starpunk/docs/decisions/ADR-021-indieauth-provider-strategy.md) - [Micropub Spec](https://www.w3.org/TR/micropub/) --- **Document Version**: 1.0 **Created**: 2025-11-24 **Author**: StarPunk Architecture Team **Status**: Proposed