LLearnCode
Academy/supabase/Policy reasoning

intermediate · 25 minute study

Predict the rows a policy will reveal

One permissive policy added for convenience can widen access despite several careful policies elsewhere. Learn to evaluate the complete policy set.

Loading progressEvidence grows with practice
Useful preparation · 1 prerequisite

Use this as a map, not a lock. If these ideas are familiar, continue.

  • Identity is not authority — A signed-in user can still be the wrong user, in the wrong company, with the wrong permission. A public key and a privileged key must never be treated as interchangeable fixes.

First, build a mental model

For an ordinary SELECT, an RLS condition behaves like an enforced row filter. Within the relevant command group, permissive policies can open rows; restrictive policies can narrow that opening.

  1. Enabled RLS with no applicable permissive policy is default deny. A SELECT may succeed while returning no rows; this is different from lacking a SELECT grant.
  2. Applicable permissive policies combine with OR; restrictive policies combine with AND. At least one permissive must pass, and every applicable restrictive must pass.
  3. ALL policies participate in the selected command group. Policy role matching also matters: a PUBLIC policy applies to all roles; an authenticated policy does not apply to anon.
  4. USING sees the existing row. Only true passes; false or NULL filters it out. Membership lookups inside real policies also need deliberate access control and performance.
Read the codesql · educational example
-- PostgreSQL / Supabase example; not SQLite syntax.
ALTER TABLE public.notes ENABLE ROW LEVEL SECURITY;
GRANT SELECT ON public.notes TO authenticated;
CREATE POLICY member_read ON public.notes
FOR SELECT TO authenticated
USING (company_id IN (
  SELECT company_id FROM public.memberships
  WHERE user_id = (SELECT auth.uid())
));
  1. Grant

    The role may issue SELECT on notes. That does not yet admit a row.

  2. Membership

    A note qualifies only if its company is in the verified actor's trusted membership set.

  3. Composition

    An additional permissive USING(true) could widen the group. A restrictive tenant fence would still have to pass.

Production thinking

Take this beyond the example.

Inventory effective policies, commands, roles, table grants and later migrations. Test direct reads for allowed, foreign and anonymous actors. A screenshot of a filtered list is not tenant-isolation proof.

Sources and further reading

Your evidence

unseen is a local learning signal, not a credential or proof of production competence.

Explain the mental model, then explicitly acknowledge it. Opening a page is not evidence.

Supported retries can complete this lesson. Independent evidence and delayed review determine the skill stage.

Next lesson · Check the row before and after a change →