## 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>
6.5 KiB
Cookie Naming Convention
Status: ACTIVE Date: 2025-11-18 Version: 1.0
Purpose
This document establishes the naming convention for HTTP cookies in StarPunk to prevent conflicts with web framework reserved names and ensure clear ownership of cookie data.
Standard
All StarPunk application cookies MUST use the starpunk_ prefix to avoid conflicts with framework-reserved names.
Rationale
Problem: Cookie name collision between application cookies and framework cookies can cause unexpected behavior. In Phase 4, we discovered that using a cookie named session conflicted with Flask's server-side session mechanism, causing an authentication redirect loop.
Solution: Namespace all application cookies with an application-specific prefix.
Reserved Names (DO NOT USE)
The following cookie names are reserved by frameworks and libraries. StarPunk MUST NOT use these names:
Flask Framework
session- Reserved for Flask's server-side session (used by flash messages, session storage)
Common Auth Frameworks
csrf_token- Common CSRF protection cookie nameremember_token- Common "remember me" authenticationauth_token- Generic authentication token
Generic Reserved Names
Avoid any single-word generic names that might conflict with frameworks or browsers:
tokenuseriddatastate
StarPunk Cookie Names
All StarPunk cookies use the starpunk_ prefix for clear ownership.
Current Cookies
| Cookie Name | Purpose | Security Attributes | Max Age |
|---|---|---|---|
starpunk_session |
Authentication session token | HttpOnly, Secure (prod), SameSite=Lax | 30 days |
Future Cookies
All future cookies must:
- Use
starpunk_prefix - Be documented in this table
- Have explicit security attributes defined
- Be reviewed for conflicts with framework conventions
Example future cookies:
starpunk_preferences- User preferences (if added)starpunk_analytics- Analytics consent (if added)starpunk_theme- Theme selection (if added)
Security Attributes
All StarPunk cookies MUST specify these security attributes:
Required Attributes
HttpOnly:
- Use for authentication and sensitive cookies
- Prevents JavaScript access
- Mitigates XSS attacks
Secure:
- Use in production (HTTPS)
- Can be
Falsein development (HTTP) - Prevents transmission over unencrypted connections
SameSite:
- Use
LaxorStrict - Prevents CSRF attacks
Laxallows top-level navigation with cookieStrictnever sends cookie cross-site
Max-Age:
- Always set explicit expiry
- Don't rely on session cookies (cleared on browser close)
- Choose appropriate lifetime for use case
Example
response.set_cookie(
"starpunk_session", # Name with prefix
session_token, # Value
httponly=True, # Prevent JS access
secure=is_production, # HTTPS only in prod
samesite="Lax", # CSRF protection
max_age=30 * 24 * 60 * 60, # 30 days
)
Implementation Checklist
When adding a new cookie:
- Name uses
starpunk_prefix - Name doesn't conflict with framework/library cookies
- Purpose is documented in this file
- Security attributes are explicitly set
- HttpOnly is used for sensitive data
- Secure is conditional on production vs development
- SameSite is set (Lax or Strict)
- Max-Age is appropriate for use case
- Cookie is reviewed by architect
- Tests verify cookie behavior
- Cookie is documented in API contracts
Reading Cookies
When reading cookies, always use the full prefixed name:
# Correct
session_token = request.cookies.get("starpunk_session")
# Incorrect - missing prefix
session_token = request.cookies.get("session")
Deletion
When deleting cookies, use the same name that was used to set them:
# Correct
response.delete_cookie("starpunk_session")
# Incorrect - missing prefix
response.delete_cookie("session")
Framework Cookie Coexistence
StarPunk and Flask cookies can coexist without conflict:
StarPunk cookies:
starpunk_session- Application authentication
Flask cookies (framework-managed):
session- Flask server-side session (for flash messages)
Both are necessary and serve different purposes. Do not interfere with Flask's session cookie.
Migration Notes
Version 0.5.1 Migration
Breaking Change: Authentication cookie renamed from session to starpunk_session.
Impact: All existing authenticated users were logged out and needed to re-authenticate.
Reason: Fix critical authentication redirect loop caused by cookie name collision.
Future Migrations: If cookie names need to change, consider:
- Dual-cookie period (read from both old and new)
- Client-side cookie migration via JavaScript
- Clear documentation of breaking change
- User communication about re-authentication
Validation
During Development
- Review cookie names in code review
- Check for
starpunk_prefix - Verify security attributes are set
- Test with browser DevTools → Application → Cookies
During Testing
- Automated tests should verify cookie names
- Integration tests should check cookie attributes
- Browser tests should verify cookie behavior
Example Test
def test_auth_cookie_name(client):
"""Test authentication uses correct cookie name"""
response = client.post("/dev/login")
# Verify correct cookie name
assert "starpunk_session" in response.headers.getlist("Set-Cookie")
# Verify does not use reserved name
cookies_str = str(response.headers.getlist("Set-Cookie"))
assert "session=" not in cookies_str or "starpunk_session=" in cookies_str
References
Internal Documentation
- Auth Redirect Loop Fix:
/docs/reports/2025-11-18-auth-redirect-loop-fix.md - ADR-011: Development Authentication Mechanism
- ADR-005: IndieLogin Authentication
External Standards
- RFC 6265 - HTTP State Management Mechanism (Cookies)
- Flask Session Documentation
- OWASP Session Management Cheat Sheet
History
Version 1.0 (2025-11-18)
- Initial version
- Established
starpunk_prefix convention - Documented reserved names
- Added security attribute requirements
- Created as part of auth redirect loop fix (v0.5.1)
Document Owner: StarPunk Architecture Team Last Updated: 2025-11-18 Status: Active Standard