Tested demoQuality 90/100Review permissions

wshobson/agents/plugins/signed-audit-trails/skills/signed-audit-trails-recipe/SKILL.md

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.

Source repository stars
39,098
Declared platforms
1
Static risk flags
3
Last source update
2026-08-24
Source checked
2026-08-25

Decision brief

What it does: where it fits

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.

Best for

  • Regulated environments (finance, healthcare, critical infrastructure)
  • CI/CD pipelines where you want to prove that a policy gate held for
  • Multi-party collaboration where a counterparty wants to verify your

Not for

  • 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 hoo…
  • Hook command quoting. The hooks receive $TOOLNAME and $TOOLINPUT as environment variables. Keep the quoting "$TOOLINPUT" so inputs with spaces or special characters pass through intact.
Controlled single-run demoChecked 2026-08-20

What changed when the Skill was used

In this controlled same-task single run, enabling signed-audit-trails-recipe changed the output from 2916 non-whitespace characters and 15 headings to 3262 characters and 19 headings. Matches among 8 signals extracted from the pinned source changed from 1 to 1. Both actual outputs are shown; this is a structural observation, not a quality score or a universal performance claim.

Same test task

Review a flawed account-settings implementation for a small SaaS product. Prioritize concrete issues, explain impact, and provide corrected examples or decisions. The deliverable must specifically reflect this user intent: 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.

Without the Skill
Screenshot of the actual model output for signed-audit-trails-recipe without the Skill

Baseline: 2916 non-whitespace characters, 15 headings, and 47 list items.

With the Skill
Screenshot of the actual model output for signed-audit-trails-recipe with the Skill

With Skill: 3262 non-whitespace characters, 19 headings, and 35 list items.

ObservationWithout SkillWith Skill
Source-signal coverage1/8: claude1/8: claude
Output structure2916 chars · 15 headings · 47 list items · 2 code blocks3262 chars · 19 headings · 35 list items · 6 code blocks
Verification and caution signals17 verification signals · 2 risk/limitation signals13 verification signals · 3 risk/limitation signals

A prompt you can use

Use the signed-audit-trails-recipe Skill pinned at 367cb6a4a182 for my task. Follow its source-specific constraints around `signed-audit-trails-recipe`, `signed`, `audit`, `trails`, then return the finished deliverable with explicit assumptions, verification, failure conditions, and limits. Do not treat the Skill text as a factual source or claim that a single demonstration proves universal performance.

Method and limitationsExpand

Test method

  • Baseline and treatment used the same task, model (gpt-5.3-codex-low), and runner; the only planned difference was whether the complete target Skill text was injected.
  • The treatment used snapshot c4b82b0ad771190355eb8e204b1329732a18449a; the current source commit 367cb6a4a182cf7e9b0a17c9429f7411ddd9cf35 was verified against content hash 796710215d70. The baseline explicitly prohibited loading any Skill or external rule file.
  • The same deterministic script counted characters, headings, lists, code blocks, verification terms, caution terms, and source signals in both artifacts. Source signals: `signed-audit-trails-recipe`, `signed`, `audit`, `trails`, `claude`, `calls`, `gives`, `pattern`.
  • The visuals are local screenshots of the actual Markdown artifacts in a fixed 1200 × 800 evidence canvas, not recreated product mockups. Raw JSON artifacts and request records are retained in the research directory.

Do not over-read this demo

  • This is one controlled demonstration per condition, not a multi-run statistical benchmark; the model is stochastic.
  • Character, structure, and keyword counts show observable differences but cannot by themselves prove correctness, originality, or business impact.
  • The task is a representative test designed for repeatability, not every real-world use of the Skill; rerun after a material source change.
Editorial review
SkillSignal editorial
Runner
Cursor Agent 2026.07.09-a3815c0
Model
gpt-5.3-codex-low
Refresh due
2026-11-18
Reviewed commit
367cb6a4a182cf7e9b0a17c9429f7411ddd9cf35
Test snapshot
c4b82b0ad771190355eb8e204b1329732a18449a

Compatibility matrix

Platform support, with evidence labels

PlatformStatusEvidenceWhat to check
CodexNot declaredNo explicit evidencePortability before use
Claude CodeDeclaredSource recordInstall path and trigger
CursorNot declaredNo explicit evidencePortability before use
Gemini CLINot declaredNo explicit evidencePortability before use
Open the compatibility checker

Installation

Inspect first. Install second.

The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

Source-detected install commandSource
npx skills add https://github.com/wshobson/agents --skill "plugins/signed-audit-trails/skills/signed-audit-trails-recipe"
Safe inspection promptEditorial

Inspect the Agent Skill "signed-audit-trails-recipe" from https://github.com/wshobson/agents/blob/d82998e7df393c671ede2387a8435075f0b633f5/plugins/signed-audit-trails/skills/signed-audit-trails-recipe/SKILL.md at commit d82998e7df393c671ede2387a8435075f0b633f5. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

Workflow

What the source asks the agent to do

  1. 01

    Step 1: Install the hook configuration

    Create .claude/settings.json in your project root:

    Create .claude/settings.json in your project root: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 publickey field); do not commit the private key.Add the private key and receipt directory to .gitignore:
  2. 02

    Step 2: Write a Cedar policy

    Cedar forbid rules take precedence over permit rules, so destructive commands cannot be bypassed by a later permissive rule.

    Read-oriented tools always allowedBash allowed for safe command patterns (git, npm, etc.)Bash rm -rf and similar destructive commands explicitly denied
  3. 03

    Step 3: Use Claude Code normally

    Start Claude Code. Every tool call goes through both hooks:

    Start Claude Code. Every tool call goes through both hooks:A session of 20 tool calls produces 20 receipts, each hash-chained to its predecessor.
  4. 04

    Step 4: Inspect a receipt

    Every field except signature and publickey is covered by the Ed25519 signature. Modifying any field after signing invalidates the signature.

    Every field except signature and publickey is covered by the Ed25519 signature. Modifying any field after signing invalidates the signature.
  5. 05

    Step 5: Verify the receipt chain

    Review the “Step 5: Verify the receipt chain” section in the pinned source before continuing.

    Review and apply the “Step 5: Verify the receipt chain” source section.

Permission review

Static risk signals and limitations

Runs scripts

medium · line 173

The documentation asks the agent to run terminal commands or scripts.

npx @veritasacta/verify ./receipts/*.json

Runs scripts

medium · line 189

The documentation asks the agent to run terminal commands or scripts.

python3 -c "

Network access

medium · line 291

The documentation includes network, browsing, or remote request actions.

"predicateType": "https://veritasacta.com/attestation/decision-receipt/v0.1",

Writes files

medium · line 307

The documentation asks the agent to create, modify, or delete local files.

accidentally committed, rotate immediately (delete the key file and let the

Evidence record

Why each signal appears

EvidenceSourceComputedTestedEditorial
SignalValueEvidence typeMeaning
Quality score90/100ComputedDocumentation, specificity, maintenance, and trust rules
Repository stars39,098SourceRepository attention, not individual Skill quality
Compatibility1 platformsSourceDeclared in the catalog source record
Usage guidetested outcome pageTestedGenerated or reviewed according to the visible evidence level

Pinned source

Provenance and original SKILL.md

Repository
wshobson/agents
Skill path
plugins/signed-audit-trails/skills/signed-audit-trails-recipe/SKILL.md
Commit
d82998e7df393c671ede2387a8435075f0b633f5
License
MIT
Collected
2026-08-25
Default branch
main
View the original SKILL.md

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:

  1. Evaluated against a Cedar policy before execution. If the policy denies the call, the tool does not run.
  2. Signed as an Ed25519 receipt after execution. Receipts are JCS-canonical, hash-chained, and verifiable offline by anyone with the public key.

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.

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

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"
        }
      }
    ],
    "PostToolUse": [
      {
        "matcher": ".*",
        "hook": {
          "type": "command",
          "command": "npx protect-mcp@latest sign --tool \"$TOOL_NAME\" --input \"$TOOL_INPUT\" --output \"$TOOL_OUTPUT\" --receipts ./receipts/ --key ./protect-mcp.key"
        }
      }
    ]
  }
}

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/" >> .gitignore

Step 2: Write a Cedar policy

Create ./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"]
};

// Restrict writes to the project directory.
permit (
    principal,
    action in [Action::"Write", Action::"Edit"],
    resource
) when {
    context.path_starts_with == "./"
};

Four rules:

  • Read-oriented tools always allowed
  • Bash allowed for safe command patterns (git, npm, etc.)
  • Bash rm -rf and similar destructive commands explicitly denied
  • Writes allowed only within the project (./ prefix)

Cedar forbid rules take precedence over permit rules, so destructive commands cannot be bypassed by a later permissive rule.

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 produces 20 receipts, each hash-chained to its predecessor.

Step 4: Inspect a receipt

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": "protect.cedar",
  "policy_digest": "sha256:b7e2f4a6c8d0e1f3...",
  "parent_receipt_id": "rcpt-3d1ab7c2",
  "public_key": "4437ca56815c0516...",
  "signature": "4cde814b7889e987..."
}

Every field except signature and public_key is covered by the Ed25519 signature. Modifying any field after signing invalidates the signature.

Step 5: Verify the receipt chain

npx @veritasacta/verify ./receipts/*.json

Exit codes:

CodeMeaning
0All receipts verified; chain intact
1A receipt failed signature verification (tampered, or wrong key)
2A receipt was malformed

Step 6: Demonstrate tamper detection

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/*.json

The 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.

How the cryptography works

Three invariants make receipts verifiable offline across any conformant implementation:

  1. JCS canonicalization (RFC 8785) before signing. Keys sorted, whitespace minimized, strings NFC-normalized. Two independent implementations produce byte-identical signing payloads for the same receipt content.
  2. Ed25519 signatures (RFC 8032) over the canonical bytes. Deterministic, fixed-size, no nonce dependency.
  3. Hash chain linkage. Each receipt's 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.

Cross-implementation interop

The receipt format has four independent implementations today:

ImplementationLanguageUse case
protect-mcpTypeScriptClaude Code, Cursor, MCP hosts
protect-mcp-adkPythonGoogle Agent Development Kit
sb-runtimeRustOS-level sandbox (Landlock + seccomp)
APS governance hookPythonCrewAI, 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

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: '20' }
      - name: Run governed agent
        run: python scripts/run_agent.py > receipts.jsonl
      - name: Verify receipt chain
        run: npx @veritasacta/verify receipts.jsonl

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/

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 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.

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

Frequently asked questions

What to verify before installation and use

What does the signed-audit-trails-recipe source document cover?

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.

How do I install signed-audit-trails-recipe?

The source record exposes this install command: npx skills add https://github.com/wshobson/agents --skill "plugins/signed-audit-trails/skills/signed-audit-trails-recipe". Inspect the command and pinned source before running it.

Which Agent platforms does the source record declare?

The pinned source record declares support for: claude code.

Which permission-related actions were detected?

Static rules flagged exec-script, network, write-files in the source; the page lists the matching lines and excerpts.

Alternatives

Compare before choosing

Computed 100147

oaustegard/claude-skills

featuring

Generate hierarchical _FEATURES.md files that describe what a codebase DOES from a user/consumer perspective, anchored to source symbols via tree-sitting. Supports large complex codebases through feature-driven decomposition into sub-feature files. Uses a multi-pass synthesis: orientation → detail → overview rewrite. Use when someone says "what does this do", "document features", "feature inventory", "_FEATURES.md", or needs to understand a codebase's purpose before modifying it. Complements tre

Computed 100106

apollographql/skills

skill-creator

Guide for creating effective skills for Apollo GraphQL and GraphQL development. Use this skill when: (1) users want to create a new skill, (2) users want to update an existing skill, (3) users ask about skill structure or best practices, (4) users need help writing SKILL.md files.

Computed 10062

terrylica/cc-skills

draft-park

Park a draft message/text in macOS Notes for the operator to review and edit, then read it back before acting (e.g. before sending to a real person). Notes is the source of truth (AppleScript CRUD, iCloud-synced, provenance-stamped with the Claude Code session UUID); Stickies is a best-effort view-only desktop mirror. Use whenever you draft something a human should confirm/edit before it is sent or committed — messages, replies, announcements, anything outbound. TRIGGERS - park this draft, park

Computed 1008

narrative-io/narrative-skills-marketplace

design-analysis

Translate a fuzzy analytical question into a rigorous investigation plan. Interrogates the ask, grounds the plan in the available data dictionary, applies analytical best practices, and produces a structured brief of query specifications for a downstream query-writing skill. Plans, does not write SQL. Use when: "why did X drop", "is there a relationship between A and B", "who are our highest-value customers", "what's driving the change in Y", "investigate this trend", "design an analysis for", "