Why exposed Supabase API keys are still safe, and why RLS matters
Contents
Recently, a browser extension that automatically detects Supabase API keys has been making the rounds. “Pulling out API keys” sounds like hacking, but in practice it is only picking up strings that are already written in a web page’s source code.
Why are they so easy to find? Because Supabase is designed with the assumption that API keys will be exposed in the frontend.
So I wanted to sort out why that design is still safe, and what the real risk actually is.
The two types of Supabase API keys
Supabase mainly has two kinds of API keys.
Anon Key
- Used in the frontend
- Safe even if it is visible
- Only has the privileges of an unauthenticated user
- Intended to be used together with RLS, which is described below
Service Role Key
- Used only on the server side
- Must never be exposed
- Can bypass RLS and access all data
- Equivalent to administrator privileges
The official documentation is very explicit about this:
Never expose your service_role and secret keys publicly. Your data is at risk.
Why it is safe for the Anon Key to be visible
A browser-based application is downloaded to the user’s machine and executed there. In other words, if you open the developer tools (F12) and inspect the source, you can find any API key.
There is no way to hide that. If you want to hide it, the only option is to route all Supabase calls through your own server.
Supabase accepts this reality and uses an architecture in which the Anon Key can be exposed safely. The key is RLS (Row Level Security).
What RLS (Row Level Security) is
RLS is a PostgreSQL feature that controls access at the row level.
For example, you can define a policy such as “users can read and write only their own data.”
-- Enable RLS on the users table
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
-- Users can read only their own data
CREATE POLICY "Users can view own data"
ON users FOR SELECT
USING (auth.uid() = id);
-- Users can update only their own data
CREATE POLICY "Users can update own data"
ON users FOR UPDATE
USING (auth.uid() = id);
With RLS enabled, even if you call the API with the Anon Key, you can access only the data that the policy allows.
The problem: apps that do not configure RLS
When you create a table in Supabase, RLS is disabled by default. If you use the Anon Key in that state, anyone can access all of the data.
The official documentation says:
Any table without RLS enabled in the public schema will be accessible to the public, using the anon role.
In other words:
- If RLS is configured correctly, the Anon Key being visible is fine
- If RLS is disabled, the database is effectively public
Why AI code generation tools are being targeted
In 2025, a vulnerability was discovered in apps created with the AI code-generation platform Lovable (CVE-2025-48757). More than 170 apps were affected, exposing data for about 13,000 users.
The cause was simple: RLS policies had not been configured.
When you ask AI to generate “working code,” it tends to prioritize making the app run first. Security settings are often left for later. The result looks like this:
- AI generates the Supabase initialization code
- Tables are created, and RLS remains disabled by default
- The app works, so it gets deployed as-is
- Anon Key is visible + RLS is disabled = all data is exposed
The extension getting attention right now is basically a tool for efficiently finding sites that are public because RLS was never configured.
SupaExplorer: a security auditing tool
One of the extensions in question is “SupaExplorer.” It is a Chrome extension for security engineers with the following features:
- Detect Supabase API keys from web pages
- Audit RLS policies
- List exposed tables
- Detect more than 15 kinds of API keys, including AWS, Stripe, and OpenAI
All processing happens locally, and no data is sent outside.
Official site: supaexplorer.com
It can be useful for checking the security of your own project.
Checklist
If you use Supabase, check the following.
Must-have
- RLS is enabled on all tables
- Proper RLS policies are configured
- The Service Role Key is not used in the frontend
- The Service Role Key is not stored in an environment variable with the
NEXT_PUBLIC_orVITE_prefix
Recommended
- Check RLS status in Supabase Dashboard under
Database > Tables - Scan your site with a tool such as SupaExplorer
- Move sensitive operations to Edge Functions
Summary
- The Supabase Anon Key being visible is by design and is not a problem by itself
- Security is provided by RLS (Row Level Security)
- If RLS is not configured, the database becomes public
- AI code-generation tools tend to forget RLS settings, so be careful
The essence of this story is that there is now a tool that automatically finds “houses with the entrance key left out but the chain lock not engaged.”
In short: lock the door when you leave the house.