Wat waar mag staan in je Supabase-project
Loop dit af voor elk project, vóór je live gaat en na elke grote wijziging. Eén vinkje te weinig is genoeg voor een lek.
- Project URL: mag overal staanHet is het adres van je project en je site heeft het nodig om je database te vinden. Dit hoeft niet geheim te blijven.
- Anon key (nieuw: publishable key): mag in je site of appDeze sleutel mag in browsercode, mobiele apps en publieke repo's. Ze is enkel veilig als de volgende twee punten kloppen.
- RLS staat aan op elke tabel die je API toontControleer in de SQL-editor met: select tablename, rowsecurity from pg_tables where schemaname = 'public'; Elke rij moet true tonen. Tabellen die je via SQL aanmaakt, hebben RLS niet automatisch.
- Elke tabel heeft policies die kloppen met wat bezoekers mogenRLS aan zonder policies betekent dat de publishable key niets ziet. Schrijf per tabel en per actie (lezen, toevoegen, wijzigen, verwijderen) wie wat mag.
- Secret (service_role key): enkel op je serverGebruik ze alleen in backendcode of Edge Functions. Ze negeert al je RLS-regels, dus alles wat ze kan, kan een vreemde ook.
- Secret staat in een environment variable, niet in je codeZet ze in een .env-bestand of in de secrets van je hostingplatform. Variabelen met een prefix als NEXT_PUBLIC_ of VITE_ belanden in de browser, dus gebruik die prefix nooit voor je secret.
- .env staat in je .gitignoreControleer met een zoekopdracht in je repo (ook in de geschiedenis) naar sb_secret_ en SERVICE_ROLE. Vind je iets, behandel de key als gelekt.
- Je secret staat niet in een chat met AIPlak nooit een echte key in ChatGPT, Claude of een andere assistent. Schrijf een placeholder zoals JOUW_SECRET_HIER.
- Browsertest: zoek je secret in je live siteOpen je site, druk F12, ga naar Sources of Network en zoek op de eerste tekens van je secret. Staat ze er, dan is ze publiek en moet je ze meteen vernieuwen.
- Gebruik de nieuwe sleutelnamenSupabase bouwt anon en service_role af tegen eind 2026. Maak een publishable en een secret key aan onder Settings > API Keys en vervang de oude.
- Gelekt? Nieuwe secret maken, vervangen, oude intrekkenMaak een nieuwe secret key, zet ze overal in de plaats van de oude en verwijder of deactiveer dan de gelekte key. Werkte je nog met legacy keys, revoke dan ook het legacy JWT secret.
- Vraag je bouwer waar de drie staanLaat je iets bouwen, vraag dan waar de project URL, de publieke key en de secret staan. Een goed antwoord is meteen en concreet.
Secret key niet in browser: dat is de enige harde regel bij Supabase. Je project URL en je publieke key (anon of publishable) mogen in je site staan. Je secret key (de service_role key) blijft op je server.
De checklist bij deze gids zegt per gegeven waar het mag staan. Hieronder leg ik uit waarom die regels bestaan, waar het in de praktijk misgaat en wat je doet als het toch gebeurd is.
Waarom mag een secret key niet in je browser?
Alles wat in je browsercode staat, kan elke bezoeker lezen. Een key die daar staat, is publiek. Bij een secret key is dat een probleem. Secret keys geven volledige toegang tot de data van je project en omzeilen Row Level Security. Wie ze vindt, ziet dus al je tabellen, ook de tabellen waar je regels voor schreef.
Technisch zit dat zo: policies gelden nooit voor een secret key, omdat service_role het BYPASSRLS-attribuut heeft. Je kan dus geen regel schrijven die dit probleem oplost. Het enige wat helpt, is de key op de server houden.
Welke Supabase-sleutels zijn er, en wat is de nieuwe naam?
De carrousel gebruikt de bekende namen: anon key en service_role key. Die bestaan nog, maar Supabase bouwt ze af tegen eind 2026 en vervangt ze door de publishable (sb_publishable_xxx) en secret (sb_secret_xxx) keys. Dat is dus dichtbij.
Zo vertaal je ze:
- Anon key wordt publishable key. Voor browsers, mobiele en desktop-apps, CLI's en publieke broncode.
- Service_role key wordt secret key. Voor servers, Edge Functions, workers en andere backendcode.
Het goede nieuws: een nieuwe key aanmaken trekt je legacy keys niet in, beide systemen werken tegelijk. Je kan dus rustig overstappen. De regels in deze gids gelden voor beide.
Project URL: geen geheim
Het adres van je project staat gewoon in je site. Zonder dat adres vindt je front-end je database niet. Daar hoef je niets mee te doen.
Publishable of anon key: veilig dankzij RLS
De publieke key is ontworpen om zichtbaar te zijn. Wat bezoekers ermee kunnen, bepaal jij met Row Level Security. Zodra je RLS aanzet, is er via de API met een publishable key niets toegankelijk tot je policies maakt. Dat is veilig: je opent alleen wat je bewust openzet.
Het gevaarlijke is het omgekeerde. Een tabel zonder RLS is open voor wie de key heeft. Vergeten RLS aan te zetten betekent een publieke tabel.
Let op, want RLS staat niet altijd automatisch aan. Tabellen die je in het Supabase Dashboard aanmaakt, hebben RLS standaard aan. Maar Postgres start een nieuwe tabel met RLS uit en de standaardrechten verschillen tussen projecten, afhankelijk van wanneer het project is aangemaakt. Controleer dus elke tabel, niet alleen de tabellen die je zelf in de interface aanmaakte.
Waar gaat het in de praktijk mis?
Meestal op de plekken waar het handig is. De secret werkt op je laptop, dus je zet ze in de code waar je front-end ze kan lezen. Of je commit je .env per ongeluk. Of je plakt een foutmelding met de key erin in een AI-chat.
Drie typische plekken:
- In je front-end. Variabelen met een prefix als NEXT_PUBLIC_ of VITE_ worden in je browserbundel gestopt. Zet je secret zo in je omgeving, dan staat ze publiek.
- In je repo. Ook als je het bestand later verwijdert, blijft de key in de geschiedenis staan. Verwijderen lost niets op, vernieuwen wel.
- In een chat met AI. Gebruik een placeholder. Je assistent heeft de echte waarde niet nodig om je code te schrijven.
Wie met AI-tools bouwt, moet ook op RLS letten. Die tools slaan row level security vaak over omdat de query werkt vanuit de SQL-editor en de typegenerator tevreden is. "Het werkt" zegt dus niets over veiligheid.
Een voorbeeld
Stel dat je een boekingssite bouwt voor een kapsalon. Er is een tabel met afspraken: naam, telefoonnummer, tijdstip. Je zet RLS uit omdat je formulier anders niet wilde opslaan. Nu kan elke bezoeker met de publieke key de hele tabel opvragen.
De juiste aanpak: RLS aan, een policy die bezoekers enkel laat toevoegen, en lezen enkel voor de beheerder. Heb je daarbovenop iets nodig dat alle afspraken mag lezen, zoals een mail met het dagoverzicht? Dan loopt dat via een server met de secret key.
Wat doe je als je secret key gelekt is?
Doe het vandaag nog. Een gelekte key blijft werken tot je ze intrekt.
Stappen bij een nieuwe secret key
- Maak een nieuwe secret key aan onder Settings > API Keys in het Dashboard.
- Vervang de gelekte key overal waar je applicatie ze gebruikt.
- Verwijder daarna de oude key. Een secret key verwijderen kan je niet ongedaan maken, dus test eerst of alles met de nieuwe werkt.
Zat je nog op de legacy service_role key?
Dan werkt het iets anders. Supabase zegt dat je de legacy anon-, service- en JWT-secrets niet meer kan roteren, dus je stapt over op nieuwe keys. Je vervangt ook de legacy anon key door een publishable key in je browser- en mobiele clients, want als je de gelekte key intrekt, worden beide legacy keys uitgeschakeld. Daarna revoke je ook het legacy JWT secret, omdat de legacy keys daarmee zijn ondertekend en een gelekte key anders nog geldig kan zijn.
Plan dus een uurtje in en doe dit niet halverwege een drukke dag. Pas daarna bouw je verder.
Hoe controleer je dit als iemand anders voor je bouwt?
Je hoeft geen code te lezen. Stel drie vragen:
- Waar staat de project URL, en welke key gebruikt de website?
- Waar staat de secret key, en wie heeft er toegang toe?
- Staat RLS aan op elke tabel, en kan je de policies zien?
Een goede bouwer antwoordt daar zonder te zoeken op. Slaat iemand de vragen over of antwoordt hij vaag, dan weet je genoeg.
Bouw je zelf maatwerk, zoals een CRM op maat met klantgegevens, dan is dit nog belangrijker: daar staan persoonsgegevens in. Wil je automatisaties bouwen die met je database praten, dan lees je eerst iets over AI automations, want daar komen secrets vaak op ongewone plekken terecht. En twijfel je over een bestaand project, dan bekijken we het samen.
Veelgestelde vragen
Mag mijn Supabase anon key in mijn website staan?
Ja, die key is bedoeld voor browsers en apps. Maar ze beschermt niets zelf: dat doet Row Level Security. Zonder RLS en policies kan iedereen met die key je tabellen aanspreken.
Wat is het verschil tussen de anon key en de publishable key?
De publishable key (sb_publishable_...) is de nieuwe versie van de anon key. Supabase bouwt de oude JWT-keys af tegen eind 2026. Voor gebruik in browsers en apps verandert er weinig, maar nieuwe projecten werken best meteen met de nieuwe namen.
Ik heb mijn secret key in een AI-chat geplakt. Is dat erg?
Behandel de key als gelekt. Je weet niet waar die chat of dat gesprek terechtkomt en je kan het niet ongedaan maken. Maak een nieuwe secret key, vervang de oude overal en verwijder of deactiveer de oude.
Is de Supabase project URL geheim?
Nee. Je site heeft het adres nodig om je project te vinden en het staat in je browsercode. De bescherming zit in je keys en je RLS-regels, niet in het adres.
Hoe weet ik of RLS aan staat op mijn tabellen?
Kijk in de Table Editor van je dashboard of voer in de SQL-editor een query op pg_tables uit en lees de kolom rowsecurity. Tabellen die je via het dashboard maakt, hebben RLS standaard aan. Tabellen die je met SQL of via een AI-tool aanmaakt, kunnen RLS missen.
Bronnen
Meer weten over ai? Bekijk wat we daarin voor je doen of lees artikels over ai.
Bereken je offerte







