Home

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.


_10
select storage.filename(name)
_10
from 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.


_10
select storage.foldername(name)
_10
from 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.


_10
select storage.extension(name)
_10
from 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
_10
create policy "Public Access"
_10
on storage.objects for select
_10
using ( bucket_id = 'public' );

Allow logged-in access to a bucket#


_10
-- 1. Allow logged-in access to any files in the "restricted" bucket
_10
create policy "Restricted Access"
_10
on storage.objects for select
_10
to authenticated
_10
using ( bucket_id = 'restricted' );

Allow individual access to a file#


_10
-- 1. Allow a user to access their own files
_10
create policy "Individual user Access"
_10
on storage.objects for select
_10
using ( auth.uid() = owner );