presidio-evidence
The signed-evidence substrate of the presidio-hardened-* family. Every component that gates an action on evidence, or produces evidence for someone else to check, uses one contract: canonical JSON and SHA-256 content addressing, detached Ed25519 or HMAC-SHA256 signatures, fail-closed verification against a trust store, and provenance parents that chain payloads into a verifiable graph. Independent of Microsoft Presidio.
The library was extracted from four production implementations before they could drift apart. Seven family repositories now conform to it. Provenance parents (ADR-0002) chain classification → gate decision → training run → runtime posture → payment into one DAG, so regulatory traceability is a data structure rather than process documentation.
The contract is schemas/ + vectors/, not the code. The Python package and the Rust crate both prove conformance against the same golden vectors, and both trees ship inside the Python package. A consumer migrates by pointing its existing tests at the vectors first and swapping imports second.
Install
pip install presidio-evidence # Layer 0 + HMAC, stdlib only
pip install 'presidio-evidence[crypto]' # adds Ed25519 (cryptography)
Python 3.11+. The runtime has no dependencies; Ed25519 needs the crypto extra.
Use
from presidio_evidence import (
EVIDENCE_REF_SCHEMA_ID_V3,
build_envelope,
content_hash,
load_trust_store,
sign_evidence_v3,
verify_envelope,
)
ch = content_hash({"item_id": "D1", "status": "evidence-present"}) # Layer 0
sig = sign_evidence_v3(ch, "my-signer", "iki-gov", "D1", key=priv_hex) # Layer 1, @3
ref = {
"item_id": "D1",
"framework": "iki-gov",
"source": "my-tool",
"source_version": "1.0",
"ledger_ref": "run-42",
"content_hash": ch,
"signer": "my-signer",
"signature": sig,
"claimed_at": "2026-10-25T00:00:00Z",
}
envelope = build_envelope([ref], schema=EVIDENCE_REF_SCHEMA_ID_V3)
trust = load_trust_store({"my-signer": {"alg": "ed25519", "public_key": pub_hex}})
results = verify_envelope(envelope, trust, expected_framework="iki-gov")
assert all(r.verified for r in results)
Verification never raises on bad evidence: a wrong key, tampered content, a relabelled subject or an unknown signer verifies as False, with a reason per ref. A malformed envelope raises EvidenceError.
Keys (ADR-0001 D3): generate_ed25519_keypair() and public_key_hex(priv) produce trust-store entries; load_private_key(path) requires mode 0600 (or reads an environment variable with env="VAR") and never echoes key material. Key custody stays with the operator; the library stores nothing.
The contract trees are package data: schemas_dir(), vectors_dir(), schema_ids() and load_schema("presidio-hardened/evidence-ref@3").
CLI
presidio-evidence verify envelope.json --trust trust-store.json
presidio-evidence verify envelope.json --trust trust-store.json --require-subject-binding iki-gov
presidio-evidence keygen --out signer.key --signer my-signer # 0600 file; prints the trust-store entry
verify exits 0 only if every ref verifies. It fails closed on malformed input, on refs that declare an optimistic or zk tier (this verifier checks signature attestations only, ADR-0003 D6), and on an @1/@2 ref claimed for more than one item.
The contract
| Schema | What it pins |
|---|---|
evidence-ref@1 |
The envelope and its eight ref fields; signature over canonical({content_hash, signer}). Frozen. |
evidence-ref@2 |
Adds an optional per-ref assurance_tier (attested / optimistic / zk, ADR-0003); same signed message. |
evidence-ref@3 |
Adds a required framework and signs the subject and the tier: canonical({assurance_tier, content_hash, framework, item_id, signer}) (ADR-0004). A ref copied under another item, framework or tier no longer verifies. |
trust-store@1 |
Signer → algorithm and keys, with rotation lists. |
training-run@1, gate-certificate@1 |
Layer-0 payloads the family's producers emit (ADR-0005 numeric encoding, ADR-0006 certificate identity). |
Layers (ADR-0001 D1): 0 canonical JSON (strict: floats rejected) and SHA-256 content addressing · 1 detached signatures and trust-store verification · 2 approval semantics, out of scope (treasury keeps its dual control).
Every schema change is append-only (ADR-0001 D5): a published vector is never edited, and a new wire format is a new major. Verifiers accept @1, @2 and @3; a gate that needs subject binding demands @3 for its framework.
Consumers
| Repository | Evidence | Layer |
|---|---|---|
| presidio-hardened-ikigov-assess | evidence-ref@1/@2 verifier, gate certificates, workshop leave-behinds |
0 + 1 |
| presidio-hardened-x402 | screening audit pipeline; SLO readings via evidence-bridge |
0 + 1 |
| presidio-hardened-x402-mcp | signed payment-decision@1 records in evidence-ref@1 envelopes |
0 + 1 |
| presidio-hardened-arch-translucency | signed SLO envelopes; training-run@1 and energy-reading@1 readings |
0 + 1 |
| presidio-hardened-scoutsuite | clean cloud controls as evidence-ref@2 refs (0.30.0+) |
0 + 1 |
| presidio-hardened-treasury | close checkpoints (Rust, dual control, keyless) | 0 |
| a private producer | evidence-ref@1 producer |
0 + 1 |
Each consumer has a golden vector here, so a regression in any of them fails this repository's CI as well as its own.
Verify a checkout
pip install -e ".[dev]"
python scripts/generate_vectors.py --check # vectors byte-stable
pytest tests/ -q # Python conformance, 100% coverage gate
cargo test --manifest-path rust/Cargo.toml # Rust conformance
Layout
schemas/ JSON Schemas (normative)
vectors/ golden test vectors, append-only, generated by scripts/generate_vectors.py
src/ Python package: Layer 0/1, refs and envelopes, keys, CLI
rust/ Rust crate: Layer 0 and the signing messages, plus conformance tests
tests/ Python conformance suite
docs/adr/ architecture decision records
docs/ MIGRATION.md (per-consumer plan)
Roadmap
| Version | Scope | Status |
|---|---|---|
| 0.1.0 – 0.4.0 | ADR-0001; schemas and vectors; Python reference implementation; consumer vectors; evidence-ref@2 tiers; Rust Layer 0; key helpers and CLI; numeric encoding and gate-certificate identity |
delivered |
| 0.5.0 | First public release: evidence-ref@3 subject binding (ADR-0004), contract trees as package data, scoutsuite consumer vector |
delivered |
| 0.5.1 | Requires Python 3.11+ (3.10 is end of life); CI on every supported Python | current |
| next | Producers dual-emit @3, consumers demand it per gate; tighter training-run@1 / gate-certificate@1 schemas (#1) |
planned |
Design rationale: ADR-0001. Requirements ledger: PRESIDIO-REQ.md. Migration order: docs/MIGRATION.md. Changes: CHANGELOG.md.
Security
See SECURITY.md for supported versions, how to report a vulnerability, and the threat model.
License
MIT
Metadata
Release files for presidio-evidence 0.5.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| presidio_evidence-0.5.1.tar.gz | 181.0 kB | With provenance | Details for presidio_evidence-0.5.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| presidio_evidence-0.5.1-py3-none-any.whl | Python 3 | none | any | Details for presidio_evidence-0.5.1-py3-none-any.whl |
Total release size: 274.6 kB
Release files / presidio_evidence-0.5.1.tar.gz
| Download URL | presidio_evidence-0.5.1.tar.gz |
|---|---|
| Size | 181.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6ffb62b409052e9dd8c416c2c67d61ced09b2696e03de9f52ecc6f8a2c197a5a
|
|
BLAKE2b-256 checksum How to use checksums |
22988223d5a1e44730dcfd194f4579f093cd9e76e116be4cd29c3d989a0b90b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logRelease files / presidio_evidence-0.5.1-py3-none-any.whl
| Download URL | presidio_evidence-0.5.1-py3-none-any.whl |
|---|---|
| Size | 93.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ad0937d84f954670193bae393adf2f465483bab24c13b454c99e49a1663c796d
|
|
BLAKE2b-256 checksum How to use checksums |
7eaacbdbf9d74a0249d8ecc78548f2d45018a84f40417630a5fadf4b80f714e1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logSecurity for presidio-evidence 0.5.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for presidio_evidence-0.5.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.