# Gateway Trust Model ## Architecture All frontend requests go through: Browser → Pangolin → frontend-v2 (SvelteKit hooks) → gateway → backend services. ## Authentication Layers ### Gateway (platform auth) - Users authenticate via `/api/auth/login` with username/password (bcrypt) - Session stored as `platform_session` cookie (HttpOnly, Secure, SameSite=Lax) - All `(app)` routes require valid session (checked in `+layout.server.ts`) ### Service-level auth Each backend service has its own auth mechanism. The gateway injects credentials when proxying: | Service | Auth Type | Injected By Gateway | Validated Against | |---------|-----------|--------------------|--------------------| | Trips | Bearer token | `Authorization: Bearer {token}` | `/api/trips` (protected endpoint) | | Fitness | Bearer token | `Authorization: Bearer {token}` | `/api/user` (protected endpoint) | | Reader | API key | `X-Auth-Token: {key}` | `/v1/feeds/counters` | | Inventory | API key | `X-API-Key: {key}` | `/summary` | | Budget | API key | `X-API-Key: {key}` | `/summary` | | Books (Shelfmark) | None (proxied) | — | Gateway auth only | | Music (Spotizerr) | None (proxied) | — | Gateway auth only | ### Frontend hooks auth (SvelteKit) - Immich proxy: validates `platform_session` cookie before proxying - Karakeep proxy: validates `platform_session` cookie before proxying - Legacy trips Immich: validates `platform_session` cookie before proxying ## Service Connections - Users connect services via Settings page - Token validation uses a **protected endpoint**, not health checks - Unknown services cannot be connected (rejected with 400) - Tokens stored in `service_connections` table, per-user ## Internal Network - All services communicate on Docker internal network - No service port is exposed to the host (except frontend-v2 via Pangolin) - Gateway is the single entry point for all API traffic ## TLS - External HTTPS: default TLS verification (certificate + hostname) - Internal services: `_internal_ssl_ctx` with verification disabled (Docker services don't have valid certs) - Image proxy: default TLS verification + domain allowlist ## Secrets - All secrets loaded from environment variables - No hardcoded credentials in code - `.env` files excluded from git - Admin credentials required via `ADMIN_USERNAME`/`ADMIN_PASSWORD` env vars