Join our Newsletter — 33% off our NHI Course
Home› Guides› Supabase Security: Row Level Security, Auth and Project…
Guide Application Security

Supabase Security: Row Level Security, Auth and Project Hardening

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 8 November 2026 14 min read
On this page

Supabase apps are often built in days, frequently with AI coding agents, and shipped with the browser talking straight to the database, so a single missing policy on a table, a storage bucket or a Realtime channel becomes a public data leak. The pattern is now familiar: a publishable key in front-end JavaScript, Row Level Security off or too broad, and anyone on the internet able to read or write the data. This guide covers the whole Supabase security surface beyond keys: how identity and access work across the Data API, Storage and Realtime, organisation roles and account security, Auth configuration, network restrictions and SSL enforcement, Security Advisor, logging and a production hardening baseline. It is for developers, platform engineers and security reviewers of Supabase projects. Key types, the service role and key rotation are covered in depth in the Supabase Keys Security Guide; this page links there rather than repeating it.

This is an independent guide from NHI Mgmt Group, based on Supabase's public documentation as of November 2026. It is not sponsored or reviewed by Supabase. Product features change, so confirm settings against Supabase's current documentation.

Key takeaways

  • Policies protect every surface, not only tables. Tables, storage.objects and realtime.messages each need their own Row Level Security policies; a correct table policy does nothing for a public bucket or a public Realtime channel.
  • Network restrictions do not cover the APIs. Supabase network restrictions apply to Postgres and the pooler only; the Data API, Storage and Auth over HTTPS stay reachable and rely on policies and keys.
  • Auth defaults need tuning for production. Enable email confirmations, keep OTP expiry at 3,600 seconds or less, add CAPTCHA, set password rules and, on paid plans, leaked password protection.
  • The account that owns the project is a privileged identity. Enforce MFA for the organisation, keep more than one Owner, and use Developer, Read-Only and project-scoped roles where your plan supports them.
  • Run Security Advisor in CI, not once. Lints such as 0013 RLS disabled in public and 0010 security definer view catch the mistakes that cause most Supabase leaks, and they can run from the CLI with supabase db advisors.

How identity and access work in Supabase

A Supabase project is a Postgres database with services in front of it: the Data API (PostgREST), Auth, Storage, Realtime and Edge Functions. Requests from the browser carry the project's publishable key and, after sign-in, a user JWT. Postgres roles and Row Level Security decide what each request can do. That makes Postgres the policy engine for almost everything.

SurfaceHow access is decidedWhat protects itTypical gap
Data API (tables, views, functions)Postgres role from the key and JWT (anon or authenticated), then RLSRLS on every exposed table, careful grants, views and functions that respect RLSRLS disabled on a table in the public schema
StorageRLS policies on storage.objects, bucket public or privatePer-operation policies scoped by bucket, folder and ownerBucket made public for convenience; listing allowed by a broad SELECT policy
Realtime Broadcast and PresenceRLS on realtime.messages for private channels"Allow public access" disabled, select and insert policies per topicPublic channels carrying private data
Realtime Postgres ChangesThe table's own RLSRLS on replicated tablesSupabase notes RLS does not filter DELETE events, so sensitive changes should use Broadcast with authorisation
Direct Postgres and poolerDatabase credentials, network restrictions, SSLNetwork Restrictions, SSL Enforcement, strong database passwordsOpen to 0.0.0.0/0 with a leaked connection string
Dashboard and Management APISupabase account, organisation role, access tokensOrganisation MFA, roles, audit logsSingle Owner with a password-only account

Row Level Security in one paragraph

Enable RLS on every table in an exposed schema, write one policy per operation, compare ownership columns to auth.uid() or auth.jwt() claims, take authorisation data from app metadata rather than user-editable metadata, and test both allowed and denied cases as the anon and authenticated roles. This is the Supabase form of preventing OWASP API1:2023 Broken Object Level Authorization and meets OWASP ASVS 5.0 V8.2.2 (data-specific access). Detailed patterns and the bypass routes through views and security definer functions are in the Supabase Keys Security Guide and the OWASP API Top 10 API1 Broken Object Level Authorization Guide.

Storage policies

Storage is deny by default: Supabase does not allow uploads to buckets without RLS policies on storage.objects. Points that catch teams out:

  • Uploads: an upload needs only an INSERT policy, but upsert (overwrite) also needs SELECT and UPDATE policies.
  • Scope by bucket and folder: restrict with bucket_id = '...' and use storage.foldername(name) to tie the first folder to the user's ID from auth.jwt()->>'sub', giving each user a private prefix.
  • Ownership: let users read files they uploaded by checking owner_id.
  • Listing versus reading: a broad SELECT policy also allows listing a bucket's contents. Supabase provides storage.allow_only_operation() and storage.allow_any_operation() so listing and object reads can have different rules.
  • Public buckets: anything in a public bucket is readable by anyone without a SELECT policy. Use public buckets only for genuinely public assets such as product images, never for uploads from users.
  • Service key: a service or secret key bypasses Storage RLS entirely, so server-side upload handlers must enforce their own checks.

Realtime authorisation

For Broadcast and Presence, turn off "Allow public access" in Realtime Settings and create channels with config: { private: true }. Policies on realtime.messages decide who can receive (select) and send or track presence (insert), and can scope by realtime.messages.extension (broadcast or presence) and by realtime.topic(). Permissions are evaluated when a client joins and cached for the connection, so a user whose access is revoked keeps receiving messages until the JWT expires: keep JWT lifetimes short. RLS is already enabled on realtime.messages; adding an ENABLE ROW LEVEL SECURITY statement for it in a migration fails with error 42501.

Admin roles and privileged access

Whoever controls the Supabase organisation can read every table, download backups, change Auth settings and create keys. Treat dashboard access as privileged access.

Organisation roleAccessUse for
OwnerFull access to organisation and project resourcesTwo or more named people, never a shared account
AdministratorNearly full access; cannot change organisation settings, move projects out of the organisation or add OwnersPlatform leads
DeveloperRead-only on organisation resources; full content access to projects; cannot change project settingsEngineers who build features
Read-OnlyView-only on organisation and project resourcesAuditors and support
No-access plus project-scoped roleOnly the projects explicitly grantedContractors and agencies

Availability: Supabase documents Read-Only, No-access and project-scoped roles on the Team and Enterprise plans, organisation MFA enforcement on Pro, Team and Enterprise, and Platform Audit Logs on Team and Enterprise.

  • Account MFA: the production checklist asks for GitHub two-factor authentication if you sign in with GitHub, or Supabase MFA for email and password sign-in. Enforce MFA at organisation level where your plan allows, so every member needs an MFA-backed session.
  • Owners: keep more than one Owner so you are not locked out, and review membership when staff or agencies change.
  • Separate production: put production in its own project, with fewer members than development, and deploy schema changes through migrations rather than dashboard edits.
  • AI coding agents: agents connected to a project through the Supabase MCP server or a personal access token act with that token's rights. Point them at development projects, scope their tokens to the minimum, and never give an agent production Owner rights. See the AI Coding Agents Security Guide.

Integrations, API tokens and service accounts

Supabase has several machine credentials, each with a different blast radius. Keys and rotation are covered in the keys guide; the summary for a security review is:

  • Publishable (or legacy anon) key: public by design; safe only when every exposed surface has correct policies.
  • Secret (or legacy service_role) key: bypasses RLS on tables and Storage. Server-side only, one per backend service, stored in a secrets manager.
  • Database connection strings: full Postgres credentials. Pair with network restrictions and SSL enforcement, and use dedicated Postgres roles for each backend rather than the default postgres user.
  • Personal access tokens and Management API tokens: act with the user's organisation rights; scope who can create them and revoke unused ones.
  • Edge Function secrets: third-party API keys used by functions; store them as function secrets or in Supabase Vault, never in client bundles.
  • Custom SMTP credentials: custom SMTP makes Auth emails come from your domain and is part of the production checklist; protect the SMTP credential like any other mail-sending key.

Inventory these as non-human identities with owners. See the API Key Management Guide and the JWT Security Guide for the token side.

Auth configuration

SettingProduction valueWhy
Email confirmationsEnabled (Authentication, Sign In / Providers)Stops sign-ups with addresses the user does not control
OTP expiry3,600 seconds or lower; increase OTP length for more entropyAlso shortens confirmation, recovery, email change and invitation links
Test phone numbersRemovedTest numbers are a fixed login path
Password strengthMinimum length of at least 8 (Supabase discourages shorter); character requirements as policy needsExisting weak passwords still sign in but return WeakPasswordError so you can prompt a change
Leaked password protectionEnabled where available (Pro Plan and above)Rejects passwords found in the HaveIBeenPwned Pwned Passwords data
Secure password changeRequire reauthentication (session newer than 24 hours, otherwise nonce) or current passwordStops a stolen session from changing the password
CAPTCHAOn sign-up, sign-in and password resetReduces automated account creation and credential stuffing (MITRE ATT&CK T1110)
Rate limitsReview defaults under Authentication, Rate Limits (for example MFA challenge and verify 15 per minute, token refresh 1,800 per hour)Tune to real traffic; lower anonymous sign-ins if unused
MFA for app usersEnabled for admin and high-risk users at leastSupabase recommends it where the app needs a higher security level
Custom SMTPConfigured (Authentication, Emails, SMTP Settings)Trusted sender domain, higher and controllable email limits

Network restrictions and SSL

Turn on SSL Enforcement under Database, Settings, SSL Configuration so direct connections must use TLS. Network Restrictions limit which IPv4 and IPv6 CIDR ranges can reach Postgres and the pooler; they need Owner or Admin permission and are set separately for each address family. The CLI's update --db-allow-cidr replaces the whole list unless you add --append, so take a copy of the current list first. Two limits matter for design: restrictions do not cover HTTPS APIs (PostgREST, Storage, Auth), and Edge Functions lose direct database access once restrictions apply, so they should connect through supabase-js instead. Removing restrictions means setting 0.0.0.0/0 and ::/0, which is also the rollback if you lock out a critical service.

Logging and detection

Supabase has three logging layers. Platform audit logs record dashboard and Platform API actions such as creating projects, inviting members, changing Edge Functions and project settings, with actor IP, email and token type; they are on Team and Enterprise plans, cannot be exported from the dashboard and can be streamed with Audit Log Drains. Auth audit logs record authentication activity in each project. Project logs cover API, Postgres and other services, and Postgres connection logging is listed among the database security features.

SignalSourcePossible meaning
New Security Advisor findings after a deploysupabase db advisors in CI, Studio /advisors/securityA migration added a table without RLS or a security definer view
Large reads by the anon role from a single IPAPI logsScraping through a missing or broad policy (Data from Information Repositories, T1213)
Member invited, role changed, network restriction or Auth setting changedPlatform audit logsAccount takeover or unapproved change
Spike in sign-ups, failed sign-ins or OTP requestsAuth audit logs, rate limit hitsBots, credential stuffing or SMS pumping
Bucket switched to public, new storage policyPlatform audit logs, migration historyExposure of uploaded files
Direct database connections from unknown IPsPostgres connection logsLeaked connection string (Valid Accounts, T1078)

Metrics:

  • Tables in exposed schemas with RLS enabled and at least one tested policy (target 100%).
  • Open Security Advisor security findings, by lint, and time to close.
  • Buckets that are public, each with a documented reason.
  • Realtime channels that are private where they carry user data.
  • Organisation members with MFA, and number of Owners (target two or more).
  • Projects with SSL Enforcement and Network Restrictions enabled.

Hardening baseline

  1. Run Security Advisor now: fix 0013 RLS disabled in public, 0007 policy exists RLS disabled, 0002 auth users exposed, 0010 security definer view and 0011 function search path mutable first. Some findings may be intentional, so confirm against your access model before changing.
  2. Policies on every surface: tables, storage.objects and realtime.messages; private buckets and channels by default. Write policies in migrations so they are reviewed and versioned.
  3. Test as an outsider: query every exposed table, bucket and channel with only the publishable key and as a second user, and confirm denials. Add these tests to CI and run supabase db advisors in the same pipeline.
  4. Auth settings: apply the table above; enable CAPTCHA and email confirmations; set OTP expiry; configure custom SMTP.
  5. Database access: SSL Enforcement on, Network Restrictions to known ranges, dedicated Postgres roles for backends, secret keys only on servers.
  6. Organisation: MFA enforced, two Owners, least-privilege roles, separate production project, agencies on project-scoped roles.
  7. Recovery: enable Point in Time Recovery where data matters (Supabase suggests it once the database is expected to exceed 4 GB, and notes free plan backups cannot be downloaded), and test a restore.
  8. Threat review: follow the checklist's advice to list how an attacker could abuse your app and review the OWASP Top 10.

Rollback: enabling RLS on a live table without policies blocks all API access to it. Roll out per table: write and test policies in a branch or staging project, enable RLS, watch API errors, and keep the policy migration revertible.

Common misconfigurations

  • RLS off with the key in the browser: a publishable key in public JavaScript is expected, so turn on RLS for every exposed table; without it, anyone with the key can read and write those tables.
  • Table policies right, bucket public: user uploads such as ID documents or invoices placed in a public bucket, readable by anyone with the URL.
  • Broad storage SELECT policy: lets any signed-in user list every object in a bucket.
  • Private data on public Realtime channels: "Allow public access" left on, so anyone with the publishable key can join a topic.
  • Relying on network restrictions to protect the API: they only cover direct database connections.
  • Single Owner, no MFA: one phished account controls every project, backup and key.
  • AI-generated schema shipped unreviewed: tables created by a coding agent without policies or with using (true). See the AI-Generated Code Review Guide.

Framework mapping

Control areaNIST SP 800-53 Rev. 5OWASP or NIST CSF 2.0
RLS on tables, Storage and RealtimeAC-3, AC-6API1:2023 BOLA; ASVS 5.0 V8.2.2, V8.2.3
Auth settings, MFA, CAPTCHA, rate limitsIA-2, IA-5API2:2023 Broken Authentication
Network restrictions and SSL enforcementSC-7, SC-8API8:2023 Security Misconfiguration
Organisation roles and project scopingAC-2, AC-6ASVS 5.0 V8.2.1
Security Advisor and policy tests in CISA-11API8:2023 Security Misconfiguration
Audit logs and drainsAU-6CSF PR.PS-04
PITR and backupsCP-9CSF PR.DS-11

Practitioner checklist

  • Run Security Advisor and clear all RLS-related findings; add supabase db advisors to CI.
  • Confirm RLS and tested policies on every exposed table, storage.objects and realtime.messages.
  • Make buckets and Realtime channels private unless the content is genuinely public.
  • Enable email confirmations, CAPTCHA, OTP expiry of 3,600 seconds or less, password rules and leaked password protection where available.
  • Turn on SSL Enforcement and set Network Restrictions to known IPv4 and IPv6 ranges.
  • Enforce organisation MFA, keep two Owners and use least-privilege roles for everyone else.
  • Keep secret keys and connection strings server-side and inventoried with owners.
  • Stream audit logs where your plan allows and alert on member, setting and bucket changes.
  • Enable PITR for production data and test a restore.

Standards and references

Related NHI Mgmt Group resources: Supabase Keys Security Guide · AI Coding Agents Security Guide · OWASP API Top 10 API1 Broken Object Level Authorization Guide · JWT Security Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 8 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org