Finding
Canonical People AuthenticatedPrincipal validated tenant_record_id with isinstance(..., UUID) and then retained the caller-owned UUID object unchanged. Python uuid.UUID instances can be altered through low-level object.__setattr__, so a caller retaining the original UUID alias could change the principal tenant after construction. The predecessor also evaluated .int sentinel equality before proving that the retained payload was the exact built-in int; a forged exact-UUID payload could therefore execute caller-defined equality behavior during validation.
The constructor also accepted str subclasses for actor_reference / scope codes and frozenset subclasses for granted_scope_codes, allowing behavior-bearing retained values across the authorization boundary. This is a concrete realization of the retained-authority/scalar invariants already recorded by the canonical product-technical gap baseline; no competing baseline edit is needed.
Repair lineage
PR #55 is the canonical owner.
- Test-first
d0799709d0d5541ae09e672919154317de2cf938 adds regressions requiring: forged UUID .int payload rejection before equality behavior; tenant UUID detachment from a caller alias; exact built-in actor/scope strings; and rejection of frozenset subclasses before subclass iteration.
- Causal repair
0853605c284cb6e9d76f14bf1e0366ffee6e5d95 captures UUID .int once, requires exact built-in int within the 128-bit range before sentinel equality, reconstructs an owned UUID, requires exact built-in str for actor/scope evidence, and requires exact built-in frozenset before iteration. Purpose authorization remains outside the principal.
The public principal fields and existing purpose separation are preserved; no Keyverse/policy logic moved into the value object.
Current evidence boundary
#55 exact head is 0853605c284cb6e9d76f14bf1e0366ffee6e5d95, direct to protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f, Draft and mergeable. Fresh exact-head workflows have materialized:
- Foundation CI
34838670623 — queued
- Security Scan
34838670519 — queued
- SAST Semgrep
34838670492 — queued
- CodeQL PR
34838670493 — queued
No predecessor GREEN/review transfers and no hosted GREEN is claimed while these remain queued. Employment descendants were ordinary-forward restacked without force-push: #149 f7595aa8c4850bfaf69787ed4016c4bb797b8182, #155 f988e1effe612170a37445e7577877fc46a9b2e0, #156 e2f6327202688d72430fcbd86be7b702c41a44f1.
Keep #330 open through exact-head acceptance and protected integration.
Finding
Canonical People
AuthenticatedPrincipalvalidatedtenant_record_idwithisinstance(..., UUID)and then retained the caller-owned UUID object unchanged. Pythonuuid.UUIDinstances can be altered through low-levelobject.__setattr__, so a caller retaining the original UUID alias could change the principal tenant after construction. The predecessor also evaluated.intsentinel equality before proving that the retained payload was the exact built-inint; a forged exact-UUID payload could therefore execute caller-defined equality behavior during validation.The constructor also accepted
strsubclasses foractor_reference/ scope codes andfrozensetsubclasses forgranted_scope_codes, allowing behavior-bearing retained values across the authorization boundary. This is a concrete realization of the retained-authority/scalar invariants already recorded by the canonical product-technical gap baseline; no competing baseline edit is needed.Repair lineage
PR #55 is the canonical owner.
d0799709d0d5541ae09e672919154317de2cf938adds regressions requiring: forged UUID.intpayload rejection before equality behavior; tenant UUID detachment from a caller alias; exact built-in actor/scope strings; and rejection of frozenset subclasses before subclass iteration.0853605c284cb6e9d76f14bf1e0366ffee6e5d95captures UUID.intonce, requires exact built-inintwithin the 128-bit range before sentinel equality, reconstructs an ownedUUID, requires exact built-instrfor actor/scope evidence, and requires exact built-infrozensetbefore iteration. Purpose authorization remains outside the principal.The public principal fields and existing purpose separation are preserved; no Keyverse/policy logic moved into the value object.
Current evidence boundary
#55 exact head is
0853605c284cb6e9d76f14bf1e0366ffee6e5d95, direct to protecteddevelop@eb9757f8649aaad026a9865508d9aad50c1a7a4f, Draft and mergeable. Fresh exact-head workflows have materialized:34838670623— queued34838670519— queued34838670492— queued34838670493— queuedNo predecessor GREEN/review transfers and no hosted GREEN is claimed while these remain queued. Employment descendants were ordinary-forward restacked without force-push: #149
f7595aa8c4850bfaf69787ed4016c4bb797b8182, #155f988e1effe612170a37445e7577877fc46a9b2e0, #156e2f6327202688d72430fcbd86be7b702c41a44f1.Keep #330 open through exact-head acceptance and protected integration.