VibeShieldVibeShield

Home / Blog

Supabase RLS Checker: Readable Rows Are Not Proof

October 14, 2026 · VibeShield

Learn what readable, empty, and blocked Supabase responses establish—and how to follow up with safe role and ownership tests on your own app.

A Supabase RLS checker can show that a request can read a table through the public API. That observation alone does not prove row-level security is disabled. An enabled policy may intentionally allow the same read.

The useful question is whether the observed access matches the data's intended audience. This guide explains how to interpret a public check; the Supabase two-user testing guide covers the next step for private user data.

Begin with an access expectation

For each exposed table or view, write one sentence describing who should see it. “Published recipes are public” and “draft recipes are visible only to their owner” are different rules even when both live in one application.

Use three test identities: a signed-out visitor, a signed-in owner, and another signed-in user. A public scan observes only a slice of that matrix. It does not replace tests of authenticated ownership.

What a public checker observes

VibeShield's Supabase check looks for a project URL and public key in the app's browser assets. When discovery succeeds, it checks the exposed API schema and uses count-only HEAD requests against up to eight tables; it does not download table rows.

Record the hostname, time, role used, table or view, and response evidence. A count can establish that rows are readable under that request context, but it cannot show whether their contents are confidential. A small sampled check also cannot establish the state of every table or policy.

Public Supabase publishable and legacy anon keys are intended for clients. Secret and service-role keys require a different response because they belong on trusted servers; consult Supabase's API key guide.

Interpret the result before changing a policy

Readable rows

In this hypothetical example, a signed-out count request reports 12 readable rows in published_recipes. The product intentionally publishes those recipes. Investigate whether drafts are excluded, but do not remove the intended public read merely to turn a report green.

Now consider the same observation for private_notes, which the product promises to keep owner-only. That mismatch is a reason to investigate the request role, grants, policies, and exposed views. It still does not identify the exact configuration error by itself.

Zero readable rows

Zero is inconclusive. The table might be empty, the role might see no matching rows, or the request might be filtered. Seed a harmless fixture in your own staging environment and repeat the owner-versus-other-user test.

Blocked or unavailable

A denied request can support a narrow statement: that particular request did not read the resource. It does not establish that every authenticated user is correctly isolated. An unavailable API, undiscovered key, or incomplete schema should be recorded as an untested area.

Follow the request's identity and permissions

Supabase API access involves both table privileges and RLS policies. Check both against the intended role. Views also need review because their execution context can change whether the underlying table policies apply; see the official RLS documentation.

Keep the request context explicit when investigating. An administrator's successful SQL query and a signed-out browser request do not test the same identity. Similarly, success for one owner account says little about another user's access.

  1. Create an owner-only staging fixture with no personal data.

  2. Confirm its owner can read and update it through the app's intended requests.

  3. Confirm a signed-out visitor and another signed-in user cannot read or modify it.

  4. Test insert, update, and delete separately if the app supports them. A read check does not establish write safety.

  5. After a configuration change, repeat the permitted action as well as the denied actions.

Turn the observation into a useful fix request

Describe the expected audience, the role tested, and the observed response. For example: “In staging, account B can read account A's disposable note through the app API. Make that note owner-only while preserving account A's read and update access.” This is a hypothetical fix request, not a finding from a customer scan.

Ask your coding assistant to explain the proposed policy and show the permitted and denied tests. Review the migration before applying it, then retest. Avoid granting broad access just to make a failing UI work.

Check your app's public surface

Create a free VibeShield account to run the available public audits. Supabase discovery and count checks provide leads for investigation; they do not inspect every authenticated policy, prove tenant isolation, or test write access.

If you built with Lovable, the Lovable launch checklist connects database review to the wider app release. Keep a manual ownership test whenever private user data is involved.