fix(data-integrity): bind artifact-read audit to issued token authority - #404
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Superseded by clean current-stack reconstruction #450. #450 is based on exact current revocation parent #449 head |
Objective
Keep verified artifact-read evidence bound to the immutable issued-link identity that produced it. The ledger previously accepted
READevents for an unknown token or another tenant/subject/document, and restart replay accepted those tampered relationships as durable audit evidence.Test-first evidence
Exact test-only head
02462d5256932266b8df93d4152a25a783f4f941, based on #402 exact headc1389e97f25157638e2ffdaa6a6eebba45cae91a, addedArtifactLinkLedgerReadAuthorityTestbefore changing production. Exact-head CI31543296702checked out that SHA and failed in the Maven test/coverage gate as expected whilerecordRead(...)andreplayRead(...)still appended parsed events without consulting the issued-link map.RCA refined one initial test assumption before the production repair: revocation is a separate temporal state, not a different immutable token identity. A request can verify before a concurrent revocation and append its audit event after the revocation transition, so rejecting a matching read solely because the token is now revoked would lose legitimate audit evidence and overconstrain the race boundary. The final regression therefore rejects unknown-token and tenant/subject/document identity mismatch on live append and restart replay, while the existing ISSUED -> REVOKED -> READ round-trip remains valid.
Implementation and GREEN evidence
Current exact implementation head is
559118e410d6e0d2f98fbf2b50ede7f1460900d0, with parent #402 still exactc1389e97f25157638e2ffdaa6a6eebba45cae91aand protectedmainstill exact55d7ae8647208e301f282350f076eeddaba61d11at the latest direct refetch.The implementation binds each read event to an existing issued token record with exact tenant, subject, and document identity before append/publication, and applies the same invariant during restart replay. Runtime mismatch raises a controlled
IllegalStateException; malformed persisted authority continues to use the ledger's generic invalid-line failure. Revocation state is deliberately not part of the immutable identity predicate, preserving legitimate audit-after-concurrent-revoke ordering.The first implementation head
78f15060f738a7ab043dbb9cd45c7308aab64f91reached functional tests but failed the repository's exact 100% branch-coverage gate because the new fail-closednull event/null token idbranches were not directly exercised. No production behavior was weakened: focused regressions were added for those malformed runtime inputs. The ancestor status-code fixture was also made authority-valid by persisting a matching ISSUED record before injecting raw READ status boundaries, so #400's independent 100..599 invariant remains isolated.Exact current-head proof:
31544505151: success;93953995574: success;93953995561: success;93953995693: success;31544505148: success;Scope and dependency
This child is deliberately stacked on #402/#400/#357 because those PRs own the same append-only artifact-link/read ledger integrity path. It changes only read-event identity binding plus focused regressions. It does not alter token signature verification, artifact byte delivery, HTTP status validation, revocation transition validation, token-expiry decisions, tenant authentication, persistence technology, or external audit storage.
Merge gate
Keep Draft while the ancestor stack remains open. #357 is the protected-main-facing parent and remains gated by live governance/independent approval; #400 and #402 must then be reconciled/integrated in order before this child is rebuilt against the resulting protected baseline. After every parent integration, regenerate base-sensitive CI/security/review evidence on the new exact child identity. Independent non-author approval remains a separate protected-merge gate.