Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to Create Client with Service Role Key #59

Closed
mariojfduarte opened this issue Sep 4, 2024 · 12 comments
Closed

Unable to Create Client with Service Role Key #59

mariojfduarte opened this issue Sep 4, 2024 · 12 comments

Comments

@mariojfduarte
Copy link

Description

After recent changes in the createServerClient.ts file, it seems that creating a client with a service role key is no longer possible. Previously, my code allowed this by setting the admin flag to true so that Service Role Key was used, but now, even with the correct environment variables set, the client does not retain service role permissions as expected. I suspect this might be related to the changes in session persistence.

Code References

Before:

export const createClient = (options?: CreateClientOptions) => {
  const { admin = true, ...rest } = options ?? {};

  const cookieStore = cookies();

  const key = admin
    ? process.env.NEXT_SUPABASE_SERVICE_ROLE_KEY!
    : process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;

  const auth = admin
    ? {
        persistSession: false,
        autoRefreshToken: false,
        detectSessionInUrl: false,
      }
    : {};

  return createServerClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, key, {
    ...rest,
    cookies: {
      get(name: string) {
        return cookieStore.get(name)?.value;
      },
      set(name: string, value: string, options: CookieOptions) {
        try {
          cookieStore.set({ name, value, ...options });
        } catch (error) {}
      },
      remove(name: string, options: CookieOptions) {
        try {
          cookieStore.set({ name, value: "", ...options });
        } catch (error) {}
      },
    },
    auth,
    global: {
      headers: {
        "user-agent": headers().get("user-agent") as string,
      },
    },
  });
};

After:

return createServerClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, key, {
  ...rest,
  cookies: {
    getAll() {
      return cookieStore.getAll();
    },
    setAll(cookiesToSet) {
      try {
        for (const { name, value, options } of cookiesToSet) {
          cookieStore.set(name, value, options);
        }
      } catch (error) {}
    },
  },
  auth,
  global: {
    headers: {
      "user-agent": headers().get("user-agent") as string,
    },
  },
});

Problem

The recent changes seem to have removed the ability to create a client with a service role key. Even when the admin flag is set to true, the client does not behave as expected with service role permissions. This could be related to the session persistence or other changes in the client creation process.

Suspected Cause

The issue may stem from the configuration of persistSession, autoRefreshToken, or other related authentication settings. These may be preventing the client from properly maintaining service role permissions.

Suggested Solution

Investigate the interaction between the auth options and the ability to use service role keys. It may be necessary to adjust how session persistence or other authentication features are handled when using service role permissions.

Additional Context

This issue was observed in the createServerClient.ts file after the following commit:

549fe62813fb9c7277f7eda9e46ee0420f8e0b5f.

@j4w8n
Copy link
Contributor

j4w8n commented Sep 4, 2024

You should be using createClient() from @supabase/supabase-js to create a service role client, not ssr versions.

@mariojfduarte
Copy link
Author

mariojfduarte commented Sep 4, 2024

You should be using createClient() from @supabase/supabase-js to create a service role client, not ssr versions.

image

why? I tried it but no luck, doesn't seem to work with cookies

@mariojfduarte
Copy link
Author

mariojfduarte commented Sep 4, 2024

image

if I comment it out, my query result always returns null

@j4w8n
Copy link
Contributor

j4w8n commented Sep 4, 2024

A service role client shouldn't need to access cookies in order to work. What are you trying to accomplish?

@mariojfduarte
Copy link
Author

mariojfduarte commented Sep 4, 2024

A bit of context:

I need the service role to bypass row-level security (RLS) policies (not using any to make sure all requests come from server side).

I want to pre-init a zustand instance with the authenticated user. To do so, I use the session to check which user is authenticated then query my own public.users table by email using a service role key (all while in server side). The thing is, when I updated the package, it stopped working.

I had to fork, make the change, and rebuild, after what it started working. Not sure why the service role needs the perserveSession set to false, but it looks like it does.

@mariojfduarte
Copy link
Author

@j4w8n
Copy link
Contributor

j4w8n commented Sep 4, 2024

Just to be clear, is your issue resolved?

@mariojfduarte
Copy link
Author

No, I need to merge the pull request (currenlty using a fork).

I can't bypass the auth options.

image

Why is it implemented this way?

auth: {
        ...(options?.cookieOptions?.name
          ? { storageKey: options.cookieOptions.name }
          : null),
        ...options?.auth,
        flowType: "pkce",
        autoRefreshToken: false,
        detectSessionInUrl: false,
        persistSession: true,
        storage,
      },

This change solves my problem:

auth: {
        ...(options?.cookieOptions?.name
          ? { storageKey: options.cookieOptions.name }
          : null),
        
        flowType: "pkce",
        autoRefreshToken: false,
        detectSessionInUrl: false,
        persistSession: true,
...options?.auth,
        storage,
      },

@j4w8n
Copy link
Contributor

j4w8n commented Sep 5, 2024

I guess I still don't understand why you can't use createClient from @supabase/supabase-js for this.

What does your query look like?

To be a bit more clear: you should be using both clients. The ssr server client to get the user data (presumably their id), then the native service role client to do the query thst bypasses RLS.

@mariojfduarte
Copy link
Author

Correct, I'm using two clients.

Still, when using superbase-js native service role client is doesn't work.

The only way to make it work is to pass the persistSession flag to false.

@j4w8n
Copy link
Contributor

j4w8n commented Sep 5, 2024

If you call getSession with the service role client, is it returning a session? If so, I suspect the issue is that you're mistakenly setting persistSession to false for your ssr client. This causes it to store the user's session in memory. And since the service role client also has that set to false, it's picking up the user session and passing along the user's JWT with your query - resulting in not bypassing RLS.

@mariojfduarte
Copy link
Author

it worked, thanks

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

No branches or pull requests

2 participants