Guide

How to secure a Supabase database

To secure a Supabase database, enable row-level security on every table, add a policy that scopes each user to their own rows, keep the service-role key on the server, and then verify from the outside that the tables are actually closed. Those four steps close the openings that expose most Supabase apps.

The steps

  • Enable RLS on every table holding user or private data.
  • Add a select policy matching rows to the signed-in user, for example auth.uid() = user_id.
  • Do trusted writes from your server with the service-role key, never from the browser.
  • Keep the service-role key out of client code entirely.

RLS on with no policy blocks everyone; RLS on with a policy scopes each user to their rows.

Verify it worked

The dashboard setting and the deployed behaviour are not the same thing until you check. Scan your live app with Plaintext, which attempts a read the way an attacker would and reports whether protected rows still come back. Confirm the table is closed before you move on.

Frequently asked

How do I secure my Supabase database?

Enable row-level security on every table, add a policy scoping each user to their own rows, keep the service-role key server-side, and verify from the outside that the tables are closed. RLS on without a policy blocks everything, so both steps are needed.

Is enabling RLS enough to secure Supabase?

Enabling RLS turns on the gate, but you also need a policy that says who may see what. RLS on with a correct policy scopes each user to their own rows; on its own it just blocks access.

Related guides

Guide by Plaintext, the security scanner for AI-built apps.