signed-audit-trails-recipe
Helps your agent create secure audit logs. It's useful for reliably tracking actions and detecting unauthorized changes.
What it does
This tool creates a secure and verifiable record of all actions an AI agent takes. Each action is checked against security rules and then digitally signed, allowing anyone to verify it hasn't been tampered with.
When to use it
- ✓In regulated industries (finance, healthcare) to prove agent behavior.
- ✓In automated development processes (CI/CD) to ensure rules were followed.
- ✓When you need someone else to verify your agent's actions without trusting you directly.
Example of what to ask your AI
“Set up signed audit trails for my tool calls.”
Want more? Open the sections below.
How to use
The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.
Skill link
Ready-to-paste message
How it works
The tool uses a plugin that first checks each command against a security policy (Cedar) and then generates a digital signature (Ed25519) for the outcome. This signature allows later verification without needing an internet connection or trusting the operator.
Installation
Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.
In the terminal (Claude Code, Codex, Cursor), in your project folder:
npx skills add wshobson/agents --skill signed-audit-trails-recipeOr download just the file:
curl -L https://raw.githubusercontent.com/wshobson/agents/main/plugins/signed-audit-trails/skills/signed-audit-trails-recipe/SKILL.md -o SKILL.mdTechnical content (original SKILL.md)
Original text by the author, straight from GitHub.
Signed Audit Trails for Claude Code Tool Calls
Cookbook-style walkthrough for cryptographically signed receipts on every
Claude Code tool call. This is the teaching skill. For the runtime
implementation, install the protect-mcp plugin.
What this gives you
Every tool call (Bash, Edit, Write, WebFetch) is:
- Evaluated against a Cedar policy before execution. If the policy denies the call, the tool does not run.
- Signed as an Ed25519 receipt after execution. Receipts are JCS-canonical and verifiable offline by anyone with the public key.
An auditor, regulator, or counterparty can verify every receipt later (Step 5). No network call, no vendor lookup, no trust in the operator.
When to use the pattern
- Regulated environments (finance, healthcare, critical infrastructure) where you need tamper-evident evidence of agent behavior
- CI/CD pipelines where you want to prove that a policy gate held for every automated build step
- Multi-party collaboration where a counterparty wants to verify your agent's behavior without trusting your operator
- Compliance contexts (EU AI Act Article 12, SLSA provenance for agent-built software) where standard logging is not sufficient
Step 1: Install the hook configuration
Install the protect-mcp plugin with /plugin install protect-mcp. Its hooks
run evaluate.sh before each tool call and sign.sh after it. Both scripts
read the hook event from stdin, because Claude Code sets no TOOL_NAME or
TOOL_INPUT variables. See
references/hook-wiring.md for the hook
configuration and what each script passes to protect-mcp.
protect-mcp 0.7.4 does not create the signing key, and without a key the
receipts are unsigned. Create ./protect-mcp.key once. The command never
replaces an existing key:
if [ ! -e ./protect-mcp.key ]; then
d=$(mktemp -d) && npx protect-mcp@0.7.4 init --dir "$d" && mv "$d/keys/gateway.json" ./protect-mcp.key
fi
Give auditors the publicKey value from that file. Do not commit the file,
because it also holds the private key.
Add the private key and receipt directory to .gitignore:
echo "/protect-mcp.key" >> .gitignore
echo "/receipts/" >> .gitignore
Step 2: Write a Cedar policy
Create ./protect.cedar from the example in
references/cedar-policy.md. It allows read-only
tools and a short list of Bash commands, denies shell chaining and destructive
commands, and limits writes to the project with .. segments denied.
Step 3: Use Claude Code normally
Start Claude Code. Every tool call goes through both hooks:
You: Please read the README and summarize it.
Claude: I will read README.md.
[PreToolUse: Read ./README.md -> allow]
[Tool: Read executes]
[PostToolUse: receipt rcpt-a8f3c9d2 signed to ./receipts/]
... summary of README ...
A session of 20 tool calls appends 20 receipts to ./receipts/receipts.jsonl.
Step 4: Inspect a receipt
protect-mcp 0.7.4 appends each receipt as one line of
./receipts/receipts.jsonl. Print the newest one:
tail -n 1 ./receipts/receipts.jsonl | python3 -m json.tool
The receipt is a signed v2 envelope that names the tool, and it holds no
public key. See references/receipt-format.md
for a sample and the signed fields.
Step 5: Verify the receipts
Pass the publicKey value from ./protect-mcp.key to the verifier:
PUB=$(node -p 'JSON.parse(require("fs").readFileSync("./protect-mcp.key")).publicKey')
npx @veritasacta/verify@0.9.2 --replay-chain ./receipts/receipts.jsonl --key "$PUB"
Exit codes:
| Code | Meaning |
|---|---|
0 |
Every receipt verified |
1 |
A receipt failed verification (tampered, wrong key, or malformed line) |
2 |
The receipts file could not be read |
Step 6: Demonstrate tamper detection
Change the newest receipt's decision from allow to deny:
python3 -c "
import json
path = './receipts/receipts.jsonl'
lines = open(path).read().splitlines()
r = json.loads(lines[-1])
r['payload']['decision'] = 'deny'
lines[-1] = json.dumps(r)
open(path, 'w').write('\n'.join(lines) + '\n')
"
npx @veritasacta/verify@0.9.2 --replay-chain ./receipts/receipts.jsonl --key "$PUB"
The verifier exits with code 1 and reports which line failed. The
Ed25519 signature no longer matches the JCS-canonical bytes of the
…
FAQ
What is a signed audit trail?
It's a log of actions that has been cryptographically signed, ensuring it hasn't been altered since creation and can be verified by anyone with the public key.
Why use Cedar?
Cedar is a policy language that lets you define security rules to control what actions the agent can perform, ensuring it operates within expected boundaries.
How does someone verify the actions?
Anyone can use the provided public key to check the digital signatures on the records. If the verification succeeds, it means the record is authentic and has not been modified.
Details
Original description by the author
Step-by-step cookbook for setting up cryptographically signed audit trails on Claude Code tool calls. Use when explaining, evaluating, or demonstrating the pattern before committing to the protect-mcp runtime hooks. Covers Cedar policy, Ed25519 receipts, offline verification, tamper detection, CI/CD integration, and SLSA composition.
repo: wshobson/agents
Popularity
- GitHub stars
- 41k
- Ranking position
- #4954
- License
- MIT
- Updated
- 10/15/2026
Comments
- …
More skills from this repository
screen-reader-testing
Has your agent test websites using screen readers to ensure they are accessible.
wshobson/agents
wcag-audit-patterns
Helps your agent audit websites for accessibility and fix issues according to WCAG guidelines.
wshobson/agents
multi-reviewer-patterns
Enables your agent to coordinate parallel code reviews, deduplicating findings and consolidating reports.
wshobson/agents
parallel-debugging
Allows the agent to debug complex issues with parallel investigations and root cause analysis.
wshobson/agents
Similar skills
django-security
Helps your agent implement security practices in Django applications. It focuses on authentication, authorization, and prevention against common attacks, ensuring more secure code.
affaan-m/ECC
laravel-security
Helps your agent secure Laravel applications against threats. Implements security practices for authentication, authorization, and common attack prevention.
affaan-m/ECC
module-regression
Helps your agent manage changes in large projects. Ensures code changes in one part don't break other parts.
affaan-m/ECC