Kort sagt
Anon key, numera kallad publishable key, är tänkt att vara publik: den motsvarar rollen anon eller authenticated, och dina RLS-policyer avgör vad den ser. Service role key, numera secret key, motsvarar service_role, som kringgår RLS helt. På min lokala testtabell med RLS på och ingen policy fick den publika nyckeln 0 rader och secret key alla 3. Lägg publishable key i webbläsaren, behåll secret key på en server och rotera den om den någonsin har skickats ut.
Jag heter Denys och är full-stack- och AI-ingenjör. En läckt secret key är det första jag letar efter när jag tar över en Supabase-app, för med den är alla andra skydd bara dekoration. Den här artikeln förklarar vad varje nyckel öppnar, med förfrågningarna jag körde för att kontrollera det.
Vad är Supabase anon key?
Anon key identifierar din app, inte din användare. Varje förfrågan från en webbläsare eller mobilapp har den med sig, så den måste vara publik: vem som helst kan läsa den i sidans källkod. En förfrågan med bara den här nyckeln körs som Postgres-rollen anon. När en användare loggar in via Supabase Auth följer samma nyckel med användarens token, och förfrågan körs som authenticated. Dina RLS-policyer är skrivna för de två rollerna.
Supabase byter namn på nycklarna. Guiden om API-nycklar kallar de nya publishable (sb_publishable_…) och secret (sb_secret_…), och avvecklar de äldre JWT-baserade nycklarna anon och service_role till slutet av 2026. Rollerna bakom dem förblir desamma.
| Nyckel | Gammalt namn | Postgres-roll | Gäller RLS? | Var den hör hemma |
|---|---|---|---|---|
Publishable sb_publishable_… |
anon key |
anon, eller authenticated med användartoken |
Ja | Webbläsare, mobilapp, allt du skickar ut |
Secret sb_secret_… |
service_role key |
service_role |
Nej, rollen har BYPASSRLS |
Bara server, Edge Function, cron-jobb |
Är det säkert att exponera Supabase anon key?
Ja, om varje tabell, vy och funktion den når är skyddad. Själva nyckeln ger inget särskilt; behörigheterna och policyerna i ditt schema avgör allt. Jag kontrollerade det på en lokal Supabase-stack (CLI 2.109.1, Postgres 17.6) med en tabell med tre falska beställningar:
| Tabellens tillstånd | Publishable key | Secret key |
|---|---|---|
| RLS av | Alla 3 rader, och en insert gav 201 Created |
Alla 3 rader |
| RLS på, ingen policy | [] |
Alla 3 rader |
RLS på, policy using (true) |
Alla 3 rader | Alla 3 rader |
Ingen behörighet för anon |
42501 permission denied, med en ledtråd som nämner den saknade GRANT |
Alla 3 rader |
Publishable key är alltså precis så säker som din svagaste tabell. En tabell utan RLS, eller med en policy som släpper in varje rad, kan läsas av alla som öppnar DevTools. Det är hålet bakom CVE-2025-48757, där 170 av 1 645 Lovable-showcase-appar levererade data till den publika nyckeln.
Vad är service role key, och varför är den farlig?
Secret key är huvudnyckeln. Den körs som service_role, som har attributet BYPASSRLS, så ingen policy du skriver gäller någonsin för den. I sista kolumnen i tabellen ovan läste den alla tre raderna i varje tillstånd. Supabases guide listar var den hör hemma: servrar som kör egna auktoriseringskontroller, Edge Functions, bakgrundsjobb och adminverktyg. Två detaljer ur guiden spelar roll i praktiken:
- Den nya secret key avvisar förfrågningar från webbläsare: Supabase matchar
User-Agentoch svarar401. Den äldreservice_role-JWT:n har ingen sådan kontroll, så en läckt äldre nyckel fungerar var som helst. Min lokala stack, som saknar en sådan gateway-kontroll, svarade ett skript med secret key med alla 3 rader. - En secret key kringgår RLS bara när förfrågan saknar användartoken. Med en inloggad användares token körs förfrågan under den användarens policyer.
En Edge Function som använder secret key måste själv kontrollera vem som anropar och filtrera på ägare eller företag, eftersom inget under den gör det.
Var hittar du nycklarna?
I Dashboard öppnar du projektets Connect-dialog för URL:en och publishable key, eller Settings → API Keys för alla nycklar, de äldre inräknade. Lokalt skriver supabase start och supabase status ut en publishable key och en secret key. Behåll dem i miljövariabler: i Next.js får bara publishable key ha prefixet NEXT_PUBLIC_, eftersom bundlern skickar allt med det prefixet till webbläsaren.
Vad gör du om service role key har läckt?
Behandla den som komprometterad: varje rad i varje tabell kunde läsas och skrivas av den som hittade den.
- Skapa en ny secret key, flytta dina servrar till den och ta sedan bort den läckta. Om läckan var en äldre
service_role-nyckel är vägen ut övergången till de nya nycklarna: skapa en publishable key och en secret key, byt över appen och inaktivera sedan de äldre nycklarna i Settings → API Keys, där de annars förblir giltiga. - Sök i den byggda JavaScript-filen och i Git-historiken efter
sb_secret_ochservice_role. Escapes skanning av 5 600 vibe-kodade appar fann över 400 exponerade hemligheter, de flesta i frontend-bundlar. - Gå igenom vad som ändrades medan den var ute: nya användare, rolländringar, borttagna rader.
Den gratis Supabase-säkerhetskontrollen läser inte din frontend, men den läser databassidan av samma problem: roller som kringgår RLS, tabeller med RLS av, policyer som släpper in varje rad och kolumner som ser känsliga ut och kan läsas av anonyma besökare. Hur du kontrollerar vad din publika nyckel når i praktiken står i vibe coding security risks, och hela listan jag kör på en app finns i min säkerhetschecklista för Lovable-appar.
Osäker på vilken nyckel din app skickar ut?
Jag tittar gärna på det och jämför erfarenheter. Ingen säljpitch.
Hör av dig