Arkitektur
Næsten hvert SaaS-MVP ender med at spørge: hvordan holder vi kundernes data adskilt? Svaret bliver ofte enten "vi tænker på det senere" (dyrt) eller "vi bygger enterprise-isolation fra dag ét" (også dyrt). Begge ekstremister har ret i noget — og begge tager fejl i timing.
Multi-tenant er ikke én arkitektur. Det er en familie af valg om data, auth og drift. Det her er den beslutningsrækkefølge vi selv bruger, når vi bygger eller refactorer et produkt.
TL;DR
De vigtigste pointer
- Start med organisation som førsteklasses begreb — også i en single-tenant MVP. Det er billigt tidligt og dyrt sent.
- Shared database + Row Level Security i Postgres er det rigtige default for de fleste B2B-SaaS.
- Schema- eller database-per-tenant er til compliance, støjende naboer eller kunder der kontraktligt kræver det — ikke til vanity.
- UI-filtre er ikke isolation. Garantien skal ligge i databasen eller i et tilsvarende autoritativt lag.
- SSO, audit-logs og "organisationer i organisationer" kan vente til der er en konkret kunde der kræver dem.
Hvad "tenant" egentlig betyder
En tenant er den grænse I sælger og isolerer imod — typisk en virksomhedskunde (organisation). Inde i den har I brugere, roller og data. Uden for den må intet lække. Det lyder banalt, indtil queries begynder at joine på tværs, webhooks mangler org-scope, eller en support-admin ser forkert kundedata fordi et filter manglede i UI'et.
Derfor starter god multi-tenant ikke med Kubernetes-namespaces. Den starter med en datamodel hvor næsten hver forretningstabel har et `organization_id` (eller tilsvarende), og hvor applikationen aldrig stoler på at klienten "husker" hvilken org den er i.
Hvis jeres MVP kun har én kunde i produktion, skal I stadig modellere organisationen. I behøver ikke tre isoleringslag — I behøver ét konsekvent.
Shared database vs. stærkere isolation
Shared database (med RLS)
Én Postgres, tenant-scope i hver række, politikker der håndhæver adgang.
- Hurtigst at bygge og migrere
- Én pipeline, ét schema, én backup-strategi
- RLS som sikkerhedsnet under applikationsfejlen
- Kræver disciplin i queries og tests
- Nogle enterprise-kunder vil kræve mere senere
Schema- eller DB-per-tenant
Stærkere isolation — og markant mere drift.
- Tydeligere compliance-historie for enkelte kunder
- Støjende workloads påvirker ikke naboerne i samme grad
- Migrationer og migrations-tooling bliver et produkt i sig selv
- Observability og connection pooling kompleksificeres
- Kun værd når et konkret krav eller risiko retfærdiggør det
Hvornår vælger vi hvad?
Læs venstre som jeres situation — højre som typisk anbefaling.
Jeres situation
B2B-SaaS MVP med få kunder og standard datakrav
Vores anbefaling
Shared DB + organisation på alle rækker + RLS. Skib produktet.
Jeres situation
I har brug for at et team-medlem kun ser egen afdeling inden for kunden
Vores anbefaling
Roller og scopes oven på org-modellen — stadig shared DB.
Jeres situation
En design-win kræver dataresidens eller kontraktlig isolation
Vores anbefaling
Dedicated DB/schema for den tenant — gerne som undtagelse, ikke som default.
Jeres situation
En kunde genererer uforholdsmæssig load
Vores anbefaling
Først query- og cache-arbejde; derefter overvej dedicated resources for den tenant.
Jeres situation
I overvejer "en database pr. kunde" fra dag ét "for at være sikre"
Vores anbefaling
Lad være — medmindre compliance allerede kræver det. I køber drift I ikke har brug for.
Jeres situation
I har single-tenant i dag og skal åbne for flere kunder
Vores anbefaling
Refactor til org-scope + RLS før I skalerer salget. Det er billigere end at rydde op efter datalæk-risiko.
Den rækkefølge vi anbefaler
Gør tingene i den her rækkefølge. Spring ikke til isolation-niveau tre før ét og to er på plads.
- 01
Organisation som kernemodel
Hver forretningsentitet tilhører en organisation. Sessionen kender aktiv org. Ingen "implicit global" data undtagen platform-admin.
- 02
Auth og medlemskab
Brugere tilhører organisationer via membership med roller. Invitationer, fjernelse og skift af aktiv org er førsteklasses flows.
- 03
Database-enforcement (RLS)
Politikker der sikrer at selv en bug i applikationskoden ikke lækker på tværs af tenants. Test politikkerne som I tester features.
- 04
Observability pr. tenant
Logs og metrics med org-id, så I kan debugge og senere fordele omkostninger uden gætterier.
- 05
Isolation-undtagelser
Først når et konkret krav dukker op: dedicated schema/DB, separat region, eller customer-managed keys — som et bevidst tillæg.
Hvad der trygt kan vente
SSO (SAML/OIDC via WorkOS, Auth0 eller lignende) kan vente til den første kunde der kræver det i kontrakten — hvis jeres auth-model allerede har organisation og eksterne id'er som begreber. At bygge SSO "fordi enterprise" uden en pipeline af enterprise-deals er spekulation.
Hierarkiske organisationer (holding → datterselskaber → teams) kan vente. De fleste produkter klarer sig længe med flade orgs og grupper/roller indeni. Hierarki er svært at få omvendt rigtigt; vent på det konkrete behov.
Per-tenant feature flags, custom domains og white-label er produktvalg — ikke isoleringsvalg. De er lettere oven på en ren org-model, og næsten umulige oven på et rod af globale tabeller.
Spørgsmål vi får igen og igen
Er Row Level Security nok?
For de fleste B2B-SaaS: ja, som database-garanti — kombineret med at applikationen altid sætter den rigtige tenant-kontekst. RLS erstatter ikke god auth eller authorization i appen; den er sikkerhedsnettet under den. I skal stadig teste at politikkerne faktisk dækker nye tabeller.
Hvordan tester vi at data ikke lækker?
Automatiserede tests der logger ind som bruger i org A og forsøger at læse org B's data — både via API og direkte via database-rollen appen bruger. Tilføj det til CI. Manuel stikprøve er ikke en strategi når I tilføjer tabeller hver sprint.
Hvad med Supabase, Clerk eller Auth0?
De løser auth og delvist org-modeller. De løser ikke automatisk at jeres forretningstabeller er korrekt scoped. Vælg dem for hastighed i login og membership — men ej stadig jeres dataisolationsmodel i databasen.
Hvornår skal vi splitte til database-per-tenant?
Når et kontraktkrav, et compliance-krav eller et konkret performance-/støjproblem gør shared model dyrere end split. Ikke når en investor nævner "enterprise-ready". Split er en driftsbeslutning med migrationsomkostning — tag den med åbne øjne.
Kan vi migrere fra single-tenant senere?
Ja, men prisen vokser med datamængde og antal integrationer. Jo tidligere I har organisation på rækkerne, jo mere er "migrering" en udvidelse. Jo længere I venter, jo mere er det et rewrite af antagelser i hele kodebasen.
Skalerer I til flere kunder?
Få en ærlig vurdering af jeres tenant-model.
Vi kigger på datamodel, auth og risiko — og siger om I skal stramme RLS, vente, eller faktisk isolere en tenant.
