Chain Verification
Chain Verification
Every ledger entry is cryptographically linked to the entry before it using SHA-256. This makes the audit trail tamper-evident: modifying any historical entry invalidates all subsequent hashes, and the break is immediately detectable.
How the chain is built
For each new ledger entry, Imara computes:
1Serialize the full entry payload to canonical JSON (sorted keys, no whitespace).
2Concatenate the previous entry's hash (hex string) with the serialized payload.
3SHA-256 hash the concatenated bytes. This becomes the current entry's hash.
4The genesis entry uses a zero hash (64 hex zeros) as the previous value.
hash_n = SHA256( hash_{n-1} + canonical_json(entry_n) )Ledger entry schema
Each entry written to the ledger and replicated to S3 contains:
{
"timestamp": "2026-04-21T14:32:01.882Z",
"fintech_id": "acme-bank",
"session_id": "sess_01HXXXXX",
"classified_act": "ACTION_PAYMENT_INITIATE",
"status": "SUCCESS",
"raw_intent": "Initiate a payment of $500 to account 9876",
"estimated_tokens": 142,
"latency_ms": 38,
"prev_hash": "a3f9c2d8e1b4...",
"hash": "b7e1a4f2c9d3..."
}Verifying via the API
The runtime exposes a chain verification endpoint that recomputes every hash and reports the first broken link.
curl http://localhost:7070/ledger/chain \
-H 'X-Imara-Token: stratus-dev-token-change-me' | jq .Intact chain response:
{
"chain_valid": true,
"entry_count": 42,
"head_hash": "d1a9e5c3b7f2...",
"broken_at": null
}Tampered chain response:
{
"chain_valid": false,
"entry_count": 42,
"head_hash": "d1a9e5c3b7f2...",
"broken_at": 7,
"expected": "c8d3b6e1f2a4...",
"got": "ffffffffffffffff..."
}Verifying independently
Any party with read access to the replicated S3 objects can verify the chain without trusting Imara. The algorithm is standard SHA-256 — no custom library or SDK required.
#!/usr/bin/env python3
import json, hashlib, boto3
s3 = boto3.client("s3")
objs = s3.list_objects_v2(Bucket="stratus-audit", Prefix="ledger/acme-bank/")
entries = sorted(o["Key"] for o in objs.get("Contents", []))
prev_hash = "0" * 64
for key in entries:
body = s3.get_object(Bucket="stratus-audit", Key=key)["Body"].read()
entry = json.loads(body)
data = prev_hash + json.dumps(entry, sort_keys=True, separators=(",",":"))
computed = hashlib.sha256(data.encode()).hexdigest()
assert computed == entry["hash"], f"Chain broken at {key}"
prev_hash = computed
print("Chain intact ✓", len(entries), "entries")Portal chain view
The regulator portal at /chain performs the same verification client-side using the ledger data fetched from S3. It highlights the broken entry and shows the expected vs. actual hash diff. No access to the Imara runtime is needed — the portal reads S3 directly.