Episode: EP7
Trigger: after any change to a table's RLS policies that use auth.uid(),
or after any client-side code that queries such a table.
auth.uid() policies create three distinct behaviours that must all be
tested — not just the happy path:
| State | Caller | Expected result |
|---|---|---|
| No session | Anon key, no JWT | Empty array (or explicit error if null guard configured) — no data leaked |
| Wrong user | Signed-in user who does not own the rows | Empty array — RLS scopes to auth.uid() |
| Owner | Signed-in user who owns the rows | Rows returned |
Both return [] with no error — a developer cannot tell whether the table is
empty, RLS is blocking them, or they forgot to sign in. All three states must be
tested explicitly; the name applied to the symptom is not the diagnosis.
- Confirm
relrowsecurity = tviapg_class - Create two test users via
auth.admin.createUser - State 1 — query with no session → assert empty array
- State 2 — query signed in as the non-owner → assert empty array
- State 3 — query signed in as the owner → assert rows returned
- Delete test users after validation
SELECT relname, relrowsecurity FROM pg_class WHERE relname = '<table>';
SELECT policyname, cmd, qual FROM pg_policies WHERE tablename = '<table>';All 3 auth states produce the expected result.