Chuyển đến nội dung chính
友田 陽大

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.

Ownership model
Operations to allow

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. 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. 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. 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 scan

No install, no signup — reads your repo locally and contacts nothing.

github.com/tomodahinata/aegis

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.