Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
"integrations/strands",
"integrations/google-adk",
"integrations/crewai",
"integrations/langchain"
"integrations/langchain",
"integrations/agentsystems-notary"
]
},
{
Expand Down
112 changes: 112 additions & 0 deletions integrations/agentsystems-notary.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: AgentSystems Notary
description: Tamper-evident audit trails for Agent Control events.
---

AgentSystems Notary writes every Agent Control event to independent, tamper-evident storage — so you can prove to auditors, regulators, and customers exactly which controls fired, when, and what they decided.

## How it works

Each Agent Control event is embedded in a Notary record alongside metadata. A SHA-256 hash of the record is written to your hash storage backend — managed WORM or Arweave — and the record bytes are stored in your S3 bucket. Auditors re-hash the stored bytes and compare against the stored hash — matching hashes prove integrity, mismatches expose tampering.

## Storage options

| Option | Best for | What you get |
|--------|----------|--------------|
| **Arweave (Decentralized)** | No vendor lock-in | Public append-only ledger, open-source verification, no account required |
| **Custodied** | Managed compliance | Write-once storage, verification UI, signed attestation PDFs |

## Setup

Notary integrates as a control event sink. Works with any framework Agent Control supports — LangChain, CrewAI, Google ADK, AWS Strands.

### Prerequisites

- A running Agent Control server with at least one agent and one control configured (see the [Quickstart](/core/quickstart))
- An S3 bucket for record storage
- A hash storage backend — either an Arweave signing key (decentralized) or an AgentSystems API key (custodied). See the [Notary docs](https://docs.agentsystems.ai/notary) for setup.

### Install and register the sink

```bash
pip install 'agentsystems-notary[agent-control]'
```

This example uses Arweave; for custodied storage, swap `ArweaveHashStorage` for `CustodiedHashStorage(api_key=..., slug=...)`. See the [Notary docs](https://docs.agentsystems.ai/notary) for either setup.

```python
import os

from agent_control.observability import register_control_event_sink
from agentsystems_notary import (
AgentControlNotarySink,
ArweaveHashStorage,
AwsS3StorageConfig,
LocalKeySignerConfig,
NotaryCore,
RawPayloadStorage,
)

notary = NotaryCore(
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"],
),
),
hash_storage=[
ArweaveHashStorage(
namespace="my-agent-namespace", # scopes your stored data
signer=LocalKeySignerConfig(
private_key_path=os.environ["ARWEAVE_PRIVATE_KEY_PATH"],
),
)
],
)

register_control_event_sink(AgentControlNotarySink(notary))
```

Once the sink is registered, every control your agents trigger is automatically notarized — no changes to your `@control()` decorators or control definitions required.

<Note>
Agent Control's event batcher flushes sink events asynchronously. In short-lived scripts, allow a few seconds for events to flush before exiting (e.g. `await asyncio.sleep(5)`). Long-running agents don't need this.
</Note>

## What gets notarized

Each Agent Control event is preserved verbatim in the `pre_execution_record` field of the Notary record — `control_name`, `evaluator_name`, `action`, `matched`, `confidence`, `trace_id`, `span_id`, and the `condition_trace` showing exactly which pattern or rule matched:

```json
{
"metadata": { "session_id": "...", "sequence": 1, "timestamp": "..." },
"input": { "selector_path": "output", "check_stage": "post" },
"output": { "matched": true, "action": "deny" },
"pre_execution_record": {
"control_name": "block-ssn",
"evaluator_name": "regex",
"action": "deny",
"matched": true,
"confidence": 1,
"agent_name": "my-agent",
"trace_id": "...",
"span_id": "...",
"metadata": {
"pattern": "\\b\\d{3}-\\d{2}-\\d{4}\\b",
"condition_trace": { "matched": true, "message": "Pattern found", "...": "..." }
},
"timestamp": "..."
}
}
```

## Verification

Download the stored bytes from your S3 bucket, compute SHA-256, and compare against your stored hashes. Use the [Verify UI](https://verify.agentsystems.ai) for a one-click verification flow, or the open-source [`agentsystems-verify` CLI](https://github.com/agentsystems/agentsystems-verify) for programmatic verification.

## Resources

- [AgentSystems Notary on PyPI](https://pypi.org/project/agentsystems-notary/)
- [Source on GitHub](https://github.com/agentsystems/agentsystems-notary)