KB-71A0

Principal-Set Separation Fix

3 min read Revision 1
fix7t1recheck-3principal-separation2026-06-09

03 - Principal-Set Separation Fix

What Codex required

U_effective_privilege_principal is a principal/role set only, used to evaluate effective privileges against #21. It must not be a member of U_legacy_object. It includes directus/runtime principals and relevant role-membership paths. Privilege checks must join U_legacy_object × U_effective_privilege_principal.

What T1 patched (blueprint doc 02 §H.4.B, doc 05, doc 06)

  • §H.4.B (doc 02): U_effective_privilege_principal = the PUBLIC pseudo-role plus every relevant login/member role derived through pg_auth_members role-membership expansion. The controlled owner qt001_cp_owner is excluded from the removable-privilege equality (owner-implicit privilege held by an unreachable NOLOGIN principal — G-OWNER-UNREACHABLE); superusers (workflow_admin) are dispositioned separately (G-SUPERUSER-BREAKGLASS).
  • The privilege comparison is a tuple join: U_legacy_object × U_effective_privilege_principal produces (object_identity, principal_identity, privilege_kind, grant_option / column scope), reconciled both-EXCEPT to the closed-world sealed privilege_set_manifest #21 over that exact tuple shape: realized − #21 = ∅ AND #21 − realized = ∅. For every legacy routine #21 grants no EXECUTE/DML → effective EXECUTE = 0 for non-owner non-superuser principals; any retained SELECT/USAGE on a table/view exists only because an exact #21 tuple grants it.
  • §H.3 item 3 (doc 02): effective privileges are explicitly computed over U_effective_privilege_principal joined to each object.
  • doc 05 (rollback): the S14/S15 owner+ACL snapshot's both-direction effective-privilege verification is over the object set and the separate principal universe (role-membership-aware) — a role is a principal, never an object member.
  • Guard G-PRINCIPAL-SET-SEPARATE (doc 06): the principal universe is role-only; the effective-privilege check is run as the object × principal tuple join (never as object-set membership); no principal is a member of U_legacy_object; fails closed if a principal is injected into the object set, the check is run as membership, or a removable role is omitted.
  • G-NOLEGACY-POST and G-U-LEGACY-OPTION-BETA-UNIFORM-ENDSTATE now explicitly operate over the object × principal tuple shape (doc 06).

Self-check

PASS. Principals live only in U_effective_privilege_principal; the privilege check is the U_legacy_object × U_effective_privilege_principal tuple join to #21; no principal is an object member.

Back to Knowledge Hub knowledge/dev/reports/architecture/t1-fix7-blueprint-patch-after-codex-recheck-3-set-separation-2026-06-08/03-principal-set-separation-fix.md