Skip to content

security(audit): hide mutable issuance registries from module consumers #213

Description

@seonghobae

Finding

Canonical shared HRIS-kernel owner PR #63 originally kept creation-bound audit authority in mutable process state. #212 made one live AuditOutboxEvent issuance single-use, and the first #213 repair removed module-level _AUDIT_LIVE_ISSUANCES / _AUDIT_CREATION_SNAPSHOTS capabilities by moving them behind closure-private operations. That intermediate design still depended on mutable issuance state even though ordinary module consumers could no longer reach the backing dictionaries directly.

This issue concerns the narrow service-TCB/canonical-evidence boundary. It is not a claim of tamper resistance against arbitrary interpreter memory or reflection.

Test-first repair history on canonical owner #63

The first repair chain remains valid history:

  • RED 701a179e95bba8e921c4bcdec5cfcf4cd310be34: production audit module must not expose the mutable backing registries.
  • Harness adoption 7b6cb6fb66267c5f14d7e163a84f1e57ab5405ac.
  • Production 70bdd6db87eda94228f91392b72beb2793ca29ab: move backing state into closure-private constrained operations.
  • Test correction cd3b2f5ba0234ccb2249fe48fb8ee5e07c773cde.
  • Manifest reseal 03d1b8b537efce97aa0b695bd9e5e23757a1d9d0.
  • Edge coverage 48bfaf7558c8623b70d3c08a736c6d2953f563b5: wrong-marker and duplicate snapshot-commit guards.

A fresh five-commit ordinary successor chain then tightened the contract further and is adopted rather than treated as a race:

  • c17af4890cf861cddc3b40b03165402d4cd2d82c — test: reject closure-exported issuance authority.
  • 8b20c53ff3afcdfa0f372bd35a06b265187c9db9 — test: require structural immutability instead of mutable issuance state.
  • 1b80534a7f39a56e335b44cb8ca702a551d3f088 — test: require immutable timestamp evidence after construction.
  • e5d4303fd3fefbf33795a4262830d16bd5a20424 — test: enforce structural immutability at the canonical boundary.
  • Production e29d180ce2e2bc531abc817fffea4eb6096c53ce — replace the mutable issuance runtime with a slotless namedtuple-backed exact AuditOutboxEvent value object. Construction validates the canonical fields and detaches occurred_at to exact UTC; export revalidates the contained values before deterministic CloudEvent/JSON/digest generation. __post_init__() is rejection-only compatibility re-entry.

The existing low-level tuple-forgery regression intentionally verifies export-time fail-closed validation for malformed forged values. This repair therefore does not claim that Python interpreter primitives are an unforgeable security boundary; it removes the product’s own mutable issuance-authority mechanism and makes canonical evidence structurally immutable under ordinary object mutation.

Current acceptance state

Exact #63 head is e29d180ce2e2bc531abc817fffea4eb6096c53ce, open · Draft · mergeable over protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f. Foundation run 33897074399, job 101102109240, is queued before checkout with steps=[], labels:["ubuntu-24.04"], and runner_id=0. Exact-head SAST Semgrep 33897074415, CodeQL PR 33897074314, Security Scan 33897074226, Required Noema 33897072213, Required PR Review Merge Scheduler 33897072247, Required OpenCode 33897072030, Strix 33897072135, and GitHub Code Quality 33897070683 are non-terminal. Hosted GREEN/100% coverage are not claimed.

The currently recorded CodeRabbit recent review covers only through 423cf66a537a0d6bc952dc4eba4207046e3e5537, and no formal review is tied to exact e29d180…; predecessor review/check evidence is not transferred. Keep #213 open until exact-head review/hosted acceptance and ordinary protected integration complete. #65 and Assignment descendants must not copy #63 source; they adopt only normally integrated protected owner truth.

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

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions