Tool Call Audit Trail
protect-mcp — Policy Enforcement + Signed Receipts

Configure Cedar policy enforcement and Ed25519 signed receipts for Claude Code tool calls. Use when setting up projects that need cryptographic audit trails, policy-gated tool execution, or compliance-ready evidence of agent actions.
--- name: protect-mcp-setup description: Configure Cedar policy enforcement and Ed25519 signed receipts for Claude Code tool calls. Use when setting up projects that need cryptographic audit trails, policy-gated tool execution, or compliance-ready evidence of agent actions. --- # protect-mcp — Policy Enforcement + Signed Receipts Cryptographic governance for every Claude Code tool call. Each invocation is evaluated against a Cedar policy and produces an Ed25519-signed receipt that anyone can verify offline. ## Overview Claude Code runs powerful tools: `Bash`, `Edit`, `Write`, `WebFetch`. By default there is no audit trail, no policy enforcement, and no way to prove what was decided after the fact. `protect-mcp` closes all three gaps: - **Cedar policies** (AWS's open authorization engine) evaluate every tool call
Overview
Cryptographic governance for every Claude Code tool call. Each invocation is evaluated against a Cedar policy and produces an Ed25519-signed receipt that anyone can verify offline.
Manual install (npx, ZIP)
npx skills add wshobson/agents --skill protect-mcp-setup -g -a claude-codemkdir -p ~/.claude/skills && curl -sL https://codeload.github.com/wshobson/agents/tar.gz/4236bb91f839 \
| tar -xz -C ~/.claude/skills --strip-components=4 agents-4236bb91f839/plugins/protect-mcp/skills/protect-mcp-setupNew-Item -ItemType Directory -Force "$HOME\.claude\skills" | Out-Null; Invoke-WebRequest "https://m.agentalley.io/zip/f9ad7f16929591dc3315/protect-mcp-setup.zip" -OutFile "$env:TEMP\protect-mcp-setup.zip"; Expand-Archive "$env:TEMP\protect-mcp-setup.zip" -DestinationPath "$HOME\.claude\skills" -ForceConnects with Agent Alley MCP · agentalley.io/mcp
Files included
SKILL.md6.6 KB
Read the files here
wshobson/
Shared references3SKILL.md reads these from elsewhere in the repo. Not in the ZIP.
- evaluate.shplugins/protect-mcp/hooks/1.5 KB
- hooks.jsonplugins/protect-mcp/hooks/459 B
- sign.shplugins/protect-mcp/hooks/656 B
Show the full text215 lines
protect-mcp — Policy Enforcement + Signed Receipts
Cryptographic governance for every Claude Code tool call. Each invocation is evaluated against a Cedar policy and produces an Ed25519-signed receipt that anyone can verify offline.
Overview
Claude Code runs powerful tools: Bash, Edit, Write, WebFetch. By default
there is no audit trail, no policy enforcement, and no way to prove what was
decided after the fact. protect-mcp closes all three gaps:
- Cedar policies (AWS's open authorization engine) evaluate every tool call before execution. Cedar deny is authoritative.
- Ed25519 receipts record each decision with its inputs, the policy that governed it, and the outcome. Receipts are hash-chained.
- Offline verification via
npx @veritasacta/verify. No server, no account, no trust in the operator.
Problem
AI agents make decisions that affect money, safety, and rights. The Claude Code session log records what happened, but the log is:
- Mutable — anyone with access can edit it
- Unsigned — there is no way to prove integrity
- Operator-bound — verification requires trusting whoever holds the log
For compliance contexts (finance, healthcare, regulated research), this is not sufficient. You need tamper-evident evidence that can be verified by third parties without trusting you.
Solution
Add protect-mcp to your Claude Code project:
# 1. Install the plugin (adds hooks + skill to your project)
claude plugin install wshobson/agents/protect-mcp
# 2. Create ./protect.cedar (see below). The plugin installs the hooks.
# 3. Start the receipt-signing server (runs locally, no external calls)
npx protect-mcp@latest serve --enforce
# 4. Use Claude Code normally. Every tool call is now policy-evaluated
# and produces a signed receipt in ./receipts/
Hook Configuration
Installing the plugin adds both hooks from hooks/hooks.json. Each hook runs a
script bundled with the plugin:
{
"hooks": {
"PreToolUse": [
{
"matcher": ".*",
"hooks": [
{ "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/evaluate.sh" }
]
}
],
"PostToolUse": [
{
"matcher": ".*",
"hooks": [
{ "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/sign.sh" }
]
}
]
}
}
Claude Code passes the hook event to the command as JSON on stdin and does not
set TOOL_NAME or TOOL_INPUT variables. evaluate.sh reads tool_name and
tool_input from that payload and passes them to protect-mcp as flags; sign.sh reads
tool_name only, because the 0.7.4 signer records nothing else. Set
PROTECT_MCP_POLICY, PROTECT_MCP_RECEIPTS, and PROTECT_MCP_KEY to change the
default paths. When the policy file is missing, the PreToolUse hook prints a
warning to stderr and allows the call.
What each hook does
PreToolUse — Runs BEFORE the tool executes. Evaluates the tool call against
your Cedar policy file. If Cedar returns deny, the hook exits with code 2 and
Claude Code blocks the tool call entirely.
PostToolUse — Runs AFTER the tool completes. Signs a receipt containing the
tool name, input hash, output hash, decision, policy digest, and timestamp.
Writes the receipt to ./receipts/<timestamp>.json.
Cedar Policy File
Create ./protect.cedar at the project root:
// Allow read-only tools by default
permit (
principal,
action in [Action::"Read", Action::"Glob", Action::"Grep", Action::"WebFetch"],
resource
);
// Require explicit allow for destructive tools
permit (
principal,
action == Action::"Bash",
resource
) when {
// Allow safe commands only
context.command_pattern in ["git", "npm", "ls", "cat", "echo", "pwd", "test"]
};
// Never allow recursive deletion
forbid (
principal,
action == Action::"Bash",
resource
) when {
context.command_pattern == "rm -rf"
};
// Require confirmation for writes outside the project
forbid (
principal,
action in [Action::"Edit", Action::"Write"],
resource
) when {
context.path_starts_with != "."
};
Verification
Verify a single receipt:
npx @veritasacta/verify receipts/2026-04-15T10-30-00Z.json
# Exit 0 = valid
# Exit 1 = tampered
# Exit 2 = malformed
Verify the entire chain:
npx @veritasacta/verify receipts/*.json
Use the plugin's slash commands from within Claude Code:
/verify-receipt receipts/latest.json
/audit-chain ./receipts/ --last 20
Receipt Format
Each receipt is a JSON file with this structure:
{
"receipt_id": "rec_8f92a3b1",
"receipt_version": "1.0",
"issuer_id": "claude-code-protect-mcp",
"event_time": "2026-04-15T10:30:00.000Z",
"tool_name": "Bash",
"input_hash": "sha256:a3f8...",
"decision": "allow",
"policy_id": "autoresearch-safe",
"policy_digest": "sha256:b7e2...",
"parent_receipt_id": "rec_3d1ab7c2",
"public_key": "4437ca56815c0516...",
"signature": "4cde814b7889e987..."
}
- Ed25519 signatures (RFC 8032)
- JCS canonicalization (RFC 8785) before signing
- Hash-chained to the previous receipt via
parent_receipt_id - Offline verifiable — no network call, no vendor lookup
Why This Matters
| Before | After |
|---|---|
| "Trust me, the agent only read files" | Cryptographically provable: every Read logged and signed |
| "The log shows it happened" | The receipt proves it happened, and no one can edit it |
| "You'd have to audit our system" | Anyone can verify every receipt offline |
| "Logs might be different by now" | Ed25519 signatures lock the record at signing time |
Standards
- Ed25519 — RFC 8032 (digital signatures)
- JCS — RFC 8785 (deterministic JSON canonicalization)
- Cedar — AWS's open authorization policy language
- IETF draft — draft-farley-acta-signed-receipts
Related
- npm: protect-mcp
- Verify CLI: @veritasacta/verify
- Source: github.com/ScopeBlind/scopeblind-gateway
- Protocol: veritasacta.com
- Integrations: Microsoft Agent Governance Toolkit (PR #667), AWS cedar-policy/cedar-for-agents (PR #64)
| 1 | |
| 2 | name protect-mcp-setup |
| 3 | description Configure Cedar policy enforcement and Ed25519 signed receipts for Claude Code tool calls. Use when setting up projects that need cryptographic audit trails, policy-gated tool execution, or compliance-ready evidence of agent actions. |
| 4 | |
| 5 | |
| 6 | # protect-mcp — Policy Enforcement + Signed Receipts |
| 7 | |
| 8 | Cryptographic governance for every Claude Code tool call. Each invocation is |
| 9 | evaluated against a Cedar policy and produces an Ed25519-signed receipt that |
| 10 | anyone can verify offline. |
| 11 | |
| 12 | ## Overview |
| 13 | |
| 14 | Claude Code runs powerful tools: `Bash`, `Edit`, `Write`, `WebFetch`. By default |
| 15 | there is no audit trail, no policy enforcement, and no way to prove what was |
| 16 | decided after the fact. `protect-mcp` closes all three gaps: |
| 17 | |
| 18 | **Cedar policies** (AWS's open authorization engine) evaluate every tool call |
| 19 | before execution. Cedar deny is authoritative. |
| 20 | **Ed25519 receipts** record each decision with its inputs, the policy that |
| 21 | governed it, and the outcome. Receipts are hash-chained. |
| 22 | **Offline verification** via `npx @veritasacta/verify`. No server, no account, |
| 23 | no trust in the operator. |
| 24 | |
| 25 | ## Problem |
| 26 | |
| 27 | AI agents make decisions that affect money, safety, and rights. The Claude Code |
| 28 | session log records what happened, but the log is: |
| 29 | |
| 30 | Mutable — anyone with access can edit it |
| 31 | Unsigned — there is no way to prove integrity |
| 32 | Operator-bound — verification requires trusting whoever holds the log |
| 33 | |
| 34 | For compliance contexts (finance, healthcare, regulated research), this is not |
| 35 | sufficient. You need tamper-evident evidence that can be verified by third |
| 36 | parties without trusting you. |
| 37 | |
| 38 | ## Solution |
| 39 | |
| 40 | Add `protect-mcp` to your Claude Code project: |
| 41 | |
| 42 | |
| 43 | # 1. Install the plugin (adds hooks + skill to your project) |
| 44 | claude plugin install wshobson/agents/protect-mcp |
| 45 | |
| 46 | # 2. Create ./protect.cedar (see below). The plugin installs the hooks. |
| 47 | |
| 48 | # 3. Start the receipt-signing server (runs locally, no external calls) |
| 49 | npx protect-mcp@latest serve --enforce |
| 50 | |
| 51 | # 4. Use Claude Code normally. Every tool call is now policy-evaluated |
| 52 | # and produces a signed receipt in ./receipts/ |
| 53 | |
| 54 | |
| 55 | ## Hook Configuration |
| 56 | |
| 57 | Installing the plugin adds both hooks from `hooks/hooks.json`. Each hook runs a |
| 58 | script bundled with the plugin: |
| 59 | |
| 60 | |
| 61 | { |
| 62 | "hooks": { |
| 63 | "PreToolUse": [ |
| 64 | { |
| 65 | "matcher": ".*", |
| 66 | "hooks": [ |
| 67 | { "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/evaluate.sh" } |
| 68 | ] |
| 69 | } |
| 70 | ], |
| 71 | "PostToolUse": [ |
| 72 | { |
| 73 | "matcher": ".*", |
| 74 | "hooks": [ |
| 75 | { "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/sign.sh" } |
| 76 | ] |
| 77 | } |
| 78 | ] |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | |
| 83 | Claude Code passes the hook event to the command as JSON on stdin and does not |
| 84 | set `TOOL_NAME` or `TOOL_INPUT` variables. `evaluate.sh` reads `tool_name` and |
| 85 | `tool_input` from that payload and passes them to `protect-mcp` as flags; `sign.sh` reads |
| 86 | `tool_name` only, because the 0.7.4 signer records nothing else. Set |
| 87 | `PROTECT_MCP_POLICY`, `PROTECT_MCP_RECEIPTS`, and `PROTECT_MCP_KEY` to change the |
| 88 | default paths. When the policy file is missing, the PreToolUse hook prints a |
| 89 | warning to stderr and allows the call. |
| 90 | |
| 91 | ### What each hook does |
| 92 | |
| 93 | **PreToolUse** — Runs BEFORE the tool executes. Evaluates the tool call against |
| 94 | your Cedar policy file. If Cedar returns `deny`, the hook exits with code 2 and |
| 95 | Claude Code blocks the tool call entirely. |
| 96 | |
| 97 | **PostToolUse** — Runs AFTER the tool completes. Signs a receipt containing the |
| 98 | tool name, input hash, output hash, decision, policy digest, and timestamp. |
| 99 | Writes the receipt to `./receipts/<timestamp>.json`. |
| 100 | |
| 101 | ## Cedar Policy File |
| 102 | |
| 103 | Create `./protect.cedar` at the project root: |
| 104 | |
| 105 | |
| 106 | // Allow read-only tools by default |
| 107 | permit ( |
| 108 | principal, |
| 109 | action in [Action::"Read", Action::"Glob", Action::"Grep", Action::"WebFetch"], |
| 110 | resource |
| 111 | ); |
| 112 | |
| 113 | // Require explicit allow for destructive tools |
| 114 | permit ( |
| 115 | principal, |
| 116 | action == Action::"Bash", |
| 117 | resource |
| 118 | ) when { |
| 119 | // Allow safe commands only |
| 120 | context.command_pattern in ["git", "npm", "ls", "cat", "echo", "pwd", "test"] |
| 121 | }; |
| 122 | |
| 123 | // Never allow recursive deletion |
| 124 | forbid ( |
| 125 | principal, |
| 126 | action == Action::"Bash", |
| 127 | resource |
| 128 | ) when { |
| 129 | context.command_pattern == "rm -rf" |
| 130 | }; |
| 131 | |
| 132 | // Require confirmation for writes outside the project |
| 133 | forbid ( |
| 134 | principal, |
| 135 | action in [Action::"Edit", Action::"Write"], |
| 136 | resource |
| 137 | ) when { |
| 138 | context.path_starts_with != "." |
| 139 | }; |
| 140 | |
| 141 | |
| 142 | ## Verification |
| 143 | |
| 144 | Verify a single receipt: |
| 145 | |
| 146 | |
| 147 | npx @veritasacta/verify receipts/2026-04-15T10-30-00Z.json |
| 148 | # Exit 0 = valid |
| 149 | # Exit 1 = tampered |
| 150 | # Exit 2 = malformed |
| 151 | |
| 152 | |
| 153 | Verify the entire chain: |
| 154 | |
| 155 | |
| 156 | npx @veritasacta/verify receipts/*.json |
| 157 | |
| 158 | |
| 159 | Use the plugin's slash commands from within Claude Code: |
| 160 | |
| 161 | |
| 162 | /verify-receipt receipts/latest.json |
| 163 | /audit-chain ./receipts/ --last 20 |
| 164 | |
| 165 | |
| 166 | ## Receipt Format |
| 167 | |
| 168 | Each receipt is a JSON file with this structure: |
| 169 | |
| 170 | |
| 171 | { |
| 172 | "receipt_id": "rec_8f92a3b1", |
| 173 | "receipt_version": "1.0", |
| 174 | "issuer_id": "claude-code-protect-mcp", |
| 175 | "event_time": "2026-04-15T10:30:00.000Z", |
| 176 | "tool_name": "Bash", |
| 177 | "input_hash": "sha256:a3f8...", |
| 178 | "decision": "allow", |
| 179 | "policy_id": "autoresearch-safe", |
| 180 | "policy_digest": "sha256:b7e2...", |
| 181 | "parent_receipt_id": "rec_3d1ab7c2", |
| 182 | "public_key": "4437ca56815c0516...", |
| 183 | "signature": "4cde814b7889e987..." |
| 184 | } |
| 185 | |
| 186 | |
| 187 | **Ed25519** signatures (RFC 8032) |
| 188 | **JCS canonicalization** (RFC 8785) before signing |
| 189 | **Hash-chained** to the previous receipt via `parent_receipt_id` |
| 190 | **Offline verifiable** — no network call, no vendor lookup |
| 191 | |
| 192 | ## Why This Matters |
| 193 | |
| 194 | | Before | After | |
| 195 | |--------|-------| |
| 196 | | "Trust me, the agent only read files" | Cryptographically provable: every Read logged and signed | |
| 197 | | "The log shows it happened" | The receipt proves it happened, and no one can edit it | |
| 198 | | "You'd have to audit our system" | Anyone can verify every receipt offline | |
| 199 | | "Logs might be different by now" | Ed25519 signatures lock the record at signing time | |
| 200 | |
| 201 | ## Standards |
| 202 | |
| 203 | **Ed25519** — RFC 8032 (digital signatures) |
| 204 | **JCS** — RFC 8785 (deterministic JSON canonicalization) |
| 205 | **Cedar** — AWS's open authorization policy language |
| 206 | **IETF draft** — [draft-farley-acta-signed-receipts] |
| 207 | |
| 208 | ## Related |
| 209 | |
| 210 | **npm**: [protect-mcp] |
| 211 | **Verify CLI**: [@veritasacta/verify] |
| 212 | **Source**: [github.com/ScopeBlind/scopeblind-gateway] |
| 213 | **Protocol**: [veritasacta.com] |
| 214 | **Integrations**: Microsoft Agent Governance Toolkit (PR #667), AWS cedar-policy/cedar-for-agents (PR #64) |
| 215 |
Details
- Updated
- Sep 21, 2026
- License
- MIT
- Stars on the repo
- ★ 39,857
- Checked
- Source
- wshobson/agents ↗
- Creator
- wshobson · 179 listings
Similar skills
See all →
SkillBrowser Testing Suite
AgentEverything MCP
AgentWeb Content Fetcher
AgentFilesystem Operations
SkillLibrary Reference Tool
SkillChrome DevTools DebuggerMore from wshobson
Skill.NET Backend Developer
SkillWCAG 2.2 Implementation
SkillMaterial Design 3 & Compose
SkillAngularJS to Angular Upgrade
SkillReverse Engineering Defense
SkillApache Airflow DAG Builder