In breve
Un bucket pubblico serve ogni file che contiene a chiunque abbia l’URL, senza chiave né login: le sue policy di storage non vengono consultate per i download. Sul mio stack locale lo stesso file di test ha restituito 200 con il suo contenuto da un bucket pubblico e 400 da uno privato. Upload, eliminazioni e spostamenti passano ancora dalle policy. Usi i bucket pubblici per i file pubblici per natura, come avatar e immagini degli articoli, e i bucket privati con signed URL per tutto il resto.
Il mio checker di sicurezza per Supabase gratuito ha due regole sui bucket: “Bucket di storage pubblici” li elenca perché lei possa confermare che ognuno sia davvero destinato a essere pubblico, e “Bucket pubblici senza limiti di upload” segnala i bucket pubblici senza limite di dimensione o di tipo di file. Ecco cosa cambia davvero il flag pubblico.
Cosa significa bucket pubblico in Supabase?
La guida ai bucket di Supabase definisce due modelli di accesso. In un bucket privato ogni operazione, download compresi, passa dalle policy RLS su storage.objects; un file si legge con il token dell’utente o con una signed URL che scade. In un bucket pubblico il recupero e la distribuzione dei file aggirano il controllo degli accessi, quindi chiunque abbia l’URL può leggere il file. Il controllo degli accessi vale ancora per upload, eliminazione, spostamento e copia.
I bucket sono privati di default. Un bucket diventa pubblico quando qualcuno spunta la casella nella Dashboard o lo crea con public: true, una scorciatoia comune quando un’immagine non si carica.
Cosa ha restituito ciascun bucket nel mio test?
Su uno stack Supabase locale (CLI 2.109.1) ho creato un bucket pubblico e uno privato, caricato in entrambi lo stesso piccolo file di testo con la secret key, poi l’ho richiesto senza alcuna chiave, come farebbe un estraneo con il link:
Richiesta di 2026/invoice-001.txt |
Bucket pubblico | Bucket privato |
|---|---|---|
/storage/v1/object/public/…, senza chiave |
200, contenuto del file |
400, “Bucket not found” |
/storage/v1/object/authenticated/…, solo publishable key |
200 |
400 |
Il bucket privato risponde come se non esistesse, ed è ciò che si vuole. Quello pubblico consegna il file a chiunque indovini o trovi il percorso.
Perché l’URL conta così tanto?
Un file pubblico è segreto solo quanto il suo percorso. I percorsi sono spesso prevedibili: un id utente, una data, un numero di fattura. Trapelano anche dal sorgente delle pagine, dai link condivisi, dalla cronologia del browser e dai log. Una fattura, la scansione di un passaporto o un contratto firmato in un bucket pubblico è di fatto pubblicato.
Come si sceglie e si corregge?
- Bucket pubblico: file destinati a tutti, come avatar, foto di prodotto e immagini del blog. Imposti sul bucket un limite di dimensione e i tipi MIME consentiti, così il percorso di upload pubblico che le sue policy permettono non può servire a ospitare altro.
- Bucket privato: documenti, export, fatture, qualsiasi cosa personale. Scarichi con la sessione dell’utente, oppure crei una signed URL che scade.
Per vedere i suoi bucket e i loro limiti:
select id, public, file_size_limit, allowed_mime_types
from storage.buckets
order by public desc, id;
Un bucket privato richiede anche policy su storage.objects, che di solito controllano che la prima cartella del percorso sia l’id dell’utente o dell’azienda. Dopo aver spostato un progetto, conti quelle policy: in un’app ogni upload falliva perché la migrazione delle policy non era mai stata eseguita, cosa che ho raccontato nella mia checklist di sicurezza per le app Lovable. Cos’altro può raggiungere la publishable key è in Supabase anon key vs service role key.