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.
What goes wrong
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 agents get it 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 Multi-Tenant Auth & RBAC Core pre-decides
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