FixRLSFixRLS
  • RLS Error
  • service_role Key
  • Publishable Key
  • Anon Key
  • MCP Setup
  • Blog
Why You Should Never Put Your Supabase `service_role` Key in the Frontend
2026/06/09

Why You Should Never Put Your Supabase `service_role` Key in the Frontend

Why the Supabase service_role key must stay out of browser code and what to do if it leaked.

Supabase projects usually expose more than one key.

That can confuse developers, especially when an app is generated by an AI coding tool and something does not work.

A common mistake is to reach for the service_role key because it "fixes" the problem.

It does fix one problem.

It creates a much bigger one.


What the service_role key does

The Supabase service_role key is powerful because it can bypass Row Level Security.

That makes it useful for trusted backend environments.

Examples:

  • server-side admin jobs
  • backend scripts
  • secure API routes
  • migration or maintenance tasks
  • trusted service-to-service operations

It is not meant for browser code.


Why it is dangerous in the frontend

Anything shipped to the browser should be treated as public.

If your frontend JavaScript contains a secret, users can inspect it.

They can find it in:

  • browser devtools
  • bundled JavaScript
  • network requests
  • source maps
  • logs
  • copied code snippets

If a service_role key leaks, an attacker may be able to bypass the RLS policies that were supposed to protect your data.


The misleading part

The dangerous thing about the service_role key is that it often appears to solve the immediate issue.

For example, you may see:

new row violates row-level security policy

Then you ask an AI assistant for help.

It might suggest using the service_role key.

The app starts working.

The error disappears.

But the reason it works is that you bypassed the authorization layer.

That is not the same as fixing RLS.


What should go in frontend code?

For browser-side Supabase clients, use the public key intended for frontend use.

In newer Supabase projects, that is commonly the publishable key.

In older code and many tutorials, you may see the anon key.

The important rule is:

Frontend keys are public. Secret keys belong on the server.

Your frontend key should still be protected by RLS policies.

The key itself is not your security boundary.

RLS is.


A safer pattern

Use the public key in the browser:

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!
);

Use secret keys only on the server:

const supabaseAdmin = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!
);

And keep server-only environment variables out of NEXT_PUBLIC_.

In Next.js, that prefix matters.

Anything with NEXT_PUBLIC_ is intended to be exposed to the browser.


When you think you need service_role

Before using service_role, ask:

  1. Is this operation truly administrative?
  2. Does it need to bypass user-level access rules?
  3. Can it run in a server-only context?
  4. Is there an RLS policy that would solve this instead?

For normal user actions like creating a todo, updating a profile, or reading user-owned records, the answer is usually:

You need a better RLS policy, not a service_role key.


What to do if you already exposed it

If you accidentally exposed a service_role key:

  1. Remove it from frontend code.
  2. Rotate the key in Supabase.
  3. Check deployment environment variables.
  4. Search the repository history.
  5. Review logs and build output.
  6. Replace the bypass with proper RLS policies.
  7. Test that users cannot access other users' data.

Do not just delete the variable and move on.

Assume it may have been copied.


Why I built a small checker-style guide

I built FixRLS to help developers reason through Supabase key placement and RLS fixes without asking them to paste secrets.

It does not connect to your Supabase project.
It does not request your keys.
It generates guidance, repair prompts, RLS starting points, and proof-of-fix tests.

For service role key issues, start here:

https://fixrls.dev/supabase-service-role-key


Final thought

If a service_role key makes your frontend app work, that is a warning sign.

It means you probably bypassed the policy layer instead of fixing it.

The safer path is:

  • public key in the browser
  • secret key on the server
  • RLS policies for user access
  • proof-of-fix tests for both allowed and denied cases

Related FixRLS page

For this specific issue, use the matching FixRLS page: https://fixrls.dev/supabase-service-role-key

All Posts

Author

avatar for FixRLS
FixRLS

Categories

  • Supabase Keys
What the service_role key doesWhy it is dangerous in the frontendThe misleading partWhat should go in frontend code?A safer patternWhen you think you need service_roleWhat to do if you already exposed itWhy I built a small checker-style guideFinal thoughtRelated FixRLS page

More Posts

Supabase Publishable Key vs Anon Key: What Actually Matters
Supabase Keys

Supabase Publishable Key vs Anon Key: What Actually Matters

What matters when choosing between Supabase publishable keys and anon keys for frontend apps.

avatar for FixRLS
FixRLS
2026/06/11
Is It Safe to Expose Your Supabase Anon Key?
Supabase RLSSupabase Keys

Is It Safe to Expose Your Supabase Anon Key?

How to reason about visible Supabase anon keys, RLS policies, and what actually protects user data.

avatar for FixRLS
FixRLS
2026/06/10
How I Fixed "new row violates row-level security policy" in Supabase
Supabase RLS

How I Fixed "new row violates row-level security policy" in Supabase

A practical mental model for fixing Supabase new row violates row-level security policy errors without bypassing RLS.

avatar for FixRLS
FixRLS
2026/06/06

Newsletter

Join the community

Subscribe to our newsletter for the latest news and updates

FixRLSFixRLS

Copy-paste RLS SQL, key guidance, MCP guardrails, and proof-of-fix tests before launch.

Independent tool. Not affiliated with Supabase. Not a scanner. Do not paste real secrets.

Fix Kit
  • RLS insert error
  • service_role key
  • publishable key
  • anon key exposed
  • Supabase MCP setup
Safety
  • Launch Safety Pack intent
  • Safety boundaries
  • Blog
  • GitHub examples
  • FAQ
Legal
  • Privacy Policy
  • Terms of Service
© 2026 FixRLS. All Rights Reserved.
GitHub