
signed-audit-trails-recipe
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.
- Installs
- 6.3K
- Last 24h
- +38
- Trending rank
- #4012
- Security
- Pass
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/wshobson/agents --skill signed-audit-trails-recipe- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads signed-audit-trails-recipe automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
Security audits
Independent scans of the skill's instructions and bundled files.
SKILL.md
The instructions your agent reads when the skill is triggered.
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
tampered payload.
Restore the field and verification passes again.
How the cryptography works
Two invariants make receipts verifiable offline across any conformant implementation:
- JCS canonicalization (RFC 8785) before signing. Keys sorted by UTF-16 code units, whitespace minimized, strings not normalized. Two independent implementations produce byte-identical signing payloads for the same receipt content.
- Ed25519 signatures (RFC 8032) over the canonical bytes. Deterministic, fixed-size, no nonce dependency.
protect-mcp 0.7.4 receipts carry no link to the previous receipt, so a deleted receipt goes undetected.
For the formal wire format see draft-farley-acta-signed-receipts.
Cross-implementation interop
The receipt format has four independent implementations today:
| Implementation | Language | Use case |
|---|---|---|
| protect-mcp | TypeScript | Claude Code, Cursor, MCP hosts |
| protect-mcp-adk | Python | Google Agent Development Kit |
| sb-runtime | Rust | OS-level sandbox (Landlock + seccomp) |
| APS governance hook | Python | CrewAI, LangChain |
A receipt produced by any of them verifies against
@veritasacta/verify.
The auditor does not need to trust the operator's tooling choice: the format
is the contract.
CI/CD integration
Verify receipts in CI so a tampered receipt fails the build.
references/ci-cd.md has a GitHub Actions workflow
that runs on pushes to the default branch. It installs the signing key from a
branch-limited environment, runs the agent, verifies the receipts, and uploads
them. It does not run on pull requests, because that would hand the key to
unreviewed code.
Composition with SLSA provenance for agent-built software
When Claude Code builds and releases software (running npm install,
npm build, npm publish as tool calls), the receipt chain is the
per-step build log. SLSA Provenance v1 has an extension point for this: the
byproducts field can reference the receipt chain alongside the build
attestation.
The agent-commit build type documents the pattern using the ResourceDescriptor shape:
{
"name": "decision-receipts",
"digest": { "sha256": "..." },
"uri": "oci://registry/org/build-xyz/receipts:sha256-...",
"annotations": {
"predicateType": "https://veritasacta.com/attestation/decision-receipt/v0.1",
"signerRole": "supervisor-hook"
}
}
The SLSA provenance is signed by the builder identity; the receipt attestation is signed by the supervisor-hook identity. Two trust domains, cross-referenced at the byproduct layer. See slsa-framework/slsa#1594 for the composition discussion.
Common pitfalls
Private key in version control. The generated ./protect-mcp.key must
not be committed. The examples above add it to .gitignore. If a key is
accidentally committed, rotate it immediately. Move the key and
./receipts/receipts.jsonl to an archive, then run the Step 1 command again.
Verify the archived receipts with the old public key.
Hook payload on stdin. Claude Code sets no $TOOL_NAME or $TOOL_INPUT
variables. A hook command that passes --tool "$TOOL_NAME" sends an empty
tool name, so the policy denies every call. Read the payload from stdin as the
plugin scripts do.
Receipts directory in CI. If Claude Code runs in CI, upload receipts as an artifact at the end of the job or the receipts are lost at job end.
Policy is missing. When ./protect.cedar does not exist, evaluate.sh
prints a warning to stderr and allows the call. No call is gated until you
create the policy in Step 2.
Related in this marketplace
protect-mcp— the runtime hook implementation (use this plugin in production)review-agent-governance— require human approval before review-surface actions; composes with protect-mcp
References
draft-farley-acta-signed-receipts— IETF draft, receipt wire format- RFC 8032 — Ed25519
- RFC 8785 — JCS
- Cedar policy language
- protect-mcp on npm
- @veritasacta/verify on npm
- in-toto/attestation#549 — Decision Receipt predicate proposal
- agent-commit build type — SLSA provenance for agent-produced commits
- Microsoft Agent Governance Toolkit (
examples/protect-mcp-governed/) - AWS Cedar for Agents
FAQ
What does the signed-audit-trails-recipe skill do?
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.
How do I install signed-audit-trails-recipe?
Run npx skills add https://github.com/wshobson/agents --skill signed-audit-trails-recipe in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/signed-audit-trails-recipe/ (personal) or .claude/skills/signed-audit-trails-recipe/ (project).
Which AI agents can use signed-audit-trails-recipe?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is signed-audit-trails-recipe safe to install?
Security partners have reviewed it: Gen Agent Trust Hub passed; Socket passed; Snyk passed. As with any skill, read the SKILL.md and bundled scripts before installing.
Who maintains signed-audit-trails-recipe?
It is published by wshobson in wshobson/agents. It has 6,289 recorded installs.
More from wshobson/agents
typescript-advanced-types
wshobson/agents
Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications. Use when implementing complex type logic, creating reusable type utilities, or ensuring compile-time type safety in TypeScript projects.
tailwind-design-system
wshobson/agents
Build scalable design systems with Tailwind CSS v4, design tokens, component libraries, and responsive patterns. Use when creating component libraries, implementing design systems, or standardizing UI patterns.
nodejs-backend-patterns
wshobson/agents
Build production-ready Node.js backend services with Express/Fastify, implementing middleware patterns, error handling, authentication, database integration, and API design best practices. Use when creating Node.js servers, REST APIs, GraphQL backends, or microservices architectures.
brand-landingpage
wshobson/agents
Brand-first landing page designer — runs a brand-identity interview (colors, typography, shape language), then generates and iterates on a polished landing page via Stitch with deployment-ready HTML. Use when the user asks to create, design, or build a landing page, homepage, or marketing page and has no established visual direction. Skip when they have a design mockup, need a dashboard or app UI, are working at component level, building a multi-page app, or restyling with known design tokens — use frontend-design instead.
python-testing-patterns
wshobson/agents
Implement comprehensive testing strategies with pytest, fixtures, mocking, and test-driven development. Use when writing Python tests, setting up test suites, or implementing testing best practices.
python-performance-optimization
wshobson/agents
Profile and optimize Python code using cProfile, memory profilers, and performance best practices. Use when debugging slow Python code, optimizing bottlenecks, or improving application performance.
Popular security skills
azure-compliance
microsoft/azure-skills
Run Azure compliance and security audits with azqr plus Key Vault expiration checks. Covers best-practice assessment, resource review, policy/compliance validation, and security posture checks. WHEN: compliance scan, security audit, BEFORE running azqr (compliance cli tool), Azure best practices, Key Vault expiration check, expired certificates, expiring secrets, orphaned resources, compliance assessment.
minimal-run-and-audit
lllllllama/rigorpilot-skills
Rigor Run skill for README-first deep learning repo reproduction. Use when the task is specifically to capture or normalize evidence from the selected smoke test or documented inference or evaluation command and write standardized reprooutputs/ files, including patch notes when repository files changed. Do not use for training execution, initial repo intake, generic environment setup, paper lookup, target selection, hidden scientific-meaning changes, or end-to-end orchestration by itself.
seo-audit
coreyhaines31/marketingskills
When the user wants to audit, review, or diagnose SEO issues on their site. Also use when the user mentions "SEO audit," "technical SEO," "why am I not ranking," "SEO issues," "on-page SEO," "meta tags review," "SEO health check," "my traffic dropped," "lost rankings," "not showing up in Google," "site isn't ranking," "Google update hit me," "page speed," "core web vitals," "crawl errors," "indexing issues," "stuck on page 2," "striking distance keywords," "title tag rewrite," "low CTR," "local SEO," "Google Business Profile," or "map pack." Use this even if the user just says something vague like "my SEO is bad" or "help with SEO" — start with an audit. For building pages at scale to target keywords, see programmatic-seo. For adding structured data, see schema. For AI search optimization, see ai-seo.
firebase-security-rules-auditor
firebase/agent-skills
Audits Firebase (Firestore, Cloud Storage) security rules for vulnerabilities, privilege escalation, role bypasses, create vs update inconsistencies, resource exhaustion, type safety, size limits, and hasOnly ownership checks. Use when auditing/reviewing rules, running red-team rule assessments, or scoring against auditor checklists. Don't use for Firebase CLI (login, deploy), Auth, Crashlytics, Remote Config, or database queries.
audit
pbakaus/impeccable
Run technical quality checks across accessibility, performance, theming, responsive design, and anti-patterns. Generates a scored report with P0-P3 severity ratings and actionable plan. Use when the user wants an accessibility check, performance audit, or technical quality review.
competitors
coreyhaines31/marketingskills
When the user wants to create competitor comparison or alternative pages for SEO and buyer-facing use. Also use when the user mentions 'alternative page,' 'vs page,' 'competitor comparison,' 'comparison page,' '[Product] vs [Product],' '[Product] alternative,' 'competitive landing pages,' 'how do we compare to X,' 'competitor teardown,' 'audit our competitor pages,' 'are our comparison pages out of date,' or 'competitive asset audit.' Use this for any content that positions your product against competitors. Covers four formats: singular alternative, plural alternatives, you vs competitor, and competitor vs competitor. For auditing existing claims (not researching competitors from scratch, which is competitor-profiling; not technical SEO on these pages, which is seo-audit), use the asset audit here. For internal battle cards and sales-specific competitor docs, see sales-enablement.