Audit logging for Claude AI agents — transparent, tamper-evident, OSS
Project description
agentlens
Tamper-evident audit logging for Claude agents — Claude Code hooks and Anthropic SDK. Local-first, append-only, OSS.
Why
Anthropic logs API calls for their own safety monitoring — but that log is not yours. When your Claude-powered agent takes an action, you need your own tamper-evident record: for compliance (EU AI Act Art. 12, ISO/IEC 42001 A.6.2.8), incident response, and accountability.
agentlens captures every tool_use / tool_result event into a SHA-256 hash-chained JSONL file on your own machine — via Claude Code hooks (recommended) or as a drop-in Anthropic SDK wrapper. It can also block dangerous tool calls before they execute (deterministic rules, no LLM in the loop).
Quickstart: Claude Code / Claude Agent SDK (v0.6.0+)
pip install agentlens-io
agentlens hook install # prints the settings.json snippet
.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{"matcher": "*", "hooks": [
{"type": "command", "command": "agentlens hook pre --log ~/.agentlens/audit.jsonl --block critical"}
]}
],
"PostToolUse": [
{"matcher": "*", "hooks": [
{"type": "command", "command": "agentlens hook post --log ~/.agentlens/audit.jsonl"}
]}
]
}
}
Now every tool call in Claude Code is audit-logged, and rm -rf /-class commands are denied before execution:
agentlens view ~/.agentlens/audit.jsonl # colorized event viewer
agentlens summary ~/.agentlens/audit.jsonl # per-session stats
agentlens verify ~/.agentlens/audit.jsonl # ✅ hash-chain integrity / ❌ tamper detected
Options: --block critical|high|off (default critical), --whitelist rules.json (false-positive suppression — suppressed violations stay in the log), --standalone (post-hook logs tool_use+result when no pre-hook is registered). Hooks are fail-open: the logger can never break your agent loop.
Design principles
- Read-only interception — requests and responses are never altered
- Append-only writes — log entries cannot be edited after creation
- No AI in the logger — capture logic is deterministic code, not an LLM
- Your data stays local — FileWriter (default) writes to your own machine; no data leaves your environment
Usage: SDK wrapper
from agentlens import AuditedAnthropic
# Drop-in replacement for anthropic.Anthropic()
client = AuditedAnthropic(log_path="./audit.jsonl")
response = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
tools=[...],
messages=[{"role": "user", "content": "..."}],
)
# Every tool_use and tool_result is now in audit.jsonl
Async (v0.7.0+)
AsyncAuditedAnthropic is the drop-in for anthropic.AsyncAnthropic — same
audit logging and pre-execution blocking, awaited:
from agentlens import AsyncAuditedAnthropic
client = AsyncAuditedAnthropic(log_path="./audit.jsonl", block_on_critical=True)
response = await client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
tools=[...],
messages=[{"role": "user", "content": "..."}],
)
# Raises PreExecutionBlockedError before a critical tool call reaches you.
Log format (JSONL)
{"event_type": "tool_use", "tool_use_id": "toolu_01xxx", "tool_name": "bash", "tool_input": {"command": "ls -la"}, "model": "claude-opus-4-6", "timestamp": "2026-04-05T10:00:00+00:00", "session_id": "..."}
{"event_type": "tool_result", "tool_use_id": "toolu_01xxx", "result_content": "file1.txt\nfile2.txt", "is_error": false, "timestamp": "2026-04-05T10:00:01+00:00", "session_id": "..."}
Custom writer
from agentlens.writers import BaseWriter
class MyWriter(BaseWriter):
def write(self, event) -> None:
# send to your own DB, S3, SIEM, etc.
my_db.insert(event.to_json())
client = AuditedAnthropic(writer=MyWriter())
Run tests
pip install -e ".[dev]"
pytest tests/
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agentlens_io-0.7.0.tar.gz.
File metadata
- Download URL: agentlens_io-0.7.0.tar.gz
- Upload date:
- Size: 26.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c39771cd2c416f89ebfc41ccc3c3642b9d0e8bf8b086ebc3fa880a87adfbf556
|
|
| MD5 |
36fe4c54a2fb2d294c390dd3fb8b657c
|
|
| BLAKE2b-256 |
d728f70f159de68927859d5944ceeef47fa9149dec98a4f90bb2b65c11d36f29
|
File details
Details for the file agentlens_io-0.7.0-py3-none-any.whl.
File metadata
- Download URL: agentlens_io-0.7.0-py3-none-any.whl
- Upload date:
- Size: 20.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a49b9f10c895484d410602de36e0973590617363dc14344d7907ef7132da740
|
|
| MD5 |
58de1e7bd2016fbc2dcee423c0d1aa05
|
|
| BLAKE2b-256 |
7a15e3c54e31ccdc09d5c11a8d23b6642ea127db636686fc3b806683992005e4
|