Supabase RLS policy generator

Pick an access pattern, enter your table name: get a copyable RLS policy plus a verification query.

Step 1 / 2

How do you want to restrict access?

Want this inside your own product?

Let's talk in a 45-min discovery call.

Book a call

Tools like Lovable, Bolt, and v0 open a Supabase table without writing the row-level access rule. When the founder turns RLS on afterward, the app stops reading its own data, and most turn it back off. This tool generates copyable SQL for five access patterns: row ownership, team/organization membership, public read, admin-only, and storage bucket access.

Every policy follows two rules straight from Supabase's own docs: auth.uid() is wrapped in select because Postgres caches the result once per statement instead of calling it per row; every policy is scoped with to authenticated (or to anon, authenticated for public read) because a policy written without a role can end up covering signed-out requests too.

The generated SQL is a template. It doesn't connect to your database or read your schema: enter your own table and column names, then test it in staging first. RLS is the layer that breaks most often; see which gaps repeat on apps built with Lovable and Bolt. If you can't close the critical ones yourself, our AI project completion service picks up from there. Want a broader check of your setup? See the launch-readiness check.

Frequently asked

Does this tool connect to my Supabase project?

No. It runs in your browser, doesn't connect to a database, and doesn't read your schema. It generates SQL from the table and column names you type; test the generated policy in staging or a fresh SQL editor session before going live.

Why does every condition wrap auth.uid() in select instead of calling it plain?

Per Supabase's own performance note: wrapping the function in select lets Postgres cache the result once per statement, instead of calling the function on every row.

Why isn't there a separate auth.uid() IS NOT NULL check in the policies?

Every policy is scoped with to authenticated (or to anon, authenticated for public read). Supabase's docs recommend always naming the role; a policy written without one can end up covering signed-out requests too, so we name the role explicitly instead.

What if I'm not sure which of the five access patterns to pick?

Each option carries a short description of who can see or change the row. If you pick wrong, the restart button resets from scratch. Nothing is saved, so no answer is ever stuck.