Skip to main content

tersign (Python)

pip install tersign

Tersign — the record layer for the machine age: what AI agents do and pay, counter-signed by a party outside the deal, anchored where no one can move it, checkable by anyone. This package is the verification-first Python SDK: zero dependencies, standard library only — the verify path a tribunal, examiner, or CI job can run with nothing installed.

python3 -m tersign verify receipt.json --signer 0x<issuer address>   # offline — no network, ever
python3 -m tersign verify 0x<digest> --ledger https://tersign.ai     # chain lookup (explicit network)
from tersign import verify_receipt, digest_of, chain_link_digest, verify_link, verify_commitment

result = verify_receipt(signed_receipt, expected_signer="0x<issuer address, out-of-band>")
# {'valid': True, 'signer': '0x…', 'signerBound': True, 'digest': '0x…'}

Bind the signer, or a PASS proves little. A signature recovers to some address for any payload, so a receipt checked without --signer (CLI) or expected_signer (library) comes back with signerBound false, and the CLI's verdict says what that means: it proves neither who signed nor that the receipt is unmodified, because an edited receipt recovers a different address and still verifies. Take the issuer's address from a channel you trust, never from the receipt. A receipt signed with a published test key — the Hardhat/Anvil default dev accounts #0–#19, or private keys 0x1, 0x2 and 0x3 — is flagged testKey whether or not it is bound: anyone can produce that signature.

verify_receipt (the library) returns valid, signer, signerBound and digest, plus testKey, unsignedFields (fields in the file that the signature does not cover) and reason when they apply. The CLI prints that result and adds tersign, verdict, signerStatus (BOUND, UNAUTHENTICATED or MISMATCH), expectedSigner, and, for an evidence-bundle record file, checked and recordFieldsNotChecked. A record file's own chain fields are reported as not checked (the bundle verifier checks them), and a file carrying any other field beside the nested artifact is refused. Exit status: 0 PASS (read verdict), 1 FAIL, 2 usage — an unknown or valueless flag is refused, never ignored. A digest lookup (verify 0x<digest> --ledger URL) prints the ledger's answer and the verdict PASS (ledger-reported) or FAIL (ledger-reported): nothing in it is verified locally.

What it covers (v0.2):

  • RFC 8785 (JCS) canonical form + the Tersign artifact digest (keccak256(utf8(JCS(v)))) and chain-link constructor — byte-compatible with the TypeScript reference, pinned by shared cross-implementation vectors.
  • EIP-712 recovery for the upstream x402 receipt domain (the merged offer-receipt extension) — pure-python secp256k1. A receipt's signature must be the one canonical encoding (0x + 130 lower-case hex digits, v 27/28, low-s); a re-encoding of a genuine signature (v 0/1, upper-case hex, the high-s twin) also recovers the issuer, under a different digest, so it is refused.
  • Counter-signature verification (verify_link): EIP-191 over the raw 32-byte chain-link digest, recovered against the published ledger signer (https://tersign.ai/v1/ledger). The counter-signature must be its one accepted encoding, checked on the bytes before recovery: 0x + 130 hex digits, v 27/28, low-s. Its high-s and v 0/1 re-encodings recover the same ledger key and are refused.
  • Chain commitment recompute (verify_commitment): since 2026-08-28 each anchor stamps a chain commitment — an accumulator over every counter-signed link — so one anchored digest covers the whole prefix; rows anchored earlier bind the head record only and say so (subjectSchema).

The bundled copy is a convenience, not a trust root. A frozen bundle ships this verify core inside itself, which is fine for a worked example and wrong for evidence handed to you by an interested party — a bundle can ship a checker that blesses it. For adversarial input fetch the checker out-of-band from the address the archive's VERIFY.md §0 names (archives built before 2026-10-08 name https://tersign.ai/verify/v1/, which serves the 2026-10-07 checker; digests at SHA256SUMS beside it), run that copy against the archive, and diff it against the bundled copy. A difference is itself the finding unless the archive is older than the checker at that address: an archive built before 2026-10-08 can carry an earlier checker than https://tersign.ai/verify/v1/ serves.

Check this package against the public corpus yourself. Since 0.1.4 the sdist carries the subset of the two-sided conformance corpus these primitives decide — 19 vectors across canonical bytes, digest recompute, chain link and chain commitment, both accept and reject arms. python3 -m unittest discover -s tests runs them. A package whose job is letting you check our records yourself should ship the means to check the package.

Issuing/signing lives in the TypeScript SDK (npm tersign); this package is the independent second implementation of the verification surface — cross-implementation by construction. Frozen evidence bundles (tersign-evidence-bundle-v1) ship their own copy of this verify core inside the artifact, so bundle verification never depends on an install.

No console script on purpose: the tersign bin name belongs to the npm package; the Python surface is python3 -m tersign.

License: Apache-2.0 from 0.2.1; earlier releases were MIT. See LICENSE and NOTICE.

Metadata

Release files for tersign 0.2.5

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

Source distribution (sdist)

Source distribution for tersign 0.2.5
File Size Uploaded
tersign-0.2.5.tar.gz 63.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tersign 0.2.5
File Interpreter ABI Platform
tersign-0.2.5-py3-none-any.whl Python 3 none any Details

Total release size: 93.9 kB

Release files / tersign-0.2.5.tar.gz

Download URL tersign-0.2.5.tar.gz
Size 63.2 kB
Tags Source
SHA-256 checksum
How to use checksums
2b477938517f886befc22085e86378c8040891b933475195f766333071d1d05b
BLAKE2b-256 checksum
How to use checksums
ac685d8645e03b5c29b39244a31d0c8e7e534c1f02e52e3b29e9e1a8a6049d17
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 14, 2026.

Transparency log

Release files / tersign-0.2.5-py3-none-any.whl

Download URL tersign-0.2.5-py3-none-any.whl
Size 30.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2b1eabb85a1528c558f612ade49fbb6ca8c5b4092fa10bab5c69d25388fb29bb
BLAKE2b-256 checksum
How to use checksums
b79753de7bf8099f6dd102380e46fc8b39f0cce9a7fd6bfd278df10dedb361ff
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 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.5 This release

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.2

2 release files

0.0.1

2 release files

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