mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
178 lines
6.3 KiB
Plaintext
178 lines
6.3 KiB
Plaintext
import Layout from '~/layouts/DefaultGuideLayout'
|
|
|
|
export const meta = {
|
|
id: 'storage-access-control',
|
|
title: 'Access Control',
|
|
description: 'Manage who can access your Supabase Storage files.',
|
|
subtitle: 'Manage who can access your Supabase Storage files.',
|
|
tocVideo: '4ERX__Y908k',
|
|
}
|
|
|
|
Supabase Storage is designed to work perfectly with [Postgres Row Level Security](/docs/guides/database/postgres/row-level-security) (RLS).
|
|
|
|
You can use RLS to create [Security Access Policies](https://www.postgresql.org/docs/current/sql-createpolicy.html) that are incredibly powerful and flexible, allowing you to restrict access based on your business needs.
|
|
|
|
## Policies
|
|
|
|
Policies are just SQL, and they're easy once you get the hang of them. For example, here is a Policy that allows public access to any files in a bucket called "my_bucket_id".
|
|
|
|
```sql
|
|
create policy "Public Access"
|
|
on storage.objects
|
|
for select -- Allow read access
|
|
to anon, authenticated -- Allow access to anonymous and authenticated users
|
|
using ( bucket_id = 'my_bucket_id' ); -- Identify the bucket
|
|
```
|
|
|
|
An easy way to get started would be to create RLS policies for `SELECT`, `INSERT`, `UPDATE`, `DELETE` operations and restrict the policies to meet your security requirements. For example, one can start with the following `INSERT` policy:
|
|
|
|
```sql
|
|
create policy "policy_name"
|
|
ON storage.objects
|
|
for insert with check (
|
|
true
|
|
);
|
|
```
|
|
|
|
and modify it to only allow authenticated users to upload assets to a specific bucket by changing it to:
|
|
|
|
```sql
|
|
create policy "policy_name"
|
|
on storage.objects for insert to authenticated with check (
|
|
-- restrict bucket
|
|
bucket_id = 'my_bucket_id'
|
|
);
|
|
```
|
|
|
|
## Metadata storage
|
|
|
|
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](/docs/reference/javascript/storage-createbucket).
|
|
|
|
## Public and private buckets
|
|
|
|
Storage buckets are private by default. For private buckets, you can access objects via the [download](/docs/reference/javascript/storage-from-download) method. This corresponds to `/object/auth/` API endpoint. Alternatively, you can create a publicly shareable URL with an expiry date using the [createSignedUrl](/docs/reference/javascript/storage-from-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](/docs/reference/javascript/storage-from-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](#policies) is required for other operations like uploading, deleting objects from public buckets as well.
|
|
|
|
Public buckets also tend to have [better performance](/docs/guides/storage-cdn#public-vs-private-buckets).
|
|
|
|
The URLs to access storage endpoints are prefixed with <code>/storage/v1</code>. For example, on the hosted Platform they will be:
|
|
|
|
<code>https://[project_ref].supabase.co/storage/v1/object/public/[id]</code>
|
|
|
|
You can access the storage API directly with the same endpoint. See the <a href="https://supabase.github.io/storage-api">API docs</a> for a full list of operations available.
|
|
|
|
## Helper functions
|
|
|
|
Supabase Storage provides SQL helper functions which you can use in your database queries and RLS policies.
|
|
|
|
### `storage.filename()`
|
|
|
|
Returns the name of a file. For example, if your file is stored in `public/subfolder/avatar.png` it would return: `'avatar.png'`
|
|
|
|
**Usage**
|
|
|
|
This example demonstrates how you would allow any user to download a file called `favicon.ico`:
|
|
|
|
```sql
|
|
create policy "Allow authenticated uploads"
|
|
on storage.objects
|
|
for select
|
|
to public
|
|
using (
|
|
storage.filename(name) = 'favicon.ico'
|
|
);
|
|
```
|
|
|
|
### `storage.foldername()`
|
|
|
|
Returns an array path, with all of the subfolders that a file belongs to. For example, if your file is stored in `public/subfolder/avatar.png` it would return: `[ 'public', 'subfolder' ]`
|
|
|
|
**Usage**
|
|
|
|
This example demonstrates how you would allow authenticated users to upload files to a folder called `private`:
|
|
|
|
```sql
|
|
create policy "Allow authenticated uploads"
|
|
on storage.objects
|
|
for insert
|
|
to authenticated
|
|
with check (
|
|
storage.foldername(name)[1] = 'private'
|
|
);
|
|
```
|
|
|
|
### `storage.extension()`
|
|
|
|
Returns the extension of a file. For example, if your file is stored in `public/subfolder/avatar.png` it would return: `'png'`
|
|
|
|
**Usage**
|
|
|
|
This example demonstrates how you would allow restrict uploads to only PNG files inside a bucket called `cats`:
|
|
|
|
```sql
|
|
create policy "Only allow PNG uploads"
|
|
on storage.objects
|
|
for insert
|
|
to authenticated
|
|
with check (
|
|
bucket_id = 'cats' and storage.extension(name) = 'png'
|
|
);
|
|
```
|
|
|
|
## Usage
|
|
|
|
Row Level Security is extremely versatile, since it simply uses SQL to express access rules for your data. You can learn more about RLS in the [Database docs](/docs/guides/database/postgres/row-level-security).
|
|
|
|
### Allowing public access to a bucket
|
|
|
|
Allow public access to any files in the "public" bucket:
|
|
|
|
```sql
|
|
create policy "Public Access"
|
|
on storage.objects for select
|
|
to public
|
|
using ( bucket_id = 'public' );
|
|
```
|
|
|
|
### Allowing logged-in access to a bucket
|
|
|
|
Allow logged-in access to any files in the "restricted" bucket:
|
|
|
|
```sql
|
|
create policy "Restricted Access"
|
|
on storage.objects for select
|
|
to authenticated
|
|
using ( bucket_id = 'restricted' );
|
|
```
|
|
|
|
### Allowing individual access to a file
|
|
|
|
Allow a user to access their own files:
|
|
|
|
```sql
|
|
create policy "Individual user Access"
|
|
on storage.objects for select
|
|
to authenticated
|
|
using ( auth.uid() = owner );
|
|
```
|
|
|
|
---
|
|
|
|
{/* Finish with a video. This also appears in the Sidebar via the "tocVideo" metadata */}
|
|
|
|
<div className="video-container">
|
|
<iframe
|
|
src="https://www.youtube-nocookie.com/embed/4ERX__Y908k"
|
|
frameBorder="1"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
allowFullScreen
|
|
></iframe>
|
|
</div>
|
|
|
|
export const Page = ({ children }) => <Layout meta={meta} children={children} />
|
|
|
|
export default Page
|