Row-level security (RLS) is een databasefunctie die per gebruiker regelt welke afzonderlijke rijen van een tabel hij mag lezen of wijzigen, waarbij de regel wordt afgedwongen door de database zelf in plaats van door je applicatie. Je schrijft één keer een policy, bijvoorbeeld ‘een gebruiker ziet alleen rijen waarvan het tenant-ID overeenkomt met dat van hemzelf’, en elke query wordt daar automatisch tegen gefilterd.
Stel je een gedeelde archiefkast voor waarin elke map een klantnaam draagt. RLS is als een baliemedewerker die, voordat hij je een map geeft, je pasje checkt en alleen de mappen meegeeft die bij jou horen. Het maakt niet uit via welke deur je binnenkwam of welk formulier je invulde; de medewerker past elke keer dezelfde regel toe.
Dit is krachtig omdat het de vangrail dichter bij de data zet. Zelfs als een ontwikkelaar een check in de app vergeet, of een rapportagetool rechtstreeks verbindt, weigert de database nog steeds rijen te tonen die de gebruiker niet hoort te zien. RLS werkt samen met authenticatie om te weten wie het vraagt en met RBAC om te bepalen wat diegene mag.
Een waarschuwing voor de praktijk: RLS is maar zo goed als de identiteit die de database vertrouwt. Postgres leest bijvoorbeeld een sessievariabele die je app per verzoek zet, dus als een verbinding wordt hergebruikt over gebruikers heen zonder die waarde te resetten, kan de een de view van de ander erven. Gepoolde verbindingen zijn de klassieke plek waar dit misgaat, en daarom ontwerp je de policy en de manier waarop je de huidige gebruiker zet samen, niet als losse toevoeging achteraf.
Bij TopDevs leunen we op row-level security in multi-tenant apps, zodat de ene klant nooit per ongeluk de data van een ander kan zien, ook niet als er elders in de stack iets misgaat.