Skip to content

Why is my service role key client getting RLS errors or not returning data?

使用设置了服务角色 API 密钥的 Authorization 头的 Supabase 客户端,总是会绕过 RLS。默认情况下,Authorization 头是 apikey,用于 createClient。如果你遇到 RLS 错误,那说明是有用户会话进入了客户端,或者你是用可发布密钥初始化的。RLS 的强制是基于 Authorization 头,而不是 apikey 头。

🌐 A Supabase client with the Authorization header set to the service role API key will ALWAYS bypass RLS. By default the Authorization header is the apikey used in createClient. If you are getting an RLS error then you have a user session getting into the client or you initialized with the publishable key. RLS in enforced based on the Authorization header and not the apikey header.

三种常见情况,createClient apikey 被用户会话/令牌替换:

🌐 Three common cases of the createClient apikey being replaced by a user session/token:

  1. SSR 客户端已使用服务角色初始化。SSR 客户端的设计是为了通过 Cookie 共享用户会话。用户会话将会覆盖 Authorization 头中的默认 createClientapikey。如果你在使用 SSR,记得总是直接用 supabase-js 创建一个单独的服务角色服务器客户端。
  2. Edge 函数或其他服务器代码在 createClient 选项中直接将 Authorization 头设置为用户令牌/JWT。当你直接设置 Authorization 头时,这会覆盖使用 apikey 作为 Authorization 头的默认操作。
  3. 服务器客户端使用服务角色初始化,通过 signUp 创建用户或执行其他认证功能。许多认证功能会将用户会话返回给发起调用的客户端。当这种情况发生时,apikey 会被 Authorization 头部中的用户令牌/JWT 替换。如果你想在服务角色客户端中创建用户,请使用 admin.createUser()。否则,请为服务角色的操作使用单独的 Supabase 客户端。

另外要注意,在 RLS 策略中添加 service_role 没有什么用。服务角色根本不会执行这些策略。

🌐 Also note that adding service_role in RLS policies does nothing. Service role will never run the policies to begin with.