Skip to content

security(people): detach accepted mutation results from adapter-retained aliases #269

Description

@seonghobae

Finding

Canonical owner is #64. The People application boundary exact-gated persistence results and checked their identities, but then returned the same frozen/slotted result object received from the mutation port. EmploymentMutationResult, PositionMutationResult, AssignmentMutationResult, and HireAcceptanceResult also retained the exact uuid.UUID objects supplied by the port.

A port therefore could retain the accepted result object or one nested UUID and mutate it after the service returned via object.__setattr__. That changes already-accepted HR mutation output after identity/replay validation. This is a checked-result/used-result alias defect, distinct from #229/#246 target/replay coherence and #267/#268 command snapshotting.

Test-first repair on #64

  • RED contract: 0cd270fc6d6f8273f7fb783f9425810493e7d7ef adds test_people_mutation_result_alias_detachment.py. For Employment, Position, Assignment and confirmed hire, it retains the exact port result, mutates both the retained nested UUID payload and the outer result field after service return, and requires the returned service value to remain the accepted identity. Against predecessor 6c8be6d44e28fe77bfe52a2e0946df4e0cbe3b83, the returned object is the same adapter-owned object, so the contract is source-level RED. Hosted RED is not claimed because GitHub-hosted runs are admission-queued.
  • Generic result fix: 6f3a54b14ee448dcb7719c98a2640ed0990a493b reconstructs each accepted generic result UUID from its once-validated exact integer and snapshots the result with dataclasses.replace(...) before replay/identity validation and return.
  • Confirmed-hire fix: 41829e0971a79012a2cd3723b8c355baa5acac3c applies the same nested UUID reconstruction plus outer result snapshot to HireAcceptanceResult.

The change does not alter SQL/schema, authorization policy, idempotent replay semantics, audit/outbox, #264 connection-capability binding, People read source, shared-kernel source, workflow bytes, or #65 authorization-decision ownership.

Acceptance

Keep this issue open until the current #64 exact head receives current-head Foundation/service GREEN, required security/governance evidence, independent review, and ordinary protected integration, or a verified successor fully inherits the regression and production delta. No predecessor evidence transfer, self-approval, force-push, destructive rebase, routine administrator bypass, gate weakening, or no-op retrigger.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions