Supabase vs Firebase: two opposite ways to be exposed
Both platforms hand your database a public key and put a rules layer in front of it. That is where the similarity stops. Firebase evaluates rules in front of the datastore and rejects whole queries; Supabase evaluates policies inside Postgres and quietly removes rows. The consequence is that one tends to fail loudly during development and the other tends to fail silently in production — and that shapes what you have to watch.
Neither Supabase nor Firebase is more secure than the other, but they fail in opposite directions. Supabase Row Level Security filters rows silently, so a broken policy returns an empty list or shows the wrong data with no error, while Firestore Security Rules reject the entire query instead and break visibly during development.
Firebase's insecure default expires: test mode is wide open but stops serving after 30 days. Supabase's historical default did not expire — tables in the public schema received API grants automatically and stayed reachable indefinitely. From 30 October 2026 that changes for existing Supabase projects too.
Supabase RLS vs Firestore Security Rules at a glance
| Supabase | Firebase | |
|---|---|---|
| Boundary | Row Level Security, inside Postgres | Security Rules, in front of Firestore |
| Written in | SQL boolean expressions | Purpose-built rules language |
| On denial | Filters rows silently, query succeeds | Rejects the whole query with an error |
| Applies to | Every client of the database | SDK access; Admin SDK bypasses it |
| Insecure default | Automatic API grants, never expired | Test mode, expires after 30 days |
| Fails | Open and silent | Closed and loud |
| Bypass credential | service_role JWT string | Admin SDK service account file |
| Public client key | anon key — not a secret | Web API key — not a secret |
| Audit trail | SQL statements in Postgres logs | Versioned rules deploys |
| Testing tooling | SQL tests, role impersonation | Rules emulator and unit tests |
Where the security boundary lives in each
In Firebase, Security Rules sit between the client and Firestore. They are written in a purpose-built language, deployed as their own artifact, and evaluated per request against the document being touched. The rules are not part of your data; they are a gate in front of it.
In Supabase, the boundary is the database. Row Level Security policies are SQL expressions attached to tables and enforced by Postgres itself, so they apply no matter what speaks to the database — PostgREST, a direct connection, a background job. Nothing routes around them except a role explicitly allowed to bypass.
Both designs are defensible. The Supabase one gives you a single enforcement point and the full expressiveness of SQL. The Firebase one gives you a boundary you can version, test and deploy independently of your schema. The trouble is that each design has a characteristic way of going wrong, and they are near opposites.
Why Firestore Rules reject queries and RLS filters rows
This is the difference that catches people migrating in either direction.
Firebase Security Rules are not filters. If a query could return a single document the caller is not permitted to read, Firebase rejects the whole query. You do not get a partial result — you get an error. The practical consequence is that your queries have to be shaped so they can only ever ask for what the rules already allow, which is why Firebase developers end up writing where("ownerId", "==", uid) into queries that the rules would enforce anyway.
Supabase RLS is a filter. The query succeeds and the rows you are not allowed to see simply are not in the result. A SELECT against a table whose policy denies you returns HTTP 200 and an empty array, which is byte-for-byte identical to the response for a table that is genuinely empty.
So the same mistake produces opposite symptoms. On Firebase, a policy that is too strict breaks your app immediately and you fix it before you ship. On Supabase, a policy that is too strict shows an empty list, and a policy that is too loose shows the right data to the wrong person — neither of which raises anything. Reads are the blind spot; writes at least fail loudly with SQLSTATE 42501.
Default security: test mode, locked mode, and automatic grants
When you create a Firestore database you pick locked mode, which denies everything, or test mode, which is allow read, write: if true — completely open to anyone on the internet. Test mode is the dangerous one, with an important mitigation: it expires after 30 days and then denies everything. A project someone spun up and forgot breaks in an obvious way rather than quietly serving your data for a year. Both modes are set out in Firebase's rules documentation.
Supabase historically failed the other way. Every new table in the public schema received grants for the anon and authenticatedroles automatically, so it was reachable through the Data API from the moment it existed. RLS was the only thing standing in front of it, and RLS is enabled by default only for tables created through the dashboard's Table Editor — not for tables created in the SQL editor or by a migration, which is how most tables in a real project get made. Nothing expired. Nothing warned. The table simply stayed public.
That asymmetry — a temporary insecure default that fails closed, versus a permanent one that fails open — is the most consequential difference between the two platforms to date.
What changes on 30 October 2026
Supabase is closing exactly that gap. Tables in the public schema are no longer exposed to the Data API and GraphQL API automatically; access has to be granted explicitly:
grant select on public.your_table to anon;
grant select, insert, update, delete on public.your_table to authenticated;The rollout has three dates, per Supabase's changelog. From 28 April 2026 it was available as an opt-in toggle at project creation. From 30 May 2026 it became the default for all new projects. From 30 October 2026 it is enforced on existing projects too.
If your project predates that and leans on the automatic grants, this is a breaking change with a deadline: endpoints that work today will start failing. It is worth finding out now which of your tables are exposed by inherited grants rather than by a decision anyone made.
service_role vs the Firebase Admin SDK
Both platforms have a credential that ignores the rules entirely, and the difference is in how easy each one is to leak by accident.
Supabase's service_role key is a JWT — a string, sitting in the same dashboard page as the anon key, looking almost identical to it. It goes in an environment variable. Give that variable a NEXT_PUBLIC_ or VITE_ prefix and your bundler compiles a key that bypasses every policy you wrote straight into a file you serve to the public.
Firebase's equivalent is the Admin SDK, authenticated with a service account JSON file you download. Also catastrophic if it leaks, but a file that has to be read from disk or an environment secret is meaningfully harder to paste into client code than a string that looks exactly like the one that belongs in client code.
Firebase's public Web API key causes the mirror-image confusion: people find it in their bundle and panic. It is not a secret, exactly as Supabase's anon key is not a secret. On both platforms, the key is not the boundary. The rules are.
What each platform lets you see after something goes wrong
Firebase's rules are a deployed artifact with version history, so you can see that the gate changed and roll it back. What you get less of is a queryable record of individual denials as they happen.
Supabase's boundary changes are ordinary SQL statements, which means they land in your Postgres logs as text you can search, attribute and alert on. ALTER TABLE ... DISABLE ROW LEVEL SECURITY is right there, with the role that ran it. Denied writes appear as SQLSTATE 42501. Denied reads appear as nothing at all, because they were filtered rather than rejected — which is the one place Firebase's reject-the-query model is genuinely easier to observe.
The practical summary: on Supabase you can reconstruct what happened from your logs, but only if something is reading them. Nothing does that by default.
Is Firebase more secure than Supabase?
- Firebase is more forgiving of inattention. The insecure default expires, the rules testing tooling is genuinely good, and an over-strict rule breaks visibly in development.
- Supabase is more forgiving of complexity. Policies are SQL, so anything you can express as a query you can express as a boundary, and it holds for every client of the database rather than one SDK.
- Supabase gives you a real audit trail. Boundary changes are statements in a log you can read, which is what makes after-the-fact investigation possible at all.
- Supabase asks for more vigilance.Silent read filtering plus historically automatic grants means the gap between "secure" and "exposed" is invisible from inside the application.
Neither list makes one platform the safe choice. They describe two different jobs. On Firebase the job is writing rules carefully and testing them. On Supabase the job is writing policies carefully — and then noticing when something changes them.
What to watch on Supabase
ALTER TABLE ... DISABLE ROW LEVEL SECURITY— the boundary coming off a table. One statement, immediate effect, critical every time.- New grants to
anonorauthenticated— after October 2026 these are deliberate acts, which makes an unexpected one worth a second look. - Write denials by table — SQLSTATE
42501. A jump after a deploy is usually a policy regression; a jump without one is usually someone probing. - Repeated authentication failures — the boundary holding under pressure is still worth knowing about, because it means someone is applying pressure.
How Defencecore fits
Defencecore reads your Supabase auth and Postgres logs continuously and opens an incident when a detection rule matches — including the moment row level security is switched off on a table, which is the single change most likely to turn a private table public. Each incident carries the raw log lines that triggered it, so you can confirm or dismiss it without reconstructing anything.
It is read-only. It holds no path that can alter your project, which is the same reasoning that should make you cautious about anything else you connect to production.
Frequently asked questions
- Is Firebase more secure than Supabase?
- Neither is more secure. They fail differently, and the difference matters more than the ranking. Firebase's insecure starting position is time-limited and fails closed — test mode stops serving requests after 30 days, so a forgotten project breaks loudly. Supabase's historical starting position failed open: a table with grants and no RLS stayed readable indefinitely and nothing complained. Supabase is closing that gap, but the failure modes still differ, and so should how you watch each one.
- Is the Supabase anon key the same as the Firebase API key?
- In the sense that matters, yes: both are designed to ship in a browser bundle and neither is a secret. Firebase's docs say so explicitly, and Supabase's anon key is a signed JWT meant to be public. In both cases the key identifies your project, and the actual security boundary is the rules layer — Firebase Security Rules or Postgres Row Level Security. Finding either key in a bundle is not a leak.
- Do Firebase Security Rules filter query results?
- No, and this is the single most misunderstood thing about them. Rules authorise a query, they do not filter it. If a query could return one document the caller is not allowed to read, Firebase rejects the entire query rather than returning a subset. You have to constrain the query so it can only ask for what the rules already permit. Supabase RLS does the opposite: it silently filters rows out of an otherwise successful query.
- What happens to Supabase projects on 30 October 2026?
- Tables in the public schema stop being exposed to the Data API and GraphQL API automatically. New projects have worked this way since 30 May 2026; on 30 October 2026 it is enforced on existing projects too. After that, a table is reachable through the API only if you have explicitly granted privileges to the anon or authenticated role. If your app relies on the old automatic grants, endpoints that work today will start returning errors.
- Can I reuse my Firebase Security Rules if I migrate to Supabase?
- No. They are different languages enforcing different things in different places. Firebase Rules are a purpose-built DSL evaluated per document request; RLS policies are SQL boolean expressions evaluated per row inside Postgres. The logic often translates conceptually, but every rule has to be rewritten, and the query-shape assumptions do not carry over at all.