# IndieAuth Removal: Phased Implementation Guide ## Overview This document breaks down the IndieAuth server removal into testable phases, each with clear acceptance criteria and verification steps. ## Phase 1: Remove Authorization Server (4 hours) ### Objective Remove the authorization endpoint and consent UI while keeping the system functional. ### Tasks #### 1.1 Remove Authorization UI (30 min) ```bash # Delete consent template rm /home/phil/Projects/starpunk/templates/auth/authorize.html # Verify ls /home/phil/Projects/starpunk/templates/auth/ # Should be empty or not exist ``` #### 1.2 Remove Authorization Endpoint (1 hour) In `/home/phil/Projects/starpunk/starpunk/routes/auth.py`: - Delete `authorization_endpoint()` function - Delete related imports from `starpunk.tokens` - Keep admin auth routes intact #### 1.3 Remove Authorization Tests (30 min) ```bash # Delete test files rm /home/phil/Projects/starpunk/tests/test_routes_authorization.py rm /home/phil/Projects/starpunk/tests/test_auth_pkce.py ``` #### 1.4 Remove PKCE Implementation (1 hour) From `/home/phil/Projects/starpunk/starpunk/auth.py`: - Remove `generate_code_verifier()` - Remove `calculate_code_challenge()` - Remove PKCE validation logic - Keep session management functions #### 1.5 Update Route Registration (30 min) Ensure no references to `/auth/authorization` in: - URL route definitions - Template URL generation - Documentation ### Acceptance Criteria ✅ **Server Starts Successfully** ```bash uv run python -m starpunk # No import errors or missing route errors ``` ✅ **Admin Login Works** ```bash # Navigate to /admin/login # Can still authenticate via IndieLogin.com # Session created successfully ``` ✅ **No Authorization Endpoint** ```bash curl -I http://localhost:5000/auth/authorization # Should return 404 Not Found ``` ✅ **Tests Pass (Remaining)** ```bash uv run pytest tests/ -k "not authorization and not pkce" # All remaining tests pass ``` ### Verification Commands ```bash # Check for orphaned imports grep -r "authorization_endpoint" /home/phil/Projects/starpunk/ # Should return nothing # Check for PKCE references grep -r "code_challenge\|code_verifier" /home/phil/Projects/starpunk/ # Should only appear in migration files or comments ``` --- ## Phase 2: Remove Token Issuance (3 hours) ### Objective Remove token generation and issuance while keeping token verification temporarily. ### Tasks #### 2.1 Remove Token Endpoint (1 hour) In `/home/phil/Projects/starpunk/starpunk/routes/auth.py`: - Delete `token_endpoint()` function - Remove token-related imports #### 2.2 Remove Token Generation (1 hour) In `/home/phil/Projects/starpunk/starpunk/tokens.py`: - Remove `create_access_token()` - Remove `create_authorization_code()` - Remove `exchange_authorization_code()` - Keep `verify_token()` temporarily (will modify in Phase 4) #### 2.3 Remove Token Tests (30 min) ```bash rm /home/phil/Projects/starpunk/tests/test_routes_token.py rm /home/phil/Projects/starpunk/tests/test_tokens.py ``` #### 2.4 Clean Up Exceptions (30 min) Remove custom exceptions: - `InvalidAuthorizationCodeError` - `ExpiredAuthorizationCodeError` - Update error handling to use generic exceptions ### Acceptance Criteria ✅ **No Token Endpoint** ```bash curl -I http://localhost:5000/auth/token # Should return 404 Not Found ``` ✅ **No Token Generation Code** ```bash grep -r "create_access_token\|create_authorization_code" /home/phil/Projects/starpunk/starpunk/ # Should return nothing (except in comments) ``` ✅ **Server Still Runs** ```bash uv run python -m starpunk # No import errors ``` ✅ **Micropub Temporarily Broken (Expected)** ```bash # This is expected and will be fixed in Phase 4 # Document that Micropub is non-functional during migration ``` ### Verification Commands ```bash # Check for token generation references grep -r "generate_token\|issue_token" /home/phil/Projects/starpunk/ # Should be empty # Verify exception cleanup grep -r "InvalidAuthorizationCodeError" /home/phil/Projects/starpunk/ # Should be empty ``` --- ## Phase 3: Database Schema Simplification (2 hours) ### Objective Remove authorization and token tables from the database. ### Tasks #### 3.1 Create Removal Migration (30 min) Create `/home/phil/Projects/starpunk/migrations/003_remove_indieauth_tables.sql`: ```sql -- Remove IndieAuth server tables BEGIN TRANSACTION; -- Drop dependent objects first DROP INDEX IF EXISTS idx_tokens_hash; DROP INDEX IF EXISTS idx_tokens_user_id; DROP INDEX IF EXISTS idx_tokens_client_id; DROP INDEX IF EXISTS idx_auth_codes_code; DROP INDEX IF EXISTS idx_auth_codes_user_id; -- Drop tables DROP TABLE IF EXISTS tokens CASCADE; DROP TABLE IF EXISTS authorization_codes CASCADE; -- Clean up any orphaned sequences DROP SEQUENCE IF EXISTS tokens_id_seq; DROP SEQUENCE IF EXISTS authorization_codes_id_seq; COMMIT; ``` #### 3.2 Run Migration (30 min) ```bash # Backup database first pg_dump $DATABASE_URL > backup_before_removal.sql # Run migration uv run python -m starpunk.migrate ``` #### 3.3 Update Schema Documentation (30 min) Update `/home/phil/Projects/starpunk/docs/design/database-schema.md`: - Remove token table documentation - Remove authorization_codes table documentation - Update ER diagram #### 3.4 Remove Old Migration (30 min) ```bash # Archive old migration mv /home/phil/Projects/starpunk/migrations/002_secure_tokens_and_authorization_codes.sql \ /home/phil/Projects/starpunk/migrations/archive/ ``` ### Acceptance Criteria ✅ **Tables Removed** ```sql -- Connect to database and verify \dt -- Should NOT list 'tokens' or 'authorization_codes' ``` ✅ **No Foreign Key Errors** ```sql -- Check for orphaned constraints SELECT conname FROM pg_constraint WHERE conname LIKE '%token%' OR conname LIKE '%auth%'; -- Should return minimal results (only auth_state related) ``` ✅ **Application Starts** ```bash uv run python -m starpunk # No database connection errors ``` ✅ **Admin Functions Work** - Can log in - Can create posts - Sessions persist ### Rollback Plan ```bash # If issues arise psql $DATABASE_URL < backup_before_removal.sql # Re-run old migration psql $DATABASE_URL < /home/phil/Projects/starpunk/migrations/archive/002_secure_tokens_and_authorization_codes.sql ``` --- ## Phase 4: External Token Verification (4 hours) ### Objective Replace internal token verification with external provider verification. ### Tasks #### 4.1 Implement External Verification (2 hours) Create new verification in `/home/phil/Projects/starpunk/starpunk/micropub.py`: ```python import hashlib import httpx from typing import Optional, Dict, Any from flask import current_app # Simple in-memory cache _token_cache = {} def verify_token(bearer_token: str) -> Optional[Dict[str, Any]]: """Verify token with external endpoint""" # Check cache token_hash = hashlib.sha256(bearer_token.encode()).hexdigest() if token_hash in _token_cache: data, expiry = _token_cache[token_hash] if time.time() < expiry: return data del _token_cache[token_hash] # Verify with external endpoint endpoint = current_app.config.get('TOKEN_ENDPOINT') if not endpoint: return None try: response = httpx.get( endpoint, headers={'Authorization': f'Bearer {bearer_token}'}, timeout=5.0 ) if response.status_code != 200: return None data = response.json() # Validate response if data.get('me') != current_app.config.get('ADMIN_ME'): return None if 'create' not in data.get('scope', '').split(): return None # Cache for 5 minutes _token_cache[token_hash] = (data, time.time() + 300) return data except Exception as e: current_app.logger.error(f"Token verification failed: {e}") return None ``` #### 4.2 Update Configuration (30 min) In `/home/phil/Projects/starpunk/starpunk/config.py`: ```python # External IndieAuth settings TOKEN_ENDPOINT = os.getenv('TOKEN_ENDPOINT', 'https://tokens.indieauth.com/token') ADMIN_ME = os.getenv('ADMIN_ME') # Required # Validate configuration if not ADMIN_ME: raise ValueError("ADMIN_ME must be configured") ``` #### 4.3 Remove Old Token Module (30 min) ```bash rm /home/phil/Projects/starpunk/starpunk/tokens.py ``` #### 4.4 Update Tests (1 hour) Update `/home/phil/Projects/starpunk/tests/test_micropub.py`: ```python @patch('starpunk.micropub.httpx.get') def test_external_token_verification(mock_get): mock_response = Mock() mock_response.status_code = 200 mock_response.json.return_value = { 'me': 'https://example.com', 'scope': 'create update' } mock_get.return_value = mock_response # Test verification result = verify_token('test-token') assert result is not None assert result['me'] == 'https://example.com' ``` ### Acceptance Criteria ✅ **External Verification Works** ```bash # With a valid token from tokens.indieauth.com curl -X POST http://localhost:5000/micropub \ -H "Authorization: Bearer VALID_TOKEN" \ -H "Content-Type: application/json" \ -d '{"type": ["h-entry"], "properties": {"content": ["Test"]}}' # Should return 201 Created ``` ✅ **Invalid Tokens Rejected** ```bash curl -X POST http://localhost:5000/micropub \ -H "Authorization: Bearer INVALID_TOKEN" \ -H "Content-Type: application/json" \ -d '{"type": ["h-entry"], "properties": {"content": ["Test"]}}' # Should return 403 Forbidden ``` ✅ **Token Caching Works** ```python # In test environment token = "test-token" result1 = verify_token(token) # External call result2 = verify_token(token) # Should use cache # Verify only one external call made ``` ✅ **Configuration Validated** ```bash # Without ADMIN_ME set unset ADMIN_ME uv run python -m starpunk # Should fail with clear error message ``` ### Performance Verification ```bash # Measure token verification time time curl -X GET http://localhost:5000/micropub \ -H "Authorization: Bearer VALID_TOKEN" \ -w "\nTime: %{time_total}s\n" # First call: <500ms # Cached calls: <50ms ``` --- ## Phase 5: Documentation and Discovery (2 hours) ### Objective Update all documentation and add proper IndieAuth discovery headers. ### Tasks #### 5.1 Add Discovery Links (30 min) In `/home/phil/Projects/starpunk/templates/base.html`: ```html
``` #### 5.2 Update User Documentation (45 min) Create `/home/phil/Projects/starpunk/docs/user-guide/indieauth-setup.md`: ```markdown # Setting Up IndieAuth for StarPunk ## Quick Start 1. Add these links to your personal website's HTML: ```html ``` 2. Configure StarPunk: ```ini ADMIN_ME=https://your-website.com TOKEN_ENDPOINT=https://tokens.indieauth.com/token ``` 3. Use any Micropub client! ``` #### 5.3 Update README (15 min) - Remove references to built-in authorization - Add "Prerequisites" section about external IndieAuth - Update configuration examples #### 5.4 Update CHANGELOG (15 min) ```markdown ## [0.5.0] - 2025-11-24 ### BREAKING CHANGES - Removed built-in IndieAuth authorization server - Removed token issuance functionality - All existing tokens are invalidated ### Changed - Token verification now uses external IndieAuth providers - Simplified database schema (removed token tables) - Reduced codebase by ~500 lines ### Added - Support for external token endpoints - Token verification caching for performance - IndieAuth discovery links in HTML ### Migration Guide Users must now: 1. Configure external IndieAuth provider 2. Re-authenticate with Micropub clients 3. Update ADMIN_ME configuration ``` #### 5.5 Version Bump (15 min) Update `/home/phil/Projects/starpunk/starpunk/__init__.py`: ```python __version__ = "0.5.0" # Breaking change per versioning strategy ``` ### Acceptance Criteria ✅ **Discovery Links Present** ```bash curl http://localhost:5000/ | grep -E "authorization_endpoint|token_endpoint|micropub" # Should show all three link tags ``` ✅ **Documentation Complete** - [ ] User guide explains external provider setup - [ ] README reflects new architecture - [ ] CHANGELOG documents breaking changes - [ ] Migration guide provided ✅ **Version Updated** ```bash uv run python -c "import starpunk; print(starpunk.__version__)" # Should output: 0.5.0 ``` ✅ **Examples Work** - [ ] Example configuration in docs is valid - [ ] HTML snippet in docs is correct - [ ] Micropub client setup instructions tested --- ## Final Validation Checklist ### System Health - [ ] Server starts without errors - [ ] Admin can log in - [ ] Admin can create posts - [ ] Micropub endpoint responds - [ ] Valid tokens accepted - [ ] Invalid tokens rejected - [ ] HTML has discovery links ### Code Quality - [ ] No orphaned imports - [ ] No references to removed code - [ ] Tests pass with >90% coverage - [ ] No security warnings ### Performance - [ ] Token verification <500ms - [ ] Cached verification <50ms - [ ] Memory usage stable - [ ] No database deadlocks ### Documentation - [ ] Architecture docs updated - [ ] User guide complete - [ ] API docs accurate - [ ] CHANGELOG updated - [ ] Version bumped ### Database - [ ] Old tables removed - [ ] No orphaned constraints - [ ] Migration successful - [ ] Backup available ## Rollback Decision Tree ``` Issue Detected? ├─ During Phase 1-2? │ └─ Git revert commits │ └─ Restart server ├─ During Phase 3? │ └─ Restore database backup │ └─ Git revert commits │ └─ Restart server └─ During Phase 4-5? └─ Critical issue? ├─ Yes: Full rollback │ └─ Restore DB + revert code └─ No: Fix forward └─ Patch issue └─ Continue deployment ``` ## Success Metrics ### Quantitative - **Lines removed**: >500 - **Test coverage**: >90% - **Token verification**: <500ms - **Cache hit rate**: >90% - **Memory stable**: <100MB ### Qualitative - **Simpler architecture**: Clear separation of concerns - **Better security**: Specialized providers handle auth - **Less maintenance**: No auth code to maintain - **User flexibility**: Choice of providers - **Standards compliant**: Pure Micropub server ## Risk Matrix | Risk | Probability | Impact | Mitigation | |------|------------|---------|------------| | Breaking existing tokens | Certain | Medium | Clear communication, migration guide | | External service down | Low | High | Token caching, timeout handling | | User confusion | Medium | Low | Comprehensive documentation | | Performance degradation | Low | Medium | Caching layer, monitoring | | Security vulnerability | Low | High | Use established providers | --- **Document Version**: 1.0 **Created**: 2025-11-24 **Author**: StarPunk Architecture Team **Status**: Ready for Implementation