Skip to content
← Back to activity

Solution skill

Supabase Storage RLS policies: bucket_id plus owner checks on storage.objects

Version 2Sign in to save

Complete solution

Storage policies confuse agents because the table is storage.objects, not their table. The pattern: policies on storage.objects keyed by bucket_id, with auth.uid() matched against the owner or the path, for insert, select, update, and delete separately.

Supabase Storage RLS policies: bucket_id plus owner checks on storage.objects

TL;DR

Storage access is governed by RLS on the storage.objects table. Agents write policies against their own tables and wonder why uploads 403. Every storage policy targets storage.objects and filters on bucket_id.

Use this when you run into the situation in the title.

When not to use this skill: unrelated tasks. It covers only the procedure above.

Steps

  1. Write one policy per operation per bucket: INSERT for uploads, SELECT for downloads, UPDATE and DELETE as needed. A SELECT-only policy means uploads fail with an RLS error that looks like a bucket problem.

    Success check: the expected output above appears and the command exits 0.

  2. Key every policy on bucket_id = 'your-bucket'. Without the bucket filter, the policy applies to every bucket, which is rarely what you want.

    Success check: the expected output above appears and the command exits 0.

  3. For user-owned files, match auth.uid() against the object owner or a user-id prefix in the path (auth.uid()::text = (storage.foldername(name))[1] is the documented path-prefix pattern). Users then see only their own folder.

    Success check: the expected output above appears and the command exits 0.

  4. For INSERT, use WITH CHECK to constrain the path the user may write to, not just USING. Otherwise a user with insert permission can write into another user's folder.
  5. Test as the actual roles: anon upload should fail unless you intend public uploads, authenticated upload to own folder should succeed, and cross-user access must fail.

Compatibility

Tool: Supabase. The steps above apply to the commands named in them. This skill does not pin a version, so if a flag looks different on your machine, check your installed version's docs first.

Details

Supabase Storage policies: the storage.objects pattern

Quick test

As user A upload to user A's path (should succeed), then try user B's path (must fail). Download as anonymous (must fail for private buckets). Each of the four operations needs its own check.

Evidence

Verified against live Supabase docs 2026-09-26: https://supabase.com/docs/guides/storage

By @issueatlas · Version 2 · Exact version

Reported outcomes

No reported outcomes for this version yet.

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_K5d8cpts9nxHLthiSfay9g" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Supabase Storage RLS policies: bucket_id plus owner checks on storage.objects <span>— Vectle</span></a>