Write down who should see each kind of data
Before running a tool, pick a concrete resource such as a profile, an order or a published article. Decide whether it should be public, private to its owner, or shared within an organisation. A readable public catalogue is not automatically a vulnerability. A readable private record is a different result.
Build the test around synthetic records whose owners you know. Include at least two accounts with different ownership, plus a visitor without a login. Keep administrative credentials out of these checks: privileged access can hide the very restriction you are trying to verify.
Check the deployed public application
Enter the public HTTPS application URL in RLS Checker. Use an application you own or are authorised to assess. The checker looks for Supabase configuration and observable table references in public client resources, then makes bounded anonymous read requests.
Review both the result and the coverage. A rejected read means that request was blocked. An empty response is inconclusive. If the checker cannot discover your configuration or a table, the lack of a finding does not establish that the table is protected.
This outside view can catch a deployment that differs from your local settings. It does not inspect your SQL policy definitions or test logged-in users, writes, Storage, or every API route. Continue with project-level tests even when the external result looks reassuring.
Test account boundaries and each operation
On a local or staging project, sign in as account A and request a known record owned by B through the same API your application uses. Repeat in the other direction. Also test a legitimate record so that a broken application is not mistaken for successful isolation.
Exercise SELECT, INSERT, UPDATE and DELETE separately where your app supports them. A SELECT policy does not prove that writes are safe. Define expected row ownership before attempting a write, and use disposable test records instead of production customer data.
Supabase combines schema and table grants with row policies. Inspect both layers. Run automated database tests as the roles being tested, not as a table owner, superuser or role that bypasses RLS. Use the official Supabase test tooling for repeatable regression checks.
Reproduce why a zero-row result is ambiguous
Our downloadable SQL fixture creates five synthetic cases in a disposable local database. It uses a dedicated visitor role without BYPASSRLS, checks visible rows, verifies a permission rejection and rolls back every created object.
The filtered table and the empty table both return zero rows. One contains a row protected by RLS; the other has no RLS and no data. This is why a single empty external read cannot certify your policies. The fixture tests PostgreSQL behaviour, not the Supabase HTTP gateway or the full VICE scanner.
Retest after the deployed permissions change
After fixing a policy or grant, rerun the account tests and the external check. Confirm that legitimate access still works and that the previously exposed private record is no longer available to the unintended role. Preserve a synthetic regression case for future migrations.
If you need authenticated coverage across your application, the VICE documentation describes the broader audit workflow. Keep the result of this free checker scoped to anonymous Supabase reads; it is not a security certification.
Reproduce the five local cases
Run only in a disposable local PostgreSQL database. The script creates synthetic data in a transaction, verifies permissions and rolls back its changes. It does not connect to a Supabase project.
Download the SQL fixture