Free RLS policy generator
Generate correct Supabase RLS policies in seconds
Pick how your rows are owned and which operations to allow. Get ready-to-paste SQL that scopes every row to its caller — with the (select auth.uid()) performance idiom and WITH CHECK on writes, the way Supabase recommends. Then verify what you shipped with the checker.
Runs entirely in your browser — nothing is sent anywhere.
Generated policies
alter table public.notes enable row level security;
create policy "notes_owner_select"
on public.notes for select
to authenticated
using ((select auth.uid()) = user_id);
create policy "notes_owner_insert"
on public.notes for insert
to authenticated
with check ((select auth.uid()) = user_id);
create policy "notes_owner_update"
on public.notes for update
to authenticated
using ((select auth.uid()) = user_id)
with check ((select auth.uid()) = user_id);
create policy "notes_owner_delete"
on public.notes for delete
to authenticated
using ((select auth.uid()) = user_id);These are correct templates for the common ownership shapes — they generate the right form, not a guarantee your authorization design is right. Confirm the columns and model fit your data, then verify with the checker. This complements design review; it does not replace it.
Why you can trust the output
Two sides of the same classifier
The generator (create) and the RLS checker (verify) reason about the same question: does a policy scope rows to the caller? Every shape here is run back through the checker's classifier in CI and can never come out over-permissive.
- 1
Correct by construction
Owner-bound predicates, WITH CHECK on every write, and the (select auth.uid()) wrapper — the exact shapes the field study found were missing in 9.2% of real apps.
- 2
Proven, not asserted
A test generates every model × operation and classifies it with the same engine as the checker, failing CI if any output is ever flagged as authenticated-only or anon-writable.
- 3
Yours to review
It generates the right form for your inputs. You confirm the columns and ownership model match your data — the tool can't know your business rules, and says so.
Generated it? Now verify the whole repo
Paste a policy into the checker to confirm it, or scan your entire project in one command. Need the access-control design reviewed end-to-end? I take that on as an audit.
npx @aegiskit/cli scanNo install, no signup — reads your repo locally and contacts nothing.
FAQ
Are the generated policies safe to paste into production?
They are the canonical owner-scoped shapes, and every one is verified by the same classifier as the RLS checker to never be over-permissive. But you must confirm the columns and ownership model match your data — the generator produces the correct form, not a guarantee your authorization design is right.
What does (select auth.uid()) do?
It is Supabase's recommended performance idiom: wrapping the function in a subquery makes Postgres evaluate it once per query instead of once per row, which is dramatically faster on large tables. The plain auth.uid() = user_id is correct but slow. Toggle it off if you have a reason to.
Why does it add WITH CHECK on writes?
USING controls which rows are visible; WITH CHECK controls which values may be written. Without it, a user can insert or update rows with someone else's owner id (a write bypass). The generator adds WITH CHECK to every INSERT/UPDATE automatically.
Does my table or column name get sent anywhere?
No. The generator runs 100% in your browser and contacts nothing. It also sanitizes your input into safe SQL identifiers, so odd input can't produce broken or injectable SQL.
How is this different from the RLS checker?
The generator creates correct policies; the checker verifies policies you already have. They are two sides of the same classifier — generate here, then paste your real migration into the checker to confirm nothing drifted.