API Scaffolding
Avoid AI Writing
Before You Build
Block No Verify
Brand Landingpage
Business Analytics
Database Design
Documentation Generation
Documentation Standards
File Conversion
Framework Migration
Frontend Mobile Development
Game Development
Hermes Tweet
Hr Legal Compliance
Incident Response
Kubernetes Operations
Machine Learning Ops
NET Contribution
Observability Monitoring
Payment Processing
Plugin Eval
Protect MCP
Python Development · Python…
Quantitative Trading
Review Agent Governance
Ship Mate
Signed Audit Trails
Skill Forge Essentials
Social Publishing
Superself
Systems Programming
183 skills · 335 min
Signed Audit Trails
Skill 161 of 183
Step-by-step cookbook for setting up cryptographically signed audit trails on Claude Code tool calls.
4 minutes · 840 words · 16 sections
Install
npx skills add wshobson/agents --skill signed-audit-trails-recipenpx skills add wshobson/agents/plugin marketplace add wshobson/agentsThe first command installs just this skill, by the name in its SKILL.md; the second installs the whole repository.
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 (opens in a new tab) plugin.
Every tool call (Bash, Edit, Write, WebFetch) is:
An auditor, regulator, or counterparty can verify the full chain later with a
single CLI command (npx @veritasacta/verify receipts/*.json). No network
call, no vendor lookup, no trust in the operator.
Create .claude/settings.json in your project root:
{
"hooks": {
"PreToolUse": [
{
"matcher": ".*",
"hook": {
"type": "command",
"command": "npx protect-mcp@latest evaluate --policy ./protect.cedar --tool \"$TOOL_NAME\" --input \"$TOOL_INPUT\" --fail-on-missing-policy false"
}
The first run of protect-mcp sign generates ./protect-mcp.key (Ed25519
private key) if one does not exist. Commit the public key fingerprint
(visible in any receipt’s public_key field); do not commit the private
key.
Add the private key and receipt directory to .gitignore:
echo "./protect-mcp.key" >> .gitignore
echo "./receipts/" >> .gitignoreCreate ./protect.cedar:
// Allow all read-oriented tools by default.
permit (
principal,
action in [Action::"Read", Action::"Glob", Action::"Grep", Action::"WebSearch"],
resource
);
// Allow Bash commands from a safe list only.
permit (
principal,
action == Action::"Bash",
resource
) when {
context.command_pattern in [
"git", "npm", "pnpm", "yarn", "ls", "cat", "pwd",
"echo", "test", "node", "python", "make"
]
};
// Explicit deny on destructive commands. Cedar deny is authoritative.
forbid (
principal,
action == Action::"Bash",
resource
) when {
context.command_pattern in ["rm -rf", "dd", "mkfs", "shred"]
Four rules:
Bash allowed for safe command patterns (git, npm, etc.)Bash rm -rf and similar destructive commands explicitly denied./ prefix)Cedar forbid rules take precedence over permit rules, so destructive
commands cannot be bypassed by a later permissive rule.
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 produces 20 receipts, each hash-chained to its predecessor.
cat ./receipts/$(ls -t ./receipts/ | head -1){
"receipt_id": "rcpt-a8f3c9d2",
"receipt_version": "1.0",
"issuer_id": "claude-code-protect-mcp",
"event_time": "2026-04-17T12:34:56.123Z",
"tool_name": "Read",
"input_hash": "sha256:a3f8c9d2e1b7465f...",
"decision": "allow",
"policy_id"
Every field except signature and public_key is covered by the Ed25519
signature. Modifying any field after signing invalidates the signature.
npx @veritasacta/verify ./receipts/*.jsonExit codes:
| Code | Meaning |
|---|---|
0 | All receipts verified; chain intact |
1 | A receipt failed signature verification (tampered, or wrong key) |
2 | A receipt was malformed |
Modify any receipt’s decision field from allow to deny:
python3 -c "
import json, os
path = './receipts/' + sorted(os.listdir('./receipts'))[-1]
r = json.loads(open(path).read())
r['decision'] = 'deny'
open(path, 'w').write(json.dumps(r))
"
npx @veritasacta/verify ./receipts/*.jsonThe verifier exits with code 1 and reports which receipt failed. The
Ed25519 signature no longer matches the JCS-canonical bytes of the
tampered payload.
Restore the field and verification passes again.
Three invariants make receipts verifiable offline across any conformant implementation:
parent_receipt_hash is the
SHA-256 of the predecessor’s canonical form. Insertions, deletions, and
reorderings break later receipts.For the formal wire format see draft-farley-acta-signed-receipts (opens in a new tab).
The receipt format has four independent implementations today:
| Implementation | Language | Use case |
|---|---|---|
| protect-mcp (opens in a new tab) | TypeScript | Claude Code, Cursor, MCP hosts |
| protect-mcp-adk (opens in a new tab) | Python | Google Agent Development Kit |
| sb-runtime (opens in a new tab) | Rust | OS-level sandbox (Landlock + seccomp) |
| APS governance hook | Python | CrewAI, LangChain |
A receipt produced by any of them verifies against
@veritasacta/verify (opens in a new tab).
The auditor does not need to trust the operator’s tooling choice: the format
is the contract.
Gate merges on receipt chain verification so no build lands with a broken evidence chain:
# .github/workflows/verify-receipts.yml
name: Verify Decision Receipts
on: [push, pull_request]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version
Archive the receipts as an artifact so the chain survives beyond the job run:
- name: Upload receipts
if: always()
uses: actions/upload-artifact@v4
with:
name: decision-receipts
path: receipts/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 (opens in a new tab) 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 (opens in a new tab) for the composition discussion.
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 immediately (delete the key file and let the
hook regenerate on next run).
Hook command quoting. The hooks receive $TOOL_NAME and $TOOL_INPUT
as environment variables. Keep the quoting "$TOOL_INPUT" so inputs with
spaces or special characters pass through intact.
Receipts directory in CI. If Claude Code runs in CI, upload receipts as an artifact at the end of the job or the chain is lost at job end.
Policy is missing. The example PreToolUse hook uses
--fail-on-missing-policy false so an absent ./protect.cedar does not
break Claude Code out of the box. Remove this flag in production so a
missing policy is treated as a hard failure.
protect-mcp (opens in a new tab) — the runtime hook implementation
(use this plugin in production)review-agent-governance (opens in a new tab) — require
human approval before review-surface actions; composes with protect-mcpdraft-farley-acta-signed-receipts (opens in a new tab) — IETF draft, receipt wire formatStep-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.
The verbatim description from this skill’s front matter — the string an agent matches on to decide whether to load it.
main, last pushed 21 September 2026.SKILL.md, not by matching a directory convention. 51 distinct layouts observed: plugins/accessibility-compliance/skills/*/SKILL.md, plugins/agent-teams/skills/*/SKILL.md, plugins/api-scaffolding/skills/*/SKILL.md, plugins/avoid-ai-writing/skills/*/SKILL.md, plugins/backend-development/skills/*/SKILL.md, plugins/before-you-build/skills/*/SKILL.md, plugins/block-no-verify/skills/*/SKILL.md, plugins/blockchain-web3/skills/*/SKILL.md, plugins/brand-landingpage/skills/*/SKILL.md, plugins/business-analytics/skills/*/SKILL.md, plugins/cicd-automation/skills/*/SKILL.md, plugins/cloud-infrastructure/skills/*/SKILL.md, plugins/conductor/skills/*/SKILL.md, plugins/data-engineering/skills/*/SKILL.md, plugins/database-design/skills/*/SKILL.md, plugins/developer-essentials/skills/*/SKILL.md, plugins/dgx-spark-ops/skills/*/SKILL.md.examples/protect-mcp-governed/)plugins/documentation-generation/skills/*/SKILL.mdplugins/documentation-standards/skills/*/SKILL.mdplugins/dotnet-contribution/skills/*/SKILL.mdplugins/file-conversion/skills/*/SKILL.mdplugins/framework-migration/skills/*/SKILL.mdplugins/frontend-mobile-development/skills/*/SKILL.mdplugins/game-development/skills/*/SKILL.mdplugins/hermes-tweet/skills/*/SKILL.mdplugins/hr-legal-compliance/skills/*/SKILL.mdplugins/incident-response/skills/*/SKILL.mdplugins/javascript-typescript/skills/*/SKILL.mdplugins/kubernetes-operations/skills/*/SKILL.mdplugins/llm-application-dev/skills/*/SKILL.mdplugins/llm-finetuning/skills/*/SKILL.mdplugins/machine-learning-ops/skills/*/SKILL.mdplugins/observability-monitoring/skills/*/SKILL.mdplugins/payment-processing/skills/*/SKILL.mdplugins/plugin-eval/skills/*/SKILL.mdplugins/pptx-deck-creation/skills/*/SKILL.mdplugins/protect-mcp/skills/*/SKILL.mdplugins/python-development/skills/*/SKILL.mdplugins/quantitative-trading/skills/*/SKILL.mdplugins/reverse-engineering/skills/*/SKILL.mdplugins/review-agent-governance/skills/*/SKILL.mdplugins/security-scanning/skills/*/SKILL.mdplugins/shell-scripting/skills/*/SKILL.mdplugins/ship-mate/skills/*/SKILL.mdplugins/signed-audit-trails/skills/*/SKILL.mdplugins/skill-forge-essentials/skills/*/SKILL.mdplugins/social-publishing/skills/*/SKILL.mdplugins/startup-business-analyst/skills/*/SKILL.mdplugins/superself/skills/*/SKILL.mdplugins/systems-programming/skills/*/SKILL.mdplugins/ui-design/skills/*/SKILL.mdh1 and no skipped levels:.claude-plugin/marketplace.json by Seth Hobson, declaring 94 plugins. It is read for editorial metadata only — never as the skill index, which is always the repository tree./wshobson/agents.md, and each skill at its own .md URL.