← Reference

Enabling Row Level Security without breaking your app

The one-line fix, the policy it needs, and the mistake that takes your app down.

01

The mistake almost everyone makes

Running ALTER TABLE … ENABLE ROW LEVEL SECURITY; on its own. With RLS on and no policy, Postgres denies everything — including your own app. Your app appears to break instantly and the instinct is to switch RLS back off.

Always add the policy in the same change as enabling RLS.

02

The usual shape

Most tables in an AI-built app have a user_id column, and the rule you want is "you can see your own rows":

Copy this
ALTER TABLE public."orders" ENABLE ROW LEVEL SECURITY;

CREATE POLICY "orders_select_own"
  ON public."orders" FOR SELECT
  TO authenticated
  USING (auth.uid() = user_id);

You need a separate policy per operation. A SELECT policy does not permit INSERT, UPDATE, or DELETE — add those explicitly, with WITH CHECK on the write ones.

03

When a table really is public

Blog posts, a public product catalogue, a leaderboard. Say so explicitly rather than leaving RLS off:

Copy this
CREATE POLICY "posts_public_read" ON public."posts" FOR SELECT TO anon USING (true);

The difference matters. An explicit policy is a decision; RLS being off is an accident, and the next table you add will inherit the accident.

04

Confirm it worked

Press "I fixed it — re-check" on the finding. We re-run just that check and tell you whether the table still answers.

To check by hand: Supabase dashboard → Database → Tables. Every table should show RLS enabled and at least one policy. Then load your app while logged out and confirm nothing appears that should not.

Not sure whether this applies to you?

Give us the address and we will tell you. No code, no access, no install — and every finding we have is shown in full, including on the free trial.

Check a site