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.
Thanks15 Replies
You still need a select policy to be met with upsert and delete. Not clear if your select policy is met or not.
SELECT should be possible for all users. INSERT, UPDATE and DELETE only authenticated
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.
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'); ?
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
.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. (
What is your current select RLS? What two paths did you use?
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}`;
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.
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 (
It's RLS is just like normal RLS.
I know and it's working perfectly for DB. Only faced these issues with storage
But I agree the Update or Select policy is not matching somehow.
Well, anyway thanks for your replies. It was so helpful👍
hello can someoen help me with this?
im trying to upload 400MB file into storage