AgentSystems Notary
Audit logging infrastructure for AI systems
AgentSystems Notary provides tamper-evident audit trails for AI systems. It creates cryptographically verifiable logs of all LLM interactions with dual-write architecture: your storage bucket (raw logs) + hash storage (verification receipts).
Features
- Multi-Framework Support: LangChain and CrewAI adapters
- Dual-Write Architecture: Your bucket (raw logs) + hash storage (receipts)
- Flexible Hash Storage: Arweave (decentralized) and/or Custodied (AgentSystems API)
- Cryptographic Verification: SHA-256 hashes with JCS canonicalization (RFC 8785)
- Multi-Tenant Support: Isolated audit trails for SaaS applications
Installation
pip install agentsystems-notary
Quick Start
Copy .env.example to .env and fill in your credentials.
LangChain
pip install langchain-anthropic
import os
from dotenv import load_dotenv
from agentsystems_notary import (
LangChainNotary,
RawPayloadStorage,
ArweaveHashStorage,
LocalKeySignerConfig,
AwsS3StorageConfig,
)
from langchain_anthropic import ChatAnthropic
load_dotenv()
# Where full audit payloads are stored (your S3 bucket)
raw_payload_storage = RawPayloadStorage(
storage=AwsS3StorageConfig(
bucket_name=os.environ["ORG_AWS_S3_BUCKET_NAME"],
aws_access_key_id=os.environ["ORG_AWS_S3_ACCESS_KEY_ID"],
aws_secret_access_key=os.environ["ORG_AWS_S3_SECRET_ACCESS_KEY"],
aws_region=os.environ["ORG_AWS_S3_REGION"],
),
)
# Where hashes are stored — Arweave for independent verification
hash_storage = [
ArweaveHashStorage(
namespace="my_namespace",
signer=LocalKeySignerConfig(
private_key_path=os.environ["ARWEAVE_PRIVATE_KEY_PATH"],
),
bundler_url=os.environ["ARWEAVE_BUNDLER_URL"],
),
]
# Initialize notary
notary = LangChainNotary(
raw_payload_storage=raw_payload_storage,
hash_storage=hash_storage,
debug=True,
)
model = ChatAnthropic(
model="claude-sonnet-4-5-20250929",
api_key=os.environ["ANTHROPIC_API_KEY"],
callbacks=[notary],
)
response = model.invoke("What is 2 + 2?")
CrewAI
pip install crewai
import os
from dotenv import load_dotenv
from agentsystems_notary import (
CrewAINotary,
RawPayloadStorage,
ArweaveHashStorage,
LocalKeySignerConfig,
AwsS3StorageConfig,
)
from crewai import Agent, Task, Crew, LLM
load_dotenv()
# Where full audit payloads are stored (your S3 bucket)
raw_payload_storage = RawPayloadStorage(
storage=AwsS3StorageConfig(
bucket_name=os.environ["ORG_AWS_S3_BUCKET_NAME"],
aws_access_key_id=os.environ["ORG_AWS_S3_ACCESS_KEY_ID"],
aws_secret_access_key=os.environ["ORG_AWS_S3_SECRET_ACCESS_KEY"],
aws_region=os.environ["ORG_AWS_S3_REGION"],
),
)
# Where hashes are stored — Arweave for independent verification
hash_storage = [
ArweaveHashStorage(
namespace="my_namespace",
signer=LocalKeySignerConfig(
private_key_path=os.environ["ARWEAVE_PRIVATE_KEY_PATH"],
),
bundler_url=os.environ["ARWEAVE_BUNDLER_URL"],
),
]
# Initialize notary (hooks register automatically)
notary = CrewAINotary(
raw_payload_storage=raw_payload_storage,
hash_storage=hash_storage,
debug=True,
)
llm = LLM(
model="anthropic/claude-sonnet-4-5-20250929",
api_key=os.environ["ANTHROPIC_API_KEY"],
)
agent = Agent(role="Analyst", goal="Answer questions", backstory="Expert analyst", llm=llm)
task = Task(description="What is 2 + 2?", expected_output="The answer", agent=agent)
crew = Crew(agents=[agent], tasks=[task])
result = crew.kickoff()
How It Works
- Capture: Intercepts LLM requests/responses via framework hooks
- Canonicalize: Deterministic JSON serialization (JCS/RFC 8785)
- Hash: SHA-256 of canonical bytes
- Dual-Write:
- Your bucket: Full canonical JSON payload
- Hash storage: Hash receipt for verification
Configuration
Raw Payload Storage
Where full audit payloads are stored (your bucket):
from agentsystems_notary import RawPayloadStorage, AwsS3StorageConfig
raw_payload_storage = RawPayloadStorage(
storage=AwsS3StorageConfig(
bucket_name="my-audit-logs",
aws_access_key_id="...",
aws_secret_access_key="...",
aws_region="us-east-1",
),
)
Hash Storage
Where hashes are stored for verification. You can use one or both.
Arweave (Decentralized) — Public blockchain, permanent storage, no vendor dependency. Verify independently with open-source CLI.
from agentsystems_notary import ArweaveHashStorage, LocalKeySignerConfig
ArweaveHashStorage(
namespace="my_namespace",
signer=LocalKeySignerConfig(
private_key_path="path/to/rsa-4096-private.pem",
),
bundler_url="https://node2.bundlr.network",
)
Custodied (AgentSystems API) — Managed service if you prefer AgentSystems to handle the complexity.
from agentsystems_notary import CustodiedHashStorage
CustodiedHashStorage(
api_key="sk_asn_prod_...", # From agentsystems.ai
slug="my_tenant",
)
Using both:
hash_storage=[
ArweaveHashStorage(namespace="my_namespace", signer=..., bundler_url="..."),
CustodiedHashStorage(api_key="...", slug="my_tenant"),
]
Debug Mode
notary = LangChainNotary(
raw_payload_storage=...,
hash_storage=[...],
debug=True, # Prints canonical JSON and hashes
)
S3 Bucket Structure
{env}/{namespace}/{YYYY}/{MM}/{DD}/{hash}.json
env:arweave,prod, ortestnamespace: Your namespace (Arweave) or tenant ID from API response (custodied)hash: SHA-256 hash of the canonical payload
Verification
For Arweave-notarized logs, use the open-source CLI — no account required:
npm install -g agentsystems-verify
agentsystems-verify --logs logs.zip
Manual verification:
import hashlib
# 1. Download payload from your bucket
with open("payload.json", "rb") as f:
canonical_bytes = f.read()
# 2. Compute hash
computed_hash = hashlib.sha256(canonical_bytes).hexdigest()
# 3. Compare with stored hash (from Arweave or custodied receipt)
assert computed_hash == stored_hash
Support
- Documentation: docs.agentsystems.ai/notary
- Dashboard: notary.agentsystems.ai
- Issues: GitHub Issues
License
Licensed under the Apache-2.0 license.
Metadata
Release files for agentsystems-notary 0.8.1
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 |
|---|---|---|---|---|
| agentsystems_notary-0.8.1.tar.gz | 33.9 kB | Without provenance | Details for agentsystems_notary-0.8.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| agentsystems_notary-0.8.1-py3-none-any.whl | Python 3 | none | any | Details for agentsystems_notary-0.8.1-py3-none-any.whl |
Total release size: 67.5 kB
Release files / agentsystems_notary-0.8.1.tar.gz
| Download URL | agentsystems_notary-0.8.1.tar.gz |
|---|---|
| Size | 33.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c7c3ee7a3d7b4cdd8f8e7aa153c2183493905b2379c4f016a6e762cf73433a26
|
|
BLAKE2b-256 checksum How to use checksums |
5d192bf1ac88f6c2f7c39aa32265b4bfff375a32a901d42ae8105c756b9dd0ad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / agentsystems_notary-0.8.1-py3-none-any.whl
| Download URL | agentsystems_notary-0.8.1-py3-none-any.whl |
|---|---|
| Size | 33.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f0546418bc7561b01e8052ab45fb0956f78a87eecc5bce03232ac0e25603d371
|
|
BLAKE2b-256 checksum How to use checksums |
ce90f3c424de7901d3e81502c9b7ab2c65c4ce24e40f409973de8c713ae7a2d0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Security for agentsystems-notary 0.8.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.