Files
StarPunk/docs/reports/micropub-401-diagnosis.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

5.0 KiB

Micropub 401 Unauthorized Error - Architectural Diagnosis

Issue Summary

The Micropub endpoint is returning 401 Unauthorized when accessed from Quill, a Micropub client. The request GET /micropub?q=config fails with a 401 response.

Root Cause Analysis

After reviewing the implementation, I've identified the primary issue:

The IndieAuth/Micropub Authentication Flow is Not Complete

The user (Quill client) has not completed the IndieAuth authorization flow to obtain an access token. The 401 error is occurring because:

  1. No Bearer Token Provided: Quill is attempting to query the Micropub config endpoint without providing an access token
  2. No Token Exists: The database shows 0 tokens and 0 authorization codes, indicating no IndieAuth flow has been completed

Authentication Flow Requirements

For Quill to successfully access the Micropub endpoint, it needs to:

  1. Complete IndieAuth Authorization:

    • Quill should redirect user to /auth/authorization
    • User logs in as admin (if not already logged in)
    • User approves Quill's authorization request
    • Authorization code is generated
  2. Exchange Code for Token:

    • Quill exchanges authorization code at /auth/token
    • Access token is generated and stored (hashed)
    • Token is returned to Quill
  3. Use Token for Micropub Requests:

    • Quill includes token in Authorization header: Bearer {token}
    • Or as query parameter: ?access_token={token}

Current Implementation Status

Correctly Implemented

  1. Micropub Endpoint (/micropub):

    • Properly extracts bearer token from header or parameter
    • Validates token by hash lookup
    • Returns appropriate 401 when token missing/invalid
  2. Token Security:

    • Tokens stored as SHA256 hashes (secure)
    • Database schema correct with proper indexes
    • Token expiry and revocation support
  3. Authorization Endpoint (/auth/authorization):

    • Accepts IndieAuth parameters
    • Requires admin login for authorization
    • Generates authorization codes with PKCE support
  4. Token Endpoint (/auth/token):

    • Exchanges authorization codes for access tokens
    • Validates all required parameters including me
    • Implements PKCE verification when used

Missing/Issues

  1. No Discovery Mechanism:

    • The site needs to advertise its IndieAuth endpoints
    • Missing <link> tags in HTML or HTTP headers
    • Quill can't discover where to authorize
  2. No Existing Tokens:

    • Database shows no tokens have been created
    • User has not gone through authorization flow

Solution Steps

Immediate Fix - Manual Authorization

  1. Direct Quill to Authorization Endpoint:

    https://your-site.com/auth/authorization?
      response_type=code&
      client_id=https://quill.p3k.io/&
      redirect_uri=https://quill.p3k.io/auth/callback&
      state={random}&
      scope=create&
      me=https://example.com
    
  2. Complete the Flow:

    • Log in as admin when prompted
    • Approve Quill's authorization request
    • Let Quill exchange code for token
    • Token will be stored and usable

Permanent Fix - Add Discovery

The site needs to advertise its IndieAuth endpoints. Add to the home page HTML <head>:

<link rel="authorization_endpoint" href="/auth/authorization">
<link rel="token_endpoint" href="/auth/token">
<link rel="micropub" href="/micropub">

Or return as HTTP Link headers:

Link: </auth/authorization>; rel="authorization_endpoint"
Link: </auth/token>; rel="token_endpoint"
Link: </micropub>; rel="micropub"

Verification Steps

  1. Check if authorization works:

    • Navigate to /auth/authorization with proper parameters
    • Should see authorization consent form after admin login
  2. Verify token creation:

    SELECT COUNT(*) FROM tokens;
    SELECT COUNT(*) FROM authorization_codes;
    
  3. Test with curl after getting token:

    curl -H "Authorization: Bearer {token}" \
         "http://localhost:5000/micropub?q=config"
    

Configuration Notes

From .env file:

  • Site URL: http://localhost:5000
  • Admin ME: https://example.com
  • Database: ./data/starpunk.db
  • Dev Mode: enabled

Summary

The 401 error is expected behavior when no access token is provided. The issue is not a bug in the code, but rather that:

  1. Quill hasn't completed the IndieAuth flow to obtain a token
  2. The site doesn't advertise its IndieAuth endpoints for discovery

The implementation is architecturally sound and follows IndieAuth/Micropub specifications correctly. The user needs to:

  1. Complete the authorization flow through Quill
  2. Add endpoint discovery to the site

Architectural Recommendations

  1. Add endpoint discovery to enable automatic client configuration
  2. Consider adding a token management UI for the admin to see/revoke tokens
  3. Add logging for authentication failures to aid debugging
  4. Document the IndieAuth flow for users setting up Micropub clients

Date: 2024-11-24 Architect: StarPunk Architecture Team Status: Diagnosis Complete