The tamper-evident audit log

For an agent that touches real systems, "what did it actually do?" has to have an answer you can trust. In OAP the record of what happened — the transcript, every authorization decision, tool sessions, trigger deliveries — is append-only and cryptographically signed: a hash-chained ledger you can verify offline.

Append-only by construction

The records that matter for audit accrete; they aren't rewritten. A write that would change an existing entry is rejected, and an append-only entry can't be deleted. History is a ledger, not a document — you can add to it, never edit it.

Signed and hash-chained

Every append-only entry carries a provenance envelope: who wrote it, a monotonic sequence number, the hash of the previous entry from that writer, and an Ed25519 signature over the whole thing. The sequence and prev-hash form a hash chain per writer, so any modification, fabrication, gap, or reordering is detectable — and, because the chain's head is anchored when the session completes, so is truncation. Signatures are verified on write, not after the fact: an unsigned or forged append-only write is rejected, whether it comes from a token holder or from in-process code.

The trust root is witnessed by Kubernetes

Each session mints its own signing keypair, and the operator anchors the public half on the AgentSession's status — a trust root Kubernetes witnessed, not something the session asserts about itself. Platform components register their public keys the same way. So verification never has to take anyone's word for which key is legitimate; it checks against keys the cluster recorded.

Verify it offline

oap audit verify <session> recomputes every writer's hash chain and signatures against those witnessed keys, entirely offline, and exits non-zero on any hard finding — an unknown key, a bad signature, a gap, a fork, a truncated tail. It won't render a verdict on a partial read of the log: a truncated ledger yields "could not verify," never a falsely clean pass.