---
title: "Supabase anon key vs service role key: cosa apre ciascuna"
description: "La anon key (publishable) di Supabase è sicura nel browser solo dietro la RLS; la service role key (secret) la aggira. Dove va ciascuna, testato in locale."
url: "https://madsalt.tech/it/blog/supabase-anon-key-vs-service-role-key/"
author: "Denys Zaichenko"
language: "it"
published: 2026-10-25
---

# Supabase anon key vs service role key: cosa apre ciascuna

In breve

La anon key, ora chiamata publishable key, è fatta per essere pubblica: corrisponde al ruolo `anon` o `authenticated`, e sono le sue policy RLS a decidere cosa vede. La service role key, ora secret key, corrisponde a `service_role`, che aggira del tutto la RLS. Sulla mia tabella di test locale, con la RLS attiva e senza policy, la chiave pubblica ha ottenuto 0 righe e la secret key tutte e 3. Metta la publishable key nel browser, tenga la secret key su un server e la ruoti se è mai stata pubblicata.

Sono Denys, ingegnere full-stack e di IA. Una secret key trapelata è la prima cosa che cerco quando prendo in mano un'app Supabase, perché con quella ogni altra protezione è decorazione. Questo articolo spiega cosa apre ciascuna chiave, con le richieste che ho eseguito per verificarlo.

## Cos'è la anon key di Supabase?

La anon key identifica la sua app, non il suo utente. Ogni richiesta da un browser o da un'app mobile la porta con sé, quindi deve essere pubblica: chiunque può leggerla nel sorgente della pagina. Una richiesta con questa sola chiave gira come ruolo Postgres `anon`. Quando un utente accede tramite Supabase Auth, la stessa chiave viaggia con il token dell'utente e la richiesta gira come `authenticated`. Le sue policy RLS sono scritte per questi due ruoli.

Supabase sta rinominando le chiavi. La [guida alle API keys](https://supabase.com/docs/guides/api/api-keys) chiama le nuove publishable (`sb_publishable_…`) e secret (`sb_secret_…`) e depreca le vecchie chiavi `anon` e `service_role` basate su JWT entro la fine del 2026. I ruoli dietro di esse restano gli stessi.

| Chiave                         | Nome precedente    | Ruolo Postgres                                     | La RLS si applica?          | Dove va                                     |
| ------------------------------ | ------------------ | -------------------------------------------------- | --------------------------- | ------------------------------------------- |
| Publishable `sb_publishable_…` | `anon` key         | `anon`, oppure `authenticated` con un token utente | Sì                          | Browser, app mobile, tutto ciò che pubblica |
| Secret `sb_secret_…`           | `service_role` key | `service_role`                                     | No, il ruolo ha `BYPASSRLS` | Solo server, Edge Function, job cron        |

## È sicuro esporre la anon key di Supabase?

Sì, se ogni tabella, vista e funzione che raggiunge è protetta. La chiave in sé non concede nulla di speciale; decidono tutto i grant e le policy del suo schema. L'ho verificato su uno stack Supabase locale (CLI 2.109.1, Postgres 17.6) con una tabella di tre ordini finti:

![In quale ruolo Postgres si trasforma ogni chiave. E se le sue policy RLS vedono la richiesta. Publishable key, non autenticato: Publishable key → ruolo anon → policy RLS applicate; Publishable key, autenticato: Publishable key + token utente → ruolo authenticated → policy RLS applicate; Secret key: Secret key → ruolo service_role → RLS saltata.](https://madsalt.tech/charts/it/supabase-anon-key-vs-service-role-key.svg)

*Figura 1. Dalla guida alle API keys di Supabase, verificata su uno stack locale, 23 ottobre 2026.*

| Stato della tabella               | Publishable key                                                               | Secret key         |
| --------------------------------- | ----------------------------------------------------------------------------- | ------------------ |
| RLS disattivata                   | Tutte e 3 le righe, e un insert ha restituito `201 Created`                   | Tutte e 3 le righe |
| RLS attiva, nessuna policy        | `[]`                                                                          | Tutte e 3 le righe |
| RLS attiva, policy `using (true)` | Tutte e 3 le righe                                                            | Tutte e 3 le righe |
| Nessun grant per `anon`           | `42501 permission denied`, con un suggerimento che nomina il `GRANT` mancante | Tutte e 3 le righe |

Quindi la publishable key è sicura quanto la sua tabella più debole. Una tabella senza RLS, o con una policy che consente ogni riga, è leggibile da chiunque apra DevTools. È la falla dietro la [CVE-2025-48757](https://mattpalmer.io/posts/2025/05/statement-on-CVE-2025-48757/), in cui 170 delle 1.645 app vetrina di Lovable servivano dati alla chiave pubblica.

## Cos'è la service role key e perché è pericolosa?

La secret key è la chiave universale. Gira come `service_role`, che ha l'attributo `BYPASSRLS`, quindi nessuna policy che scrive si applica mai a lei. Nell'ultima colonna della tabella qui sopra ha letto tutte e tre le righe in ogni stato. La guida di Supabase elenca dove va usata: server che eseguono controlli di autorizzazione propri, Edge Function, job in background e strumenti di amministrazione. Due dettagli della guida contano nella pratica:

- La nuova secret key rifiuta le richieste dal browser: Supabase confronta lo `User-Agent` e risponde `401`. Il vecchio JWT `service_role` non ha questo controllo, quindi una vecchia chiave trapelata funziona da qualsiasi posto. Il mio stack locale, che non ha un controllo di questo tipo sul gateway, ha risposto a uno script con la secret key restituendo tutte e 3 le righe.
- Una secret key aggira la RLS solo quando la richiesta non porta un token utente. Con il token di un utente autenticato, la richiesta gira sotto le policy di quell'utente.

Una Edge Function che usa la secret key deve controllare da sola chi chiama e filtrare da sola per proprietario o azienda, perché sotto non c'è più nulla che lo faccia.

## Dove si trovano le chiavi?

Nella Dashboard, apra la finestra Connect del progetto per l'URL e la publishable key, oppure Settings → API Keys per tutte le chiavi, comprese quelle vecchie. In locale, `supabase start` e `supabase status` stampano una publishable key e una secret key. Le tenga in variabili d'ambiente: in Next.js solo la publishable key può avere il prefisso `NEXT_PUBLIC_`, perché il bundler consegna al browser tutto ciò che ha quel prefisso.

## Cosa fare se la service role key è trapelata?

La consideri compromessa: ogni riga di ogni tabella era leggibile e scrivibile da chi l'ha trovata.

1. Crei una nuova secret key, sposti i suoi server su di essa, poi elimini quella trapelata. Se era una vecchia `service_role` key, la via d'uscita è il passaggio alle nuove chiavi: crei una publishable key e una secret key, cambi l'app, poi disattivi le vecchie chiavi in Settings → API Keys, dove altrimenti restano valide.
2. Cerchi `sb_secret_` e `service_role` nel JavaScript compilato e nella cronologia Git. La scansione di Escape su 5.600 app vibe-coded ha trovato [oltre 400 segreti esposti](https://escape.tech/blog/methodology-how-we-discovered-vulnerabilities-apps-built-with-vibe-coding/), la maggior parte nei bundle del frontend.
3. Riveda cosa è cambiato mentre era fuori: nuovi utenti, cambi di ruolo, righe eliminate.

Il [Controllo sicurezza Supabase](https://madsalt.tech/it/tools/supabase-security-check/) gratuito non legge il suo frontend, ma legge il lato database dello stesso problema: ruoli che aggirano la RLS, tabelle con la RLS disattivata, policy che consentono ogni riga e colonne che sembrano sensibili e sono leggibili dai visitatori anonimi. Per controllare cosa raggiunge in pratica la sua chiave pubblica, i passaggi sono in [rischi di sicurezza del vibe coding](https://madsalt.tech/it/blog/vibe-coding-security-risks/), e la lista completa che seguo su un'app è nella mia [checklist di sicurezza per le app Lovable](https://madsalt.tech/it/blog/lovable-app-security-checklist/).

Non è sicuro di quale chiave pubblichi la sua app?

Do volentieri un'occhiata e mi confronto con Lei. Nessuna vendita.

[Mi contatti](https://madsalt.tech/it/#contact)
