Add SESSION_COOKIE_DOMAIN so /admin SSR sees the session cookie

Production splits web (descrybe.io) and API (api.descrybe.io). The session
cookie was host-only for api.descrybe.io, so the browser never sent it to
the web host. The /admin SvelteKit SSR gate (fetchMeStaff in
+layout.server.ts) forwards the incoming cookie header to /api/auth/me —
with no cookie to forward it always got 401 and bounced every successful
login back to /login?next=/admin (login POST 200, /me 200 from the
browser, /me 401 from the web server).

New SESSION_COOKIE_DOMAIN env (default empty = host-only, local dev
unchanged) sets the session cookie Domain attribute; set it to the parent
domain (descrybe.io) in production so both hosts receive the cookie.
Leading dot is normalized away. CSRF needs no change — it already seeds
cross-origin via the X-CSRF-Token response header.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-18 00:31:58 +02:00
co-authored by Claude Fable 5
parent b595398389
commit 0eef202f56
6 changed files with 35 additions and 5 deletions
+5
View File
@@ -36,6 +36,7 @@ type Config struct {
// (e.g. redis/postgres) so boot can warn that memory was forced.
RateLimitBackendRequested string
SessionCookieName string
SessionCookieDomain string
SessionSecure bool
CSRFCookieName string
PublicAPIURL string
@@ -141,6 +142,10 @@ func Load() (Config, error) {
RateLimitMultiReplica: getenvBool("RATE_LIMIT_MULTI_REPLICA", false),
RateLimitBackend: "memory",
SessionCookieName: getenv("SESSION_COOKIE_NAME", "descrybe_session"),
// Empty = host-only cookie (localhost). Set to the parent domain
// (e.g. descrybe.io) when web + api run on sibling subdomains so
// SvelteKit SSR (descrybe.io) receives the session cookie too.
SessionCookieDomain: getenv("SESSION_COOKIE_DOMAIN", ""),
// Default Secure=true when APP_ENV is production|prod so cookies are HTTPS-only
// even if SESSION_SECURE is unset; explicit false still fails closed in validate.
SessionSecure: getenvBool("SESSION_SECURE", isProductionEnvValue(appEnv)),