OpenWright — the Agent Evidence Layer
Turn the runtime behavior of AI agents into signed, tamper-evident, control-mapped audit evidence — verifiable by anyone, offline.
OpenWright sits on top of your existing OpenTelemetry instrumentation, forks a copy of your agent's runtime behavior, and turns it into signed, append-only, tamper-evident records mapped to specific regulatory controls. The evidence is verifiable by a third party without access to your data or infrastructure, and the ledger holds only hashes — never prompts or PII.
It ships five built-in, primary-source-cited framework crosswalks — plus a
narrowed EU AI Act v1 review subset (eu-ai-act-v1) and deployer-profile
variants of Art. 14 (in-the-loop / on-the-loop) and Art. 27 (FRIA-gated). You can
also write your own:
| Crosswalk | Covers | Controls |
|---|---|---|
| EU AI Act (Reg. 2024/1689) | Art. 12, 13, 14, 26, 27, 73 (high-risk subset) | 6 |
| NIST AI RMF 1.0 | Govern / Map / Measure / Manage subset | 7 |
| ISO/IEC 42001:2023 | Annex A AI-management-system subset | 6 |
| GDPR (Reg. 2016/679) | Art. 5, 22, 25, 30, 33, 35 (accountability + automated decisions) | 8 |
| SOC 2 | Trust Services Criteria — Common Criteria + Processing Integrity | 7 |
These crosswalks are maintainer-authored and cited, but not yet legally reviewed — they produce evidence, not a compliance determination.
OpenWright produces evidence that controls were exercised. It does NOT assert legal compliance, certification, or an audit opinion — those are for qualified auditors and counsel. Every artifact carries this boundary.
Install
pip install openwright-core
The distribution is openwright-core; it imports as openwright. Requires Python 3.10+.
Try it (one command)
openwright demo
Runs a complete, self-hosted, no-network demo: it instruments a sample high-risk
agent, forks the telemetry into an evidence ledger, records human approvals and
risk classifications, produces a signed report (JSON + PDF + OSCAL + SARIF)
against the EU AI Act crosswalk, verifies it offline, and shows that tampering
fails verification. It then opens an interactive page in your browser that
walks through what happened and lets you verify the real signed report
yourself — offline, in-browser (WebAssembly) — including a "Tamper" button to
watch verification fail and a "Restore" button to watch it pass again. (Use
openwright demo --no-browser for headless/CI.)
It also prints where the artifacts landed and a command to verify them yourself:
openwright verify <report.json> --pubkey <public_key.pem> --deep
Use it in your code
from datetime import timedelta
from openwright.ledger import FileLedgerBackend, Ledger
from openwright.sdk import EvidenceClient
from openwright.signing import InMemoryKeySource # use FileKeySource in production
from openwright.crosswalk import evaluate
from openwright.crosswalk_loader import load_builtin
from openwright.report import build_report
from openwright.verify import verify_report
key = InMemoryKeySource()
ledger = Ledger(FileLedgerBackend("./ledger"), retention=timedelta(days=200))
client = EvidenceClient(ledger, agent_id="my-agent")
# Record the evidence telemetry can't infer — linked by task id.
with client.task("task-42", context_id="session-7"):
approval = client.record_human_approval(reviewer="me@example.com", rationale="looks good")
client.record_risk_classification("high", rationale="high-impact decision", fria="FRIA-1")
client.record_decision(
output="APPROVED",
risk_classification="high",
rationale="meets policy",
approval_ref=approval.event_id, # links the decision to the approval
control="art-14-human-oversight",
)
# Evaluate a crosswalk, build a signed report, verify it offline.
result = evaluate(load_builtin("eu-ai-act"), list(ledger.events()))
report = build_report(ledger, result, key, scope_description="my agent")
verdict = verify_report(report, trusted_public_key_raw=key.public_key_raw())
print({c["control_id"]: c["status"] for c in report["controls"]})
print("verified offline:", verdict.valid)
Collect from a live agent
Point your app's OTLP exporter at the collector; your existing backend keeps receiving telemetry unchanged while a copy is forked into the evidence ledger:
openwright collector --downstream http://your-existing-otlp-backend:4318
CLI
openwright demo Run the full end-to-end demo.
openwright collector --downstream URL Run the OTLP collector (gRPC+HTTP); fan out + fork to ledger.
openwright report LEDGER --key K Build a signed report (JSON/PDF/OSCAL/SARIF) from a ledger.
openwright verify REPORT --pubkey K Verify a signed report offline (--deep re-checks verdicts).
openwright gate REPORT -r CONTROL CI/CD gate: non-zero exit if a required control is unsatisfied.
openwright crosswalks List built-in crosswalks.
openwright connectors list List installed connectors (sources/forwarders/exporters/storage).
openwright export REPORT --to NAME Export a report to a sink (GRC/CI) via an installed exporter.
openwright keygen --out key.pem Generate an Ed25519 signing key you control.
openwright version
Connectors
OpenWright exposes a small, versioned connector contract (openwright.connectors,
v1.0): framework-capture sources, downstream forwarders, report exporters, and
pluggable ledger/checkpoint storage backends. Connectors are independently
installable openwright-<name> packages discovered via entry points — core never
depends on a connector, so adding one needs zero core change. Resolve storage by
URI (openwright collector --ledger-backend postgres://… --checkpoint-store s3://…)
and see what's installed with openwright connectors list.
Run openwright --help for the full list.
License
Apache-2.0.
Metadata
Release files for openwright-core 0.7.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 |
|---|---|---|---|---|
| openwright_core-0.7.1.tar.gz | 110.8 kB | With provenance | Details for openwright_core-0.7.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| openwright_core-0.7.1-py3-none-any.whl | Python 3 | none | any | Details for openwright_core-0.7.1-py3-none-any.whl |
Total release size: 249.7 kB
Release files / openwright_core-0.7.1.tar.gz
| Download URL | openwright_core-0.7.1.tar.gz |
|---|---|
| Size | 110.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9c2fa411319a824aa23730c34b233cca008c6b73de7682023da48c027a29a56a
|
|
BLAKE2b-256 checksum How to use checksums |
7144c64ff413f7db815eb4442b06266d2b236401d52764e99b09d6f45314292f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Jun 4, 2026.
Transparency logRelease files / openwright_core-0.7.1-py3-none-any.whl
| Download URL | openwright_core-0.7.1-py3-none-any.whl |
|---|---|
| Size | 138.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4d18b590d13edd5efb350668fed521b5b53447207df52baeeb8bd9955f2b1b96
|
|
BLAKE2b-256 checksum How to use checksums |
9adb25c2e8b72313590969d455cbf431e60b12dd039d7c614b2ca1fa7b47a7d4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Jun 4, 2026.
Transparency logSecurity for openwright-core 0.7.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 openwright_core-0.7.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 Jun 4, 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.