Implements tag/category system backend following microformats2 p-category specification. Database changes: - Migration 008: Add tags and note_tags tables - Normalized tag storage (case-insensitive lookup, display name preserved) - Indexes for performance New module: - starpunk/tags.py: Tag management functions - normalize_tag: Normalize tag strings - get_or_create_tag: Get or create tag records - add_tags_to_note: Associate tags with notes (replaces existing) - get_note_tags: Retrieve note tags (alphabetically ordered) - get_tag_by_name: Lookup tag by normalized name - get_notes_by_tag: Get all notes with specific tag - parse_tag_input: Parse comma-separated tag input Model updates: - Note.tags property (lazy-loaded, prefer pre-loading in routes) - Note.to_dict() add include_tags parameter CRUD updates: - create_note() accepts tags parameter - update_note() accepts tags parameter (None = no change, [] = remove all) Micropub integration: - Pass tags to create_note() (tags already extracted by extract_tags()) - Return tags in q=source response Per design doc: docs/design/v1.3.0/microformats-tags-design.md Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
6.9 KiB
IndieAuth Architecture Assessment
Date: 2025-11-24 Author: StarPunk Architect Status: Critical Review
Executive Summary
You asked: "WHY? Why not use an established provider like indieauth for authorization and token?"
The honest answer: The current decision to implement our own authorization and token endpoints appears to be based on a fundamental misunderstanding of how IndieAuth works, combined with over-engineering for a single-user system.
Current Implementation Reality
StarPunk has already implemented its own authorization and token endpoints:
/auth/authorization- Full authorization endpoint (327 lines of code)/auth/token- Full token endpoint implementation- Complete authorization code flow with PKCE support
- Token generation, storage, and validation
This represents significant complexity that may not have been necessary.
The Core Misunderstanding
ADR-021 reveals the critical misunderstanding that drove this decision:
"The user reported that IndieLogin.com requires manual client_id registration, making it unsuitable for self-hosted software"
This is completely false. IndieAuth (including IndieLogin.com) requires no registration whatsoever. Each self-hosted instance uses its own domain as the client_id automatically.
What StarPunk Actually Needs
For a single-user personal CMS, StarPunk needs:
-
Admin Authentication: Log the owner into the admin panel
- ✅ Currently uses IndieLogin.com correctly
- Works perfectly, no changes needed
-
Micropub Token Verification: Verify tokens from Micropub clients
- Only needs to verify tokens, not issue them
- Could delegate entirely to the user's chosen authorization server
The Architectural Options
Option A: Use External Provider (Recommended for Simplicity)
How it would work:
-
User adds these links to their personal website:
<link rel="authorization_endpoint" href="https://indielogin.com/auth"> <link rel="token_endpoint" href="https://tokens.indieauth.com/token"> <link rel="micropub" href="https://starpunk.example/micropub"> -
Micropub clients discover endpoints from user's site
-
Clients get tokens from indieauth.com/tokens.indieauth.com
-
StarPunk only verifies tokens (10-20 lines of code)
Benefits:
- ✅ Simplicity: 95% less code
- ✅ Security: Maintained by IndieAuth experts
- ✅ Reliability: Battle-tested infrastructure
- ✅ Standards: Full spec compliance guaranteed
- ✅ Zero maintenance: No security updates needed
Drawbacks:
- ❌ Requires user to configure their personal domain
- ❌ Dependency on external service
- ❌ User needs to understand IndieAuth flow
Option B: Implement Own Endpoints (Current Approach)
What we've built:
- Complete authorization endpoint
- Complete token endpoint
- Authorization codes table
- Token management system
- PKCE support
- Scope validation
Benefits:
- ✅ Self-contained system
- ✅ No external dependencies for Micropub
- ✅ User doesn't need separate domain configuration
- ✅ Complete control over auth flow
Drawbacks:
- ❌ Complexity: 500+ lines of auth code
- ❌ Security burden: We maintain all security
- ❌ Over-engineered: For a single-user system
- ❌ Spec compliance: Our responsibility
- ❌ Maintenance: Ongoing updates needed
My Honest Assessment
Was This the Right Decision?
No, probably not. For a single-user personal CMS that values simplicity:
- We solved a problem that didn't exist (registration requirement)
- We added unnecessary complexity (500+ lines vs 20 lines)
- We took on security responsibilities unnecessarily
- We violated our core principle: "Every line of code must justify its existence"
Why Did This Happen?
- Misunderstanding: Believed IndieAuth required registration
- Scope creep: Wanted StarPunk to be "complete"
- Over-engineering: Built for theoretical multi-user future
- Momentum: Once started, kept building
What Should We Do Now?
Option 1: Keep Current Implementation (Pragmatic)
Since it's already built and working:
- Document it properly
- Security audit the implementation
- Add comprehensive tests
- Accept the maintenance burden
Rationale: Sunk cost, but functional. Changing now adds work.
Option 2: Simplify to External Provider (Purist)
Remove our endpoints and use external providers:
- Delete
/auth/authorizationand/auth/token - Keep only admin auth via IndieLogin
- Add token verification for Micropub
- Document user setup clearly
Rationale: Aligns with simplicity principle, reduces attack surface.
Option 3: Hybrid Approach (Recommended)
Keep implementation but make it optional:
- Default: Use external providers (simple)
- Advanced: Enable built-in endpoints (self-contained)
- Configuration flag:
INDIEAUTH_MODE = "external" | "builtin"
Rationale: Best of both worlds, user choice.
My Recommendation
For V1 Release
Keep the current implementation but:
- Document the trade-offs clearly
- Add configuration option to disable built-in endpoints
- Provide clear setup guides for both modes:
- Simple mode: Use external providers
- Advanced mode: Use built-in endpoints
- Security audit the implementation thoroughly
For V2 Consideration
- Measure actual usage: Do users want built-in auth?
- Consider removing if external providers work well
- Or enhance if users value self-contained nature
The Real Question
You asked "WHY?" The honest answer:
We built our own auth endpoints because we misunderstood IndieAuth and over-engineered for a single-user system. It wasn't necessary, but now that it's built, it does provide a self-contained solution that some users might value.
Architecture Principles Violated
- ✗ Minimal Code: Added 500+ lines unnecessarily
- ✗ Simplicity First: Chose complex over simple
- ✗ YAGNI: Built for imagined requirements
- ✗ Single Responsibility: StarPunk is a CMS, not an auth server
Architecture Principles Upheld
- ✓ Standards Compliance: Full IndieAuth spec implementation
- ✓ No Lock-in: Users can switch providers
- ✓ Self-hostable: Complete solution in one package
Conclusion
The decision to implement our own authorization and token endpoints was architecturally questionable for a minimal single-user CMS. It adds complexity without proportional benefit.
However, since it's already implemented:
- We should keep it for V1 (pragmatism over purity)
- Make it optional via configuration
- Document both approaches clearly
- Re-evaluate based on user feedback
The lesson: Always challenge requirements and complexity. Just because we can build something doesn't mean we should.
"Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away." - Antoine de Saint-Exupéry
This applies directly to StarPunk's auth architecture.