diff --git a/apps/docs/content/guides/storage/schema/helper-functions.mdx b/apps/docs/content/guides/storage/schema/helper-functions.mdx index b8fef508159..afdc2ba8d06 100644 --- a/apps/docs/content/guides/storage/schema/helper-functions.mdx +++ b/apps/docs/content/guides/storage/schema/helper-functions.mdx @@ -61,3 +61,57 @@ with check ( bucket_id = 'cats' and storage.extension(name) = 'png' ); ``` + +### `storage.allow_only_operation()` + +Returns `true` when the current Storage API operation exactly matches the provided operation name. + +This is useful when a single SQL privilege such as `SELECT` is used by multiple Storage actions, but you want a policy to apply to only one of them, such as object listing versus object download. + +The current operation names are defined in [`src/http/routes/operations.ts`](https://github.com/supabase/storage/blob/master/src/http/routes/operations.ts). + +Storage normalizes operation names before comparing them, so both of the following forms are treated as equivalent: + +- `storage.object.list` +- `object.list` + +The comparison remains exact after normalization. Partial values such as `object` do not match `object.list`. If the current operation is not set, or the input is empty, the function returns `false`. + +**Usage** + +This example demonstrates how you would allow authenticated users to list only their own objects: + +```sql +create policy "Allow users to list their own objects" +on storage.objects +for select +to authenticated +using ( + storage.allow_only_operation('object.list') + and owner_id = (select auth.uid()::text) +); +``` + +### `storage.allow_any_operation()` + +Returns `true` when the current Storage API operation exactly matches any operation in the provided array. + +Use this when the same policy should apply to a small set of Storage actions. + +**Usage** + +This example demonstrates how you would allow authenticated users to list their own objects and read their own authenticated objects: + +```sql +create policy "Allow users to list and read their own authenticated objects" +on storage.objects +for select +to authenticated +using ( + storage.allow_any_operation(ARRAY[ + 'object.list', + 'storage.object.get_authenticated' + ]) + and owner_id = (select auth.uid()::text) +); +``` diff --git a/apps/docs/content/guides/storage/security/access-control.mdx b/apps/docs/content/guides/storage/security/access-control.mdx index 29b1ce4a1d3..909896d1a62 100644 --- a/apps/docs/content/guides/storage/security/access-control.mdx +++ b/apps/docs/content/guides/storage/security/access-control.mdx @@ -16,6 +16,8 @@ By default Storage does not allow any uploads to buckets without RLS policies. Y You can find the documentation for the storage schema [here](/docs/guides/storage/schema/design) , and to simplify the process of crafting your policies, you can utilize these [helper functions](/docs/guides/storage/schema/helper-functions) . +If you need different `SELECT` policies for different Storage actions, such as listing objects versus reading authenticated objects, use the operation-aware helpers `storage.allow_only_operation()` and `storage.allow_any_operation()` documented in [Storage Helper Functions](/docs/guides/storage/schema/helper-functions). + The RLS policies required for different operations are documented [here](/docs/reference/javascript/storage-createbucket)