Supabase storage bucket public: can anyone download or list my files?
Short answer: anyone with the URL can download every object in a public bucket without auth. Listing is separate. It depends on SELECT policies on storage.objects. For your own sites and projects, run a free SniffPup scan to see what your live site exposes. Use the checks below for your bucket settings and policies.
Home › Guides › Public storage bucket · Last updated · By Ember, SniffPup
1. Public means anyone with the URL can download
Supabase's bucket docs explain that public buckets bypass access control for downloads. This applies to every object in that bucket. An owner policy does not protect a public download.
Use getPublicUrl to get the URL, or use the path shown in the serving assets docs:
https://YOUR-PROJECT.supabase.co/storage/v1/object/public/x/USER-ID/file.pdf
const { data } = supabase.storage.from('x').getPublicUrl('USER-ID/file.pdf')Uploads, deletes and listing still go through RLS on storage.objects. Making a bucket public does not grant those operations.
2. Can anyone list my files?
Listing objects is governed by SELECT policies on storage.objects. A policy for anon with using (true) lets anyone list. A condition like bucket_id = 'x' lets anyone list objects in that bucket. It does not limit the caller to their own folder.
Review your storage policies in the dashboard. The access control docs describe policies on storage.objects. Check both public and private buckets.
3. Make private files private
Turn off the bucket's Public toggle in the dashboard, or run this SQL for your bucket:
update storage.buckets set public=false where id = 'x';
Replace broad SELECT policies with a policy scoped to the signed-in user's folder. Store each user's files under their user ID as the first folder. Replace x with your bucket ID:
create policy "Users read their own folder" on storage.objects for select to authenticated using ( bucket_id = 'x' and (storage.foldername(name))[1] = auth.uid()::text );
Use the same folder scope for upload and delete policies where those operations are needed. Remove the old broad policies rather than leaving them alongside this one.
Private buckets require either an authenticated request passing RLS on storage.objects or a signed URL. Use createSignedUrl with an expiry in seconds:
// Use a client authenticated as the user allowed by the SELECT policy.
const { data, error } = await supabase.storage
.from('x')
.createSignedUrl('USER-ID/file.pdf', 60)
// data.signedUrl expires after 60 seconds.4. Test without signing in
On sites and projects you own, try a known object URL without credentials. Then make a list call with only the anon key, with no signed-in user token:
# Public download: no auth
curl -i "https://YOUR-PROJECT.supabase.co/storage/v1/object/public/x/USER-ID/file.pdf"
# List with only the anon key (repeat for folders you need to check)
curl -i -X POST "https://YOUR-PROJECT.supabase.co/storage/v1/object/list/x" \
-H "apikey: YOUR_ANON_KEY" \
-H "Authorization: Bearer YOUR_ANON_KEY" \
-H "Content-Type: application/json" \
--data '{"prefix":"USER-ID/","limit":100,"offset":0}'Before the fix, a public object URL serves the file. After making the bucket private, that public URL should no longer serve it. The anon list call should not return private objects. An empty list does not prove downloads are private: test both calls. Then check that each signed-in user can access only their own folder, and test the signed URL before and after its expiry.
FAQ
Supabase storage bucket public: can anyone download or list my files?
Anyone with an object URL can download it without auth from a public bucket. Listing is separate: SELECT policies on storage.objects decide which objects a caller can list.
Does RLS protect downloads from a public bucket?
No. Public downloads bypass access control. Uploads, deletes and listing still go through RLS on storage.objects.
How do I share a private file?
Use createSignedUrl with an expiry, or an authenticated request that passes RLS on storage.objects.
Sources: Supabase Storage Buckets, Storage Access Control and Serving assets from Storage. Checked November 4, 2026.