<- Alle artikelen
Technischmaart 20266 min lezen

Row-Level Security is geen suggestie

Waarom multi-tenant isolation in de database moet zitten, niet in de applicatie.

Een gedachte-experiment. Jij gebruikt een SaaS-platform. Je concurrent gebruikt hetzelfde platform. Jullie slaan allebei inventory, gradingresultaten, prijzen en klantinformatie op. De vraag: wat verhindert je concurrent om jouw data te zien?

Als het antwoord is "de applicatiecode checkt welke tenant je bent en toont alleen jouw data" — gefeliciteerd, je hebt application-level security. Dat betekent dat een bug in applicatiecode, een verkeerd geconfigureerd API-endpoint, SQL-injection of een te behulpzame developer met databasetoegang potentieel data van tenant A aan tenant B kan tonen.

Als het antwoord is "de database zelf dwingt isolatie af, en geen enkele query kan data van een andere tenant teruggeven, ongeacht hoe ze geschreven is" — dan heb je row-level security. Dat zijn heel verschillende dingen.

Het application layer-probleem

Application-level tenant isolation werkt zo: elke query bevat een filter. WHERE tenant_id = 'your-tenant'. De applicatie voegt die filter toe aan elke databasecall. Als de filter aanwezig is, zie je je data. Als hij ontbreekt — door een bug, een oversight, een nieuw endpoint dat de check vergat, of een developer die snel een query in productie draait — geeft de database vrolijk alles terug.

De database weet niets over tenants. De database slaat rijen op. Het is de taak van de applicatie om de juiste rijen te vragen. En de applicatie, software geschreven door mensen, kan fouten maken.

Dit is niet theoretisch. Multi-tenant datalekken zijn een van de meest voorkomende security-incidenten in SaaS-platformen. Een developer schrijft een nieuw API-endpoint en vergeet de tenantfilter. Een migratiescript draait zonder WHERE-clausule. Een debugging-sessie verbindt rechtstreeks met de database en draait een SELECT * die records van elke tenant teruggeeft. Elk van die dingen is een simpele fout. Elk kan je inventory, prijzen en klantdata blootleggen.

Application-level security betekent dat het slot op de deur zit. Row-level security betekent dat de muren uit beton bestaan. Deuren kunnen open blijven staan. Beton niet.

Row-level security: de database als handhaver

Postgres Row Level Security (RLS) werkt anders. In plaats van op de applicatie te rekenen om data te filteren, dwingt de database zelf de regels af. Elke tabel heeft een policy die zegt: "deze tenant mag alleen rijen zien waarvan tenant_id overeenkomt met hun sessie." De policy wordt afgedwongen op databaseniveau. Geen applicatiecode kan ze overrulen. Geen query kan ze omzeilen. Een SELECT * geeft alleen jouw rijen terug, niet omdat de applicatie filterde, maar omdat de database weigert iets anders te tonen.

Als een developer een buggy endpoint schrijft zonder tenantfilter, geeft de database nog altijd alleen de data van de juiste tenant terug. Als iemand een raw query draait, geldt de policy. Als een nieuwe feature gehaast wordt toegevoegd en access control onvolledig is, maakt het de database niet uit — de policy staat er, permanent en onvergetelijk.

RLS vervangt application security niet. Je hebt nog altijd authenticatie, autorisatie en degelijk API-design nodig. Maar RLS is het vangnet — de garantie dat tenantdata niet lekt wanneer de applicatie een fout maakt. Het is het verschil tussen "we vertrouwen de code" en "de architectuur laat het niet toe".

Waarom dit telt voor ITAD

ITAD-platformen verwerken van nature gevoelige data. Inventory bevat serienummers en assethistoriek. Pricing onthult commerciële strategie. Klantenlijsten zijn competitieve intelligentie. Erasure-records bevatten metadata over wat er op het toestel stond voor het werd gewist — en hoewel de data zelf weg is, is de metadata (welke klanten welke toestellen met welke dataclassificaties hadden) waardevol en gevoelig.

Als je als ITAD-bedrijf een multi-tenant platform evalueert, hoort de vraag "hoe wordt mijn data van andere tenants geïsoleerd?" in je eerste mail. En het antwoord moet zijn: "op databaseniveau, met RLS-policies op elke tabel." Niet "onze applicatiecode regelt dat." Niet "we hebben toegangscontroles." Niet "onze developers zijn heel zorgvuldig." Zorgvuldig is geen securityarchitectuur. Zorgvuldig is hoop.

Row-level security is geen feature die je naar voorkeur aan- of uitzet. Het is een fundamentele architectuurkeuze die bepaalt of je multi-tenant platform echte isolatie heeft of gesimuleerde isolatie. Het verschil is onzichtbaar als alles goed werkt. Het verschil is alles wanneer iets fout loopt.

Je concurrent gebruikt hetzelfde platform. Kan die je data zien? Als het antwoord afhangt van een applicatie die nooit een fout mag maken, is het antwoord "nog niet".