Files
StarPunk/docs/decisions/ADR-044-endpoint-discovery-implementation.md
Phil Skentelbery e589f5bd6c docs: Fix ADR numbering conflicts and create comprehensive documentation indices
This commit resolves all documentation issues identified in the comprehensive review:

CRITICAL FIXES:
- Renumbered duplicate ADRs to eliminate conflicts:
  * ADR-022-migration-race-condition-fix → ADR-037
  * ADR-022-syndication-formats → ADR-038
  * ADR-023-microformats2-compliance → ADR-040
  * ADR-027-versioning-strategy-for-authorization-removal → ADR-042
  * ADR-030-CORRECTED-indieauth-endpoint-discovery → ADR-043
  * ADR-031-endpoint-discovery-implementation → ADR-044

- Updated all cross-references to renumbered ADRs in:
  * docs/projectplan/ROADMAP.md
  * docs/reports/v1.0.0-rc.5-migration-race-condition-implementation.md
  * docs/reports/2025-11-24-endpoint-discovery-analysis.md
  * docs/decisions/ADR-043-CORRECTED-indieauth-endpoint-discovery.md
  * docs/decisions/ADR-044-endpoint-discovery-implementation.md

- Updated README.md version from 1.0.0 to 1.1.0
- Tracked ADR-021-indieauth-provider-strategy.md in git

DOCUMENTATION IMPROVEMENTS:
- Created comprehensive INDEX.md files for all docs/ subdirectories:
  * docs/architecture/INDEX.md (28 documents indexed)
  * docs/decisions/INDEX.md (55 ADRs indexed with topical grouping)
  * docs/design/INDEX.md (phase plans and feature designs)
  * docs/standards/INDEX.md (9 standards with compliance checklist)
  * docs/reports/INDEX.md (57 implementation reports)
  * docs/deployment/INDEX.md (deployment guides)
  * docs/examples/INDEX.md (code samples and usage patterns)
  * docs/migration/INDEX.md (version migration guides)
  * docs/releases/INDEX.md (release documentation)
  * docs/reviews/INDEX.md (architectural reviews)
  * docs/security/INDEX.md (security documentation)

- Updated CLAUDE.md with complete folder descriptions including:
  * docs/migration/
  * docs/releases/
  * docs/security/

VERIFICATION:
- All ADR numbers now sequential and unique (50 total ADRs)
- No duplicate ADR numbers remain
- All cross-references updated and verified
- Documentation structure consistent and well-organized

These changes improve documentation discoverability, maintainability, and
ensure proper version tracking. All index files follow consistent format
with clear navigation guidance.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 13:28:56 -07:00

3.5 KiB

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

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:

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)