Skip to content
System One

Supabase RLS Linter

An experimental linter for Postgres Row Level Security policies, built with Jev. It sends nine judgments about a submitted policy and table schema in a single request to check whether access controls actually restrict users to their own data, not just that RLS is turned on.

Still from Supabase RLS LinterPlay the video in the post below
Still from x.com

Post on X

Views
23,881
Likes
60
Reposts
7

Read from X on . Counts change daily.

Supabase RLS Linter takes a pasted Postgres row level security policy, written as one or more CREATE POLICY statements, along with the table’s schema, and checks whether the policy actually keeps one user out of another user’s rows rather than just existing. A traditional linter can confirm RLS is turned on and a policy is present; it can’t tell that auth.uid() is not null was meant to be auth.uid() = user_id, since both parse fine and only one of them restricts access.

Ali Waseem built it around nine judgments about one policy, sent to Jev in a single request. Two of them can only be answered from the schema, which is why the table DDL is required. The result is one of three verdicts: OK when no judgment trips its threshold, Review when something needs a human, and Fail when at least one reads as a leak. The page also ships an eval set of example policies, each with an expected result, covering cases such as an UPDATE with no WITH CHECK clause, a claim read from app_metadata, an ownership check against the wrong column, a null tenant treated as global and a tautology.

Waseem calls the tool experimental and built it while trying out Jev. Try it directly at rls-jev-tester.vercel.app.

Open on Web

More like this

Use cases this is tagged with