Skip to main content

ODIN OPE (Open Proof Envelope)

Lightweight, production-grade primitives for verifiable AI↔AI / AI↔Human communication.
This package gives you deterministic canonical JSON, CID hashing, Ed25519 signatures, and helpers to build/verify envelopes & export bundles used across the ODIN ecosystem.

  • Deterministic canonical JSON → stable hashes and signatures
  • CID: sha256:<hex> computed over canonical bytes
  • Envelope signing: sign "{cid}|{trace_id}|{ts}" with Ed25519
  • Bundle signing: sign "{bundle_cid}|{trace_id}|{exported_at}"
  • Signer backends: local seed (default). Optional extras for GCP KMS / AWS KMS / Azure KV.

Install

pip install odin-ope
# or with extras: pip install "odin-ope[gcpkms]"  # etc.

Quick start

from odin_ope.signers import FileSigner
from odin_ope.envelope import build_envelope, sign_envelope
from odin_ope.verify import verify_envelope, build_jwks_for_signers
from odin_ope.bundle import build_bundle, sign_bundle, verify_bundle

# 1. Create a signer (Ed25519, deterministic seed for demo)
seed_b64u = "A"*43  # 32-byte Ed25519 seed as base64url (example placeholder)
signer = FileSigner(seed_b64u=seed_b64u)  # kid derived from public key

# 2. Build and sign an envelope
payload = {"invoice_id": "INV-1", "amount": 100.25, "currency": "USD"}
env = build_envelope(payload, payload_type="openai.tooluse.invoice.v1", target_type="invoice.iso20022.v1")
signed_env = sign_envelope(env, signer)

# 3. Build JWKS and verify the envelope
jwks = build_jwks_for_signers([signer])

ok, reason = verify_envelope(signed_env, jwks)
assert ok, reason  # (or use verify_envelope_or_raise for exceptions)

# 4. Create and sign a bundle
receipts = [
    {"hop": 0, "receipt_hash": "h0", "prev_receipt_hash": None},
    {"hop": 1, "receipt_hash": "h1", "prev_receipt_hash": "h0"}
]
bundle = build_bundle(trace_id=signed_env["trace_id"], receipts=receipts)
sig = sign_bundle(bundle, signer)
ok2, reason2 = verify_bundle(bundle, sig, jwks, kid=signer.kid)
assert ok2, reason2

See examples/end_to_end.py for a full, annotated script.


FAQ: Common errors

Q: ModuleNotFoundError: No module named 'odin_ope' A: Make sure your PYTHONPATH includes the src directory, or install the package in editable mode: pip install -e .

Q: ValueError: Ed25519 seed must be 32 bytes A: The seed for FileSigner must be a base64url-encoded string representing exactly 32 bytes.

Q: Envelope verification fails with cid_mismatch A: The payload was likely modified after signing. Always verify before mutating envelopes.

Q: How do I generate a valid Ed25519 seed? A: Use os.urandom(32) and encode with base64.urlsafe_b64encode(seed).rstrip(b'=').

Q: How do I run the tests? A: PYTHONPATH=src pytest (or on Windows: $env:PYTHONPATH='src'; python -m pytest)

Reason Codes

Code Meaning
cid_mismatch Payload hash changed after signing
missing_sig_or_kid Envelope missing sender_sig or kid
kid_not_found KID not present in supplied JWKS
signature_invalid Signature verification failed
timestamp_skew ts outside allowed skew window
schema_error Structural or field validation error
not_yet_valid not_before is in the future
expired expires_at is in the past

These map 1:1 to exception subclasses (see odin_ope.exceptions).

CLI

The package installs a odin-ope CLI:

odin-ope sign-envelope --payload payload.json --payload-type t --target-type tgt --seed <base64url-seed>
odin-ope verify-envelope --envelope env.json --jwks jwks.json --json --max-skew 300 --strict

Use --json for structured output and --no-skew to disable time skew checks.

Development

Install dev extras and run tests + type checking:

pip install -e .[dev]
pytest -q
mypy src/odin_ope
python scripts/gen_sbom.py --out sbom.json  # generate CycloneDX SBOM

Programmatic version: import odin_ope; print(odin_ope.__version__). \n+## Development \n+Install dev extras and run tests + type checking: \n+``` pip install -e .[dev] pytest -q mypy src/odin_ope

## Publishing
## Publishing

A GitHub Actions workflow is included (`.github/workflows/publish.yml`).  
Create a repository, push, add `PYPI_API_TOKEN` secret, then tag a release like `v0.9.0`.
The workflow produces:
- Signed artifacts published to PyPI
- CycloneDX SBOM artifact (download from workflow run)
- Build provenance attestation (GitHub Attestations UI / API)

---

## License

Apache-2.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

odin_ope-0.9.0.tar.gz (16.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

odin_ope-0.9.0-py3-none-any.whl (15.4 kB view details)

Uploaded Python 3

File details

Details for the file odin_ope-0.9.0.tar.gz.

File metadata

  • Download URL: odin_ope-0.9.0.tar.gz
  • Upload date:
  • Size: 16.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for odin_ope-0.9.0.tar.gz
Algorithm Hash digest
SHA256 96575b727e418d1a4544c4dbd7a10ecd4c2a0c1b94a7fc630421012f8e5546cc
MD5 f9f5b8119526e45dd072dc535f7fdd16
BLAKE2b-256 44eb9008ecff71a917591b58019d8b957bbbbb95a66f2846bec45b4ade87d208

See more details on using hashes here.

File details

Details for the file odin_ope-0.9.0-py3-none-any.whl.

File metadata

  • Download URL: odin_ope-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 15.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for odin_ope-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6f96cc3af5bb511d3b4e90269a0f5048c1d78f1118b7435eec312f4d8e773c34
MD5 ec2a6809c796c39184e305398e22edab
BLAKE2b-256 aa5dd2796487acda128af30881d0047f9c330f74f1a148840f27dda999d03301

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.9.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page