03 mrt 2025·8 min leestijd

PostgreSQL rijniveaubeveiliging voor multi-tenant apps

Leer PostgreSQL rijniveaubeveiliging (RLS) met praktische patronen voor tenant-isolatie en rolregels, zodat toegang in de database wordt afgedwongen en niet alleen in de app.

PostgreSQL rijniveaubeveiliging voor multi-tenant apps

Waarom database-afgedwongen toegang belangrijk is voor business-apps

Business-apps hebben vaak regels zoals “gebruikers mogen alleen de records van hun bedrijf zien” en “alleen managers kunnen refunds goedkeuren.” Veel teams dwingen die regels af in de UI of API en gaan ervan uit dat dat genoeg is. Het probleem is dat elke extra toegang naar de database een nieuwe kans is om data te lekken: een intern admin-gereedschap, een background job, een analytics-query, een vergeten endpoint of een bug die een check overslaat.

Tenant-isolatie betekent dat één klant (tenant) nooit de gegevens van een andere klant kan lezen of wijzigen, zelfs niet per ongeluk. Rolgebaseerde toegang betekent dat mensen binnen dezelfde tenant toch verschillende bevoegdheden hebben, zoals agenten versus managers versus finance. Deze regels zijn makkelijk te beschrijven, maar moeilijk consistent te houden als ze op veel plekken leven.

PostgreSQL Row-Level Security (RLS) is een databasefunctie waarmee de database bepaalt welke rijen een verzoek mag zien of wijzigen. In plaats van te vertrouwen op elke query in je app om de juiste WHERE-clausule te onthouden, past de database policies automatisch toe.

RLS is geen magisch schild voor alles. Het ontwerpt je schema niet, vervangt geen authenticatie en beschermt je niet tegen iemand die al een machtige databaseroom heeft (zoals een superuser). Het voorkomt ook geen logische fouten zoals “iemand kan een rij updaten die hij niet kan selecteren” tenzij je policies voor zowel lezen als schrijven schrijft.

Wat je wél krijgt is een sterk vangnet:

  • Eén set regels voor elke codeweg die de database raakt
  • Minder “oeps”-momenten wanneer een nieuwe feature live gaat
  • Duidelijkere audits, omdat toegangsregels zichtbaar zijn in SQL
  • Betere verdediging als een API-bug door de mazen glipt

Er is een kleine setup-kost. Je hebt een consistente manier nodig om “wie is deze gebruiker” en “welke tenant” in de database door te geven, en je moet policies bijhouden naarmate je app groeit. De opbrengst is groot, vooral voor SaaS en interne tools waar gevoelige klantgegevens op het spel staan.

Rijniveaubeveiliging (RLS) zonder jargon

Row-Level Security (RLS) filtert automatisch welke rijen een query kan zien of wijzigen. In plaats van te vertrouwen op elk scherm, API-endpoint of rapport om de regels te "onthouden", past de database ze voor je toe.

Met PostgreSQL row-level security schrijf je policies die bij elke SELECT, INSERT, UPDATE en DELETE worden gecontroleerd. Als de policy zegt “deze gebruiker mag alleen rijen voor tenant A zien”, dan krijgt een vergeten admin-pagina, een nieuwe query of een gehaaste hotfix nog steeds dezelfde veiligheidsmaatregelen.

RLS verschilt van GRANT/REVOKE. GRANT bepaalt of een rol een tabel überhaupt mag gebruiken (of specifieke kolommen). RLS bepaalt welke rijen binnen die tabel toegestaan zijn. In de praktijk gebruik je vaak beide: GRANT om te beperken wie de tabel kan openen, en RLS om te beperken wat ze kunnen benaderen.

Het werkt ook in de rommelige praktijk. Views gehoorzamen meestal RLS omdat de toegang tot de onderliggende tabel nog steeds de policy activeert. Joins en subqueries worden nog steeds gefilterd, zodat een gebruiker zich niet via een join toegang kan verschaffen tot andermans data. En de policy geldt ongeacht welke client de query uitvoert: app-code, een SQL-console, een background job of een rapportagetool.

RLS is een goede keuze als je sterke tenant-isolatie nodig hebt, meerdere wegen hebt om dezelfde data te bevragen, of veel rollen hebt die tabellen delen (veelvoorkomend in SaaS en interne tools). Het kan te veel zijn voor piepkleine apps met één vertrouwde backend, of voor data die niet gevoelig is en nooit een enkele gecontroleerde service verlaat. Zodra je meer dan één toegangspunt hebt (admin-tools, exports, BI, scripts) verdient RLS zich meestal terug.

Begin met het in kaart brengen van tenants, rollen en data-eigendom

Voordat je één policy schrijft, maak duidelijk wie wat bezit. PostgreSQL row-level security werkt het beste wanneer je datamodel al tenants, rollen en eigendom weerspiegelt.

Begin met tenants. In de meeste SaaS-apps is de simpelste regel: elke gedeelde tabel die klantgegevens bevat heeft een tenant_id. Dat geldt voor “voor de hand liggende” tabellen zoals invoices, maar ook voor dingen die mensen vergeten, zoals attachments, comments, audit logs en background jobs.

Noem daarna de rollen die mensen daadwerkelijk gebruiken. Houd de set klein en menselijk: owner, manager, agent, read-only. Dit zijn zakelijke rollen die je later aan policychecks koppelt (ze zijn niet hetzelfde als databaseroepen).

Bepaal vervolgens hoe records eigendom hebben. Sommige tabellen zijn eigendom van één gebruiker (bijvoorbeeld een privénotitie). Andere zijn team-owned (bijvoorbeeld een gedeelde inbox). Het door elkaar gebruiken van beide zonder plan leidt tot policies die moeilijk te lezen en makkelijk te omzeilen zijn.

Een eenvoudige manier om je regels te documenteren is voor elke tabel dezelfde vragen te beantwoorden:

  • Wat is de tenant-grens (welke kolom dwingt die af)?
  • Wie kan rijen lezen (per rol en per eigendom)?
  • Wie kan rijen aanmaken en bijwerken (en onder welke voorwaarden)?
  • Wie kan rijen verwijderen (meestal de strengste regel)?
  • Welke uitzonderingen zijn toegestaan (supportpersoneel, automatisering, exports)?

Voorbeeld: “Invoices” kan managers toestaan alle tenant-invoices te zien, agenten invoices voor toegewezen klanten, en read-only gebruikers alleen bekijken maar nooit bewerken. Bepaal van tevoren welke regels strikt moeten zijn (tenant-isolatie, deletes) en welke flexibel kunnen zijn (extra zichtbaarheid voor managers). Als je bouwt in een no-code tool zoals AppMaster helpt deze mapping ook om UI-verwachtingen en databaseregels op één lijn te houden.

Ontwerp patronen voor multi-tenant tabellen

Multi-tenant RLS werkt het best als je tabellen voorspelbaar zijn. Als elke tabel de tenant op een andere manier opslaat, veranderen je policies in een puzzel. Een consistente vorm maakt PostgreSQL row-level security makkelijker te lezen, te testen en correct te houden over tijd.

Begin met het kiezen van één tenant-identifier en gebruik die overal. UUIDs zijn gebruikelijk omdat ze moeilijk te raden en makkelijk te genereren zijn in veel systemen. Integers zijn ook prima, vooral voor interne apps. Slugs (zoals "acme") zijn mensvriendelijk, maar kunnen veranderen, dus gebruik ze als displayveld, niet als hoofdkey.

Voor tenant-gebonden data voeg je een tenant_id-kolom toe aan elke tabel die bij een tenant hoort, en maak die NOT NULL wanneer mogelijk. Als een rij kan bestaan zonder tenant is dat meestal een geur van een probleem. Vaak betekent het dat je globale en tenant-data in één tabel mengt, wat RLS-policies moeilijker en fragieler maakt.

Indexering is simpel maar belangrijk. De meeste queries in een SaaS-app filteren eerst op tenant en daarna op een bedrijfsveld zoals status of datum. Een goede default is een index op tenant_id, en voor hoge-traffic tabellen een samengestelde index zoals (tenant_id, created_at) of (tenant_id, status) gebaseerd op je veelgebruikte filters.

Bepaal vroeg welke tabellen globaal zijn en welke tenant-gescoord. Veelvoorkomende globale tabellen zijn countries, currency codes of plan-definities. Tenant-gescoorde tabellen zijn customers, invoices, tickets en alles wat de tenant bezit.

Als je regels wilt die onderhoudbaar blijven, houd ze dan smal:

  • Tenant-gescoorde tabellen: tenant_id NOT NULL, RLS ingeschakeld, policies controleren altijd tenant_id.
  • Globale referentietabellen: geen tenant_id, geen tenant-policies, read-only voor de meeste rollen.
  • Gedeelde-maar-gecontroleerde tabellen: scheid tabellen per concept (vermijd het mengen van globale en tenant-rijen).

Als je bouwt met een tool zoals AppMaster betaalt deze consistentie zich terug in het datamodel. Zodra tenant_id een standaardveld is, kun je dezelfde patronen in modules hergebruiken zonder verrassingen.

Stap voor stap: maak je eerste tenant-policy

Zet bedrijfsregels op één plek
Zet rollen, eigendom en goedkeuringen om in backendlogica zonder overal autorisatiechecks te herschrijven.
Maak project

Een goede eerste winst met PostgreSQL row-level security is één tabel die alleen binnen de huidige tenant leesbaar is. Het punt is simpel: zelfs als iemand een WHERE-clausule vergeet in de API, weigert de database rijen van andere tenants terug te geven.

Begin met een tabel die een tenant_id-kolom bevat:

ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;

Zodra RLS is ingeschakeld, verrast het standaardgedrag vaak mensen: als een rol aan RLS onderhevig is en er geen passende policy is, geeft SELECT nul rijen terug (en falen writes). Dat is precies wat je wilt bij de start.

Voeg nu een minimale leespolicy toe. Dit voorbeeld gaat ervan uit dat je app na login een sessievariabele zoals app.tenant_id zet:

CREATE POLICY invoices_tenant_read
ON invoices
FOR SELECT
USING (tenant_id = current_setting('app.tenant_id')::uuid);

Voeg daarna schrijfrechten toe. In RLS beheert USING welke bestaande rijen je kunt aanraken, en WITH CHECK bepaalt welke nieuwe waarden je mag schrijven.

CREATE POLICY invoices_tenant_insert
ON invoices
FOR INSERT
WITH CHECK (tenant_id = current_setting('app.tenant_id')::uuid);

CREATE POLICY invoices_tenant_update
ON invoices
FOR UPDATE
USING (tenant_id = current_setting('app.tenant_id')::uuid)
WITH CHECK (tenant_id = current_setting('app.tenant_id')::uuid);

CREATE POLICY invoices_tenant_delete
ON invoices
FOR DELETE
USING (tenant_id = current_setting('app.tenant_id')::uuid);

Policies zijn standaard PERMISSIVE, wat betekent dat één enkele policy toegang kan toestaan. Kies RESTRICTIVE wanneer je regels wilt die allemaal moeten slagen (handig als je een tweede controle wilt toevoegen zoals “alleen actieve accounts”).

Houd policies klein en rol-gericht. In plaats van één gigantische regel met veel OR's, maak aparte policies per doelgroep (bijvoorbeeld invoices_tenant_read_app_user en invoices_tenant_read_support_agent). Dat is makkelijker te testen, makkelijker te reviewen en veiliger om later te veranderen.

Context voor tenant en gebruiker veilig doorgeven

Voor PostgreSQL row-level security moet de database weten “wie roept aan” en “tot welke tenant horen ze”. RLS-policies kunnen alleen rijen vergelijken met waarden die de database tijdens de query kan lezen, dus je moet die context in de sessie zetten.

Een veelgebruikt patroon is sessievariabelen zetten na authenticatie en policies die ze lezen met current_setting(). De app bewijst identiteit (bijvoorbeeld door een JWT te valideren) en kopieert daarna alleen de velden die nodig zijn (tenant_id, user_id, role) naar de databaseconnectie.

-- Run once per request (or per transaction)
SELECT set_config('app.tenant_id', '3f2a0c3e-9c7b-4d3f-9c5c-3c5e9c5d1a11', true);
SELECT set_config('app.user_id',   '8d9c6b1a-6b6d-4e32-9c0d-2bfe6f6c1111', true);
SELECT set_config('app.role',      'support_agent', true);

-- In a policy
-- tenant_id column is a UUID
USING (tenant_id = current_setting('app.tenant_id', true)::uuid);

Het gebruik van het derde argument true maakt het “lokaal” voor de huidige transactie. Dat is belangrijk bij connection pooling: een gepoolde connectie kan door een andere request hergebruikt worden, dus je wilt niet dat de tenant-context van gisteren blijft hangen.

Context vullen vanuit JWT-claims

Als je API JWT's gebruikt, behandel claims als invoer, niet als waarheid. Verifieer eerst de token-handtekening en expiry, en kopieer daarna alleen de velden die je nodig hebt (tenant_id, user_id, role) naar sessie-instellingen. Vermijd dat clients deze waarden direct als headers of queryparams sturen.

Ontbrekende of ongeldige context: standaard weigeren

Ontwerp policies zo dat ontbrekende instellingen resulteren in geen rijen.

Gebruik current_setting('app.tenant_id', true) zodat ontbrekende waarden NULL teruggeven. Cast naar het juiste type (zoals ::uuid) zodat ongeldige formaten snel falen. En faal de request als tenant-/user-context niet gezet kan worden, in plaats van te gokken naar een default.

Dit houdt toegangscontrole consistent, zelfs wanneer een query de UI omzeilt of er later een nieuw endpoint bijkomt.

Praktische rolpatronen die onderhoudbaar blijven

Test RLS-vriendelijke appflows
Prototypeer tenant-isolatie-workflows snel en itereren zonder technische schulden op te bouwen.
Begin nu

De makkelijkste manier om RLS-policies leesbaar te houden is identiteit te scheiden van permissies. Een goed uitgangspunt is een users-tabel plus een memberships-tabel die een gebruiker aan een tenant en een rol (of meerdere rollen) koppelt. Dan kunnen je policies één vraag beantwoorden: “Heeft de huidige gebruiker de juiste membership voor deze rij?”

Houd rolnamen verbonden aan echte acties, niet aan functietitels. “invoice_viewer” en “invoice_approver” verouderen vaak minder snel dan “manager”, omdat de policy geschreven kan worden in duidelijke termen.

Hier een paar rolpatronen die simpel blijven naarmate je app groeit:

  • Owner-only: de rij heeft een created_by_user_id (of owner_user_id) en de toegang controleert precies die match.
  • Team-only: de rij heeft een team_id, en de policy controleert dat de gebruiker lid is van dat team binnen dezelfde tenant.
  • Approved-only: lezen is alleen toegestaan wanneer status = 'approved', en schrijven is beperkt tot approvers.
  • Gemengde regels: begin streng en voeg daarna kleine uitzonderingen toe (bijvoorbeeld “support kan lezen, maar alleen binnen de tenant”).

Cross-tenant admins zorgen vaak voor problemen. Handel ze expliciet af, niet als een verborgen “superuser”-omweg. Maak een apart concept zoals platform_admin (globaal) en vereis een bewuste check in de policy. Nog beter: houd cross-tenant toegang standaard read-only en maak writes moeilijker.

Documentatie is belangrijker dan het klinkt. Zet een korte commentaar boven elke policy die de intentie uitlegt, niet alleen de SQL. “Approvers kunnen status veranderen. Viewers mogen alleen goedgekeurde invoices lezen.” Zes maanden later is dat aantekening wat veranderingen veilig houdt.

Als je bouwt met een no-code tool zoals AppMaster, gelden deze patronen nog steeds. Je UI en API kunnen snel bewegen, maar de databaseregels blijven stabiel omdat ze vertrouwen op memberships en duidelijke rolbetekenis.

Voorbeeldscenario: een simpele SaaS met invoices en support

Bouw veilige interne tools
Maak facturen, tickets en admin-schermen met beschermingen die overeenkomen met je databaseregels.
Probeer het nu

Stel je een kleine SaaS voor die meerdere bedrijven bedient. Elk bedrijf is een tenant. De app heeft invoices (geld) en supporttickets (dagelijks hulp). Gebruikers kunnen agenten, managers of support zijn.

Datamodel (vereenvoudigd): elke invoice- en ticket-rij heeft een tenant_id. Tickets hebben ook assignee_user_id. De app zet de huidige tenant en gebruiker in de database-sessie direct na login.

Zo verandert RLS het dagelijkse risico:

Een gebruiker van Tenant A opent het invoices-scherm en probeert een invoice-id van Tenant B te raden (of de UI stuurt die per ongeluk). De query draait nog steeds, maar de database geeft nul rijen terug omdat de policy invoice.tenant_id = current_tenant_id vereist. Er is geen “access denied”-lek, alleen een leeg resultaat.

Binnen één tenant versmallen rollen de toegang verder. Een manager kan alle invoices en tickets van hun tenant zien. Een agent kan alleen tickets zien die aan hen zijn toegewezen, plus misschien hun eigen concepten. Hier gaan teams vaak de mist in in de API, vooral wanneer filters optioneel zijn.

Support is een speciaal geval. Ze moeten soms invoices kunnen bekijken om klanten te helpen, maar mogen geen gevoelige velden veranderen zoals amount, bank_account of tax_id. Een praktisch patroon is:

  • Sta SELECT op invoices toe voor de support-rol (nog steeds tenant-gescoord).
  • Sta UPDATE alleen toe via een “veilige” weg (bijvoorbeeld een view die bewerkbare kolommen blootstelt, of een strikte update-policy die wijzigingen aan beschermde velden afwijst).

Het “per ongeluk API-bug”-scenario: een endpoint vergeet tijdens een refactor de tenant-filter toe te passen. Zonder RLS kan dat cross-tenant invoices lekken. Met RLS weigert de database rijen buiten de sessie-tenant terug te geven, dus de bug wordt een kapot scherm, geen datalek.

Als je dit soort SaaS in AppMaster bouwt, wil je deze regels nog steeds in de database. UI-checks zijn nuttig, maar databaseregels houden het vast wanneer er iets slipping gebeurt.

Veelgemaakte fouten en hoe ze te vermijden

PostgreSQL row-level security is krachtig, maar kleine slordigheden kunnen “veilig” stilletjes in “verrassend” veranderen. De meeste problemen ontstaan wanneer een nieuwe tabel wordt toegevoegd, een rol verandert of iemand test met de verkeerde databasegebruiker.

Een veelvoorkomende fout is vergeten RLS in te schakelen op een nieuwe tabel. Je schrijft misschien zorgvuldige policies voor je kern-tabellen, voegt later een “notes” of “attachments” tabel toe en shipped die met volledige toegang. Maak er een gewoonte van: nieuwe tabel betekent RLS inschakelen, plus ten minste één policy.

Een andere valkuil is mismatchende policies over acties heen. Een policy die INSERT toestaat maar SELECT blokkeert kan voelen als “data verdwijnt” direct na het aanmaken. Het tegenovergestelde is ook vervelend: gebruikers kunnen rijen lezen die ze niet kunnen aanmaken, dus werken ze rond de beperking in de UI. Denk in flows: “create then view”, “update then re-open”, “delete then list”.

Wees voorzichtig met SECURITY DEFINER functies. Ze draaien met de privileges van de functie-eigenaar, wat RLS kan omzeilen als je niet strikt bent. Als je ze gebruikt, houd ze klein, valideer inputs en vermijd dynamic SQL tenzij het echt nodig is.

Vertrouw ook niet op app-side filtering terwijl je database-toegang open laat. Zelfs goedgebouwde API's groeien nieuwe endpoints, background jobs en admin-scripts. Als de databaseroom alles kan lezen, gebeurt er vroeg of laat iets.

Om problemen vroeg te vangen, houd de checks praktisch:

  • Test met dezelfde DB-rol die je productieapp gebruikt, niet met je persoonlijke admin-user.
  • Voeg per tabel één negatieve test toe: een gebruiker van een andere tenant moet nul rijen zien.
  • Bevestig dat elke tabel de verwachte acties ondersteunt: SELECT, INSERT, UPDATE, DELETE.
  • Review SECURITY DEFINER gebruik en documenteer waarom het nodig is.
  • Zet “RLS ingeschakeld?” op de checklist voor code reviews en migraties.

Voorbeeld: als een support-agent een invoice-notitie aanmaakt maar die niet terug kan lezen, is dat vaak een INSERT-policy zonder een bijpassende SELECT-policy (of tenant-context wordt niet gezet voor die sessie).

Snelle checklist om je RLS-setup te valideren

Standaardiseer je tenant-datamodel
Modelleer tenant_id één keer in Data Designer en hergebruik het in elke tabel en module.
Begin met bouwen

Row-Level Security kan er correct uitzien in review en toch falen in echt gebruik. Validatie gaat minder om policies lezen en meer om proberen ze te breken met realistische accounts en queries. Test het zoals je app het zal gebruiken, niet hoe je hoopt dat het werkt.

Maak eerst een kleine set testidentiteiten. Gebruik minstens twee tenants (Tenant A en Tenant B). Voor elke tenant voeg je een normale gebruiker en een admin of manager-rol toe. Als je “support agent” of “read-only” rollen ondersteunt, voeg die ook toe.

Druk daarna RLS met een klein, herhaalbaar set checks:

  • Voer de kernoperaties uit voor elke rol: lijst rijen, haal een enkele rij op via id, insert, update en delete. Probeer voor elke operatie zowel “toegestaan” als “moet geblokkeerd worden” gevallen.
  • Bewijs tenant-grenzen: probeer als Tenant A data van Tenant B te lezen of te wijzigen met ids die je weet dat bestaan. Je zou nul rijen terug moeten krijgen of een permissiefout, nooit "sommige rijen".
  • Test joins op lekken: join beschermde tabellen met andere tabellen (inclusief lookup-tabellen). Bevestig dat een join geen gerelateerde rijen van een andere tenant binnenhaalt via een foreign key of view.
  • Controleer dat ontbrekende of verkeerde context toegang weigert: maak de tenant-/user-context leeg (wat je app per request zet) en probeer opnieuw. “Geen context” moet gesloten falen. Probeer ook een ongeldige tenant-id.
  • Bevestig basisperformance: kijk naar queryplannen en zorg dat indexes je tenant-filterpatroon ondersteunen (meestal tenant_id plus waar je op sorteert of zoekt).

Als een test je verrast, fix eerst de policy of het context-zetten. Patch het niet in de UI of API en hoop dat de databaseregels “meestal houden”.

Volgende stappen: veilig uitrollen en consistent houden

Behandel PostgreSQL row-level security als een veiligheidsysteem: introduceer het voorzichtig, verifieer het vaak en houd de regels simpel genoeg dat je team ze volgt.

Begin klein. Kies de tabellen waar een lek het meest pijn doet (betalingen, invoices, HR-data, klantberichten) en zet daar eerst RLS aan. Vroege successen zijn beter dan een enorme uitrol die niemand volledig begrijpt.

Een praktische uitrolvolgorde ziet er vaak zo uit:

  • Kern “owned” tabellen eerst (rijen behoren duidelijk tot één tenant)
  • Tabellen met persoonlijke data (PII)
  • Tabllen die gedeeld maar tenant-gefilterd zijn (reports, analytics)
  • Join-tabellen en edgecases (many-to-many relaties)
  • De rest zodra de basics stabiel zijn

Maak testen verplicht. Geautomatiseerde tests moeten dezelfde queries uitvoeren als verschillende tenants en rollen en bevestigen wat verandert. Voeg zowel “moet toestaan” als “moet weigeren” checks toe, want de duurste bugs zijn stille overpermissie.

Houd één duidelijke plek in je requestflow waar sessiecontext wordt gezet voordat queries draaien. Tenant-id, user-id en rol moeten één keer, vroeg en zonder te gokken toegepast worden. Als je context midden in een transactie zet, voer je uiteindelijk een query uit met ontbrekende of verouderde waarden.

Als je bouwt met AppMaster, plan voor consistentie tussen je gegenereerde backend-APIs en je PostgreSQL-policies. Standaardiseer hoe tenant- en rolcontext in de database wordt gezet (bijvoorbeeld dezelfde sessievariabelen voor elk endpoint) zodat policies overal hetzelfde gedrag geven. Als je AppMaster gebruikt op appmaster.io is RLS nog steeds het laatste woord voor tenant-isolatie, zelfs als je ook toegang in de UI reguleert.

Tot slot: let op wat faalt. Autorisatie-fouten zijn nuttige signalen, vooral vlak na uitrol. Volg herhaalde weigeringen en onderzoek of ze wijzen op een echte aanval, een kapotte clientflow of een te strikte policy.

Een korte gewoontelijst die helpt dat RLS gezond blijft:

  • Default-deny mindset, met uitzonderingen die bewust worden toegevoegd
  • Duidelijke policy-namen (tabel + actie + doelgroep)
  • Policy-wijzigingen reviewed zoals codewijzigingen
  • Weigeringen gelogd en beoordeeld tijdens vroege uitrol
  • Een kleine testset toegevoegd voor elke nieuwe tabel met RLS
Gemakkelijk te starten
Maak iets geweldigs

Experimenteer met AppMaster met gratis abonnement.
Als je er klaar voor bent, kun je het juiste abonnement kiezen.

Aan de slag