Supabase Storage file upload - 403 Unauthorized

Hello everyone. I've been trying to upload files into bucket (my backend express+nodejs) but getting 403 unauthorized constantly, despite RLS are created for INSERT, UPDATE, DELETE for authorized users. const filePath = images/${product.sku}/${Date.now()}_${fileName}; const { data, error } = await supabase.storage.from('products').upload(filePath, file.buffer, { upsert: true, contentType: file.mimetype || 'application/octet-stream', }); I want files sorted by folders. As folder name I want to use product sku (0001, 0002, 0003, etc.) which will be nested folders of the root folder (images). I have feeling that RLS don't work for nested folders in a bucket. My RLS policies: -- For INSERT operations (uploading files) CREATE POLICY "Enable insert for authenticated users" ON storage.objects FOR INSERT TO authenticated WITH CHECK (bucket_id = 'products' AND auth.role() = 'authenticated'); -- For SELECT operations (reading/downloading files) CREATE POLICY "Enable read access for all users" ON storage.objects FOR SELECT USING (bucket_id = 'products' and name like 'public/%'); -- For UPDATE operations CREATE POLICY "Enable update for authenticated users" ON storage.objects FOR UPDATE USING (bucket_id = 'products' AND auth.role() = 'authenticated') WITH CHECK (bucket_id = 'products' AND auth.role() = 'authenticated'); -- For DELETE operations CREATE POLICY "Enable delete for authenticated users" ON storage.objects FOR DELETE USING (bucket_id = 'products' AND auth.role() = 'authenticated'); What am I doing wrong? It's so frustrating. Bucket set as public. I will be appreciated for any help or advice. Thanks
15 Replies
garyaustin
garyaustin3w ago
You still need a select policy to be met with upsert and delete. Not clear if your select policy is met or not.
CuriousLama
CuriousLamaOP3w ago
SELECT should be possible for all users. INSERT, UPDATE and DELETE only authenticated
garyaustin
garyaustin3w ago
Your select has an extra condition it on it. Your pathname would need to start with public/ So your file path name when you upload (with upsert which requires select policy) has to be 'public/folder2/folder3/filename.ext' type format where public is a folder name.
CuriousLama
CuriousLamaOP3w ago
So, it means SELECT also needs policy for authenticated users? Something like this: -- For SELECT operations (reading/downloading files) CREATE POLICY "Enable read access for all users" ON storage.objects FOR SELECT USING (bucket_id = 'products' AND auth.role() = 'authenticated'); ?
garyaustin
garyaustin3w ago
Does not have to. Could be To Public and True for the policy. You said it is a public bucket so everyone can download. But limiting to Authenticated would work as a Public bucket will still let non authenticated users use the Public URL. Also you should not use auth.role() as it is depreciated. Just use the TO clause. Like TO authenticated.
CuriousLama
CuriousLamaOP3w ago
updated path and RLS as you suggested, but I was able to upload one file, at the second I got 403 again and I was uploading at the same folder. (
garyaustin
garyaustin3w ago
What is your current select RLS? What two paths did you use?
CuriousLama
CuriousLamaOP3w ago
Current policies: -- For INSERT operations (uploading files) CREATE POLICY "Enable insert for authenticated users" ON storage.objects FOR INSERT TO authenticated WITH CHECK (bucket_id = 'products'); -- For SELECT operations (reading/downloading files) CREATE POLICY "Enable read access for all users" ON storage.objects FOR SELECT USING (bucket_id = 'products'); -- For UPDATE operations CREATE POLICY "Enable update for authenticated users" ON storage.objects FOR UPDATE TO authenticated WITH CHECK (bucket_id = 'products'); -- For DELETE operations CREATE POLICY "Enable delete for authenticated users" ON storage.objects FOR DELETE TO authenticated USING (bucketid = 'products'); Path const filePath = `public/images/${product.sku}/${Date.now()}${fileileName}`;
garyaustin
garyaustin3w ago
Why do you have public in the path? Just curious. Are you uploading to the same path twice? Your Update policy changed and is now not correct. You dropped the USING clause which is required for Update policy. With Check is optional for that.
CuriousLama
CuriousLamaOP3w ago
Added USING into Update policy, but it didn't work. Removed for now " upsert: true" and it worked. SO, I assume SELECT or UPDATE policies still were not correct. Unfortunately, there is not much official documentation on storage (
garyaustin
garyaustin3w ago
It's RLS is just like normal RLS.
CuriousLama
CuriousLamaOP3w ago
I know and it's working perfectly for DB. Only faced these issues with storage
garyaustin
garyaustin3w ago
But I agree the Update or Select policy is not matching somehow.
CuriousLama
CuriousLamaOP3w ago
Well, anyway thanks for your replies. It was so helpful👍
rickyschay
rickyschay2w ago
hello can someoen help me with this? im trying to upload 400MB file into storage

Did you find this page helpful?