Problem/Motivation

Keyed chain integrity is valuable only when verification is routinely executed and failures leave the writer's trust boundary. Operator-triggered verification and local-only evidence do not provide the continuous, independently reviewable trust floor needed by governed high-assurance actions.

Proposed resolution

Add scheduled keyed verification, explicit integrity-failure alerting, and a versioned off-system stream/export contract. Preserve Audit Chain product ownership while allowing consumers to bind their governance-evidence semantics through the contract.

Acceptance criteria

  • Scheduled verification uses keyed HMAC and rejects unkeyed fallback for the enterprise assurance
  • profile.

  • Verification detects mutation, deletion, insertion, reordering, wrong-key use, and broken
  • checkpoints.

  • Failure emits a durable alert and a non-success health state without rewriting the affected chain.
  • Verified evidence can stream or export to an independently controlled destination with replay and
  • checkpoint semantics.

  • The export is data-minimized, tenant/partition aware, and does not leak secrets.
  • Tests cover schedule execution, alert delivery, destination outage, retry, duplicate delivery,
  • recovery, and key rotation.

  • Existing configured-key downgrade lineage remains closed and is referenced rather than reopened.

API changes

Adds versioned verification-status, alert, checkpoint, and off-system stream/export contracts.

Comments

jmcerda created an issue. See original summary.

jmcerda’s picture

Public working mirror: GitHub #18.

Drupal.org remains the authority for this work item; implementation discussion and pull-request linkage may occur in the mirror.

jmcerda’s picture

Status: Active » Needs review

Part 1 is up for review on the public working mirror: https://github.com/Wilkes-Liberty/audit_chain/pull/19

Scheduled verification (cron, configurable interval, disabled by default), durable health on the status report (failure = error; quiet or never-run schedule = warning; assurance profile without a schedule = warning), and the alert contract: a failure logs to the audit_chain channel and dispatches a verification-failed event so consumers bind their own delivery. The enterprise assurance profile (verify_require_keyed) refuses unkeyed operation with a stable reason instead of falling back to unkeyed SHA-256, and rejects unkeyed history; rotated keys keep verifying through previous_hash_keys. Verification is strictly read-only — the tamper test asserts the chain is byte-identical after a failing run.

Part 2 — the versioned off-system stream/export contract with checkpoint and replay semantics — follows on this same issue.

Coverage: eight kernel tests (schedule execution and interval skip, keyless assurance failure with alert and error health, tamper failure with event dispatch and chain preservation, unkeyed-history rejection, key rotation, overdue and unscheduled warnings); full module suite 37 tests / 227 assertions green.

  • jmcerda committed 470ffb7e on 1.x
    Issue #3616535: Resolve the signing key before claiming keyed operation
    

  • jmcerda committed 569654ac on 1.x
    Issue #3616535: Snapshot chain rows without the Drupal 11-only FetchAs...

  • jmcerda committed 7eba07e1 on 1.x
    Issue #3616535: Schedule keyed verification with durable health and an...
jmcerda’s picture

Part 2 (off-system evidence export) is up for review on the public working mirror: https://github.com/Wilkes-Liberty/audit_chain/pull/21

Chain rows export as versioned, data-minimized NDJSON — identifiers and hash-chain columns only; metadata, IP addresses, user agents and entity labels never leave the system — to an https:// ingest endpoint or a file path. Delivery is at-least-once with per-destination checkpoints: an outage leaves the checkpoint for retry, limited runs are resumable, replays never move it backwards, and consumers deduplicate on the row id. Export refuses while the last scheduled verification is failing, plain HTTP off-host is refused, and ingest URLs are logged and checkpointed with credentials stripped. Surfaces: drush audit-chain:export plus an optional cron leg.

Eleven kernel tests cover checkpoint/resume, replay, minimization, channel filtering, outage/recovery, duplicate delivery, and the verification gate; the full suite is 51 tests / 287 assertions green. With part 1 shipped in 1.4.0, this completes the issue's scope.

  • jmcerda committed 994e650e on 1.x
    Issue #3616535: Export data-minimized evidence off-system with...
jmcerda’s picture

Status: Needs review » Fixed

Part 2 merged to 1.x (https://github.com/Wilkes-Liberty/audit_chain/pull/21); git.drupalcode.org is in sync. With part 1 released in 1.4.0 and the export half now on the branch, the issue's full scope — scheduled keyed verification, integrity alerting, and the off-system evidence stream — is committed. The export ships in the next release.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.