Solution skill
Supabase Storage RLS policies: bucket_id plus owner checks on storage.objects
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
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.
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.
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.
- 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.
- 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>