OneShot

All packsMulti-Tenant Auth & RBAC CoreSolve

postgres column level grants restrict role escalation

Table-level UPDATE grants let an admin rewrite an invite's role

A plain UPDATE grant on invites lets any permitted caller change the invited role, not just revoke the invite -- column-level grants narrow that to exactly one field.

This is one of the things Multi-Tenant Auth & RBAC Core already handles. Sign-in, organisations, invites and roles — with one customer's data provably unable to reach another's.

Buy for $1492 of 3 clean-room builds passed · full refund if it fails on your machine

Is this you?

If the app role has a blanket UPDATE grant on the invites table, then any code path allowed to revoke a pending invite is also, technically, allowed to rewrite that invite's target role, email, or token -- an admin who should only be able to cancel an admin-level invite someone else sent could instead quietly upgrade a pending member invite to an admin invite by writing to a column nothing in the app's own logic intended to expose.

Why this one is easy to get wrong

A table-level GRANT is the default unit most ORMs and tutorials reach for -- "this role can update this table" -- and application-level checks (only allow revoking, never editing) look sufficient because they gate every code path the app actually calls. What they don't gate is a bug or a future code path that forgets to restrict itself, and Postgres itself doesn't stop that write if the grant is table-wide.

What you get instead

Core decision 11 grants app_user UPDATE only on invites.revoked_at and only on org_members.role -- not the whole row. An admin can revoke any pending invite, including one an owner sent, but nothing can rewrite an invite's role, email, or token; and re-pointing a membership's user_id or org_id is a 42501 permission error before any RLS policy even runs, closing off the escalation path at the grant level, not just the application level.

Source: ARCHITECTURE.md core decision 11 — checkable in the pack you receive

How you actually use this

You don’t install a library or wire up an SDK. Your own coding agent builds the code in your project, and you keep it — no runtime dependency on us.

  1. Step 1

    Download and unzip

    You get a folder: the docs that tell an agent what to build, a starting skeleton, and the test suite that decides when it's done.

  2. Step 2

    Open it in Claude Code or Cursor

    Point your coding agent at the folder. Nothing to install, no account with us, no API key.

  3. Step 3

    Paste one prompt

    The pack contains the exact prompt. Paste it as your first message and leave it alone — it works through the build itself, choosing a cheaper or stronger model per task.

  4. Step 4

    Run ./verify.sh

    One command. It prints a pass or fail for every check. Green means the build is done — the same script we ran to produce the receipt on this page.

Typical build: about 12 minutes of your agent working, mostly unattended. Then you integrate the working module into your app the way you would any code you’d written yourself.

Why you can believe this

2 of 3 runs passed

We ran this pack from an empty folder 3 times and published exactly what happened — every check, the model, the token cost, the wall time. Not a testimonial, and not our opinion: the same verify.sh you run yourself. Read the full receipt →

Buy for $14914-day refund if verify.sh fails →

Related problems