Implement AUDIT-WP-0007 hash-chain integrity.

Accept now extends a single-schema chain. Verify walks it; a rewritten
payload_hash is a break. Tamper evidence is that detector plus an
external chain-head attestation, not WORM.
This commit is contained in:
tegwick 2026-08-16 01:18:30 +02:00
parent 5faede18fc
commit 5fd04e2095
17 changed files with 696 additions and 29 deletions

View file

@ -4,6 +4,7 @@ import types
from audit_core.cli import build_parser
from audit_core.ingestion import build_backend
from audit_core.integrity import ChainReport, GENESIS
from audit_core.interface import AcceptResult, RetentionPolicy
@ -36,6 +37,16 @@ class _FakePostgres:
def close(self):
self.closed = True
def verify_chain(self, attestation=None):
return ChainReport(
intact=True,
events=0,
head=GENESIS,
head_event_id=None,
head_accepted_at=None,
first_break=None,
)
@property
def retention_policy(self):
return RetentionPolicy(
@ -109,6 +120,19 @@ def test_replay_command_reconciles(monkeypatch, capsys):
assert body["reference"] == "audit:evt-1"
def test_verify_chain_command(monkeypatch, capsys):
def fake(dsn, **kwargs):
return _FakePostgres(dsn, **kwargs)
monkeypatch.setenv("AUDIT_CORE_DATABASE_URL", "postgresql://example/audit_core")
_install_fake_postgres(monkeypatch, fake)
args = build_parser().parse_args(["verify-chain", "--schema", "audit_core"])
assert args.func(args) == 0
body = json.loads(capsys.readouterr().out)
assert body["intact"] is True
assert body["head"] == GENESIS
def test_replay_command_missing_event(monkeypatch, capsys):
def fake(dsn, **kwargs):
return _FakePostgres(dsn, **kwargs)