Python Reference Verifier
Packaged Python verifier for Allowly Receipt Format wire version 5.
Install
pip install allowly-receipt-format
Runtime dependencies are PyJWT with cryptography for standard JWS 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
--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
Signature-command exit codes: 0 valid, 1 invalid evidence/checkpoint/chain,
2 command-line usage error.
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:
evidence = 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}")
verify_receipt returns the authenticated evidence dictionary. The wire object
has exactly protected, payload and signature; it is not the evidence
dictionary. decode_receipt(wire) strictly decodes it for display but does
not verify a signature or authorize an action.
jws_signing_input(evidence, key_id) supplies standard JWS bytes to an external
Ed25519 signer such as KMS. jws_receipt(evidence, key_id, signature) packages
the returned 64-byte signature. These helpers do not sign or verify.
Separate official OPA replay
allowly-policy-replay first verifies the receipt with a caller-trusted
workspace and key fingerprint, then authenticates the full engine manifest,
complete policy definition, original inner OPA input, Rego bytes, official OPA
binary and retained runtime archive. It verifies the retained evaluator bundle
using stock OPA and the manifest-bound release public key, then runs the pinned OPA
query and compares the complete provisional result.
allowly-policy-replay receipt.json keys.json \
--workspace-id "$ALLOWLY_WORKSPACE_ID" \
--trusted-key-fingerprint "$ALLOWLY_TRUSTED_KEY_FINGERPRINT" \
--manifest engine-manifest.json --definition policy-definition.json \
--input original-opa-input.json --opa-binary /path/to/opa \
--rego-file allowly_basic.rego --runtime-artifact runtime.tar
Library users import replay_policy from allowly_receipt_format.policy.
Replay exit codes are 0 matched, 3 mismatched, 4 not checked, and
1 invalid signature evidence or input file. Missing artifacts or unsupported
engines never count as a replay success. The command prints only the receipt ID,
status and diagnostic, with separate signature/enforcement/witness fields;
private input and result values stay local.
Native replay supports only fixed official OPA 1.21.1 artifacts for
darwin/arm64, linux/arm64 and linux/amd64. Linux uses the release's static
artifacts. The complete reported Linux commit includes -dirty; this is pinned
exactly, not normalized. Each artifact SHA-256 was verified against the
immutable release
metadata digest and its individual checksum asset. The recorded manifest's
platform, commit and digest must match one fixed pin, and its platform must
match the replay host. A binary from another supported platform is not a
fallback. Existing signed Darwin vectors remain unchanged.
Other OS/architecture combinations return not_checked. A valid signature
alone accepts any well-shaped engine identity; replay support is checked
separately. Retained source-generation evidence is not running-process
attestation.
OPA's provisional result can differ from top-level decision and reason.
Successful replay checks no final budget/day reservation, identity fence,
approval consumption or TLSNotary proof. Read
the complete replay profile.
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:
SchemaErrorUnknownKeyErrorKeyOutsideActiveWindowErrorSignatureMismatchError
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 5.1.0
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 |
|---|---|---|---|---|
| allowly_receipt_format-5.1.0.tar.gz | 37.4 kB | With provenance | Details for allowly_receipt_format-5.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| allowly_receipt_format-5.1.0-py3-none-any.whl | Python 3 | none | any | Details for allowly_receipt_format-5.1.0-py3-none-any.whl |
Total release size: 73.7 kB
Release files / allowly_receipt_format-5.1.0.tar.gz
| Download URL | allowly_receipt_format-5.1.0.tar.gz |
|---|---|
| Size | 37.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
895a47373733609d76dfe57ba99711f5d23754b7c6a40dd337041ab95aca12d8
|
|
BLAKE2b-256 checksum How to use checksums |
e2876d0bbfda4fbb42d2c8291f8e9deee6bae75dbd71b26e198fa2f8faa45caa
|
| 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 Nov 3, 2026.
Transparency logRelease files / allowly_receipt_format-5.1.0-py3-none-any.whl
| Download URL | allowly_receipt_format-5.1.0-py3-none-any.whl |
|---|---|
| Size | 36.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a8488f7c53d200ebbfa3f556f64ec84c6b5d136d520a42f4599b844db31dfd16
|
|
BLAKE2b-256 checksum How to use checksums |
7eb610b910aac747d1a842d05b8a833775fd5eb6da61757a709a79e9844b2f53
|
| 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 Nov 3, 2026.
Transparency logSecurity for allowly-receipt-format 5.1.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.
Attestation for allowly_receipt_format-5.1.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 Nov 3, 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.