S
Supabase2w ago
Mike

TUS Resumable Uploads + Clerk JWT returning 403 RLS error

Need help: TUS resumable uploads with Clerk JWT getting 403 RLS error Running into a persistent issue with resumable uploads using Clerk third-party auth. Would appreciate any guidance. Setup: - Next.js 15 + Clerk for authentication - Supabase Storage with TUS protocol for resumable uploads - Clerk configured as third-party provider (Dashboard → Auth → Third-Party) - Using direct storage endpoint: https://<project-id>.storage.supabase.co/storage/v1/upload/resumable TUS request headers:
Authorization: Bearer <Clerk session token> // from await Clerk.session.getToken()
apikey: <SUPABASE_ANON_KEY>
x-upsert: false
Tus-Resumable: 1.0.0
Upload-Length: <file-size>
Authorization: Bearer <Clerk session token> // from await Clerk.session.getToken()
apikey: <SUPABASE_ANON_KEY>
x-upsert: false
Tus-Resumable: 1.0.0
Upload-Length: <file-size>
Problem: - TUS POST returns 403 new row violates row-level security policy - Storage auth test works (can list buckets with same Bearer token → returns 200) - Small file uploads via service_role work fine - Storage policies use requesting_user_id() which calls convert_to_uuid(auth.jwt()->>'sub') RLS Policy (simplified):
CREATE POLICY "project_files_insert"
ON storage.objects FOR INSERT TO authenticated
WITH CHECK (
bucket_id = 'project-files' AND
EXISTS (
SELECT 1 FROM projects p
WHERE p.id::text = (storage.foldername(name))[1]
AND p.created_by = requesting_user_id()
)
);
CREATE POLICY "project_files_insert"
ON storage.objects FOR INSERT TO authenticated
WITH CHECK (
bucket_id = 'project-files' AND
EXISTS (
SELECT 1 FROM projects p
WHERE p.id::text = (storage.foldername(name))[1]
AND p.created_by = requesting_user_id()
)
);
Questions: 1. Does the Bearer token from Clerk.session.getToken() have the right format for Supabase Storage RLS? 2. Should I be using a different Clerk token method or template? 3. Is there a way to debug what requesting_user_id() returns during the Storage RLS evaluation? What works: - ✅ JWKS endpoint is accessible - ✅ Storage auth test passes (listBuckets returns 200) - ✅ JWT has sub, iss, role: "authenticated", exp - ✅ User exists in project_members with proper role What fails: - ❌ TUS POST to /storage/v1/upload/resumable → 403 RLS
1 Reply
ihm40
ihm402w ago
My first suggestion would be in you requesting_user_id function try and raise some logs using RAISE LOG 'lOG: %', auth.jwt(); or something similar and see the output that you are getting. I'm assuming that this is a database function you have defined somewhere and it is worth checking if it is in a format that you expect and that it'sv values point to something in the projects table Also as a side note, just to isolate the issue down, if you simplify the RLS for that bucket to just authenticated users are things working for you?

Did you find this page helpful?