Reputation: 3
I am new to Supabase and trying to set up a private storage bucket where only users with an "Admin" role in their JWT can upload and manage files.
I’ve created the necessary policies, roles, and privileges in Supabase, but when I try to upload or retrieve files using the Supabase API, I keep getting authentication errors such as:
Despite my efforts, I can’t get Supabase Storage to recognize my JWT claims properly.
Here’s everything I’ve done step-by-step:
Created a Private Storage Bucket named Documents to store uploaded files.
I manually created the "Admin" role in Supabase to distinguish privileged users.
I enabled Row Level Security and added policies for the "Admin" role.
CREATE POLICY "Allow only Admins to insert files"
ON storage.objects
FOR INSERT
TO authenticated
WITH CHECK (
((auth.jwt() ->> 'role') = 'Admin')
OR ((auth.jwt() -> 'app_metadata' ->> 'role') = 'Admin')
);
I generated a custom JWT that includes role: "Admin" in the app_metadata.
const jwt = require('jsonwebtoken');
exports.getSupabaseToken = (userId, email, role = 'Admin', expirationTime = '2h') => {
return jwt.sign(
{
aud: "authenticated",
sub: userId,
email,
app_metadata: { role },
user_metadata: {},
role,
},
process.env.SUPABASE_JWT_SECRET,
{ expiresIn: expirationTime }
);
};
This is the decoded jwt
{
"aud": "authenticated",
"sub": "005f43c1-b7ad-4895-a6ba-6a26ff108d69",
"email": "[email protected]",
"app_metadata": {
"role": "Admin"
},
"user_metadata": {},
"role": "Admin",
"iat": 1740258968,
"exp": 1740345368
}
When I run in supabase:
SELECT auth.jwt();
I get NULL, which means Supabase is not recognizing the JWT from my request.
To test authentication, I tried cURL requests:
curl -X GET "https://gegsudafxipazfnenzrc.supabase.co/storage/v1/object/authenticated/Documents/ricevuta.pdf" \
-H "apikey: <SUPABASE_ANON_KEY>" \
-H "Authorization: Bearer <MY_JWT>"
Which gave me:
{
"statusCode": "403",
"error": "Unauthorized",
"message": "new row violates row-level security policy"
}
Or { "code": "42501", "message": "permission denied to set role "Admin"" }
Even though the JWT has role: "Admin", Supabase does not grant the "Admin" role dynamically.
This is how I pass the token to the client:
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY, {
global: {
headers: {
Authorization: `Bearer ${supabaseToken}`
}
}
});
I'm really stuck on this. I feel like I'm missing a key step in how Supabase reads JWT roles and applies policies. Any guidance would be amazing!
Upvotes: 0
Views: 9