Offline verifier for AetherProof v1 signed manifests (Ed25519 + RFC 8785 JCS)
Project description
aetherproof-verify
Offline, zero-trust verifier for AetherProof v1 signed manifests.
AetherProof is a cryptographic provenance system for AI-generated code. Every code artifact produced by an AetherProof-enabled pipeline is paired with a signed manifest containing the exact SHA-256 of the code, the prompt that generated it, the verifier gate evidence, the provider attestation, and the timestamp — all signed with an Ed25519 key and canonicalized per RFC 8785 (JCS).
This package lets any auditor, buyer, or third party verify those manifests entirely offline, without contacting any AetherProof server.
Install
pip install aetherproof-verify
All wheels published to PyPI are signed with PEP 740 attestations via PyPI Trusted Publishers (OIDC → Sigstore), bound to this package's public GitHub repository. See Supply-chain posture below.
Usage
You need three inputs to verify a manifest:
- The manifest JSON — fetched from
https://api.aetherlang.online/v1/manifests/{id}, or delivered out-of-band. - The public key — fetched from
https://keys.aetherlang.online/keys.jsonand converted to PEM, or pinned out-of-band. - (Optional) The expected fingerprint — pinned from a trusted source. Belt-and-suspenders: catches silent key rotation.
CLI
aetherproof-verify check \
--manifest ./manifest.json \
--pubkey ./key.pem \
--fingerprint sha256:f95a45bdc15db8f6ef61fa853366e860726aefe16474e943ebe79b132a17e022
Or via module invocation (equivalent):
python -m aetherproof_verify check --manifest ./m.json --pubkey ./k.pem
Library
from pathlib import Path
from aetherproof_verify.__main__ import check
rc = check(Path("manifest.json"), Path("key.pem"), expected_fpr=None)
assert rc == 0 # EXIT_OK
You can also import the Pydantic schema directly for custom integrations:
from aetherproof_verify.schema import AetherProofManifest
Exit codes
| Code | Meaning |
|---|---|
0 |
OK — signature valid and fingerprint matches |
1 |
Signature mismatch — payload was tampered or wrong key used |
2 |
Fingerprint mismatch — wrong key or silent rotation |
3 |
Schema validation error — malformed manifest |
4 |
File I/O error — cannot read manifest or key |
What this verifier does
- Parses the manifest JSON (supports both bare manifest and the
{request_id, manifest, canonical_bytes_len}envelope returned byapi.aetherlang.online). - Schema-validates the payload against the frozen Pydantic v1 schema
mirror (
extra="forbid",frozen=True). - Fingerprint-gates — computes SHA-256 of the raw Ed25519 public key bytes
and matches against the
public_key_fprembedded in the manifest. If--fingerprintis passed, additionally pin-checks against it. - Cryptographically verifies — reconstructs canonical bytes via
RFC 8785 JCS over the manifest with the
signaturefield removed, and verifies the Ed25519 signature.
No network calls. No telemetry. No side channels.
Trust boundaries
AetherProof operates four independent trust boundaries:
| Boundary | Role |
|---|---|
github.com/contrario/aetherproof-verify |
Source of this verifier |
keys.aetherlang.online |
Public key distribution (keys.json) |
releases.aetherlang.online |
Reproducible demo bundle (tarball) |
api.aetherlang.online |
Manifest lookup (/v1/manifests/{id}) |
A compromise of any one boundary does not grant control of the others. Buyers should verify each independently.
Supply-chain posture
- Build provenance: every release wheel is built in GitHub Actions and attested via PEP 740 / Sigstore. The attestation binds the artifact digest to this repository's workflow identity.
- Trusted Publishers: publishing to PyPI uses OIDC token exchange (no long-lived API tokens). See PyPI docs.
- Reproducible builds: deterministic tarball and wheel construction; same source tree + same build environment → byte-identical artifact.
- Pinned dependencies: all transitive dependencies locked in
pyproject.toml;cryptography>=46.0.7(no known CVEs at release time). - Zero-network verify: the CLI makes no network calls. Everything needed is passed as file paths.
Security model assumptions
- You trust your own Python interpreter and the
cryptographylibrary built against your OpenSSL. - You obtained the public key through a channel you trust (HTTPS to
keys.aetherlang.onlinewith a modern CA root bundle, or out-of-band delivery). - You obtained this package through PyPI with trusted-publisher attestation intact, or built it from source yourself after auditing.
If any of these assumptions fail, verification results are meaningless. Verify your chain of custody before relying on verification output.
Development
git clone https://github.com/contrario/aetherproof-verify
cd aetherproof-verify
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
pytest
License
Apache License 2.0 — see LICENSE.
Security contact
Report vulnerabilities privately to security@aetherlang.online.
Do not open public issues for suspected security flaws.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aetherproof_verify-0.1.0.tar.gz.
File metadata
- Download URL: aetherproof_verify-0.1.0.tar.gz
- Upload date:
- Size: 12.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38c75652d5a465adb8cf061afcd9663f5a73e0437e87cfb6926cce67576c7fb9
|
|
| MD5 |
3cbde8e1f96b98b6a06a9dfb46b0748d
|
|
| BLAKE2b-256 |
5dc6b80915d079ca9e1656466503ae619f52ef486f3305b760ac6aaca20a28e1
|
Provenance
The following attestation bundles were made for aetherproof_verify-0.1.0.tar.gz:
Publisher:
release.yml on contrario/aetherproof-verify
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aetherproof_verify-0.1.0.tar.gz -
Subject digest:
38c75652d5a465adb8cf061afcd9663f5a73e0437e87cfb6926cce67576c7fb9 - Sigstore transparency entry: 1354260875
- Sigstore integration time:
-
Permalink:
contrario/aetherproof-verify@26dd8ca328f109b54f04023caad2e35719322a0a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/contrario
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@26dd8ca328f109b54f04023caad2e35719322a0a -
Trigger Event:
push
-
Statement type:
File details
Details for the file aetherproof_verify-0.1.0-py3-none-any.whl.
File metadata
- Download URL: aetherproof_verify-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e0869cd77783929fcbfa63a27ea1fc10cf258634f197399a807e487c9088c29
|
|
| MD5 |
e3009e3f61bf31aa40688be80d5d6920
|
|
| BLAKE2b-256 |
72db7cbe46a6d33a01c9a87504f60a9e478b52a8b5962941231536b4f8139e2d
|
Provenance
The following attestation bundles were made for aetherproof_verify-0.1.0-py3-none-any.whl:
Publisher:
release.yml on contrario/aetherproof-verify
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aetherproof_verify-0.1.0-py3-none-any.whl -
Subject digest:
1e0869cd77783929fcbfa63a27ea1fc10cf258634f197399a807e487c9088c29 - Sigstore transparency entry: 1354261043
- Sigstore integration time:
-
Permalink:
contrario/aetherproof-verify@26dd8ca328f109b54f04023caad2e35719322a0a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/contrario
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@26dd8ca328f109b54f04023caad2e35719322a0a -
Trigger Event:
push
-
Statement type: