Service key client seems to be passing around a session
I'm getting this using the service key server side to insert data.
As I understand it the service key bypasses RLS? Or do you still need to add some kind of policy?
Currently I have RLS enabled without any policies attached for this table. I basically want to restrict access completely to this table unless the service key is used.
35 Replies
You can't use auth-helpers clients for service role.
Use supabase-js regular client.
@supabase/supabase-js this is the regular client no?
Oh sorry the name you gave it sounds like an auth-helpers client.
No worries
What is the error you are getting on the insert?
Do you use Prisma?
Double check your service role.
K so it is not grants.
Are you signing in a user into the same client later?
Not using Prisma
I just verified that the service role key is correct
Somewhere you are either setting anon key into the client making the call or a user jwt is getting set into the client which will override the key.
I've never seen an RLS error from service role helping people here. It starts out like this, but in the end somehow another token is getting sent out in the call.
You can add an rls policy for TO anon and true as the policy. If that fails use TO authenticated and true. One of those will likely work and point which way is going wrong.
Tried to set anon: true, same error.
Tried to set auth: true, worked.
authenticated? If so you are signing in a user into that client somehow. You can't share clients.
Hmm odd, I mean at this stage there's no user signed in this specific flow.
This is the sign up flow, I'm however passing a JWT token to this endpoint (that's not related to Supabase auth).
If you set the authorization header for this client to a jwt then it is no longer service role. service_role can't be used with a user session at all.
You have the right auth flags set to avoid getting sessions from the url or local storage.
Oh hmm ok I guess this could be the issue.
The thing is that we have a flow where the user pays on stripe before signing up. Paid users retrieve an email with a link containing a JWT token. Once clicked they end up on a protected route where the form is connected to this endpoint.
You really should use two separate clients.
I'm not following sorry
You should do serviceRoleClient = createClient(blah)
And serverClient = createClient(blah)
Each is an object that holds state.
I think you might be sharing the object with the way you are doing your create and imports. But I don't do server side stuff myself.
Ah
I have 4 different utility functions:
This is where I bow out. You may need to ask a specific question on your environment and the way you are setting up the client if you don't figure out. I just know enough to spot issues from helping those of you do the serverside stuff here.
There's only one client used in this endpoint and it's the server-service
That won't work for service role.
As soon as the object gets a user session in from elsewhere it becomes that user.
It's this one:
According to:

It is clear your service role client is being used somewhere else as it is getting a session in from a user. It can't be shared anywhere else.
createClient creates an object to store state. If you reuse the object elsewhere then it will get the user state. Next time you use it where you expect it to be service role, it won't be. It will be an authenticated user.
Only used server-side

Silentworks is saying the same thing. The auth-helpers supabase clients can't be shared for service role.
And the env variable is only used in server-service

Does inport createClient reuse the same client?
I believe it would, so won't work.
I believe you need to export two clients.
One for service role and one for normal stuff.
My other util fn: client, server, middleware they all import client from @supabase/ssr
So there is only one client that imports from @supabase/supabase-js
OK. If you don't use it somewhere else how is it getting a user session in it?
That's what I don't understand
I thought you just showed it being used in several places.
But as I said I don't know auth-helpers or server environments to figure out what you are doing. Someone who uses those might be able to explain exactly what you are doing to cause the session to get there. I would ask a new question with that as the topic versus RLS.
You have to be reusing that exported client somewhere with a session in it. As soon as that happens it is no longer a service role client.
Ok cool!
I will create a different topic for this.
Thanks a lot for the help!
Just want to make clear based on your change. The service key client will absolutely pass around a session anywhere you use it. The issue is some where it is getting the session put in it. That is what you have to solve.
Found the issue.
I forgot about await supabase.auth.signUp... in the same endpoint. It returns a session.
Thanks!