Files
StarPunk/docs/decisions/ADR-011-development-authentication-mechanism.md
Phil Skentelbery 0cca8169ce feat: Implement Phase 4 Web Interface with bugfixes (v0.5.2)
## Phase 4: Web Interface Implementation

Implemented complete web interface with public and admin routes,
templates, CSS, and development authentication.

### Core Features

**Public Routes**:
- Homepage with recent published notes
- Note permalinks with microformats2
- Server-side rendering (Jinja2)

**Admin Routes**:
- Login via IndieLogin
- Dashboard with note management
- Create, edit, delete notes
- Protected with @require_auth decorator

**Development Authentication**:
- Dev login bypass for local testing (DEV_MODE only)
- Security safeguards per ADR-011
- Returns 404 when disabled

**Templates & Frontend**:
- Base layouts (public + admin)
- 8 HTML templates with microformats2
- Custom responsive CSS (114 lines)
- Error pages (404, 500)

### Bugfixes (v0.5.1 → v0.5.2)

1. **Cookie collision fix (v0.5.1)**:
   - Renamed auth cookie from "session" to "starpunk_session"
   - Fixed redirect loop between dev login and admin dashboard
   - Flask's session cookie no longer conflicts with auth

2. **HTTP 404 error handling (v0.5.1)**:
   - Update route now returns 404 for nonexistent notes
   - Delete route now returns 404 for nonexistent notes
   - Follows ADR-012 HTTP Error Handling Policy
   - Pattern consistency across all admin routes

3. **Note model enhancement (v0.5.2)**:
   - Exposed deleted_at field from database schema
   - Enables soft deletion verification in tests
   - Follows ADR-013 transparency principle

### Architecture

**New ADRs**:
- ADR-011: Development Authentication Mechanism
- ADR-012: HTTP Error Handling Policy
- ADR-013: Expose deleted_at Field in Note Model

**Standards Compliance**:
- Uses uv for Python environment
- Black formatted, Flake8 clean
- Follows git branching strategy
- Version incremented per versioning strategy

### Test Results

- 405/406 tests passing (99.75%)
- 87% code coverage
- All security tests passing
- Manual testing confirmed working

### Documentation

- Complete implementation reports in docs/reports/
- Architecture reviews in docs/reviews/
- Design documents in docs/design/
- CHANGELOG updated for v0.5.2

### Files Changed

**New Modules**:
- starpunk/dev_auth.py
- starpunk/routes/ (public, admin, auth, dev_auth)

**Templates**: 10 files (base, pages, admin, errors)
**Static**: CSS and optional JavaScript
**Tests**: 4 test files for routes and templates
**Docs**: 20+ architectural and implementation documents

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 23:01:53 -07:00

14 KiB

ADR-011: Development Authentication Mechanism

Status

Accepted

Context

During Phase 4 development (Web Interface), the team needs to test authentication-protected routes locally. However, IndieLogin.com requires:

  • A publicly accessible callback URL (HTTPS)
  • A real domain with valid DNS
  • External network connectivity

This creates friction for local development:

  • Cannot test protected routes without deploying
  • Cannot run tests without network access
  • Cannot develop offline
  • Slow iteration cycle (deploy to test auth flows)

The question: Should we implement a development-only authentication mechanism?

Requirements for Dev Auth (if implemented)

  1. Must work for local testing - Allow developers to authenticate locally
  2. Must be easy to use - Minimal configuration required
  3. Must NEVER exist in production - Critical security requirement
  4. Must integrate seamlessly - Work with existing auth module
  5. Must allow protected route testing - Enable full workflow testing
  6. Must not compromise security - No backdoors in production code

Security Criticality

This is an extremely sensitive decision. Implemented incorrectly, a dev auth mechanism could:

  • Create a production authentication bypass
  • Expose admin functionality to attackers
  • Violate IndieWeb authentication principles
  • Undermine the entire security model

Decision

YES - Implement a development authentication mechanism with strict safeguards

Approach: Environment-Based Toggle with Explicit Configuration

We will implement a separate development authentication pathway that:

  1. Only activates when explicitly configured
  2. Uses a different route from production auth
  3. Clearly indicates development mode
  4. Requires explicit opt-in via environment variable
  5. Logs prominent warnings when active
  6. Cannot coexist with production configuration

Implementation Design

Configuration

# Development mode (mutually exclusive)
DEV_MODE=true
DEV_ADMIN_ME=https://yoursite.com  # Identity to simulate

# Production mode
DEV_MODE=false  # or unset
ADMIN_ME=https://yoursite.com
SITE_URL=https://production.example.com

Route Structure

# Production authentication (always available)
GET  /admin/login          # IndieLogin flow
POST /admin/login          # Initiate IndieLogin
GET  /auth/callback        # IndieLogin callback
POST /admin/logout         # Logout

# Development authentication (DEV_MODE only)
GET  /dev/login            # Development login form
POST /dev/login            # Instant login (no external service)

Dev Auth Flow

# /dev/login (GET)
def dev_login_form():
    # Check DEV_MODE is enabled
    if not current_app.config.get('DEV_MODE'):
        abort(404)  # Route doesn't exist in production

    # Render simple form or auto-login
    return render_template('dev/login.html')

# /dev/login (POST)
def dev_login():
    # Check DEV_MODE is enabled
    if not current_app.config.get('DEV_MODE'):
        abort(404)

    # Get configured dev admin identity
    me = current_app.config.get('DEV_ADMIN_ME')

    # Create session directly (bypass IndieLogin)
    session_token = create_session(me)

    # Log warning
    current_app.logger.warning(
        f"DEV MODE: Created session for {me} without authentication"
    )

    # Set cookie and redirect
    response = redirect('/admin')
    response.set_cookie('session', session_token,
                       httponly=True, secure=False)
    return response

Safeguards

1. Route Registration Protection

# In app.py or routes module
def register_routes(app):
    # Always register production routes
    register_production_auth_routes(app)

    # Only register dev routes if DEV_MODE enabled
    if app.config.get('DEV_MODE'):
        app.logger.warning(
            "=" * 60 + "\n"
            "WARNING: Development authentication enabled!\n"
            "This should NEVER be used in production.\n"
            "Set DEV_MODE=false for production deployments.\n" +
            "=" * 60
        )
        register_dev_auth_routes(app)

2. Configuration Validation

def validate_config(app):
    dev_mode = app.config.get('DEV_MODE', False)

    if dev_mode:
        # Require DEV_ADMIN_ME
        if not app.config.get('DEV_ADMIN_ME'):
            raise ConfigError("DEV_MODE requires DEV_ADMIN_ME")

        # Prevent production config in dev mode
        if app.config.get('SITE_URL', '').startswith('https://'):
            app.logger.error(
                "WARNING: DEV_MODE with production SITE_URL detected"
            )
    else:
        # Require production config
        if not app.config.get('ADMIN_ME'):
            raise ConfigError("Production mode requires ADMIN_ME")

3. Visual Indicators

<!-- base.html template -->
{% if config.DEV_MODE %}
<div style="background: red; color: white; padding: 10px; text-align: center;">
  ⚠️ DEVELOPMENT MODE - Authentication bypassed
</div>
{% endif %}

4. Test Detection

# In tests/conftest.py
@pytest.fixture
def app():
    app = create_app()
    app.config['DEV_MODE'] = True
    app.config['DEV_ADMIN_ME'] = 'https://test.example.com'
    app.config['TESTING'] = True
    return app

File Organization

starpunk/
├── auth.py              # Production auth functions (unchanged)
├── dev_auth.py          # Development auth functions (new)
└── routes/
    ├── auth.py          # Production auth routes
    └── dev_auth.py      # Dev auth routes (conditional registration)

templates/
└── dev/
    └── login.html       # Simple dev login form

Rationale

Why Implement Dev Auth?

Development Velocity: 10/10

  • Test protected routes instantly
  • No deployment required for auth testing
  • Faster iteration cycle
  • Enable offline development
  • Simplify CI/CD testing

Developer Experience: 10/10

  • Remove friction from local development
  • Make onboarding easier
  • Enable rapid prototyping
  • Reduce cognitive load

Testing Benefits: 10/10

  • Test auth flows without network
  • Deterministic test behavior
  • Faster test execution
  • Enable integration tests
  • Mock external dependencies

Why This Specific Approach?

Separate Routes (vs modifying production routes):

  • Clear separation of concerns
  • No conditional logic in production code
  • Easy to audit security
  • Impossible to accidentally enable in production

Explicit DEV_MODE (vs detecting localhost):

  • Explicit is better than implicit
  • Prevents accidental activation
  • Clear intent in configuration
  • Works in any environment

Separate Configuration Variables (vs reusing ADMIN_ME):

  • Prevents production config confusion
  • Makes dev mode obvious
  • Enables validation logic
  • Clear intent

Module Separation (vs mixing in auth.py):

  • Production auth code stays clean
  • Easy to review for security
  • Can exclude from production builds
  • Clear architectural boundary

Consequences

Positive

  1. Faster Development - Test auth flows without deployment
  2. Better Testing - Comprehensive test coverage possible
  3. Offline Development - No network dependency
  4. Simpler Onboarding - New developers can start immediately
  5. CI/CD Friendly - Tests run without external services
  6. Clear Separation - Dev code isolated from production

Negative

  1. Additional Code - ~100 lines of dev-specific code
  2. Maintenance Burden - Another code path to maintain
  3. Potential Misuse - Could be accidentally enabled
  4. Security Risk - If misconfigured, creates vulnerability

Mitigations

For Accidental Activation:

  • Startup warnings if DEV_MODE enabled
  • Configuration validation
  • Visual indicators in UI
  • Documentation emphasizing risk

For Security:

  • Separate routes (not modifying production)
  • Explicit configuration required
  • 404 if DEV_MODE disabled
  • Logging all dev auth usage
  • Code review checklist

For Maintenance:

  • Keep dev auth code simple
  • Document clearly
  • Include in test coverage
  • Regular security audits

Alternatives Considered

1. No Dev Auth - Always Use IndieLogin (Rejected)

Approach: Require deployment for auth testing

Pros:

  • No security risk
  • No additional code
  • Forces realistic testing

Cons:

  • Slow development cycle
  • Cannot test offline
  • Requires deployment infrastructure
  • Painful onboarding

Verdict: Rejected - Too much friction for development


2. Mock IndieLogin in Tests Only (Rejected)

Approach: Mock httpx responses in tests, no dev mode

Pros:

  • Works for tests
  • No production risk
  • Simple implementation

Cons:

  • Doesn't help manual testing
  • Cannot test in browser
  • Doesn't solve local development
  • Still requires deployment for UI testing

Verdict: Rejected - Solves tests but not development workflow


3. Localhost Detection (Rejected)

Approach: Auto-enable dev auth if running on localhost

Pros:

  • No configuration needed
  • Automatic

Cons:

  • Implicit behavior (dangerous)
  • Could run production on localhost
  • Hard to disable
  • Security through obscurity

Verdict: Rejected - Too implicit, risky


4. Special Password (Rejected)

Approach: Accept a special dev password for local auth

Pros:

  • Familiar pattern
  • Easy to implement

Cons:

  • Password in code or config
  • Could leak to production
  • Not IndieWeb-compatible
  • Defeats purpose of IndieLogin

Verdict: Rejected - Undermines authentication model


5. Self-Hosted IndieAuth Server (Rejected)

Approach: Run local IndieAuth server for development

Pros:

  • Realistic auth flow
  • No dev auth code needed
  • Tests full integration

Cons:

  • Complex setup
  • Additional service to run
  • Doesn't work offline
  • Violates simplicity principle

Verdict: Rejected - Too complex for V1


6. Session Injection via CLI (Considered)

Approach: Command-line tool to create dev sessions directly in DB

python -m starpunk dev-login --me https://test.com

Pros:

  • No web routes needed
  • Very explicit
  • Hard to misuse
  • Clean separation

Cons:

  • Less convenient than web UI
  • Doesn't test login flow
  • Requires DB access
  • Extra tooling

Verdict: Good alternative, but web route is more ergonomic


7. Separate Dev Auth Endpoint with Token (Considered)

Approach: /dev/auth?token=SECRET route with shared secret

Pros:

  • Prevents accidental use
  • Simple implementation
  • Works in browser

Cons:

  • Secret in URL (logs)
  • Still a backdoor
  • Not much better than env var

Verdict: Similar risk profile, less clear

Implementation Phases

Phase 1: Core Dev Auth (Phase 4)

  • Implement dev_auth.py module
  • Add DEV_MODE configuration
  • Create /dev/login routes
  • Add configuration validation
  • Update documentation

Phase 2: Developer Experience (Phase 4)

  • Visual dev mode indicators
  • Startup warnings
  • Better error messages
  • Quick-start guide

Phase 3: Security Hardening (Before v1.0)

  • Security audit of dev auth
  • Penetration testing
  • Code review checklist
  • Production deployment guide

Security Checklist

Before v1.0 release:

  • DEV_MODE defaults to false
  • Production docs emphasize security
  • Deployment guide includes check for DEV_MODE=false
  • Startup warnings are prominent
  • Routes return 404 when DEV_MODE=false
  • No way to enable DEV_MODE in production config
  • Security audit completed
  • Code review of dev auth implementation
  • Test that production build doesn't include dev routes
  • Documentation warns about risks

Testing Strategy

Unit Tests

  • Test dev auth functions in isolation
  • Test configuration validation
  • Test route registration logic
  • Test DEV_MODE toggle behavior

Integration Tests

  • Test full dev auth flow
  • Test production auth still works
  • Test DEV_MODE disabled blocks dev routes
  • Test visual indicators appear

Security Tests

  • Test dev routes return 404 in production mode
  • Test configuration validation catches mistakes
  • Test cannot enable with production URL
  • Test logging captures dev auth usage

Documentation Requirements

Developer Guide

  • How to enable DEV_MODE for local development
  • Clear warnings about production use
  • Explanation of security model
  • Troubleshooting guide

Production Deployment Guide

  • Checklist to verify DEV_MODE=false
  • How to validate production configuration
  • What to check before deployment

Security Documentation

  • Threat model for dev auth
  • Security trade-offs
  • Mitigation strategies
  • Incident response if misconfigured

Success Criteria

Dev auth implementation is successful if:

  1. ✓ Developers can test protected routes locally
  2. ✓ No production deployment needed for auth testing
  3. ✓ Tests run without network dependencies
  4. ✓ DEV_MODE cannot be accidentally enabled in production
  5. ✓ Clear visual/log indicators when active
  6. ✓ Production auth code remains unchanged
  7. ✓ Security audit passes
  8. ✓ Documentation is comprehensive

References


ADR: 011 Date: 2025-11-18 Status: Accepted Decision: Implement environment-based development authentication with strict safeguards Impact: Development workflow, testing, security architecture