Skip to content

PREWAVE-BE-114 — Persist the Tamper-Evident Audit Stream and Production Keyring #815

Open

Description

@dDevAhmed

Problem context

AuditStreamService defaults to InMemoryAuditStreamStore when no store is injected. That store keeps records and checkpoints in process-local Maps, so a restart or multiple API replicas can lose or fork the tamper-evident audit chain. The AuditKeyRegistry is also an in-memory keyring; historical records identify the key used for their HMAC, so production verification requires a configured keyring that retains prior verification keys after rotation.

The repository has a hash-chained audit stream design and documentation, but the production durable-store/keyring boundary is not implemented in the inspected service path.

Technical scope

  • Implement a durable AuditStreamStore backed by the approved database persistence layer.
  • Persist records and checkpoints with unique constraints on stream ID/sequence and transactional head advancement.
  • Make concurrent appends safe across replicas; no two records may claim the same sequence or previous hash.
  • Wire the durable store into the production audit module. Keep InMemoryAuditStreamStore test-only/local-only and fail startup if production resolves to it.
  • Configure the active HMAC key and historical verification keyring from the approved secret-management boundary. Persist non-secret key metadata and retain old verification keys for as long as referenced records/checkpoints require them.
  • Make key rotation/revocation explicit and auditable without storing raw key material in ordinary application tables.
  • Ensure checkpoint creation, export, verification, and tamper findings operate against durable records and stable key IDs.

Required tests

  • Audit records and checkpoints survive restart and are visible across replicas.
  • Concurrent append attempts serialize safely and preserve unique sequence/previous-hash continuity.
  • Crash between record and checkpoint writes is transactionally safe or recoverable.
  • Historical records remain verifiable after active-key rotation and restart.
  • Unknown/revoked key IDs fail closed without invalidating unrelated historical keys.
  • Tampered payload, missing record, sequence gap, checkpoint mismatch, and chain-context mismatch are detected.
  • Production module fails startup if an in-memory store or missing active key is configured.

Security and architecture constraints

  • Audit record payloads remain privacy-sanitized and canonical-serialized before hashing.
  • Raw HMAC secrets must never be stored in application tables, logs, exports, or status responses.
  • Durable sequence/head advancement must be atomic and cross-process safe.
  • Do not treat an in-memory audit chain as production evidence.

Acceptance criteria

  • A durable production AuditStreamStore is implemented and wired.
  • Production cannot silently fall back to InMemoryAuditStreamStore.
  • Concurrent append and checkpoint operations preserve chain integrity.
  • Active and historical key verification works after restart and rotation.
  • Tests cover tamper detection, gaps, concurrency, and recovery.
  • Documentation describes persistence, retention, key rotation, and recovery.
  • Exact-head CI and independent security review pass.

Dependencies

  • Existing audit hash-chain serialization, binding, sanitizer, and verification contracts.
  • Approved production secret-management boundary for HMAC key material.

Non-goals

  • Replacing the existing audit hash-chain format.
  • Publishing raw audit secrets or changing audit privacy policy.
  • Treating this stream as proof of on-chain protocol state.

Complexity and points

  • High — 200 points

Candidate only. Activation remains maintainer-controlled.

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