- Home
- Skills
- Data & Databases
- Supabase RLS Review
Works with the AI Agents you already use
Supabase RLS Review
This skill walks your agent through a careful review of a project you own and stops before anything touches production.
$19
Supabase RLS Review
Example session with this skill installed
Before we launch, review my Supabase project todo-ai for RLS and policy mistakes. I own it. The anon key is in our React frontend. I ran your catalog query in the SQL Editor and saved the result as check_result.csv.
- Read your context and instructions
- Compiled the supabase rls review
Summary
Fictional demo project
todo-ai, reviewed from an exported catalog query (no keys used). 3 findings: 0 Critical, 2 High, 1 Medium, 0 Low. No write tests were performed.
| Severity | Object | Rule | What it means for you |
|---|---|---|---|
| High | public.todos | rls_disabled | RLS is off. Anyone holding the anon key from your frontend can read and change every todo through the REST API, depending on grants. |
| High | public.profiles | policy_true (read_every_profile) | The policy condition is literally true, so every user can read every profile. |
| Medium | storage.todo-attachments | public_bucket | Anyone with a file URL can download attachments. Fine for public images, not for private uploads. |
Draft fix (review on staging, not applied)
BEGIN;
ALTER TABLE public.todos ENABLE ROW LEVEL SECURITY;
CREATE POLICY "todos: owner can read" ON public.todos FOR SELECT TO authenticated USING ((select auth.uid()) = user_id);
CREATE POLICY "todos: owner can insert" ON public.todos FOR INSERT TO authenticated WITH CHECK ((select auth.uid()) = user_id);
CREATE POLICY "todos: owner can update" ON public.todos FOR UPDATE TO authenticated USING ((select auth.uid()) = user_id) WITH CHECK ((select auth.uid()) = user_id);
CREATE POLICY "todos: owner can delete" ON public.todos FOR DELETE TO authenticated USING ((select auth.uid()) = user_id);
DROP POLICY "read_every_profile" ON public.profiles;
CREATE POLICY "profiles: owner can read" ON public.profiles FOR SELECT TO authenticated USING ((select auth.uid()) = id);
ROLLBACK; -- change to COMMIT only after review and the isolation test
Before I finalize this: is todos.user_id the ownership column, and should other signed-in users see any part of a profile (for example a display name)? If yes, we move those fields to a separate public view.
Next steps
- Export current policies (
select * from pg_policies where schemaname in ('public','storage')) so you can roll back. - Apply the draft on a staging branch and run
reference/isolation-test.sqlagainstpublic.todos. Every block must print PASS. - Decide whether
todo-attachmentsshould be private; if so, use the per-user folder pattern frompolicy-patterns.md. - Re-export the catalog query and rebuild the report to confirm the findings are gone.
This is a configuration review, not a penetration test. An empty report would not prove the app is safe.
Connects securely to your tools. The creator never sees your data.
About this skill
Apps built quickly with Lovable, Bolt, v0 or by hand often ship the Supabase anon key in the frontend while Row Level Security is off, or on with a policy that is just true. This skill walks your agent through a careful review of a project you own and stops before anything touches production.
What your agent does with it
- Installs the open-source supabase-rls-check CLI (MIT, pinned to v0.2.0), or registers its MCP server.
- Prints a read-only catalog query for you to run in the Supabase SQL Editor. It reads
pg_class,pg_policies,pg_proc,pg_extensionandstorage.buckets, never table rows. No service_role key or database password is needed. - Builds an HTML/Markdown report and a
fix.sqldraft wrapped inBEGIN … ROLLBACK. - Explains each finding as "who can read or change what" before showing any SQL.
- Replaces the placeholder policy with a pattern that fits your data model: owner-only rows, team membership, public read-only catalog, per-user Storage folders, or a locked-down SECURITY DEFINER helper. It asks which column holds ownership instead of guessing.
- Proves the fix on staging with a two-user isolation test (plain SQL, or a pgTAP version for
supabase test dbin CI). - Re-runs the check and lists anything left as accepted risk.
Rules checked
RLS disabled, true policies, anon/public policies on tables that look personal or payment-related, SECURITY DEFINER functions the anon role can execute, SECURITY DEFINER functions without a fixed search_path, views that bypass RLS, views that expose auth.users to the API, policies that trust user-editable user_metadata, auth.uid() calls re-evaluated per row (performance), public Storage buckets, extensions installed in public. With your consent and the public anon key, an optional probe checks which tables answer an anonymous read and whether a service_role JWT appears in your site's JavaScript.
Ground rules built in
- Only projects you own or have written permission to test.
- Never asks for the service_role key or a database password.
- Read-only. Fixes are drafts you apply on staging first.
- This is a configuration review, not a penetration test. Zero findings does not prove an app is safe.
What's inside
SKILL.md plus reference/rules.md, policy-patterns.md, isolation-test.sql, pgtap-rls-test.sql and staging-checklist.md. The plain-SQL isolation test was run on PostgreSQL: correct owner policies pass, and a using (true) policy or a table with RLS off fails as expected.
Read-only audit only, not a pen-test. User must manually run a SQL export query. Requires staging environment for fix verification. Cannot bypass RLS or access projects without permission.
How to use
- 1
Connect your agent to the Agensi MCP
Copy the prompt and paste it into Claude, ChatGPT, Cursor or any agent that supports MCP. It sets up the connection for you. Manual setup
- 2
Sign in to Agensi
Your agent shows a sign-in link. Sign in and click Allow.
- 3
Ask for what you need
Your agent loads this skill and uses it on your task. It always asks before any payment.
Reviews
No reviews yet
Be one of the first to try it. Every listed skill goes through the trust checks below.
Security scanned
Checked by our 8-point scan before listing
Fresh listing
Recently published to Agensi
Money-back guarantee
Doesn't do what its page promises? You get your money back.
Trust & safety
Security scan
Security scan passed today
- Accounts
Supabase
- Software
Python 3.11+pipxsupabase-rls-check (open source, MIT)
Permissions
Allowed Hosts
Terminal: installs and runs the supabase-rls-check CLI. Read/Write files: reads the exported catalog CSV and writes report.html, report.md and fix.sql locally. Network: pipx install from GitHub, and the optional anonymous probe against your own project. Environment variable: SUPABASE_ANON_KEY for that optional probe only. The skill never asks for the service_role key and never writes to your database.