Skip to content

Evidence packs

An evidence pack is a portable, offline-verifiable snapshot of what your AI system did during a period. Built for auditors, DPOs, lawyers, and regulators.

When to create one

  • Monthly as a routine — for your DPA archive.
  • During an incident — the period around a suspicious event.
  • For a regulator request — exactly the window they ask for.
  • For due diligence — a prospective customer or investor asks for proof.

Create

Via dashboard: AI → Evidence packs → New pack.

Via API:

Terminal window
curl -X POST https://api.monsys.ai/api/v1/ai/evidence-packs \
-b cookies.txt \
-H "Content-Type: application/json" \
-d '{
"period_start": "2026-04-01T00:00:00Z",
"period_end": "2026-04-30T23:59:59Z",
"app_id": 42, // optional, otherwise all apps for the tenant
"include_blobs": true // bundle redacted content
}'

Response:

{
"pack_id": "7",
"trace_count": 14233,
"span_count": 37501,
"blob_count": 12044,
"total_cost_micro_eur": 89412300,
"manifest_sha256": "3abb09…",
"signing_public_hex": "d2f60e21…",
"download_url": "/api/v1/ai/evidence-packs/7/download",
"verify_with": "Use tools/evidence-pack-verify.py — manifest is Ed25519-signed by the hub."
}

Bundle layout

pack-7.tar.gz
├── manifest.json
├── manifest.sig ← Ed25519 signature over manifest.json bytes (base64)
├── traces.jsonl ← one line per trace
├── spans.jsonl ← one line per span
└── blobs/
├── 1bd2ea92….txt ← redacted content per hash
├── 8a48cdca….txt
└── ...

manifest.json keys

KeyTypeDescription
schema_versionintPack format version (starts at 1)
pack_idstringNumeric ID
tenant_iduuidThe owner
app_idint/nullOne app or all apps of the tenant
period_start/_endRFC3339The window
trace_countintNumber of traces in the pack
span_countintNumber of spans
blob_countintNumber of unique content blobs
traces_sha256hexSHA256 of traces.jsonl bytes
spans_sha256hexSHA256 of spans.jsonl bytes
blob_index[]array{hash, sha256} per blob — recompute & check
signing_public_hexhexEd25519 public key — cross-verify with monsys
created_atRFC3339Pack generation timestamp

Offline verification

Terminal window
pip install cryptography
python3 evidence-pack-verify.py pack-7.tar.gz \
--expected-pubkey <pinned fingerprint from monsys.ai/security/keys>
# Quiet mode, exit-code only:
python3 evidence-pack-verify.py --quiet pack-7.tar.gz --expected-pubkey

Example output:

pack_id : 7
tenant_id : 77198636-a5fe-484e-93fe-98b11a55ca84
period : 2026-04-01T00:00:00Z → 2026-04-30T23:59:59Z
traces : 14233
spans : 37501
blobs : 12044
signing key : d2f60e21e0d496252b92bb308310e1a1dd1d5010f8fcaabbe169bdae1e2b7173
✓ signature valid
✓ traces.jsonl hash matches (3abb0918cda7…)
✓ spans.jsonl hash matches (b517235df141…)
✓ all 12044 content blobs hash-matched
RESULT: OK

Exit codes:

  • 0 — everything matches
  • 1 — at least one hash or the signature does not match — pack has been altered

What does the auditor do with the public key?

The manifest contains a signing_public_hex. But who says that’s the right key?

Two options:

  1. Cross-verify against monsys.ai/security/keys (the public page where we publish our Ed25519 fingerprints).
  2. Request a printed certificate at onboarding — we send you a PDF with the fingerprint that you keep in your archive.

This lets the auditor independently confirm that the signature wasn’t made by someone with a spoofed key.

Guarantees

  • Tamper-evident: one byte changed in a blob → verifier raises.
  • Period-bound: the manifest pins which window the pack covers — you cannot retroactively add “extra” data without re-signing.
  • Reproducible: same period + same data → byte-identical manifest_sha256 (deterministic serialisation).
  • No monsys account needed to verify.

Retention

We keep evidence packs on disk for at least 12 months. For longer retention export to your own object store; monsys.ai does not guarantee long-term archival (NIS2 requires you to keep the evidence anyway).