Prove what your
AI decided.
Give every AI decision you instrument a tamper evident record. Seal batches with your own Ed25519 key, then hand an auditor the records and your public key and let them prove nothing changed after sealing, on their machine, with no service to call.
An audit trail that shows
if a sealed record changed.
Ordinary application logs can be edited, and nothing in them shows whether they were. You seal decision records into signed batches instead, so a later edit is provable rather than deniable.
Append only ingest
Each decision you record captures the system and model that decided, when the call started and ended, and digests of the content, with detector results and oversight actions attached when they apply. It writes as CloudEvents 1.0 JSON, and the store interface is append and query, nothing that edits.
Digests, not content
The record has no prompt or completion field. What lands in the store is a SHA-256 digest over the canonicalized input and output, so you can prove which content ran without retaining it.
Merkle sealed, Ed25519 signed
Hand a batch of records to the signer. It builds an RFC 6962 Merkle tree, the Certificate Transparency construction, and signs the 32 byte root with a key that never leaves your infrastructure. Where you cut a batch is your call.
Retention with legal holds
Presets for 6 month, 3 year, and 4 year retention windows. Pass your hold registry to a prune run and matching records survive it, whatever the cutoff says. PruneAndCertifyAsync signs a certificate for the run, so a gap in the trail comes with a signed account of it.
Export endpoint
MapEvidenceExport serves the trail as NDJSON or a JSON array with a required time range and an optional tenant filter, written straight out of the store rather than buffered. Ships with no authentication on purpose, so you attach your own policy.
In process, no egress
Your app builds each record inside your own process, where the decision happens. The package makes no network calls at all, including model downloads. Verification runs offline against your public key.
using Invarix.Guard.Evidence;
using Invarix.Guard.Evidence.Extensions;
builder.Services.AddInvarixGuardEvidence(options =>
{
options.AISystemId = "invoice-classifier";
options.AISystemVersion = "2.3.1";
options.ModelId = "gpt-4o-mini";
options.ModelVersion = "2024-07-18";
})
.UseJsonlStore("/var/evidence/decisions.jsonl");
// then, per decision:
var record = factory.NewBuilder()
.WithStartTime(started)
.WithEndTime(DateTimeOffset.UtcNow)
.WithInputHashSha256(prompt.ToSha256Hex())
.WithOutputHashSha256(completion.ToSha256Hex())
.WithOutcome(DecisionOutcome.Allowed)
.Build();
await sink.WriteAsync(record);Four steps between
a decision and a proof.
The chain below is the whole cryptographic mechanism. It runs inside your process: no call to Invarix when a record is written, when a batch is signed, or when someone comes asking about it years later.
- 1
Record
Your app builds a decision record at the moment it decides. You hash the input and output yourself with ContentHasher, which canonicalizes before digesting so the same content always reproduces the same hash. The record has no field for the raw prompt.
- 2
Seal
You hand a batch of records to the signer, which builds a Merkle tree over them. You can compute an inclusion proof for any record, tying it to a single 32 byte root.
- 3
Sign
The root is signed with an Ed25519 key held on your own infrastructure. The signature covers the root, the tree size, the batch ID, the key ID, and the timestamp you assert.
- 4
Verify
Give an auditor the record, its proof, the signed commitment, and your public key. The check then runs entirely on their machine.
Every feature ships
in the free package.
There is no paid tier of Invarix.Guard.Evidence. Signing, sealing, retention presets, and the export endpoint are all in the package you install.
Evidence
No paid tierThe whole package. Use it and self host it inside commercial products. The limits are the ELv2 ones, so you cannot offer it to third parties as a hosted or managed service, and you have to keep the license notices intact.
- CloudEvents 1.0 decision records, append only ingest
- SHA-256 content digests, no prompt field in the record
- Merkle batch sealing with Ed25519 signed commitments
- Retention presets, a legal hold API, Ed25519 signed deletion certificates
- JSONL store for single node, in memory for tests, or your own adapter
- Streaming export endpoint for ASP.NET Core
- No support of any kind, no SLA, five docs packed in the nupkg
What to check
before you install.
dotnet add package Invarix.Guard.Evidence --prerelease. Without it NuGet refuses to resolve a prerelease and tells you there are no stable versions available. The release candidate tag means the public API and the signed wire formats are frozen, not that coverage is thin: over 440 tests pass, plus a separate harness that exercises the packed package itself.