Repository navigation
Integrations Claude Agent SDK
Stable: tested with
tests/adapter_contract.pyagainst the pinned library on every push to main and every pull request (what's stable).
tracekit.integrations.claude_agent_sdk.tracekit_hooks gates the tools of a Claude Agent SDK (Python) agent. Before
each tool call it asks the Tracekit signer for a policy decision; after the tool runs it records the outcome.
TracekitSessionStore wraps your SessionStore and commits every saved transcript to the signer. Both work with a
tracekit.sdk.client.Client or any object that implements the signer RPC (tracekit.signer.rpc_schema.SignerAPI),
including tracekit.testing.FakeSigner.
pip install tracekit-ai "claude-agent-sdk>=0.2.165,<0.3"Python 3.10 or newer (the SDK's own requirement).
from claude_agent_sdk import ClaudeAgentOptions, query
from tracekit.integrations.claude_agent_sdk import TracekitSessionStore, tracekit_hooks
from tracekit.sdk.client import Client
signer = Client()
run = signer.register_run({"agent": {"name": "repo-agent"}})
options = ClaudeAgentOptions(
hooks=tracekit_hooks(signer, run),
session_store=TracekitSessionStore(my_store, signer, run), # optional: only if you mirror sessions to a store
)
async for message in query(prompt="fix the failing test", options=options):
...Register the run when the session starts; the hooks close it at SessionEnd. To add hooks of your own, extend the
lists in the mapping. Tools run in the CLI subprocess under their Claude Code names (Bash, Edit, Write, ...), so
the signer's coding packs apply to them as they do to the Claude Code hook.
| When | RPC | Sent |
|---|---|---|
| PreToolUse | decide |
tool_use_id, tool name, the tool input as the CLI sends it (parsed) |
| PreToolUse, right before it runs | approval_consume |
the same call and arguments, and the approval id when the hook waited for one |
| PostToolUse / PostToolUseFailure | complete |
status ok or error, a sha256: commitment to the tool response (not the response), or the error message |
after each SessionStore.append
|
state_write |
the transcript's digest and the digest it started from (prev_digest) |
| SessionEnd | close_run |
the CLI's reason |
No hook carries the model's messages: hand each message of query() (or ClaudeSDKClient.receive_response())
to tracekit_said. It records each AssistantMessage's thinking (a summary, with its signature), text and tool uses,
under the tool_use_ids the PreToolUse hook decides them by. A tool executor's call is recorded under its action's
name: the hook notes its tool_use_id for the executor server's handler, which hands it to the executor, so the
executor decides the call under the model's id.
from tracekit.integrations.claude_agent_sdk import tracekit_said
said = tracekit_said(signer, run)
async for message in query(prompt="close ACC-9", options=options):
await said(message)Opus 4.7 and later return only the thinking's signature unless asked: ClaudeAgentOptions(thinking={"type": "adaptive", "display": "summarized"}). The message itself is kept only when the signer's content vault is on; without it the record holds a commitment. A message that can't be recorded only warns. Which frameworks and providers return readable reasoning, and how to turn it on: reasoning.
- allow: the tool runs.
-
deny: the hook answers
permissionDecision: deny. The model getsTool call blocked by policy: <rule ids>as the tool's error result and the session goes on. -
ask: the hook opens an approval in the signer and holds the call until a person approves or rejects it there
(CLI, web), for at most
APPROVAL_WAIT_S(540 s). The PreToolUse matcher's timeout is set toHOOK_TIMEOUT_S(600 s), so the hook answers before the CLI gives up on it. A call not approved in time, or rejected, is denied.
Every call that is not denied runs only after the signer's approval_consume agrees: nothing the SDK holds is taken
as proof that no approval is needed. If the signer cannot be reached, the call is denied unless the run's fail_modes
make its tool class fail open (closed by default).
The gate is the PreToolUse hook, not the can_use_tool permission callback: the CLI skips can_use_tool for calls
its permission mode or allow rules approve (bypassPermissions, allowed_tools), while PreToolUse runs for every call.
The hook returns no opinion on an allowed call, so your permission settings still apply on top.
TracekitSessionStore(store, signer, run) passes every call to your store. After each append it sends
state_write with the digest of the transcript (canonical JSON of each entry, chained, so a store that reorders JSON
keys gives the same digest) and the digest the transcript had before (prev_digest). When a session resumes from the
store, load recomputes the digest from what the store gives back; if the transcript was changed in the store since
the last write, the next write starts from another digest than the signer recorded, and the signer writes a signed
capture.gap of kind state_tamper. The signer compares writes within one run: resume the session in the same run
(same run_id and run_token) for the check to apply.
- The hook holds a call while it waits for an approval: there is no saved state to resume in a new process, so a wait
longer than
APPROVAL_WAIT_Sends in a denial and the model may try again. - The CLI gives every tool use its own
tool_use_idand runs it once, so every call is attempt 0. - A store that keeps an entry twice (a retried append without de-duplication by
uuid) changes the transcript's digest, and the next resume records astate_tamper. - The LLM gateway's verified tool results (signer.yaml
verify_tool_results) can't be used with this integration: it records the structured tool response, not what the model is sent, so every result would mismatch (gateway).
Generated from docs/ at v1.4.1. Edit the docs in the repository, not here.
Get started
- Quickstart: the v2 signer
- Quickstarts
- Quickstart: Claude Agent SDK
- Quickstart: a custom agent
- Quickstart: LangChain and LangGraph
- Quickstart: MCP client
- Quickstart: OpenAI Agents SDK
- Coding agents other than Claude Code
- tracekit doctor
- Walkthrough: Tracekit end to end
How it works
- How Tracekit works
- Overview
- The life of a tool call
- The evidence format
- Verification and assurance
- Witnesses and monitoring
- Policy
- Approvals
- Detection and containment
- Capture and completeness
- Custody
- Provenance and tracekit why
- Deployment and isolation
- Storage, durability and performance
- Integrations
- Security model
- Architecture
- tracekit why: architecture
Integrations
- Integrations
- Adapters
- OpenTelemetry
- Remote clients
- Kubernetes agent-sandbox
- agentgateway
- agentsh and Tracekit
- Browser Use
- Claude Agent SDK
- Claude Code's sandbox
- Codex's sandbox
- CrewAI
- Docker MCP Gateway
- E2B
- Falco
- Gemini CLI's sandbox
- Google ADK
- Haystack
- LangChain v1
- LiteLLM
- LlamaIndex
- MCP client
- microsandbox
- Microsoft Agent Framework
- OpenAI Agents SDK
- NVIDIA OpenShell
- Pydantic AI
- sandbox-runtime's proxy on its own
- Strands Agents
- Tetragon
- Vercel AI SDK
- Wassette
Policy and approvals
- Policy reference
- Approvals
- Findings
- Reading the model's reasoning
- Incidents and containment
- Webhooks
Deploy and operate
- Deploying the signer
- The signer as a container
- The signer on Kubernetes
- The compose stack
- Identity
- Tool executor
- MCP gateway
- LLM gateway
- Egress observation
- Witnesses
- Log monitor
- Record-key issuer
- Signer observability
- Viewer
- tracekit why: causal investigation and replay
- Migrating
- Platforms
Verify the evidence
- Reading a v2 verify report
- Evidence format v2
- Auditor guide
- Sample evidence bundle
- Signing
- What Tracekit guarantees
Security and privacy
- Threat model: the v2 signer
- Threat model: the v1 laptop signer
- HTTP security checklist
- Threat-model review packet
- Privacy
- Known limits and trade-offs
- What's stable
Compliance
- Compliance mapping
- EU AI Act
- ISO/IEC 42001
- NIST AI RMF and the Generative AI Profile
- OWASP Top 10 lists for LLM and agentic applications
Evaluation
Demos
- Demos
- Agent approvers within bounds
- Completeness and tamper evidence
- Detection and containment
- Network coverage: an egress observer
- Guardrails: allow, deny, or ask a person
- MCP tools, gated and recorded
- Prompt injection held by provenance
- Why: which input caused the action
Help