Files
headquarter/openspec/changes/oauth-traefik-integration/design.md
T
Fusion 577b052c05 feat: implement user profile management and oauth/traefik integration
User Profile (US-004):
- Add authenticated profile endpoints (GET/PUT /users/me)
- Add avatar upload with file validation (PNG/JPEG, max 2MB)
- Create frontend profile page with edit form and avatar upload
- Update app shell to link to profile page

OAuth/Traefik Integration:
- Externalize all Authentik URLs to environment variables
- Add domain configuration (API_DOMAIN, WEB_DOMAIN, AUTHENTIK_DOMAIN)
- Create docker-compose.traefik.yml for reverse proxy deployment
- Update OAuth redirect/callback URLs to use configured domains
- Add VITE_APP_URL for frontend public URL configuration

Quality gates: pytest (50 passed), ruff, mypy, npm test (12 passed), typecheck, lint, build
2026-05-17 23:17:10 +02:00

3.6 KiB

Context

The current docker-compose.yml is a standalone development setup without reverse proxy support. The API has hardcoded Authentik URLs in config.py (https://authentik.local/...) which makes it impossible to deploy in real environments without code changes. The frontend also hardcodes VITE_API_URL=http://localhost:8000.

For production deployment, the platform needs to work behind an existing Traefik reverse proxy (common in self-hosted stacks) and have all external service endpoints fully configurable.

Goals / Non-Goals

Goals:

  • Make all Authentik URLs configurable via environment variables (no hardcoded defaults).
  • Make OAuth redirect/callback URLs configurable and domain-aware.
  • Create docker-compose.traefik.yml for deployment behind an existing Traefik instance.
  • Support configuring the public web domain, API domain, and Authentik domain via env vars.
  • Ensure both development (docker-compose.yml) and traefik modes work correctly.

Non-Goals:

  • Setting up Traefik itself (assumes existing Traefik instance).
  • Authentik installation/configuration (assumes existing Authentik instance).
  • SSL certificate management (handled by Traefik).
  • Changing the authentication flow or token logic.

Decisions

  1. Remove all hardcoded URLs from config.py and require env vars

    • Rationale: Deployment environments have different domains. Hardcoded values are a deployment blocker.
    • Alternative: Keep defaults and override in prod. Rejected because defaults mask configuration errors.
  2. Use API_DOMAIN and WEB_DOMAIN env vars for constructing public URLs

    • Rationale: Centralizes domain configuration and makes it easy to switch between dev/prod.
    • API_PUBLIC_URL will default to http://${API_DOMAIN} or can be overridden.
    • WEB_PUBLIC_URL will default to http://${WEB_DOMAIN} or can be overridden.
  3. Create a separate docker-compose.traefik.yml instead of modifying the existing one

    • Rationale: The existing docker-compose.yml is for standalone development. Traefik deployment is a different topology.
    • Alternative: Use compose profiles or overrides. Rejected to keep each file simple and explicit.
  4. Add VITE_APP_URL for the frontend so it knows its public URL

    • Rationale: OAuth redirect URI needs to be absolute and must match the public web URL.
    • Frontend will use this for login redirect if needed.
  5. Use Traefik labels for routing instead of ports

    • Rationale: Standard Traefik pattern - services are discovered via Docker labels.
    • No port mappings exposed; Traefik handles all ingress.

Risks / Trade-offs

  • [Missing env vars cause startup failures] -> Document all required variables in .env.example and add validation in config.py.
  • [OAuth redirect URI mismatch] -> Ensure the redirect URI configured in Authentik matches the env-configured callback URL exactly.
  • [Local development still works] -> Keep docker-compose.yml unchanged for dev; traefik file is additive.
  • [Cookie secure flag] -> Ensure cookie_secure property in config reads from env properly for HTTPS deployments.

Migration Plan

  1. Update config.py to read all Authentik URLs from environment with no defaults.
  2. Update auth.py to construct redirect/callback URLs from env-configured domains.
  3. Update .env.example with all new variables.
  4. Create docker-compose.traefik.yml with Traefik labels.
  5. Test that both docker-compose.yml (dev) and docker-compose.traefik.yml (prod) work.

Rollback:

  • Revert config.py and auth.py changes; remove docker-compose.traefik.yml.

Open Questions

  • Should we add a startup health check that validates all required env vars are set?