Observed since 20 Oct, 23:34 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Double-signed receipts for AI-agent tool invocations — DSSE + JCS + Ed25519, verifiable offline (Python port of @p-vbordei/agent-toolprint)
Python port of @p-vbordei/agent-toolprint.
Byte-deterministic-compatible: passes the same conformance vectors.
agent-toolprint is a double-signed receipt format for AI-agent tool
invocations. The agent signs. The tool counter-signs. Anyone with the public
keys can verify offline — no host, no service, no chain.
pip install agent-toolprint
import asyncio, base64, os, uuid
from datetime import datetime, timezone
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from agent_toolprint import (
Plaintext, VerifyOptions,
countersign_tool, did_key_from_ed25519_pubkey, did_key_resolver,
sha256_hash, sign_agent, verify,
)
def gen():
sk = Ed25519PrivateKey.generate()
return (
sk.private_bytes(serialization.Encoding.Raw, serialization.PrivateFormat.Raw, serialization.NoEncryption()),
sk.public_key().public_bytes(serialization.Encoding.Raw, serialization.PublicFormat.Raw),
)
async def main():
agent_sk, agent_pk = gen()
tool_sk, tool_pk = gen()
args, response = {"query": "bun docs"}, {"results": ["https://bun.sh/docs"]}
receipt = {
"v": "tp/0.1",
"id": str(uuid.uuid4()),
"ts": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
"agent": {"did": did_key_from_ed25519_pubkey(agent_pk), "key_id": "agent"},
"tool": {"did": did_key_from_ed25519_pubkey(tool_pk), "key_id": "tool"},
"call": {"name": "search", "args_hash": sha256_hash(args)},
"result": {"status": "ok", "response_hash": sha256_hash(response)},
"nonce": base64.b64encode(os.urandom(32)).decode("ascii"),
}
env = countersign_tool(sign_agent(receipt, agent_sk), tool_sk)
res = await verify(env, VerifyOptions(
resolver=did_key_resolver,
plaintext=Plaintext(args=args, args_provided=True, response=response, response_provided=True),
))
print(res.ok) # True
asyncio.run(main())
The TypeScript reference defines a small, stable receipt protocol (DSSE + JCS +
Ed25519, did:key identities). This package is the Python implementation of the
same wire format — produced bytes are byte-identical, signatures verify across
languages, and the same conformance vectors pass.
uv run pytest -v
All 15 TS vectors across SPEC §6 clauses C1–C4 pass here.
Apache 2.0 — see LICENSE.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.0 | 19 May 2026 | 7 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 20 Oct, 23:34 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:bb8ca041e2d3f13e4b4de40f17adfef863b3b0ea8342cb73dd984620ec467f25