Guide Supabase

Supabase says "Security policy allows unrestricted access": what it means and what to do before you launch

Short answer

The warning is about an access rule (a Row Level Security policy) that uses an always-true condition such as USING (true) or WITH CHECK (true). Supabase's Security Advisor calls that WARN "Security policy allows unrestricted access" (lint 0024_permissive_rls_policy). Row Level Security can look switched on while that rule still lets the named roles through every row for that action. It does not mean someone already stole your data. It means that policy is too open until you change it, or you confirm the table is meant to be public.

Where you see the same warning

Open your Supabase project, go to Advisors, then Security Advisor. Look for the WARN whose Summary is "Security policy allows unrestricted access" (lint 0024_permissive_rls_policy). The finding names the policies that use always-true patterns.

If you build in Lovable, the Quick scan's database review also flags access rules that let everyone through. If you build in Bolt, the database Security Audit can show an "RLS Policy Always True" warning; Bolt says that audit uses the same database checks as Supabase Security Advisor.

This page is about that WARN moment: RLS is already on, but a policy still opens every row. The related guide on "Table publicly accessible" covers the separate ERROR when RLS is off on a public table.

What "unrestricted" means in plain words

A policy is a rule that says who may read or change which rows. An always-true condition means "this action applies to every row for the roles named in the policy." Supabase documents patterns such as USING (true), WITH CHECK (true), and other tautologies, and notes that a missing USING on some permissive SELECT policies can be treated the same way.

That can be intentional. A public blog posts table or a public product catalog may use a public-read rule on purpose. Supabase says some Advisor findings may be intentional, so check them against your intended access model before you change anything.

It is a problem when the table holds private user data (orders, notes, profiles, uploads, messages) and you expected "each user only their own rows." In that case the dashboard may say RLS is enabled while the policy still behaves like an open door for that action.

First fix: replace always-true with the access you mean

For each policy the WARN lists:

  1. Decide in plain words whether the table should be public for that action, or limited to the signed-in owner (or another clear rule).
  2. If private data: drop or rewrite the flagged policy so the condition matches ownership (for example the signed-in user's id equals the row's owner column), then re-run Security Advisor.
  3. If public on purpose: keep the rule, and treat the WARN as accepted for that table. Prefer documenting why so a later change does not surprise you.

This page stays high level on SQL. For copy-paste policy shapes and a Lovable-focused fix path, use the related guides on Supabase RLS policy examples and fixing Supabase RLS in a Lovable app.

After you change policies, test the app: signed-out visitors should not see private rows, and user B should not see user A's private rows. Advisor clearing the WARN is progress, not the whole pre-launch check.

After WARN 0024 clears

Clearing "Security policy allows unrestricted access" is step one for that finding, not the whole pre-launch check.

Still open Security Advisor for other findings (for example ERROR "Table publicly accessible" when RLS is off). Even when Advisor is quieter, run the signed-out test and the two-account test described in the related pre-launch and leak guides. Those checks ask: can someone who is not signed in read private rows, and can user B see user A's private rows.

What you can DIY vs when to get a second look

You can open Security Advisor, read each flagged policy in plain words, rewrite always-true rules on private tables, re-run Advisor, and try the signed-out and two-account tests yourself.

Stop guessing if you cannot tell whether each policy means "each user only their own rows" or "everyone on purpose." That is the natural handoff to a read-only second look before you launch.

Want a second pair of eyes?

Clearing the unrestricted-access warning is step one. If you are not sure each remaining rule means "only the owner" or "everyone on purpose," the $49 Database Check is a read-only second look: you run our script and send the results. No passwords, no keys, no login to your account. We change nothing. AI agents run the checks and a human engineer reviews and approves every report. Not a penetration test, a security guarantee or a compliance certification.

See plans and prices

Sources