More screenshots

    Works with the AI Agents you already use

    Claude CodeClaude CodeCursorCursorCodex CLICodex CLIDeepSeekDeepSeekMuseMuse+22 more

    Supabase RLS Audit + Cross-Tenant Leak Test

    1

    Audit Supabase RLS like a senior reviewer, then prove tenant isolation: your agent tries to read and write another tenant's rows in every table. Exact fix SQL + a CI guard for every PR.

    $19

    Secure checkout via Stripe

    Money-back guarantee

    Converts to your local currency at checkout

    Security scanned
    Supabase RLS Audit + Cross-Tenant Leak Test

    Supabase RLS Audit + Cross-Tenant Leak Test

    Example session with this skill installed

    Audit my Supabase project for tenant data leaks before we launch. The tenant column is tenant_id. I'm running supabase start locally, so you can run the leak test there.

    • Read your context and instructions
    • Compiled the supabase rls audit

    I ran the 20 database checks and the cross-tenant leak test on your local database. Tenant isolation does not hold: a user of tenant A can read tenant B's documents, and anyone can unlock tenant B's invoices by editing their own user_metadata. Inserts into another tenant are blocked everywhere.

    Supabase security audit — local (supabase start)
    Verdict: 2 tables leak across tenants and 1 table has RLS disabled. 13 high-severity issues need fixing too; two of them cause the leaks.

    Severity Findings
    Critical 3 (2 proven leaks + 1 table without RLS)
    High 13
    Medium 11
    Low 2
    Scope: schema public + storage, tenant column tenant_id, database: local, leak test run as a real user of tenant A.

    Leak test
    Table Read B Update B Delete B Insert B Forged metadata Result
    public.documents 1 row 0 0 denied 1 row LEAK
    public.invoices 0 0 0 denied 1 row LEAK
    public.memberships 0 denied denied denied 0 PASS
    public.orders 0 denied denied denied 0 PASS
    Every write attempt was rolled back; your data is unchanged.

    Findings

    1. [Critical] Any signed-in user reads every tenant's documents — public.documents
      Evidence: leak test LEAK (reads 1 row of tenant B) + check R07: policy members_read_all is using (true).
      Why it matters: every customer can read every other customer's documents through the API.

    Fix
    drop policy members_read_all on public.documents;
    create policy documents_select on public.documents for select to authenticated
    using (tenant_id in (select private.my_tenants()));
    2. [Critical] Tenant taken from user-editable metadata — public.invoices
    Evidence: leak test LEAK (a forged user_metadata unlocks 1 row of tenant B) + check R04 on policy tenant_from_metadata.
    Why it matters: any user can call auth.updateUser() to point their metadata at another tenant and read its invoices.

    Fix
    drop policy tenant_from_metadata on public.invoices;
    create policy invoices_select on public.invoices for select to authenticated

      using (tenant_id in (select private.my_tenants()));
    create index on public.invoices (tenant_id);  -- also fixes R08
    
    1. [Critical] RLS disabled — public.audit_log
      Evidence: check R01; anon and authenticated hold INSERT, UPDATE and DELETE on it.

    Fix

    alter table public.audit_log enable row level security;
    revoke all on public.audit_log from anon, authenticated;
    
    1. [High] Write grants with no policy behind them — announcements, audit_log, invoices, notes
      Evidence: check R10. Today only RLS's default deny stops these writes; one future permissive policy would open them.
      Fix: revoke insert, update, delete on public.announcements, public.invoices, public.notes from anon; and keep only the writes each role really needs.
      …plus 7 more high findings with their fixes:
    an INSERT policy with check (true) on notes;
    a SECURITY DEFINER function callable by anon, with a mutable search_path;
    a view without security_invoker;
    an exposed materialized view;
    a storage policy that ignores the bucket;
    a role with BYPASSRLS.
    Fixes 1 and 2 use the private.my_tenants() helper from the secure pattern; I'll create it in the same migration.
    

    What's already right
    orders and memberships are fully isolated: no reads, writes or forged-metadata access across tenants.
    No table accepts an insert into another tenant.
    Not checked
    Code checks (service keys in the client, Edge Functions with verify_jwt = false): no repo access in this session.
    Next step: say "apply fixes 1–3 as a migration" and I'll write the migration file, re-run the leak test, and show before/after. When everything passes, I can install the CI guard so a future PR can't reopen these leaks.

    Connects securely to your tools. The creator never sees your data.

    About this skill

    "Can one customer see another customer's data?" On Supabase, the answer lives in your RLS policies, grants and functions. One using (true), one policy that trusts user_metadata, or one SECURITY DEFINER function in public is enough to leak every tenant's rows through the public API.

    This skill makes your coding agent answer that question with evidence, not guesses.

    What it does

    1. Audit — 20 read-only checks Reads only Postgres catalogs, never your data. Catches:

    tables without RLS; permissive or role-less policies; policies that scope neither tenant nor user; trust in user-editable metadata; SECURITY DEFINER functions and views that bypass RLS, and functions with a mutable search_path; leftover write grants and dangerous default privileges (including Postgres 17's new MAINTAIN privilege); public storage buckets and loose storage policies; roles that bypass RLS, unindexed tenant columns and slow per-row auth.uid() calls. It merges the results with Supabase's Security Advisor.

    1. Leak test — proof, not suspicion On staging, a branch or a local database, the agent signs in as a real user of tenant A, exactly like the Data API does. Then, in every table with your tenant column, it tries to:

    read tenant B's rows; update them; delete them; insert into tenant B. It repeats the read with a forged user_metadata pointing at tenant B, and once more as anonymous. Every write is rolled back automatically. Each table gets PASS, LEAK (with exactly what crossed) or INCONCLUSIVE; it never reports a false "safe".

    1. Code review Looks for service keys reachable by the browser, Edge Functions with verify_jwt = false, service-key functions that don't check tenant membership, client-side writes, migration drift and secrets in git history.

    2. Report with fixes A prioritized report a founder reads in 30 seconds and an engineer can act on. Every finding comes with evidence and ready-to-adapt fix SQL, plus a reference secure multi-tenant pattern.

    3. CI guard — keep it fixed A GitHub Action that, on every pull request touching supabase/, starts a throwaway Supabase database in the runner. It applies your migrations, re-runs the checks and the leak test, and fails the PR on critical or high findings or any leak.

    No secrets needed; it never connects to your projects. Reviewed exceptions go in an allowlist with a reason. Safety by design Database checks are read-only. The leak test refuses to run without explicit setup, never runs on production, and rolls back every write. The agent proposes fixes and applies nothing without your approval. What's inside SKILL.md: the full audit workflow for your agent. queries/audit.sql: the 20 checks. queries/leak_test.sql: the automated cross-tenant leak test. references/: what each check means, fix templates, the secure pattern and the report template. ci/: the guard script and the GitHub Actions workflow.

    Frameworks & tools

    Specifically built for Supabase projects using PostgreSQL, RLS, and Auth. Supports GitHub Actions for CI integration and works with local Supabase CLI environments.

    Why this beats prompting it yourself

    Writing a reliable cross-tenant leak test that covers forged JWT metadata and transactional rollbacks is complex. This skill uses a standardized battery of 20+ specific RLS checks and a proven testing harness that prevents false positives by verifying isolation with actual data operations.

    Use cases

    • Auditing a Supabase SaaS project before a public launch.
    • Verifying that new database migrations haven't introduced RLS regressions.
    • Investigating if a specific user can access another customer's data.
    • Hardening Edge Functions and storage bucket policies against unauthorized access.

    Known limitations

    The automated leak test cannot run on production databases for safety reasons. It requires a staging, branch, or local database environment to execute write-based isolation tests.

    "Can one customer see another customer's data?" On Supabase, the answer lives in your RLS policies, grants and functions. One using (true), one policy that trusts user_metadata, or one SECURITY DEFINER function in public is enough to leak every tenant's rows through the public API.

    This skill makes your coding agent answer that question with evidence, not guesses.

    What it does

    1. Audit — 20 read-only checks Reads only Postgres catalogs, never your data. Catches:

    • tables without RLS;
    • permissive or role-less policies;
    • policies that scope neither tenant nor user;
    • trust in user-editable metadata;
    • SECURITY DEFINER functions and views that bypass RLS, and functions with a mutable search_path;
    • leftover write grants and dangerous default privileges (including Postgres 17's new MAINTAIN privilege);
    • public storage buckets and loose storage policies;
    • roles that bypass RLS, unindexed tenant columns and slow per-row auth.uid() calls.

    It merges the results with Supabase's Security Advisor.

    2. Leak test — proof, not suspicion On staging, a branch or a local database, the agent signs in as a real user of tenant A, exactly like the Data API does. Then, in every table with your tenant column, it tries to:

    • read tenant B's rows;
    • update them;
    • delete them;
    • insert into tenant B.

    It repeats the read with a forged user_metadata pointing at tenant B, and once more as anonymous. Every write is rolled back automatically. Each table gets PASS, LEAK (with exactly what crossed) or INCONCLUSIVE; it never reports a false "safe".

    3. Code review Looks for service keys reachable by the browser, Edge Functions with verify_jwt = false, service-key functions that don't check tenant membership, client-side writes, migration drift and secrets in git history.

    4. Report with fixes A prioritized report a founder reads in 30 seconds and an engineer can act on. Every finding comes with evidence and ready-to-adapt fix SQL, plus a reference secure multi-tenant pattern.

    5. CI guard — keep it fixed A GitHub Action that, on every pull request touching supabase/, starts a throwaway Supabase database in the runner. It applies your migrations, re-runs the checks and the leak test, and fails the PR on critical or high findings or any leak.

    • No secrets needed; it never connects to your projects.
    • Reviewed exceptions go in an allowlist with a reason.

    Safety by design

    • Database checks are read-only.
    • The leak test refuses to run without explicit setup, never runs on production, and rolls back every write.
    • The agent proposes fixes and applies nothing without your approval.

    What's inside

    • SKILL.md: the full audit workflow for your agent.
    • queries/audit.sql: the 20 checks.
    • queries/leak_test.sql: the automated cross-tenant leak test.
    • references/: what each check means, fix templates, the secure pattern and the report template.
    • ci/: the guard script and the GitHub Actions workflow.

    Tested

    • Every check and the leak test are covered by an automated test suite, run against a Postgres database seeded with real-world RLS mistakes.
    • The leak test and the CI guard were run on real Supabase stacks, Postgres 15 and 17:
      • a deliberately broken app fails with exactly its 2 seeded leaks;
      • the secure pattern passes with zero false positives.
    • The CI workflow was also run on GitHub against a production SaaS schema: it passes the clean schema and blocks a pull request that adds a table without RLS.
    • A write test that can't run (for example on a read-only connection) reports INCONCLUSIVE, never a false PASS.

    Find more skills like this on the Claude Skills Marketplace, the Codex Skills Marketplace and the Gemini Skills Marketplace, or browse Claude Skills for Data & Databases.

    The leak test needs staging, a Supabase branch or a local database, plus one test user in tenant A and a tenant B with data; without those it is skipped and the report says so. Multi-tenant checks assume one consistent tenant column across tables (single-tenant apps are audited per user instead). Auth settings such as leaked-password protection and MFA come from the Security Advisor, not SQL. Code checks need repo access.

    How to use

    1. 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. 2

      Sign in to Agensi

      Your agent shows a sign-in link. Sign in and click Allow.

    3. 3

      Ask for what you need

      Your agent loads this skill and uses it on your task. It always asks before buying a skill.

    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 1 day ago

    Software
    PythonGitSupabase project (Postgres 15+)
    A way to run SQL: Supabase MCP, psql
    orthe SQL Editor
    Optional
    GitHub Actions (CI guard)Supabase CLIDocker (local leak test)

    Run the leak test on staging, a Supabase branch or a local `supabase start`, never on production. The audit itself is read-only and safe anywhere.

    Permissions

    Terminal / Shell
    Read Files
    Write Files
    Network Access
    Environment Variables

    File Scopes

    supabase/**
    .github/workflows/rls-guard.yml
    .rls-guard/**
    .env*
    src/**

    Terminal and network: to run SQL against your database (MCP, psql) and the CI guard. Read files: migrations, config.toml and client code, to review policies and look for leaked keys. Write files: only the report, a migration you approve, and the CI guard files. Environment variables: reads the database URL (never prints keys or secrets).

    Listed1 day ago

    What's inside

    Frequently Asked Questions

    This skill automates the testing of Row Level Security (RLS) by simulating cross-tenant attacks in a safe environment, identifying leaks that manual reviews or basic SQL prompts often miss. It provides evidence-based proof of isolation, ensuring one customer cannot access another's data.

    For safety and data integrity, the automated leak test is designed to run on staging, local Supabase CLI environments, or branching environments. It executes write-based tests within transactions that are rolled back, avoiding any permanent impact on your data.

    You will receive the AI agent skill configuration, a suite of diagnostic SQL audit scripts, and a ready-to-use GitHub Action template for CI/CD integration. It also includes a prioritized remediation guide for patching any discovered vulnerabilities.

    The skill works with any AI agent capable of executing SQL queries via a database connection or analyzing codebases via CLI, such as GPT-4 based agents with tool-calling capabilities. It is optimized for projects using the Supabase CLI and GitHub Actions.

    Yes, the skill is designed to detect 'SECURITY DEFINER' functions, risky views, and improperly configured storage bucket policies that might bypass RLS. It provides specific SQL recommendations to wrap these functions in secure checks.

    The audit reads system catalogs only, never application rows. The leak test runs only where you allow it (never production) and rolls back every write it attempts.

    It includes the Advisor's results and adds tenant-specific checks the Advisor doesn't do (policies that don't scope the tenant, trusted user metadata, leftover grants), an actual attempt to cross tenants, and a CI guard so a future migration can't reopen a leak.

    No. It gives you the exact fix SQL for each finding and applies it only if you say so, preferably as a migration file. Then it re-runs the leak test to prove the fix.

    New in Data & Databases