Service role not bypassing RLS

I'm creating a SupabaseServerClient using the @supabase/ssr package, it looks like this:
export default async function createSupabaseServerClient() {
const cookieStore = cookies();
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value;
},

set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options });
},

remove(name: string, options: CookieOptions) {
cookieStore.set({ name, value: "", ...options });
},
},
}
);
}
export default async function createSupabaseServerClient() {
const cookieStore = cookies();
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value;
},

set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options });
},

remove(name: string, options: CookieOptions) {
cookieStore.set({ name, value: "", ...options });
},
},
}
);
}
This client is used in my Auth callback route to fetch user data, determining if the user is new or not. If I disable RLS on the users table, it returns the expected result. If I enable RLS on the users table, it returns a blank result. The users table has no RLS policies. Why is this? I might be misunderstanding something, but I thought the Service Key is meant to bypass RLS. Thanks.
4 Replies
silentworks
silentworks2y ago
GitHub
Performing administration tasks on the server side with the service...
By default, the auth-helpers do not permit the use of the service_role secret. This restriction is in place to prevent the accidental exposure of your service_role secret to the public. Since the a...
WreckNoFear
WreckNoFearOP2y ago
Hi there, This makes sense but now I'm confused. I modified my code to this:
"use server";

import { createServerClient, type CookieOptions } from "@supabase/ssr";
import { cookies } from "next/headers";

export default async function createSupabaseServerClient() {
const cookieStore = cookies();

return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!,
{
auth: {
persistSession: false,
autoRefreshToken: false,
detectSessionInUrl: false,
},
cookies: {
get(name: string) {
return cookieStore.get(name)?.value;
},

set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options });
},

remove(name: string, options: CookieOptions) {
cookieStore.set({ name, value: "", ...options });
},
},
}
);
}
"use server";

import { createServerClient, type CookieOptions } from "@supabase/ssr";
import { cookies } from "next/headers";

export default async function createSupabaseServerClient() {
const cookieStore = cookies();

return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!,
{
auth: {
persistSession: false,
autoRefreshToken: false,
detectSessionInUrl: false,
},
cookies: {
get(name: string) {
return cookieStore.get(name)?.value;
},

set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options });
},

remove(name: string, options: CookieOptions) {
cookieStore.set({ name, value: "", ...options });
},
},
}
);
}
However, you mention in that discussion that you should use createClient from the regular supabase package. Isn't that meant for client-side use, or am I misunderstanding something? Even so, if I use createClient, the cookies section errors out, so how am I managing cookies then, or do I even need to since this client is only used by my API. Thanks again, apologies for confusion.
silentworks
silentworks2y ago
You need to create a separate client (createClient) as the link stated. You cannot use the ssr client because its shared between the client side and server side, this will leave your service role key exposed to the client which you do not want to happen as this gives someone full access to your project without any protection.
WreckNoFear
WreckNoFearOP2y ago
Makes sense now, thanks for your help and that clarification!

Did you find this page helpful?