mirror of
https://github.com/supabase/agent-skills.git
synced 2026-03-27 10:09:26 +08:00
3.0 KiB
3.0 KiB
title, tags
| title | tags |
|---|---|
| Configure Storage Access Control | storage, buckets, public, private, rls, policies, security |
Configure Storage Access Control
Storage access combines bucket visibility settings with RLS policies on
storage.objects. Understanding both is essential.
Public vs Private Buckets
"Public" ONLY affects unauthenticated downloads. All other operations require RLS policies.
| Operation | Public Bucket | Private Bucket |
|---|---|---|
| Download | No auth needed | Signed URL or auth header |
| Upload | RLS required | RLS required |
| Update | RLS required | RLS required |
| Delete | RLS required | RLS required |
Incorrect assumption:
// "Public bucket means anyone can upload" - WRONG
await supabase.storage.from('public-bucket').upload('file.txt', file);
// Error: new row violates row-level security policy
Bucket Configuration
insert into storage.buckets (id, name, public, file_size_limit, allowed_mime_types)
values (
'avatars',
'avatars',
true,
5242880, -- 5MB
array['image/jpeg', 'image/png', 'image/webp']
)
on conflict (id) do nothing;
Storage Helper Functions
Use these in RLS policy expressions:
storage.filename(name) -- 'folder/file.jpg' -> 'file.jpg'
storage.foldername(name) -- 'user/docs/f.pdf' -> ['user', 'docs']
storage.extension(name) -- 'file.jpg' -> 'jpg'
Common RLS Patterns
User Folder Isolation
create policy "User folder access"
on storage.objects for all to authenticated
using (
bucket_id = 'user-files' and
(storage.foldername(name))[1] = (select auth.uid())::text
)
with check (
bucket_id = 'user-files' and
(storage.foldername(name))[1] = (select auth.uid())::text
);
Owner-Based Access
create policy "Owner access"
on storage.objects for all to authenticated
using (owner_id = (select auth.uid()::text))
with check (owner_id = (select auth.uid()::text));
File Type Restriction
create policy "Images only"
on storage.objects for insert to authenticated
with check (
bucket_id = 'images' and
storage.extension(name) in ('jpg', 'jpeg', 'png', 'webp', 'gif')
);
Public Read, Authenticated Write
create policy "Public read"
on storage.objects for select to public
using (bucket_id = 'public-assets');
create policy "Auth write"
on storage.objects for insert to authenticated
with check (bucket_id = 'public-assets');
SDK Method to RLS Operation
| SDK Method | SQL Operation |
|---|---|
| upload | INSERT |
| upload (upsert) | SELECT + INSERT + UPDATE |
| download | SELECT |
| list | SELECT |
| remove | DELETE |
| move | SELECT + UPDATE |
| copy | SELECT + INSERT |
| copy (upsert) | SELECT + INSERT + UPDATE |
Related
- db/rls-common-mistakes.md - General RLS pitfalls
- db/rls-policy-types.md - PERMISSIVE vs RESTRICTIVE
- Docs