# ADR-031: IndieAuth Endpoint Discovery Implementation Details ## Status Accepted ## Context The developer raised critical implementation questions about ADR-030-CORRECTED regarding IndieAuth endpoint discovery. The primary blocker was the "chicken-and-egg" problem: when receiving a token, how do we know which endpoint to verify it with? ## Decision For StarPunk V1 (single-user CMS), we will: 1. **ALWAYS use ADMIN_ME for endpoint discovery** when verifying tokens 2. **Use simple caching structure** optimized for single-user 3. **Add BeautifulSoup4** as a dependency for robust HTML parsing 4. **Fail closed** on security errors with cache grace period 5. **Allow HTTP in debug mode** for local development ### Core Implementation ```python def verify_external_token(token: str) -> Optional[Dict[str, Any]]: """Verify token - single-user V1 implementation""" admin_me = current_app.config.get("ADMIN_ME") # Always discover from ADMIN_ME (single-user assumption) endpoints = discover_endpoints(admin_me) token_endpoint = endpoints['token_endpoint'] # Verify and validate token belongs to admin token_info = verify_with_endpoint(token_endpoint, token) if normalize_url(token_info['me']) != normalize_url(admin_me): raise TokenVerificationError("Token not for admin user") return token_info ``` ## Rationale ### Why ADMIN_ME Discovery? StarPunk V1 is explicitly single-user. Only the admin can post, so any valid token MUST belong to ADMIN_ME. This eliminates the chicken-and-egg problem entirely. ### Why Simple Cache? With only one user, we don't need complex profile->endpoints mapping. A simple cache suffices: ```python class EndpointCache: def __init__(self): self.endpoints = None # Single user's endpoints self.endpoints_expire = 0 self.token_cache = {} # token_hash -> (info, expiry) ``` ### Why BeautifulSoup4? - Industry standard for HTML parsing - More robust than regex or built-in parsers - Pure Python implementation available - Worth the dependency for correctness ### Why Fail Closed? Security principle: when in doubt, deny access. We use cached endpoints as a grace period during network failures, but ultimately deny access if we cannot verify. ## Consequences ### Positive - Eliminates complexity of multi-user endpoint discovery - Simple, clear implementation path - Secure by default - Easy to test and verify ### Negative - Will need refactoring for V2 multi-user support - Adds BeautifulSoup4 dependency - First request after cache expiry has ~850ms latency ### Migration Impact - Breaking change: TOKEN_ENDPOINT config removed - Users must update configuration - Clear deprecation warnings provided ## Alternatives Considered ### Alternative 1: Require 'me' Parameter **Rejected**: Would violate Micropub specification ### Alternative 2: Try Multiple Endpoints **Rejected**: Complex, slow, and unnecessary for single-user ### Alternative 3: Pre-warm Cache **Rejected**: Adds complexity for minimal benefit ## Implementation Timeline - **v1.0.0-rc.5**: Full implementation with migration guide - Remove TOKEN_ENDPOINT configuration - Add endpoint discovery from ADMIN_ME - Document single-user assumption ## Testing Strategy - Unit tests with mocked HTTP responses - Edge case coverage (malformed HTML, network errors) - One integration test with real IndieAuth.com - Skip real provider tests in CI (manual testing only) ## References - W3C IndieAuth Specification Section 4.2 (Discovery) - ADR-043-CORRECTED (Original design) - Developer analysis report (2025-11-24)