All packsMulti-Tenant Auth & RBAC CoreSolve
postgres rls using policy without with check cross tenant insert
A USING policy blocks reads but not cross-tenant inserts
A row-level security policy without a WITH CHECK clause correctly filters SELECTs but still lets a request INSERT rows into another tenant's org.
What goes wrong
A Postgres RLS policy's USING clause governs which existing rows a query can see or touch (SELECT, UPDATE, DELETE) -- it says nothing about which rows a new INSERT is allowed to create. A policy written with only a USING clause correctly blocks tenant A from reading tenant B's rows, and still lets tenant A insert a row claiming to belong to tenant B's org_id.
Why agents get it wrong
USING reads as "the rule for this table" in the CREATE POLICY syntax, and a policy that filters reads correctly passes every test that checks whether cross-tenant data is visible -- the insert path is a separate, easy-to-forget clause (WITH CHECK) that most RLS tutorials mention once and most generated policies omit, because the SQL still runs without it.
What Multi-Tenant Auth & RBAC Core pre-decides
Every INSERT/UPDATE policy in the pack's frozen migration carries an explicit WITH CHECK (org_id = app.current_org_id() AND ...) alongside its USING clause -- separate policies per command, not one combined policy, specifically so a write path can't rely on a read-oriented rule that was never designed to gate it. A cross-tenant write attempt fails with 42501, and the verify suite's isolation tests probe writes directly, not just reads.
Source: ARCHITECTURE.md core decision 7, 'Traps this pack pre-empts'