Skip to main content

Standalone offline verification for AiGentsy ProofPack v2 bundles, attestations, and policy_layer display

Project description

aigentsy-verify

Standalone offline verification for AiGentsy proof bundles and attestations. Zero dependency on AiGentsy's runtime.

Install

pip install aigentsy-verify

Adapter-backed replay availability. aigentsy-verify@1.4.0 on PyPI was built before adapter.py was on disk and therefore did not perform adapter-backed replay. Fixed in aigentsy-verify@1.5.0 — the published 1.5.0 wheel includes adapter.py and the full 7-step adapter-backed replay path works from pip install aigentsy-verify==1.5.0. The 5-step bundle-verification path is byte-identical to 1.4.0.

CLI

Verify a bundle offline (default — no network calls):

aigentsy-verify bundle proofpack.json
# Bundle steps run without an STH key. Adapter-backed replay is
# available from `aigentsy-verify==1.5.0` (the 1.4.0 wheel was missing
# adapter.py; fixed in 1.5.0).

Bundle verification with public key fetch:

aigentsy-verify bundle proofpack.json --fetch-key
# All bundle steps PASS when the bundle is well-formed.

JSON output for scripting:

aigentsy-verify bundle proofpack.json --json

Strict mode (fails if STH signature is skipped):

aigentsy-verify bundle proofpack.json --strict --fetch-key

Download and verify a real ProofPack:

curl -o proofpack.json https://aigentsy-ame-runtime.onrender.com/protocol/proofs/demo_deal_08effb15193a/export
aigentsy-verify bundle proofpack.json --fetch-key

Python SDK — Verify in 60 Seconds

from aigentsy_verify import verify_bundle, verify_attestation, fetch_public_key
import json, urllib.request

# 1. Fetch public key (cache this — it rarely changes)
public_key = fetch_public_key()

# 2. Verify a proof bundle
bundle = json.load(open("bundle.json"))
result = verify_bundle(bundle, public_key_base64=public_key)
print(result["verified"])  # True or False

# 3. Verify an attestation
resp = json.loads(urllib.request.urlopen(
    "https://aigentsy-ame-runtime.onrender.com/protocol/agents/AGENT_ID/attestation"
).read())
ok = verify_attestation(resp["attestation"], resp["signature"], public_key)
print(ok)  # True or False

Verify a Proof Bundle

import json
from aigentsy_verify import verify_bundle, fetch_public_key

# Load a bundle (from file, API, or any source)
with open("bundle.json") as f:
    bundle = json.load(f)

# Fetch the public key (once — cache it)
public_key = fetch_public_key()

# Verify — returns per-step results
result = verify_bundle(bundle, public_key_base64=public_key)

print(result["verified"])  # True or False
for step, detail in result["steps"].items():
    print(f"  {step}: {'PASS' if detail['passed'] else 'SKIP' if detail.get('skipped') else 'FAIL'}")

Verify an Attestation

import json, urllib.request
from aigentsy_verify import verify_attestation, fetch_public_key

# Fetch attestation from AiGentsy
resp = json.loads(urllib.request.urlopen(
    "https://aigentsy-ame-runtime.onrender.com/protocol/agents/AGENT_ID/attestation"
).read())

# Fetch public key
public_key = fetch_public_key()

# Verify signature
ok = verify_attestation(
    resp["attestation"],
    resp["signature"],
    public_key,
)
print(f"Attestation valid: {ok}")

Sample Artifacts

The tests/fixtures/ directory contains sample artifacts you can verify immediately:

# Clone and verify offline
python -c "
import json
from aigentsy_verify import verify_bundle, verify_attestation

bundle = json.load(open('tests/fixtures/sample_bundle.json'))
print('Bundle:', verify_bundle(bundle)['verified'])

att = json.load(open('tests/fixtures/sample_attestation.json'))
print('Attestation:', verify_attestation(att['attestation'], att['signature'], att['public_key_base64']))
"

Sample fixtures include a test Ed25519 key pair — they verify without network access.

Public Key

The production Ed25519 public key is served at:

https://aigentsy-ame-runtime.onrender.com/protocol/merkle/public-key

Load it programmatically:

from aigentsy_verify import fetch_public_key
key = fetch_public_key()  # returns base64-encoded Ed25519 public key

Or from a local file:

from aigentsy_verify import load_public_key_from_file
key = load_public_key_from_file("log_public_key.json")

Bundle Verification (5 steps in verify_bundle)

Step What it checks Required?
1. Bundle hash SHA-256 of canonical JSON matches claimed hash Yes
2. Event chain Each event's hash and prev_hash link are correct Yes
3. Merkle inclusion RFC 6962 proof path from leaf to root If present
4. STH signature Ed25519 signature on signed tree head If key provided
5. Cross-reference Merkle root matches STH root hash If both present

(ProofPack spec_version 3.0.0 adds a sixth actor_signatures step that verifies per-event actor signatures; older bundles remain byte-identical at 5 steps.)

Adapter-backed Replay (source-current, 7 checks in verify_adapter_replay)

When a ProofPack carries an embedded adapter_evaluation (Pass 66+ adapter contracts), the source verifier replays every claim it makes. Each check returns a status code; the overall adapter_replay_status is ok only if every step is ok.

Step What it checks Status field
1. Schema Embedded adapter_contract declaration passes the on-disk schema adapter_contract_schema_status
2. Contract hash sha256(canonical(declaration)) matches contract_hash contract_hash_status
3. Input-schema hash sha256(canonical(input_schema)) matches input_schema_hash input_schema_hash_status
4. Normalized inputs Every key in normalized_policy_inputs is in allowed_policy_fields normalized_policy_inputs_status
5. Validator declaration Declared validator_name + validator_version are present and consistent with the evaluation result adapter_validator_status
6. Policy replay A REJECTED event's matched_rule actually fires against its own evaluated inputs policy_replay_status
7. Overall verdict Aggregate ok only if every check above is ok adapter_replay_status

Per-check status codes (verbatim from source):

  • ok — check passed
  • legacy_no_adapter — the event predates adapter contracts; no replay required
  • schema_fail — adapter contract declaration failed schema validation
  • contract_hash_mismatch — recomputed contract hash does not match claimed value
  • input_schema_hash_mismatch — recomputed input-schema hash does not match claimed value
  • normalized_inputs_not_in_allowed_policy_fields — claim referenced a field not declared by the contract
  • validator_declaration_missing — required validator metadata absent
  • validator_result_inconsistent — validator result contradicts the declared validator
  • matched_rule_does_not_fire_against_evaluated_inputs — the rule the runtime claims matched does not fire on replay
  • adapter_evaluation_shape_invalid — top-level shape of adapter_evaluation is malformed

The 7-step adapter-backed replay path is available from the published wheel starting with aigentsy-verify==1.5.0. The 1.4.0 wheel was missing adapter.py; that gap is closed in 1.5.0 (see install note at the top).

API

verify_bundle(bundle, public_key_base64="", sth=None) -> dict

Complete 5-step verification. Returns {"verified": bool, "steps": {...}}.

verify_attestation(attestation, signature_base64, public_key_base64) -> bool

Verify an Ed25519-signed outcome attestation.

verify_inclusion(leaf_hash, leaf_index, tree_size, proof, expected_root) -> bool

Verify an RFC 6962 Merkle inclusion proof.

verify_sth_signature(sth, public_key_base64) -> bool

Verify a signed tree head signature.

verify_consistency(old_size, new_size, old_root, new_root, proof) -> bool

Verify an RFC 6962 Merkle consistency proof (append-only guarantee).

verify_anchor_receipt(receipt) -> tuple[bool, dict]

Verify an STH anchor receipt's digest integrity. Returns (passed, details).

fetch_public_key(url=...) -> str

Fetch the Ed25519 public key from AiGentsy's runtime.

load_public_key_from_file(path) -> str

Load the public key from a local JSON file.

compute_bundle_hash(deal_id, proofs, events, merkle_inclusion) -> str

Compute the SHA-256 bundle hash.

verify_event_chain(events) -> dict

Verify event hash integrity and prev_hash chain linkage.

verify_adapter_replay(bundle) -> dict

Adapter-backed replay over an embedded adapter_evaluation. Returns the seven per-check status fields plus the overall adapter_replay_status. Available in the published wheel from aigentsy-verify==1.5.0 (the 1.4.0 wheel did not include adapter.py).

Resources

License

MIT — see LICENSE.

Project details


Download files

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

Source Distribution

aigentsy_verify-1.5.0.tar.gz (56.8 kB view details)

Uploaded Source

Built Distribution

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

aigentsy_verify-1.5.0-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

File details

Details for the file aigentsy_verify-1.5.0.tar.gz.

File metadata

  • Download URL: aigentsy_verify-1.5.0.tar.gz
  • Upload date:
  • Size: 56.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for aigentsy_verify-1.5.0.tar.gz
Algorithm Hash digest
SHA256 1188d5ac6e3ccb25e3679b74bd0c83e5a73a627548517db53f603d31a92cc55f
MD5 9b79baa10ee22bb9d4b1e44a14f9357a
BLAKE2b-256 8e62867d13cd5255b08c8b14e47b32e47ca66e8290e2fbd94f2b0386539309c7

See more details on using hashes here.

File details

Details for the file aigentsy_verify-1.5.0-py3-none-any.whl.

File metadata

File hashes

Hashes for aigentsy_verify-1.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9a57e2108bb78520190ea8c0971f0177f431dec11371cb96c0dda4cb8f8e87f5
MD5 04ea7c126ae49d1b94cda0b26da91a9e
BLAKE2b-256 f134bcd37f6a47544ee03af6a0f4ff7027609e51b2447fac0ad871e25dc854b6

See more details on using hashes here.

Supported by

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