Skip to main content
← All posts
5 min readEngineering

Adding a Forensic Witness to your AI stack: an engineering guide

How engineering teams integrate Decision Keep into existing model pipelines, manage keys, and verify the witness layer without adding latency to the decision path.

About the author+

Jamil Luketic

Executive Director at Decision Keep

Former Data & Tech Leader at Oracle, Mastercard, Coles, Optus, and Reece.

Connect on LinkedIn
Illustration for Adding a Forensic Witness to your AI stack: an engineering guide

Most engineering teams adopt AI for its speed, not its paperwork. The model infers, the API responds, the business moves on. Then audit or compliance asks for proof, and the team realises the decision path produced no evidence an outsider can trust.

This post is for the engineers who have to fix that without slowing the decision path down.

The integration constraint

The Forensic Witness must not sit in the hot path. Adding a network call, a database write, or a consensus round-trip to every inference will break latency targets and create a new failure mode.

The solution is separation. The operational layer runs the model. The witness layer records what happened after the decision completes, using an asynchronous hand-off.

What you capture

You do not need the raw payload. You need a canonical summary that is enough to reconstruct the decision later:

  • Model version - the exact identifier from your model registry.
  • Input references - hashes or identifiers, not raw personal data.
  • Output - the decision, score, or class.
  • Routing outcome - approved, declined, flagged, escalated.
  • Actor type - model, agent, human override.

That summary is the content hash input. The record itself is small enough to hand off to a sidecar or queue without touching the critical path.

Key management for engineers

The root of trust is your Ed25519 key. A few rules:

  1. Generate the key in your environment. Do not let a vendor generate it for you if you want the signature to be authentically yours.
  2. Store the private key in your KMS or HSM. Cloud KMS (AWS KMS, GCP Cloud KMS, Azure Key Vault) or an on-prem HSM. Never check it into source control.
  3. Publish the public key. Auditors verify against this. It can be public.
  4. Rotate on a schedule. When you rotate, chain the new key to the old one so the history stays verifiable.

In Client-signs mode, your service signs the record before it ever leaves your network. The ledger receives only the signed envelope and the content hash.

SDK and API patterns

The typical hand-off looks like this:

model.infer(request)
  -> capture(modelVersion, inputRefs, output, routingOutcome)
  -> sign(capture, privateKey)
  -> chain(previousHash)
  -> timestamp(rfc3161Authority)
  -> sendToLedger(signedRecord)

Most of that runs in a background job or sidecar after the response is returned. The user sees model latency only.

If you use a message queue, the witness consumer picks up the capture event, builds the record, and pushes it to the ledger. If the queue is down, the capture event is retained locally and retried. The decision is not lost.

Verification in CI

Treat the witness chain like any other critical control. Add a verification step to CI that:

  1. Checks out the current chain head.
  2. Recomputes every content hash and chain hash.
  3. Verifies every signature against your published public key.
  4. Confirms chain continuity back to genesis.

A failed verification should page someone. It means either the chain was tampered with or the key material changed without rotation.

You can run the same check offline with no account. A one-liner in a script, a step in a deploy pipeline, or a scheduled job against an exported chain.

Performance and scale

The witness record is small: a few hundred bytes per decision. A hash chain is append-only with no read amplification. Timestamp authorities are stateless and can be cached.

At scale, the limiting factor is not the ledger. It is the rate at which you can produce signed records. Ed25519 signing is fast; the bottleneck is usually key access in a KMS with per-request latency. Cache keys in-process for the lifetime of the process if your KMS supports it.

The sovereignty boundary

The evidence must live on infrastructure you control. If the only way to see the record is a vendor console, you do not own the evidence.

Run the verifier locally. Export the chain regularly. Run your own timestamp authority or use a public one as a fallback. The witness is only as good as your ability to check it without asking permission.

For the full context on why this architecture matters, see The Forensic Witness: why automated decisions need an independent record.

FAQ

Questions auditors, risk and legal actually ask

Does the Forensic Witness add latency to the decision path?+
No. The witness layer records a signed, hash-chained summary after the decision completes. The AI keeps its speed and logic while evidence is captured independently.
What does the engineering integration look like?+
Capture the model version, input references, output, and routing outcome at the inference layer. Sign the record with your Ed25519 key, chain it to the previous entry, and send it to the ledger. The SDK handles signing, chaining, and timestamping.
Who holds the signing key?+
You do. In Client-signs mode the signing happens in your environment and the raw payload never leaves your infrastructure. In Custodian mode we host the ledger but seal each payload to your published key. In Operator-signs mode we sign on your behalf.
How do I test the witness layer?+
Run the verifier against a known-good chain in CI. Treat a failed verification as a severity-1 control failure. You can also verify individual receipts offline with no account.

Sources

References & further reading

Independent analysis and standards cited in this article.

Prove every AI decision

Decision Keep gives your organisation a tamper-evident, verifiable record of every automated decision. Book a demo to see it on your stack.

Keep reading

Documentation

Go deeper in the docs