Skip to main content

Python Reference Verifier

Packaged Python verifier for Allowly Receipt Format wire version 4.

Install

pip install allowly-receipt-format

Runtime dependencies are cryptography for Ed25519 verification and rfc8785 for SEAL record canonicalization.

CLI

Verify a single receipt:

allowly-receipt-verify \
  --workspace-id "$ALLOWLY_WORKSPACE_ID" \
  --trusted-key-fingerprint "$ALLOWLY_TRUSTED_KEY_FINGERPRINT" \
  path/to/receipt.json path/to/keys.json

Verify a whole export or audit-package chain in one go (.jsonl or .jsonl.gz):

# Each line is either a bare receipt (audit-package chain.jsonl) or a
# {"receipt_id", ..., "receipt": {...}} export wrapper — both are handled.
allowly-receipt-verify \
  --export chain.jsonl \
  --workspace-id "$ALLOWLY_WORKSPACE_ID" \
  --trusted-key-fingerprint "$ALLOWLY_TRUSTED_KEY_FINGERPRINT" \
  keys.json

If the export includes checkpoint evidence, recompute every listed checkpoint from the already verified receipt lines:

allowly-receipt-verify \
  --export chain.jsonl \
  --checkpoint-evidence checkpoint_evidence.json \
  --workspace-id "$ALLOWLY_WORKSPACE_ID" \
  --trusted-key-fingerprint "$ALLOWLY_TRUSTED_KEY_FINGERPRINT" \
  keys.json

Verify only one authorization's chain and check its structure (exactly one authorization.create, at most one authorization.revoke, well-formed timestamps), printing the timeline:

allowly-receipt-verify \
  --export export.jsonl.gz \
  --authorization-id auth_01HXZ2... \
  --workspace-id "$ALLOWLY_WORKSPACE_ID" \
  --trusted-key-fingerprint "$ALLOWLY_TRUSTED_KEY_FINGERPRINT" \
  keys.json

Replay conditional policy evidence for every selected action receipt while verifying an export. Signed authorization.create receipts in the export are used as the historical rule snapshots:

allowly-receipt-verify \
  --export chain.jsonl \
  --check-policy-evaluation \
  --workspace-id "$ALLOWLY_WORKSPACE_ID" \
  --trusted-key-fingerprint "$ALLOWLY_TRUSTED_KEY_FINGERPRINT" \
  keys.json

The policy mode prints one bounded line containing the receipt ID, status, and diagnostic for each action receipt, followed by matched, mismatch, and not-checked counts. It does not print receipt context or evaluation payloads. Lifecycle receipts provide creation evidence and are not counted as action results. Missing creation receipts, unsupported historical versions, and action receipts without policy_eval remain visible as not_checked.

--workspace-id and at least one --trusted-key-fingerprint are required. Fingerprints use sha256:<64 lowercase hex> over the decoded raw 32-byte Ed25519 public key. Repeat the fingerprint flag for every trusted rotation key that may have signed the selected receipts.

For local development without installing from PyPI:

pip install -e .
python verifier.py \
  --workspace-id "$ALLOWLY_WORKSPACE_ID" \
  --trusted-key-fingerprint "$ALLOWLY_TRUSTED_KEY_FINGERPRINT" \
  path/to/receipt.json path/to/keys.json

Exit codes:

  • 0 — all presented receipts are valid; in policy mode, at least one action receipt was selected and every selected action receipt is matched
  • 1 — invalid receipt evidence, a checkpoint failure, or a chain anomaly (reason on stderr)
  • 2 — command-line usage error
  • 3 — policy mode found one or more mismatch results; this takes precedence over incomplete coverage
  • 4 — policy mode found not_checked, selected no action receipts, or received an empty unscoped export

Library

from allowly_receipt_format import verify_receipt, VerificationError, load_keys_from_json
import json
import os

with open("receipt.json") as f:
    receipt = json.load(f)
with open("keys.json") as f:
    keys_doc = json.load(f)
configured_workspace_id = os.environ["ALLOWLY_WORKSPACE_ID"]
trusted_fingerprints = {os.environ["ALLOWLY_TRUSTED_KEY_FINGERPRINT"]}
if keys_doc.get("workspace_id") != configured_workspace_id:
    raise ValueError("key document workspace does not match configuration")
keys = load_keys_from_json(keys_doc)

try:
    verify_receipt(
        receipt,
        keys,
        expected_workspace_id=configured_workspace_id,
        trusted_key_fingerprints=trusted_fingerprints,
    )
    print("valid")
except VerificationError as e:
    print(f"invalid: {e}")

Replay conditional policy evidence

verify_policy_evaluation authenticates the action receipt and every supplied authorization receipt before replay. The expected workspace and trusted key fingerprints are required. Its result uses the same snake-case fields as the TypeScript verifier:

from allowly_receipt_format import verify_policy_evaluation

result = verify_policy_evaluation(
    action_receipt,
    authorization_creation_receipts,
    keys,
    expected_workspace_id=configured_workspace_id,
    trusted_key_fingerprints=trusted_fingerprints,
)

if result["status"] == "matched":
    print("recorded conditional evidence matches the replay")
elif result["status"] == "mismatch":
    print("recorded conditional evidence differs from the replay")
else:
    print("policy evidence could not be checked:", result["diagnostic"])

The supported profile is allowly-conditional-evaluation-v1. A match compares only the complete policy_eval object. It does not claim that the final allow, deny, confirm, or escalate decision was reproduced; budgets, revocation, rate limits, approvals, and other state can affect that decision. See spec/profiles/allowly-conditional-evaluation-v1.md for the exact engine, operator, typed-comparison, missing-field, and context-reconstruction rules.

Always pass expected_workspace_id to bind the receipt to a workspace — a key_id alone does not (spec §7, "Workspace binding"). Take that ID from caller-trusted configuration, never from the receipt or key document, and reject a key document that declares a different workspace. The CLI requires that caller-trusted workspace ID plus one or more caller-trusted key fingerprints. It checks the workspace against the key document and receipts, and requires every selected receipt key to be pinned. A workspace ID or fingerprint copied from the same untrusted bundle as the receipts is not an independent trust anchor:

verify_receipt(
    receipt,
    keys,
    expected_workspace_id="ws_01HXA1B2C3D4E5F6G7H8J9K0L1",
    trusted_key_fingerprints={"sha256:<64 lowercase hex>"},
)

public_key_fingerprint(key) returns that canonical fingerprint over the decoded raw 32-byte Ed25519 public key. load_keys_from_json validates an advertised public_key_fingerprint, but the advertised value is not itself a trust anchor.

The package exposes typed verifier exceptions:

  • SchemaError
  • UnknownKeyError
  • KeyOutsideActiveWindowError
  • SignatureMismatchError

All inherit from VerificationError.

Hash and verify a SEAL record

Use the raw function when JSON text comes from a file, form, or workflow. It can reject duplicate decoded keys and number tokens that a normal parser would silently change:

from allowly_receipt_format import hash_seal_json, verify_seal_json

record_sha256 = hash_seal_json(raw_json)
result = verify_seal_json(
    raw_json,
    signed_receipt,
    keys,
    expected_workspace_id=configured_workspace_id,
    trusted_key_fingerprints=trusted_fingerprints,
)
assert result.signature_verified and result.record_matches

hash_seal_value and verify_seal_value are the explicit already-parsed boundary. They cannot recover duplicate member names or original number-token spellings. SealInputError.code identifies strict-input failures. A SEAL verification result always reports signature verification separately from record matching.

Verify a daily checkpoint

verify_checkpoint verifies the checkpoint and member signatures, period, count, Merkle root, and optional prior linkage. The workspace id must come from caller-trusted configuration, and key fingerprints should come from an authenticated channel:

from allowly_receipt_format import verify_checkpoint

verify_checkpoint(
    checkpoint,
    member_receipts,
    keys,
    expected_workspace_id=configured_workspace_id,
    trusted_key_fingerprints=trusted_fingerprints,
    previous_checkpoint=previous_checkpoint,
)

Success proves the supplied set matches the signed commitment. Without an external anchor it does not prove the issuer registered or retained every receipt before constructing the checkpoint.

Match a keyed pseudonym reference

matches_ref implements the optional hmac-v1 convention in specification Appendix A. Decode the show-once integration key, then match locally:

import base64
from allowly_receipt_format import matches_ref

encoded_key = "<pseudonym_key_b64url>"
key = base64.urlsafe_b64decode(encoded_key + "=" * (-len(encoded_key) % 4))

assert matches_ref(
    key,
    "record",
    "MRN-48291",
    receipt["context"]["record_ref"],
)

Use the context.ref_key_version recorded in the receipt to select the retained key version. Matching occurs entirely offline; it does not ask Allowly to resolve an identifier.

verify_receipt accepts an already-parsed object, so it cannot detect duplicate raw JSON names that a normal parser has already overwritten. The CLI uses a duplicate-aware parser and rejects them. The verifier also rejects parsed floating-point values, including the results of 1.0 and 1e0; callers using a different parser must preserve that distinction (spec §4.2).

Test vectors

Run against the shared test vectors:

pip install -e .
python test_vectors.py ../../test-vectors.json
python test_exception_types.py ../../test-vectors.json
python test_seal.py ../../vectors/seal/profile-v1.json ../../vectors/seal/verification-v1.json
pytest -q test_policy_evaluation.py

All should_verify vectors must pass; all should_reject vectors must be rejected with the expected reason.

License

Apache 2.0.

Metadata

Release files for allowly-receipt-format 4.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for allowly-receipt-format 4.3.0
File Size Uploaded Provenance Actions
allowly_receipt_format-4.3.0.tar.gz 32.7 kB With provenance Details for allowly_receipt_format-4.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for allowly-receipt-format 4.3.0
File Interpreter ABI Platform Actions
allowly_receipt_format-4.3.0-py3-none-any.whl Python 3 none any Details for allowly_receipt_format-4.3.0-py3-none-any.whl

Total release size: 64.7 kB

Release files / allowly_receipt_format-4.3.0.tar.gz

Download URL allowly_receipt_format-4.3.0.tar.gz
Size 32.7 kB
Tags Source
SHA-256 checksum
How to use checksums
899bbff57bc7e2aad8100cbf696ec629728dad80c8621b7e0dfb3fb8f96e1a78
BLAKE2b-256 checksum
How to use checksums
e6b64aeb254b4f0a4c7492598441262f26ca3f48bc50003e9d0375709b84c785
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 Oct 8, 2026.

Transparency log

Release files / allowly_receipt_format-4.3.0-py3-none-any.whl

Download URL allowly_receipt_format-4.3.0-py3-none-any.whl
Size 32.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e7fa7dd298e7c09b2fd44052548bd12c5243e57e2abbe2e7e4e9a3b1cb83880b
BLAKE2b-256 checksum
How to use checksums
f29b2607d491b68cee6a9bb2c5d76c21ddfda8cb278a21b813864ff7d27f7a60
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 Oct 8, 2026.

Transparency log

Security for allowly-receipt-format 4.3.0

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

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for allowly_receipt_format-4.3.0.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 Oct 8, 2026.

Transparency log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page