Skip to content

Conversation

@7ttp
Copy link

@7ttp 7ttp commented Dec 17, 2025

when using a service role key with createServerClient, the client was reading user sessions from cookies and using that token for authorization instead of the service role key. this caused rls to be applied even though service role keys should bypass it.

this fix detects service role keys by checking thejwtpayload and disables persistSession, ensuring the service role key is used directly for all requests.

fixes the 403 unauthorized error on storage operations when using secret keys.

closes #141

@j4w8n
Copy link
Contributor

j4w8n commented Dec 17, 2025

This might be something the maintainers wanna go ahead and do, but if you're using the key that bypasses RLS you'd typically just use the native createClient from supabase-js.

@7ttp
Copy link
Author

7ttp commented Dec 17, 2025

This might be something the maintainers wanna go ahead and do, but if you're using the key that bypasses RLS you'd typically just use the native createClient from supabase-js.

fair point, but @supabase/ssr is the recommended package for ssr frameworks as per the docs https://supabase.com/docs/guides/auth/server-side
if someone swaps anon key for service role key, it should just work. its just a minimal fix 😅

@j4w8n
Copy link
Contributor

j4w8n commented Dec 17, 2025

I understand wanting to have an ssr library native way of doing this.

Perhaps they can introduce something like createAdminClient(), because right now I'm seeing two issues with your solution:

  1. It causes a typescript error because createServerClient requires the cookies option at the very least, but it doesn't make sense to define cookie storage if we aren't persisting a session to storage. It "forces" you to define something that'll never be used.
  2. The check doesn't account for using the new secret key format, which doesn't have three "parts" separated by periods like the legacy ones do. You could have an "or" check to see if the key is prefixed with sb_secret though.

P.S. if you weren't aware, persistSession = false still stores the "session" in memory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Server client fed with a secret key returns a storage client that does not bypass RLS

2 participants