Dropdown viser begge arbeidsflater med absolutte URLer (ws.synops.no og adm.synops.no). Navigasjon mellom subdomener fungerer uten å miste sesjon. Erfaringsnotat: multi-subdomain med SvelteKit — ORIGIN-fellen, cookie-domene, CSRF, OIDC redirect URIs, sjekkliste for nye subdomener. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4.2 KiB
Erfaring: Multi-subdomain med SvelteKit (mars 2026)
Kontekst
Innføring av adm.synops.no som admin-domene ved siden av
ws.synops.no (app) avslørte flere arkitekturelle blindsoner.
Problemer vi møtte
1. ORIGIN låser hostname
Symptom: event.url.hostname returnerte alltid ws.synops.no
uansett hvilken Host-header som kom inn.
Årsak: ORIGIN=https://ws.synops.no i .env. SvelteKit
adapter-node bruker ORIGIN for å konstruere event.url — den
overskriver Host-headeren.
Løsning: Fjern ORIGIN. AUTH_TRUST_HOST=true lar SvelteKit
lese hostname fra selve HTTP Host-headeren.
Læring: ORIGIN er ment for single-origin deployments. Multi-subdomain krever at SvelteKit leser Host dynamisk.
2. Session-cookie bundet til ett subdomain
Symptom: Login på ws.synops.no ga ikke tilgang til
adm.synops.no. Brukeren ble bedt om å logge inn igjen.
Årsak: Session-cookie var satt med domain=ws.synops.no
(default). Cookien var ikke tilgjengelig for adm.synops.no.
Løsning: Sett cookie-domene til .synops.no i auth.ts.
Alle subdomener deler sesjonen.
Læring: Wildcard cookie-domene (.synops.no) er nødvendig
når flere subdomener trenger samme autentisering. Det er trygt
så lenge alle subdomener er under vår kontroll.
3. CSRF cross-origin blokkering
Symptom: Cross-site POST form submissions are forbidden
ved login-callback fra Authentik.
Årsak: SvelteKit sin innebygde CSRF-sjekk sammenligner
request origin mot ORIGIN-variabelen. POST fra adm.synops.no
til OIDC-callback ble blokkert.
Løsning: csrf: { checkOrigin: false } i svelte.config.js.
Trygt fordi OIDC bruker PKCE + state som CSRF-beskyttelse.
Læring: SvelteKit sin CSRF-sjekk er for streng for multi-origin. Deaktiver den når du har egen CSRF-mekanisme.
4. Authentik redirect URI
Symptom: OIDC-callback feilet fordi adm.synops.no ikke
var registrert som gyldig redirect URI.
Årsak: Bare ws.synops.no var registrert i Authentik.
Løsning: Legg til adm.synops.no/auth/callback/authentik
i Authentik sin provider-konfig.
Læring: Hvert subdomain trenger egen redirect URI i OIDC.
5. TLS-sertifikat
Ikke et problem: Caddy henter automatisk sertifikat for
nye domener via Let's Encrypt ACME. adm.synops.no fikk
sertifikat i løpet av sekunder ved første request.
Læring: Caddy sin auto-TLS er utmerket for nye subdomener. Bare legg til i Caddyfile og restart.
Arkitekturprinsipper vi trekker ut
1. Ikke hardkod hostnames i konfigfiler
ORIGIN, cookie-domene, redirect URIs — alt som binder til
et spesifikt hostname gjør multi-subdomain vanskelig.
Foretrekk dynamisk host-deteksjon (AUTH_TRUST_HOST=true).
2. Cookies på toppdomenet for relaterte subdomener
Når flere subdomener trenger samme sesjon, sett cookie på
.synops.no. CSRF-token kan forbli host-bound (__Host-
prefix) for ekstra sikkerhet.
3. Samme SvelteKit-instans for alle subdomener
Ikke kjør separate SvelteKit-instanser per subdomain. Én instans som leser hostname og tilpasser seg. Enklere deploy, delt kodebase, felles sesjon.
4. Caddy gjør routing, SvelteKit gjør logikk
Caddy ruter domene → SvelteKit. SvelteKit sjekker hostname og tilpasser innhold. Caddy trenger ingen hostname-logikk utover reverse proxy.
Hva ble gjort riktig
- Caddy-konfig: Enkelt å legge til nytt subdomain
- Delt SvelteKit: Ingen duplisert kode
- Cookie-wildcard: Riktig for relaterte subdomener
- AUTH_TRUST_HOST: Fungerer godt uten ORIGIN
Hva vi tenderer til å glemme
- ORIGIN-variabelen — den overstyrer alt. Sjekk den først.
- Cookie-domene — default er gjeldende hostname, ikke parent.
- OIDC redirect URIs — må oppdateres for hvert nytt domene.
- Be bruker slette cookies — gammel cookie fra ett domene kræsjer med ny cookie fra wildcard-domenet.
Sjekkliste for nytt subdomain
- DNS A-record (Hetzner DNS Console)
- Caddy-blokk i Caddyfile (auto-TLS)
- Authentik redirect URI
- Verifiser at ORIGIN ikke er satt (eller er kompatibel)
- Verifiser cookie-domene (
.synops.no) - Test: login → callback → riktig side
- Be bruker slette cookies hvis problemer