Gå til indhold

Supabase anon key vs service role key: hvad åbner de?

Vis som MarkdownÅbn i ClaudeÅbn i ChatGPTÅbn i Perplexity

Spørgsmålet kopieres også. Hvis chatten åbner tom, så indsæt det.

TL;DR

Anon key, som nu hedder publishable key, er lavet til at være offentlig: den svarer til rollen anon eller authenticated, og dine RLS-policies afgør, hvad den ser. Service role key, nu secret key, svarer til service_role, som omgår RLS helt. På min lokale testtabel med RLS slået til og ingen policy fik publishable key 0 rækker og secret key alle 3. Læg publishable key i browseren, hold secret key på en server, og rotér den, hvis den nogensinde er sluppet ud.

Jeg er Denys, fullstack- og AI-ingeniør. En lækket secret key er det første, jeg leder efter, når jeg overtager en Supabase-app, for med den er alle andre beskyttelser pynt. Denne artikel forklarer, hvad hver nøgle åbner, med de anmodninger, jeg kørte for at kontrollere det.

Hvad er Supabase anon key?

Anon key identificerer din app, ikke din bruger. Hver anmodning fra en browser eller en mobilapp bærer den, så den må være offentlig: alle kan læse den i sidens kilde. En anmodning med kun denne nøgle kører som Postgres-rollen anon. Når en bruger logger ind gennem Supabase Auth, rejser den samme nøgle med brugerens token, og anmodningen kører som authenticated. Dine RLS-policies er skrevet til de to roller.

Supabase omdøber nøglerne. Guiden til API-nøgler kalder de nye publishable (sb_publishable_…) og secret (sb_secret_…) og udfaser de gamle JWT-baserede nøgler anon og service_role inden udgangen af 2026. Rollerne bag dem forbliver de samme.

Nøgle Gammelt navn Postgres-rolle Gælder RLS? Hvor den hører hjemme
Publishable sb_publishable_… anon-nøglen anon, eller authenticated med brugerens token Ja Browser, mobilapp, alt hvad du udsender
Secret sb_secret_… service_role-nøglen service_role Nej, rollen har BYPASSRLS Kun server, Edge Function, cron-job

Er det sikkert at eksponere Supabase anon key?

Ja, hvis hver tabel, hvert view og hver funktion, den kan nå, er beskyttet. Selve nøglen giver intet særligt; rettighederne og policies i dit schema afgør alt. Jeg kontrollerede det på en lokal Supabase (CLI 2.109.1, Postgres 17.6) med én tabel med tre falske ordrer:

Hvilken Postgres-rolle hver nøgle bliver til. Og om dine RLS-policies ser anmodningen. Publishable key, logget ud: Publishable key → rolle anon → RLS-policies gælder; Publishable key, logget ind: Publishable key + brugertoken → rolle authenticated → RLS-policies gælder; Secret key: Secret key → rolle service_role → RLS omgås.
Figur 1. Fra Supabases guide til API-nøgler, kontrolleret på en lokal stack, 23. oktober 2026.
Tabellens tilstand Publishable key Secret key
RLS slået fra Alle 3 rækker, og en indsættelse gav 201 Created Alle 3 rækker
RLS slået til, ingen policy [] Alle 3 rækker
RLS slået til, policy using (true) Alle 3 rækker Alle 3 rækker
Ingen rettighed til anon 42501 permission denied, med et hint der nævner den manglende GRANT Alle 3 rækker

Publishable key er altså lige så sikker som din svageste tabel. En tabel uden RLS, eller med en policy der tillader hver række, kan læses af alle, der åbner DevTools. Det er hullet bag CVE-2025-48757, hvor 170 af 1.645 Lovable-showcase-apps udleverede data til den offentlige nøgle.

Hvad er service role key, og hvorfor er den farlig?

Secret key er hovednøglen. Den kører som service_role, som har attributten BYPASSRLS, så ingen policy, du skriver, gælder nogensinde for den. I sidste kolonne i tabellen ovenfor læste den alle tre rækker i enhver tilstand. Supabases guide angiver, hvor den hører hjemme: servere, der selv laver autorisationstjek, Edge Functions, baggrundsjobs og admin-værktøjer. To detaljer fra guiden betyder noget i praksis:

  • Den nye secret key afviser anmodninger fra browsere: Supabase matcher User-Agent og returnerer 401. Den gamle service_role-JWT har ikke sådan et tjek, så en lækket gammel nøgle virker fra hvor som helst. Min lokale stack, som ikke har et sådant gateway-tjek, svarede et script med secret key med alle 3 rækker.
  • En secret key omgår kun RLS, når anmodningen ikke bærer en brugers token. Med en indlogget brugers token kører anmodningen under den brugers policies.

En Edge Function, der bruger secret key, skal selv tjekke, hvem der kalder, og filtrere efter ejer eller virksomhed, fordi intet under den gør det.

Hvor finder du nøglerne?

I Dashboard åbner du dit projekts Connect-dialog for URL og publishable key, eller Settings → API Keys for alle nøgler, de gamle inklusive. Lokalt skriver supabase start og supabase status en publishable key og en secret key ud. Hold dem i miljøvariabler: i Next.js må kun publishable key have præfikset NEXT_PUBLIC_, fordi bundleren sender alt med det præfiks til browseren.

Hvad gør du, hvis service role key lækkede?

Betragt den som kompromitteret: hver række i hver tabel kunne læses og skrives af den, der fandt den.

  1. Opret en ny secret key, flyt dine servere over på den, og slet den lækkede. Hvis lækagen var en gammel service_role-nøgle, er vejen ud at skifte til de nye nøgler: opret en publishable og en secret key, skift appen over, og deaktivér derefter de gamle nøgler i Settings → API Keys, hvor de ellers forbliver gyldige.
  2. Søg i den byggede JavaScript og i Git-historikken efter sb_secret_ og service_role. Escapes scanning af 5.600 apps lavet med vibe coding fandt over 400 afslørede hemmeligheder, de fleste i frontend-bundles.
  3. Gennemgå, hvad der ændrede sig, mens den var ude: nye brugere, rolleændringer, slettede rækker.

Det gratis Supabase sikkerhedstjek læser ikke din frontend, men det læser databasesiden af det samme problem: roller, der omgår RLS, tabeller med RLS slået fra, policies der tillader hver række, og kolonner der ligner følsomme data og kan læses af anonyme besøgende. Hvordan du tjekker, hvad din offentlige nøgle når i praksis, står i vibe coding security risks, og den fulde liste, jeg kører på en app, står i min sikkerhedstjekliste til Lovable-apps.

Usikker på, hvilken nøgle din app sender ud?

Jeg kigger gerne på den og udveksler erfaringer. Ingen salgstale.

Kontakt mig

© 2026 Denys Zaichenko. Original artikel: https://madsalt.tech/da/blog/supabase-anon-key-vs-service-role-key/