# Is Supabase safe for production?

**Answer:** Yes, it can be: Supabase gives you the primitives a production app needs, namely Postgres row level security, a public key that only reaches what RLS allows, a secret key that stays on your server, and a Security Advisor that flags common mistakes, on a platform Supabase says is SOC 2 Type 2 compliant and ISO 27001 certified. What decides whether your data is safe is how your project uses them, and Supabase's shared responsibility model puts that on you: RLS on every exposed table, policies that check who the caller is, and the secret key kept out of the browser.

## Why this matters

The question usually comes after a post about an app whose users' data anyone could read. The causes this site's guides cover are settings in the app's own project rather than the platform: a table with RLS off, a policy that lets everyone through, a service role key shipped to the browser. Supabase's own Security Advisor reports the first one as an error, saying "Anyone with your project URL can read, edit, and delete all data in this table". So the useful question is not whether Supabase is safe in general, but whether your project is set up the way the platform expects.

## What to check before you trust a Supabase project with real users

- Run the Security Advisor and work through every error. It is in the dashboard, and the same checks run from the Supabase CLI (supabase db advisors), the MCP server and the Management API. Supabase says some findings may be intentional, so check each one against the access you meant to give.

- Make sure every table in the public schema has row level security on. Supabase turns it on for tables created in the dashboard, but tables created in SQL, migrations included, need it enabled explicitly. Every row this returns is a table without it:

```sql
select tablename
from pg_tables
where schemaname = 'public' and rowsecurity = false;
```

- Read every policy's condition, not its name, and replace using (true) on anything that belongs to one user.

- Keep the secret or service role key on the server: never behind NEXT_PUBLIC_ or VITE_, never in a "use client" file, never in a repo. Supabase says a secret key "bypasses every Row Level Security policy you have".

- Lock down functions and views in the public schema: revoke execute from anon and authenticated on functions only your server calls, and set security_invoker on views over protected tables.

- Go through Supabase's production checklist for the account and Auth settings: MFA on your Supabase account, SSL enforcement, network restrictions, email confirmations, a reasonable OTP expiry and a custom SMTP server.

- Test the policies: a pgTAP file per table, or at least a second account that should see none of the first account's data.

## What Supabase handles and what is yours

From Supabase's shared responsibility model and its security docs.

### What Supabase says it handles

Postgres backups and observability, operating system maintenance, and the infrastructure and its security. Its security page says the platform is SOC 2 Type 2 compliant and ISO 27001 certified, that DDoS attacks are handled at the edge via Cloudflare, and that fail2ban blocks IP addresses after repeated abuse such as failed authentication attempts.

### What is shared

API rate limiting, Postgres security controls, upgrades, performance tuning and resource allocation.

### What is yours

Your Supabase account, access management for the account, database and tables, your data, and applying security controls. Supabase sends security alerts through the Security Advisor and says "applying the recommendations are your responsibility". It also says you are responsible for managing your database secrets and API keys.

### Why the defaults leave room for mistakes

Supabase says it could put many more restrictions in place, but that you would eventually find them prohibitive, so it gives you full access to the database instead. Two defaults follow from Postgres and the platform rather than from your app. Postgres creates every table with RLS off; Supabase turns it on for tables created in the dashboard, but not for tables created in SQL or migrations. And on existing projects a new table in public is granted to anon and authenticated until you revoke it, a default Supabase is changing so exposure becomes opt-in.

## Optional repo check

For AI-built Vercel + Supabase apps, the free Supabase RLS checker (linked below) reads migration SQL you paste, in your browser, and `npx -y viberaven@1.6.3 check` reads the whole repo: public tables without RLS, using (true) policies, security definer functions the anon key can call, and a service role key behind a client prefix such as NEXT_PUBLIC_ or VITE_, or in client code. In a run on 2026-10-05 it did not flag a view without security_invoker or a function without a fixed search_path, and it reads no Auth or account settings, so it does not replace the Security Advisor. It is advice, not a gate, and a repository check, not a live database or security test. A clean result does not prove the app is secure. It exits with code 1 when it finds a blocker and writes a `.viberaven` folder that it does not add to `.gitignore`.

## FAQ

### Is Supabase secure?

The platform side rests on Supabase's compliance work (SOC 2 Type 2, ISO 27001) and its infrastructure controls. Whether your app is secure on it depends on your project: row level security on every exposed table, policies that check the caller, and keys in the right place. The Security Advisor checks the database side of that for you.

### Is the Supabase free plan safe for production?

Row level security is part of Postgres, so your policies work the same on any plan. Some Auth protections depend on the plan: Supabase says leaked password protection is available on the Pro Plan and above.

### Does it matter that the anon key is in my frontend?

No, that is where it belongs. It only reaches what your RLS policies and grants allow. The key that must never reach the frontend is the service role or secret key.

## Related guides

- Is the Supabase anon key safe to expose? https://viberaven.dev/supabase-anon-key-safe-to-expose
- Supabase service role key leaked or exposed: how do I rotate it? https://viberaven.dev/supabase-service-role-key-leaked
- How do I test Supabase RLS policies? https://viberaven.dev/test-supabase-rls-policies
- How do I find Supabase tables missing RLS in my migrations? https://viberaven.dev/find-supabase-tables-missing-rls
- What does using (true) mean in a Supabase RLS policy, and when is it wrong? https://viberaven.dev/supabase-policy-using-true
- Can anyone call my Supabase RPC functions with the anon key? https://viberaven.dev/supabase-security-definer-function-anon
- What can a repo scan prove about Supabase security, and what needs a live test? https://viberaven.dev/repo-scan-vs-live-supabase-security-test
- Free Supabase RLS checker https://viberaven.dev/supabase-rls-checker
- What do the Supabase Security Advisor warnings mean, and how do I fix them? https://viberaven.dev/supabase-security-advisor-warnings

## Sources

Read on 2026-10-04.

- Supabase, Shared Responsibility Model: https://supabase.com/docs/guides/deployment/shared-responsibility-model
- Supabase, Security: https://supabase.com/docs/guides/security
- Supabase, Production Checklist: https://supabase.com/docs/guides/deployment/going-into-prod
- Supabase, Advisors: https://supabase.com/docs/guides/observability/advisors
- Supabase, Securing your API: https://supabase.com/docs/guides/api/securing-your-api
- Supabase, Row Level Security: https://supabase.com/docs/guides/database/postgres/row-level-security
- Supabase, API keys: https://supabase.com/docs/guides/getting-started/api-keys
- Supabase, Password security: https://supabase.com/docs/guides/auth/password-security

HTML page: https://viberaven.dev/is-supabase-safe-for-production
