Architectuuroverzicht

Alle tenants delen dezelfde Supabase-database. Isolatie wordt afgedwongen door Row-Level Security (RLS)-beleidsregels — PostgreSQL-niveauregels die elke query filteren op basis van de geverifieerde gebruiker's JWT-claims.

Wanneer een gebruiker inlogt, bevat hun JWT een workspace_id-claim. Elk RLS-beleid controleert deze claim tegen een workspace_id-kolom in de tabel. Gebruikers kunnen letterlijk geen data opvragen van andere workspaces — de database dwingt dit af, niet de applicatiecode.

Dit patroon is de industriestandaard die bedrijven als Adyen en Booking.com gebruiken in hun interne tools — en met Supabase kun je het implementeren in een fractie van de tijd en kosten.

De workspace-structuur opzetten

Tabellen die je nodig hebt:

1. workspaces (id, name, plan, created_at) 2. workspace_members (id, workspace_id, user_id, role, created_at) 3. Al je zakelijke tabellen (met workspace_id-kolom)

Wanneer een gebruiker zich registreert, maak je een workspace en een workspace_members-record aan in een Supabase-databasefunctie. workspace_id wordt in de JWT van de gebruiker gezet via een aangepaste claim-hook.

Voor Nederlandse B2B SaaS-bedrijven raden we aan ook het KVK-nummer (KvK-nummer) op te slaan in de workspaces-tabel. Dit vereenvoudigt facturering en maakt automatische verrijking van klantdata via de KvK API mogelijk.

RLS-beleidsregels schrijven

Voor elke tenant-scoped tabel activeer je RLS en voeg je deze beleidsregels toe:

SELECT-beleid: CREATE POLICY "users can read own workspace data" ON your_table FOR SELECT USING (workspace_id = (auth.jwt() ->> 'workspace_id')::bigint);

INSERT-beleid: CREATE POLICY "users can insert to own workspace" ON your_table FOR INSERT WITH CHECK (workspace_id = (auth.jwt() ->> 'workspace_id')::bigint);

Dit dwingt isolatie af op databaseniveau — ongeacht wat je frontend of API doet. Een onjuiste WeWeb-binding of een bug in Xano kan nooit data lekken tussen klanten — de database is de laatste verdedigingslinie.

Rolgebaseerde toegangscontrole

Binnen een workspace hebben verschillende gebruikers verschillende rechten (owner, admin, member). Sla dit op in workspace_members.role.

Voor data-niveau RBAC gebruik je Supabase-functies in je RLS-beleidsregels:

CREATE FUNCTION get_user_role() RETURNS text AS $$ SELECT role FROM workspace_members WHERE user_id = auth.uid() AND workspace_id = (auth.jwt() ->> 'workspace_id')::bigint $$ LANGUAGE sql STABLE;

Dan in beleidsregels: USING (get_user_role() IN ('admin', 'owner'))

Voor Nederlandse enterprise-klanten is het gebruikelijk om ook afdelingsgebaseerde toegang te willen (bijv. "alleen HR kan salarisdata zien"). Dit bouwt eenvoudig als extra rol of een aparte permissietabel.

Koppelen in WeWeb

In WeWeb configureer je je Supabase-databron met het token van de geverifieerde gebruiker. WeWeb stuurt de JWT automatisch mee met elk verzoek.

Voor de navigatie en UI van je app lees je de rol uit een globale variabele (gevuld vanuit de workspace_members-tabel bij inloggen). Toon/verberg menu-items, knoppen en hele secties op basis van rol — dit is alleen presentatie, de echte beveiliging zit in RLS.

Hardcode nooit tenant-ID's in WeWeb. Alle datafiltering moet komen van de JWT van de geverifieerde gebruiker — Supabase regelt de rest. Dit maakt je WeWeb-app veilig te distribueren zelfs aan technisch onderlegde klanten die netwerkverkeer inspecteren.

Testen en valideren

Test altijd je RLS-beleidsregels door in te loggen als twee verschillende gebruikers uit verschillende workspaces en te verifiëren dat data nooit kruist.

Supabase's Policy Editor heeft een ingebouwde testfunctie: je kunt een query simuleren als een specifieke gebruiker en het gefilterde resultaat zien. Gebruik dit uitvoerig.

Voor Nederlandse klanten die due diligence uitvoeren (bijv. grotere enterprise-klanten of regulated industries): documenteer je RLS-beleidsregels als onderdeel van je beveiligingsdocumentatie. Een eenvoudige tabel die laat zien welk beleid welke tabel beschermt is een krachtig argument bij verkoopcycli met procurement-teams. App Studio heeft 50+ multi-tenant apps geleverd op deze architectuur.