# 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

```bash
# 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

```python
# 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

```python
# /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**
```python
# 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**
```python
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**
```html
<!-- 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**
```python
# 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

```bash
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-005: IndieLogin Authentication](/home/phil/Projects/starpunk/docs/decisions/ADR-005-indielogin-authentication.md)
- [ADR-010: Authentication Module Design](/home/phil/Projects/starpunk/docs/decisions/ADR-010-authentication-module-design.md)
- [OWASP Authentication Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html)
- [The Twelve-Factor App - Dev/Prod Parity](https://12factor.net/dev-prod-parity)

---

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