Skip to main content

attest-protocol

Python SDK for the Action Receipts protocol

PyPI License: Apache 2.0 Python CI


Create, sign, hash-chain, store, and verify cryptographically signed audit trails for AI agent actions.

Spec • TypeScript SDK • Reference Implementation


Install

pip install attest-protocol

Quick start

Create and sign a receipt

from attest_protocol import (
    create_receipt,
    generate_key_pair,
    hash_receipt,
    sign_receipt,
    CreateReceiptInput,
    Chain,
    Issuer,
    Outcome,
    Principal,
)
from attest_protocol.receipt.create import ActionInput

# Generate an Ed25519 key pair
keys = generate_key_pair()

# Create an unsigned receipt
unsigned = create_receipt(CreateReceiptInput(
    issuer=Issuer(id="did:agent:my-agent"),
    principal=Principal(id="did:user:alice"),
    action=ActionInput(
        type="filesystem.file.read",
        risk_level="low",
    ),
    outcome=Outcome(status="success"),
    chain=Chain(
        sequence=1,
        previous_receipt_hash=None,
        chain_id="chain_session-1",
    ),
))

# Sign and hash
receipt = sign_receipt(unsigned, keys.private_key, "did:agent:my-agent#key-1")
receipt_hash = hash_receipt(receipt)

Verify a receipt

from attest_protocol import verify_receipt

valid = verify_receipt(receipt, keys.public_key)
print(f"Signature valid: {valid}")  # True

Verify a chain

from attest_protocol import verify_chain

# Verify a list of receipts (e.g. [receipt] from the example above)
result = verify_chain([receipt], keys.public_key)
print(f"Chain valid: {result.valid}")
print(f"Receipts verified: {result.length}")
if not result.valid:
    print(f"Broken at index: {result.broken_at}")

Action taxonomy

The standardized action taxonomy (action types and risk levels) is defined in the protocol specification. Taxonomy classification will be added in a future milestone (M3).

What is an Action Receipt?

A W3C Verifiable Credential signed with Ed25519, recording:

Field What it captures
Action What happened, classified by a standardized taxonomy
Principal Who authorized it (human or organization)
Issuer Which agent performed it
Outcome Success/failure, reversibility, undo method
Chain SHA-256 hash link to the previous receipt (tamper-evident)
Privacy Parameters are hashed, never stored in plaintext

API reference

Receipt creation and signing

from attest_protocol import (
    create_receipt,       # Build an unsigned receipt from input fields
    generate_key_pair,    # Ed25519 key pair (PEM-encoded)
    sign_receipt,         # Sign with Ed25519Signature2020 proof
    verify_receipt,       # Verify a receipt's signature
)

Hashing and canonicalization

from attest_protocol import (
    canonicalize,         # RFC 8785 JSON canonicalization
    hash_receipt,         # Hash receipt (excluding proof) -> "sha256:<hex>"
    sha256,               # Hash arbitrary data -> "sha256:<hex>"
)

Chain verification

from attest_protocol import (
    verify_chain,         # Verify signatures, hash links, and sequence numbering
)

Types (Pydantic v2 models)

from attest_protocol import (
    ActionReceipt,        # Signed receipt with proof
    UnsignedActionReceipt,  # Receipt before signing
    Action, ActionTarget, Authorization, Chain,
    CredentialSubject, Intent, Issuer, Operator,
    Outcome, Principal, Proof, StateChange,
)

Subpackage imports

from attest_protocol.receipt import create_receipt, sign_receipt
from attest_protocol.receipt.hash import canonicalize
from attest_protocol.receipt.types import CONTEXT, CREDENTIAL_TYPE

TypeScript SDK compatibility

camelCase aliases are available for users coming from the TS SDK:

from attest_protocol import (
    createReceipt,    # = create_receipt
    generateKeyPair,  # = generate_key_pair
    signReceipt,      # = sign_receipt
    verifyReceipt,    # = verify_receipt
    hashReceipt,      # = hash_receipt
    verifyChain,      # = verify_chain
)

Cross-language compatibility

This SDK produces byte-identical output to @attest-protocol/attest-ts:

  • RFC 8785 canonical JSON matches exactly
  • SHA-256 hashes are identical
  • Ed25519 signatures from either SDK verify in the other

Cross-language compatibility is verified by test vectors generated from the TypeScript SDK.

Project structure

src/attest_protocol/
  receipt/
    types.py       # Pydantic models for all receipt types
    create.py      # Receipt creation with auto-generated IDs
    signing.py     # Ed25519 signing and verification
    hash.py        # RFC 8785 canonicalization + SHA-256
    chain.py       # Chain verification

Development

uv sync --all-extras
uv run pytest              # run tests
uv run ruff check .        # lint
uv run ruff format .       # format
uv run pyright             # type check
Language Python 3.11+
Types Pydantic v2, pyright strict mode
Linting ruff
Testing pytest
Dependencies pydantic>=2.0, cryptography>=41.0

Ecosystem

Repository Description
attest-protocol/spec Protocol specification, JSON Schemas, canonical taxonomy
attest-protocol/attest-ts TypeScript SDK (npm)
attest-protocol/attest-py (this package) Python SDK
ojongerius/attest MCP proxy + CLI (reference implementation)

License

Apache 2.0 — see LICENSE.

Metadata

Release files for attest-protocol 0.2.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 attest-protocol 0.2.0
File Size Uploaded
attest_protocol-0.2.0.tar.gz 49.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for attest-protocol 0.2.0
File Interpreter ABI Platform
attest_protocol-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 69.6 kB

Release files / attest_protocol-0.2.0.tar.gz

Download URL attest_protocol-0.2.0.tar.gz
Size 49.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f72331c5179748c15993b7a1b13ce2126edccc0cbcacf3ebd5e7bfcc75567272
BLAKE2b-256 checksum
How to use checksums
c059884693e56a429b22105c6e56ff7ca04663724673bfedbaf4e3b89dacdced
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Mar 31, 2026.

Transparency log

Release files / attest_protocol-0.2.0-py3-none-any.whl

Download URL attest_protocol-0.2.0-py3-none-any.whl
Size 19.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9e35e3dfcd5e5bfe941b240f7ca81ac5e06d50e66baf09b9c85bb799a9f9a901
BLAKE2b-256 checksum
How to use checksums
7beee7ab4aca164523beea94e2a7b6040634e8a9e305aaf3781a5ee3ec866f8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Mar 31, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

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