Access Control
Supabase Storage is integrated with your Postgres Database.
This means that you can use the same Row Level Security Policies
for managing access to your files. Supabase Storage stores metadata in the objects
and buckets
table in the storage schema.
To allow read access to files, the RLS policy must allow users to SELECT
the objects
table and for uploading a new object, the RLS policy must grant users access to INSERT
into the objects
table and so on. The mapping between the different API calls and the database permissions required is documented in the Reference docs.
note
Access control for Storage is mapped to CRUD operations on the buckets
and objects
table via RLS policies.
Public and private buckets#
Storage buckets are private by default. For private buckets, you can access objects via the download method. This corresponds to /object/auth/
API endpoint.
Alternatively, you can create a publicly shareable URL with an expiry date using the createSignedUrl method
which calls the /object/sign/
API.
For public buckets, you can access the assets directly without a token or an Authorisation header. The getPublicUrl
helper method returns the full public URL for an asset. This calls the /object/public/
API endpoint internally. While no authorization is required for accessing objects in a public bucket, proper access control is required for other operations like uploading, deleting objects from public buckets as well. Public buckets also tend to have better performance.
Advanced: reverse proxy
The URLs returned are proxied through the API Proxy. They are prefixed by /storage/v1
.
For example, on the hosted Platform they will be
https://[project_ref].supabase.co/storage/v1/object/public/[id]
You can access the storage API directly with the same endpoint. See the API docs for a full list of operations available.
Helper functions#
Supabase Storage provides SQL helper functions which you can use in your database queries and policies.
storage.filename()
Returns the name of a file.
_10select storage.filename(name)_10from storage.objects;
For example, if your file is stored in public/subfolder/avatar.png
it would return:
'avatar.png'
storage.foldername()
Returns an array path, with all of the subfolders that a file belongs to.
_10select storage.foldername(name)_10from storage.objects;
For example, if your file is stored in public/subfolder/avatar.png
it would return:
[ 'public', 'subfolder' ]
storage.extension()
Returns the extension of a file.
_10select storage.extension(name)_10from storage.objects;
For example, if your file is stored in public/subfolder/avatar.png
it would return:
'png'
Policy examples#
Allow public access to a bucket#
_10-- 1. Allow public access to any files in the "public" bucket_10create policy "Public Access"_10on storage.objects for select_10using ( bucket_id = 'public' );
Allow logged-in access to a bucket#
_10-- 1. Allow logged-in access to any files in the "restricted" bucket_10create policy "Restricted Access"_10on storage.objects for select_10to authenticated_10using ( bucket_id = 'restricted' );
Allow individual access to a file#
_10-- 1. Allow a user to access their own files_10create policy "Individual user Access"_10on storage.objects for select_10using ( auth.uid() = owner );