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:
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
| Key | Type | Description |
|---|---|---|
schema_version | int | Pack format version (starts at 1) |
pack_id | string | Numeric ID |
tenant_id | uuid | The owner |
app_id | int/null | One app or all apps of the tenant |
period_start/_end | RFC3339 | The window |
trace_count | int | Number of traces in the pack |
span_count | int | Number of spans |
blob_count | int | Number of unique content blobs |
traces_sha256 | hex | SHA256 of traces.jsonl bytes |
spans_sha256 | hex | SHA256 of spans.jsonl bytes |
blob_index[] | array | {hash, sha256} per blob — recompute & check |
signing_public_hex | hex | Ed25519 public key — cross-verify with monsys |
created_at | RFC3339 | Pack generation timestamp |
Offline verification
pip install cryptographypython3 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 : 7tenant_id : 77198636-a5fe-484e-93fe-98b11a55ca84period : 2026-04-01T00:00:00Z → 2026-04-30T23:59:59Ztraces : 14233spans : 37501blobs : 12044signing key : d2f60e21e0d496252b92bb308310e1a1dd1d5010f8fcaabbe169bdae1e2b7173✓ signature valid✓ traces.jsonl hash matches (3abb0918cda7…)✓ spans.jsonl hash matches (b517235df141…)✓ all 12044 content blobs hash-matched
RESULT: OKExit codes:
0— everything matches1— 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:
- Cross-verify against monsys.ai/security/keys (the public page where we publish our Ed25519 fingerprints).
- 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).