Files
StarPunk/docs/decisions/ADR-050-remove-custom-indieauth-server.md
Phil Skentelbery a3bac86647 feat: Complete IndieAuth server removal (Phases 2-4)
Completed all remaining phases of ADR-030 IndieAuth provider removal.
StarPunk no longer acts as an authorization server - all IndieAuth
operations delegated to external providers.

Phase 2 - Remove Token Issuance:
- Deleted /auth/token endpoint
- Removed token_endpoint() function from routes/auth.py
- Deleted tests/test_routes_token.py

Phase 3 - Remove Token Storage:
- Deleted starpunk/tokens.py module entirely
- Created migration 004 to drop tokens and authorization_codes tables
- Deleted tests/test_tokens.py
- Removed all internal token CRUD operations

Phase 4 - External Token Verification:
- Created starpunk/auth_external.py module
- Implemented verify_external_token() for external IndieAuth providers
- Updated Micropub endpoint to use external verification
- Added TOKEN_ENDPOINT configuration
- Updated all Micropub tests to mock external verification
- HTTP timeout protection (5s) for external requests

Additional Changes:
- Created migration 003 to remove code_verifier from auth_state
- Fixed 5 migration tests that referenced obsolete code_verifier column
- Updated 11 Micropub tests for external verification
- Fixed test fixture and app context issues
- All 501 tests passing

Breaking Changes:
- Micropub clients must use external IndieAuth providers
- TOKEN_ENDPOINT configuration now required
- Existing internal tokens invalid (tables dropped)

Migration Impact:
- Simpler codebase: -500 lines of code
- Fewer database tables: -2 tables (tokens, authorization_codes)
- More secure: External providers handle token security
- More maintainable: Less authentication code to maintain

Standards Compliance:
- W3C IndieAuth specification
- OAuth 2.0 Bearer token authentication
- IndieWeb principle: delegate to external services

Related:
- ADR-030: IndieAuth Provider Removal Strategy
- ADR-050: Remove Custom IndieAuth Server
- Migration 003: Remove code_verifier from auth_state
- Migration 004: Drop tokens and authorization_codes tables

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 17:23:46 -07:00

12 KiB

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:
    -- 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:

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:
    <link rel="authorization_endpoint" href="https://indieauth.com/auth">
    <link rel="token_endpoint" href="https://tokens.indieauth.com/token">
    
  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

# 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


Document Version: 1.0 Created: 2025-11-24 Author: StarPunk Architecture Team Status: Proposed