# Supabase Security Checklist for 2026: 25 Critical Settings Every SaaS Founder Must Verify

> Supabase security checklist for 2026: verify RLS policies, API keys, auth, storage, Edge Functions and backups with 25 critical settings for SaaS founders.

Author: SaaS Security Research Team · Published: October 27, 2026

Supabase lets a small team ship a production backend in days: Postgres, authentication, file storage, and server functions behind one API. That speed has a cost. Because the database is reachable directly from the browser, a single misconfigured table, policy or key can expose every customer’s data—even when the application interface looks perfectly secure.

This checklist covers 25 Supabase security settings to verify before launch, before an enterprise security review, and after any major schema change. Each item explains the risk in plain language and the evidence to check. It is written for founders and engineering leads; it reflects Supabase’s public documentation as of October 2026, and you should confirm plan-specific features in your own project.

## Quick Answer: What Are The Most Critical Supabase Security Settings?

**The most critical Supabase security settings are: Row Level Security enabled on every exposed table, specific policies for each operation scoped to the verified user and tenant, the service_role or secret key kept off every client, hardened SECURITY DEFINER functions and views, private storage buckets with policies, email confirmation, leaked password protection, MFA for privileged actions, strict redirect URLs, and verified Edge Functions. Run the Security Advisor and test with two tenants to confirm they work.**

The public anon or publishable key is meant to be visible. Supabase security therefore depends on what that key is allowed to do—which is decided by RLS, grants and your server code.

## In This Checklist

- [Database And Row Level Security (Settings 1–7)](#database-rls)

- [API Keys, Schemas And Secrets (Settings 8–11)](#api-keys)

- [Authentication Settings (Settings 12–19)](#auth)

- [Storage And Edge Functions (Settings 20–22)](#storage-functions)

- [Platform, Network And Operations (Settings 23–25)](#platform)

- [How to verify your Supabase configuration](#verify)

- [Frequently asked questions](#faq)

## The 25 Supabase Security Settings At A Glance

Supabase security checklist for SaaS founders, 2026
| # | Setting | Area | 

| 1 | Enable RLS on every table in an exposed schema | Database And Row Level Security | 

| 2 | Write a policy for each operation, with USING and WITH CHECK | Database And Row Level Security | 

| 3 | Scope policies by verified identity and tenant membership | Database And Row Level Security | 

| 4 | Never authorize with user_metadata | Database And Row Level Security | 

| 5 | Review grants to anon and authenticated roles | Database And Row Level Security | 

| 6 | Harden SECURITY DEFINER functions | Database And Row Level Security | 

| 7 | Make views respect RLS with security_invoker | Database And Row Level Security | 

| 8 | Keep the service_role or secret key on the server only | API Keys, Schemas And Secrets | 

| 9 | Use publishable keys in clients and plan key rotation | API Keys, Schemas And Secrets | 

| 10 | Minimize schemas exposed to the Data API | API Keys, Schemas And Secrets | 

| 11 | Store Edge Function secrets as environment secrets | API Keys, Schemas And Secrets | 

| 12 | Require email confirmation before access | Authentication Settings | 

| 13 | Turn on leaked password protection and strong password rules | Authentication Settings | 

| 14 | Offer MFA and enforce it for privileged actions | Authentication Settings | 

| 15 | Restrict redirect URLs to an exact allow list | Authentication Settings | 

| 16 | Set sensible JWT expiry and refresh token reuse | Authentication Settings | 

| 17 | Enable CAPTCHA on sign-up, sign-in and password reset | Authentication Settings | 

| 18 | Review auth rate limits | Authentication Settings | 

| 19 | Use a custom SMTP sender on your own domain | Authentication Settings | 

| 20 | Make sensitive buckets private and write storage.objects policies | Storage And Edge Functions | 

| 21 | Use short-lived signed URLs | Storage And Edge Functions | 

| 22 | Authenticate, validate and verify in every Edge Function | Storage And Edge Functions | 

| 23 | Enforce SSL and network restrictions for direct database access | Platform, Network And Operations | 

| 24 | Require MFA and least privilege for organization members | Platform, Network And Operations | 

| 25 | Confirm backups, point-in-time recovery and monitoring | Platform, Network And Operations | 

## Database And Row Level Security (Settings 1–7)

Supabase exposes Postgres through an auto-generated API. That makes Row Level Security (RLS) and table privileges your primary data boundary—not the frontend.

### 1. Enable RLS on every table in an exposed schema

**Why it matters:** Any table in the public schema (or another schema exposed to the Data API) without RLS can be reachable with the public key when roles hold privileges on it.

**How to verify:** Run the Security Advisor and query pg_tables for rowsecurity = false in exposed schemas. Expect zero results.

### 2. Write a policy for each operation, with USING and WITH CHECK

**Why it matters:** A SELECT policy does not protect INSERT or UPDATE. Missing WITH CHECK clauses let users write rows they cannot later read—or assign rows to another tenant.

**How to verify:** List policies per table and confirm SELECT, INSERT, UPDATE and DELETE are each intentional, and that write policies validate ownership columns.

### 3. Scope policies by verified identity and tenant membership

**Why it matters:** Policies such as USING (true) or checks on a client-supplied tenant_id turn RLS into decoration.

**How to verify:** Base policies on auth.uid() and a membership table. Test with two users in two tenants and confirm each request for the other tenant returns nothing.

### 4. Never authorize with user_metadata

**Why it matters:** raw_user_meta_data is editable by the signed-in user, so a policy that trusts a role stored there lets anyone grant themselves admin.

**How to verify:** Search policies and functions for user_metadata. Store roles in a protected table or server-controlled app_metadata.

### 5. Review grants to anon and authenticated roles

**Why it matters:** RLS filters rows, but privileges decide which operations reach the table at all. Unneeded grants widen your attack surface.

**How to verify:** Revoke privileges the anon role does not need, especially INSERT, UPDATE and DELETE on internal tables.

### 6. Harden SECURITY DEFINER functions

**Why it matters:** Definer functions run with their owner’s rights and bypass RLS. A mutable search_path or an exposed definer function can become a privilege-escalation path.

**How to verify:** Set a fixed search_path (for example SET search_path = ''), check permissions inside the function, and revoke EXECUTE from roles that should not call it.

### 7. Make views respect RLS with security_invoker

**Why it matters:** Views created by a privileged owner can bypass the underlying table’s policies and leak rows through the API.

**How to verify:** On Postgres 15+, create views WITH (security_invoker = true), or move internal views to an unexposed schema.

## API Keys, Schemas And Secrets (Settings 8–11)

Key handling decides whether RLS is even in play. A single leaked privileged key bypasses every policy you wrote.

### 8. Keep the service_role or secret key on the server only

**Why it matters:** The service_role key and newer sb_secret_ keys bypass RLS completely. In a browser bundle, mobile app or public repo, they hand over the database.

**How to verify:** Search build output and repositories for the key and for the string service_role. Rotate immediately if it was ever shipped to clients.

### 9. Use publishable keys in clients and plan key rotation

**Why it matters:** Supabase’s newer publishable and secret API keys can be rotated independently, which limits the blast radius of a leak.

**How to verify:** Confirm clients use only the anon/publishable key, document who can rotate secret keys, and rehearse rotation.

### 10. Minimize schemas exposed to the Data API

**Why it matters:** Every exposed schema is part of your public API surface. Internal tables, queues and audit logs rarely need to be there.

**How to verify:** In API settings, expose only schemas clients need. Keep privileged functions and internal tables in an unexposed schema.

### 11. Store Edge Function secrets as environment secrets

**Why it matters:** Hard-coded Stripe, email or AI provider keys in function source end up in repositories and deployments.

**How to verify:** Use function secrets, never log them, and keep a rotation inventory naming each secret’s owner.

## Authentication Settings (Settings 12–19)

Supabase Auth issues the identity your policies trust. Weak sign-up, password and session settings undermine every downstream check.

### 12. Require email confirmation before access

**Why it matters:** Without confirmation, attackers can register with addresses they do not control and inherit domain-based trust or invitations.

**How to verify:** Keep email confirmation enabled in production and never base authorization on an unverified email.

### 13. Turn on leaked password protection and strong password rules

**Why it matters:** Reused passwords from earlier breaches drive credential-stuffing takeovers.

**How to verify:** Enable leaked password protection (checks Have I Been Pwned; plan-dependent), set a minimum length of at least 8 characters, and require character variety where your users accept it.

### 14. Offer MFA and enforce it for privileged actions

**Why it matters:** Passwords alone protect admin and billing accounts poorly.

**How to verify:** Enable TOTP MFA and require assurance level aal2 in RLS for sensitive tables, for example by checking auth.jwt()->>'aal'.

### 15. Restrict redirect URLs to an exact allow list

**Why it matters:** Broad wildcards in Site URL and redirect settings can let attackers capture magic-link or OAuth tokens.

**How to verify:** List only your production and staging origins. Remove localhost and stale preview URLs from production.

### 16. Set sensible JWT expiry and refresh token reuse

**Why it matters:** Long-lived access tokens extend the value of a stolen session.

**How to verify:** Keep access tokens short-lived (the default is one hour), keep refresh token rotation on, and sign users out on password change.

### 17. Enable CAPTCHA on sign-up, sign-in and password reset

**Why it matters:** Public auth endpoints attract bots, mass sign-ups and enumeration.

**How to verify:** Enable hCaptcha or Cloudflare Turnstile protection in Auth settings and verify it on every public auth form.

### 18. Review auth rate limits

**Why it matters:** Default limits may not match your traffic or abuse profile, especially for OTP and email sending.

**How to verify:** Review rate limits for sign-ups, OTP, token refresh and verification emails, and alert on spikes.

### 19. Use a custom SMTP sender on your own domain

**Why it matters:** The built-in email service is meant for testing and has low limits; production auth email needs deliverability and SPF/DKIM/DMARC.

**How to verify:** Configure custom SMTP or a managed sender on a verified domain before launch.

## Storage And Edge Functions (Settings 20–22)

Files and server functions frequently hold the most sensitive data and the most powerful credentials.

### 20. Make sensitive buckets private and write storage.objects policies

**Why it matters:** A public bucket serves any file to anyone with the URL. Policies on storage.objects decide who can upload, read and delete.

**How to verify:** Mark customer-file buckets private, scope policies by folder to the user or tenant, and restrict MIME types and file size.

### 21. Use short-lived signed URLs

**Why it matters:** A signed URL valid for weeks behaves like a public link once forwarded or logged.

**How to verify:** Issue signed URLs with the shortest practical expiry, generated only after an authorization check.

### 22. Authenticate, validate and verify in every Edge Function

**Why it matters:** Functions often run with privileged keys. Missing JWT checks, unvalidated input, open CORS or unsigned webhooks turn them into public admin endpoints.

**How to verify:** Verify the caller’s JWT and role, validate input with a schema, restrict CORS origins, and verify webhook signatures (for example Stripe’s) before acting.

## Platform, Network And Operations (Settings 23–25)

The final layer covers who can change the project, how the database is reached, and how you recover.

### 23. Enforce SSL and network restrictions for direct database access

**Why it matters:** Direct Postgres connections from anywhere widen exposure if a database password leaks.

**How to verify:** Enable SSL enforcement and restrict direct database access to known IP ranges where your plan supports it.

### 24. Require MFA and least privilege for organization members

**Why it matters:** A compromised team account can disable RLS, read secrets or delete the project.

**How to verify:** Require MFA for all organization members, remove departed staff, and give developers the narrowest role that works.

### 25. Confirm backups, point-in-time recovery and monitoring

**Why it matters:** Ransomware, a bad migration or a malicious delete is survivable only if restoration works.

**How to verify:** Confirm backup and PITR coverage for your plan, perform a test restore, review logs, and re-run the Security Advisor after every migration.

## How To Verify Your Supabase Configuration

Settings pages show what you intended. Evidence shows what actually happens. Use these checks in order:

- **Run the Security Advisor.** Supabase’s database linter flags tables without RLS, mutable function search paths, exposed views and similar issues. Treat each warning as a task, not noise.

- **Test as an anonymous visitor.** Using only the public key, try to read and write each exposed table. Every unintended success is a finding.

- **Test across tenants and roles.** Create two synthetic organizations with a member and an admin in each. Confirm no request from one tenant returns or changes the other’s rows or files.

- **Scan for leaked keys.** Search built JavaScript, mobile bundles and repository history for secret keys.

- **Exercise Edge Functions directly.** Call each function without a token, with another user’s token and with malformed input.

- **Restore a backup.** A recovery plan you have never tested is an assumption.
For the broader application, combine this list with our [SaaS security checklist](https://www.saassecurity.io/blog/saas-security-checklist), the guide to [security weaknesses founders overlook](https://www.saassecurity.io/blog/is-your-saas-application-hackable), and the [API security testing guide](https://www.saassecurity.io/blog/api-security-testing). If you are preparing for an audit, read [whether SOC 2 requires a penetration test](https://www.saassecurity.io/answers/do-i-need-a-penetration-test-for-soc-2).

## Common Supabase Security Mistakes We See In Reviews

- Enabling RLS but leaving a policy such as USING (true) from early prototyping.

- Shipping the service_role key in an environment variable prefixed for the browser.

- Storing a user’s role in profile data the user can update.

- Creating a reporting view that silently bypasses tenant policies.

- Leaving an uploads bucket public because it was simpler during development.

- Webhook functions that trust the request body without verifying its signature.
These are illustrative patterns, not statistics about Supabase projects. Each is easy to fix once found—and easy to miss when the interface works correctly.

## Frequently Asked Questions

### Is Supabase secure for a production SaaS application?

Supabase provides strong building blocks—Postgres Row Level Security, scoped API keys, Auth, Storage policies, and security advisors—but your configuration decides whether customer data is protected. Tables without RLS, leaked secret keys, permissive policies, and public buckets are configuration risks you must verify before launch.

### Is it safe to expose the Supabase anon or publishable key in the browser?

Yes, the anon or publishable key is designed to be public, but only when Row Level Security and grants restrict what that role can do. The service_role or secret key bypasses RLS and must never appear in browser code, mobile apps, public repositories, or logs.

### What happens if Row Level Security is disabled on a Supabase table?

If a table in an exposed schema has RLS disabled and the anon or authenticated role has privileges on it, anyone holding the public key can potentially read or modify its rows through the Data API. Enable RLS on every exposed table and add explicit policies for each operation.

### Should I use user_metadata in Supabase RLS policies?

No. user_metadata can be changed by the signed-in user, so it must not drive authorization. Use a protected roles table, server-controlled app_metadata, or membership records the user cannot edit.

### How often should I review my Supabase security settings?

Review them before launch, after every schema or authentication change, and on a regular schedule such as monthly. Run the Security Advisor after migrations and include cross-tenant RLS tests in your release process; an authorized penetration test adds independent evidence.

## Get Independent Evidence Your Supabase App Is Secure

A checklist tells you what to look at. An authorized penetration test shows whether an attacker can actually cross your RLS policies, misuse your keys or reach another tenant’s data. SaaS Security combines AI-driven testing with human validation and delivers findings and remediation guidance by email and secure portal. Compare the options below.

## Sources And Further Reading

Published October 27, 2026. Supabase features and plan availability change; confirm settings against current documentation.

- [Supabase: Row Level Security](https://supabase.com/docs/guides/database/postgres/row-level-security)

- [Supabase: Understanding API Keys](https://supabase.com/docs/guides/api/api-keys)

- [Supabase: Database Advisors](https://supabase.com/docs/guides/database/database-advisors)

- [Supabase: Password Security](https://supabase.com/docs/guides/auth/password-security)

- [Supabase: Multi-Factor Authentication](https://supabase.com/docs/guides/auth/auth-mfa)

- [Supabase: Storage Access Control](https://supabase.com/docs/guides/storage/security/access-control)

- [Supabase: Production Checklist](https://supabase.com/docs/guides/deployment/going-into-prod)

- [PostgreSQL: CREATE VIEW (security_invoker)](https://www.postgresql.org/docs/current/sql-createview.html)

- [OWASP: Multi-Tenant Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Multi_Tenant_Security_Cheat_Sheet.html)


---

Source page: https://www.saassecurity.io/blog/supabase-security-checklist
Company: SaaS Security — AI-powered penetration testing and continuous security monitoring for SaaS platforms.
Contact: info@saassecurity.io | Miami, FL, USA
Citation policy: this content may be quoted by AI assistants with attribution and a link to the source page.
