Skip to content

feat: add protect-mcp plugin — Cedar policies + signed receipts (closes #471)#484

Merged
wshobson merged 2 commits intowshobson:mainfrom
tomjwxf:feat/protect-mcp-plugin
Apr 16, 2026
Merged

feat: add protect-mcp plugin — Cedar policies + signed receipts (closes #471)#484
wshobson merged 2 commits intowshobson:mainfrom
tomjwxf:feat/protect-mcp-plugin

Conversation

@tomjwxf
Copy link
Copy Markdown
Contributor

@tomjwxf tomjwxf commented Apr 15, 2026

Summary

Closes #471.

Adds protect-mcp, the first cryptographic governance plugin in the marketplace. Every Claude Code tool call is:

  1. Evaluated against a Cedar policy before it runs (PreToolUse hook). Cedar deny → exit 2 → tool blocked.
  2. Signed with an Ed25519 key after it runs (PostToolUse hook). Receipts are hash-chained and written to ./receipts/.
  3. Verifiable offline by anyone via npx @veritasacta/verify — no network, no vendor lookup, no trust in the operator.

Directory structure matches what was requested in #471:

plugins/protect-mcp/
├── .claude-plugin/plugin.json
├── README.md
├── skills/protect-mcp-setup/SKILL.md
├── agents/policy-enforcer.md        (opus)
├── agents/receipt-verifier.md       (sonnet)
├── commands/verify-receipt.md       (/verify-receipt <path>)
├── commands/audit-chain.md          (/audit-chain [--last N])
└── hooks/hooks.json

Also adds the marketplace entry under category: security. If you'd prefer a new governance category, happy to add one in a follow-up — I defaulted to security since that category already exists.

Why this is a good fit

Test plan

  • python3 -m json.tool validates plugin.json, hooks.json, and the updated marketplace.json
  • claude plugin install wshobson/agents/protect-mcp (after merge)
  • Claude Code session with a Bash tool call + ./protect.cedar present produces a receipt file
  • npx @veritasacta/verify receipts/*.json exits 0 on the produced receipts
  • Tampering with a receipt file causes npx @veritasacta/verify to exit 1
  • /verify-receipt and /audit-chain slash commands render from within Claude Code

Notes

  • The hooks are written to fail-open on missing policy (--fail-on-missing-policy false) so installing the plugin doesn't break existing projects that haven't configured a Cedar policy yet.
  • Receipts are written to ./receipts/ by default, configurable via PROTECT_MCP_RECEIPTS.
  • The plugin's skill includes a full setup guide with example Cedar policies for research, development, and production contexts.

cc @wshobson — happy to iterate on anything here.

tomjwxf pushed a commit to tomjwxf/agency-agents that referenced this pull request Apr 15, 2026
Two new specialized agents for agent governance workflows:

specialized/receipt-auditor.md — Forensic specialist for Ed25519 signed
receipt chains. Verifies authenticity, walks hash chains, diagnoses
tampering, and explains verification failures in plain English. Reads
receipts produced by protect-mcp, Microsoft Agent Governance Toolkit,
and Cedar-enforced gateways.

specialized/cedar-policy-reviewer.md — Cedar policy specialist who
reviews authorization rules for agent tool calls, identifies
over-permissive allow rules, catches missing deny rules on dangerous
operations, and validates policies against schemas. Fluent in Cedar
for Claude Code, MCP gateways, and AGT deployments.

Both agents are designed to complement (not duplicate) the existing
Agentic Identity & Trust Architect — the Architect designs the
system, the Auditor and Reviewer are the execution-level specialists
who verify individual artifacts day-to-day.

References:
- Cedar WASM bindings merged: cedar-policy/cedar-for-agents#64
- Microsoft AGT integration merged: microsoft/agent-governance-toolkit#667
- protect-mcp plugin submitted to wshobson/agents#484
- IETF draft-farley-acta-signed-receipts
tomjwxf pushed a commit to tomjwxf/wshobson-agents that referenced this pull request Apr 15, 2026
Per review feedback on wshobson#484: introducing a new governance category for
better discoverability. This is the first governance-focused plugin in
the marketplace; existing low-count categories (testing, payments,
gaming, finance, blockchain, accessibility) show that niche categories
are acceptable once they have a clear inhabitant.

Also adds a keywords array for searchability.

No changes to plugin contents — this is a marketplace-entry-only update.
@tomjwxf
Copy link
Copy Markdown
Contributor Author

tomjwxf commented Apr 15, 2026

Thanks for the review! Addressing each point:

🟡 Governance category — done (just pushed)

Commit 0f1bb6f moves the plugin to a new `governance` category and adds a `keywords` array for discovery. Looking at existing categories in the marketplace (testing, payments, gaming, finance, blockchain, accessibility all have 1-2 plugins each), a new single-inhabitant category seems acceptable — happy to revert if you'd rather keep it in `security` until there's a second governance plugin.

🟡 Automated tests — agreed as follow-up

Good suggestion. I'll open a follow-up PR once this one lands that adds a `plugins/protect-mcp/test/` directory with:

  • A test Cedar policy + synthetic tool call that should deny → exercises the PreToolUse block path
  • A PostToolUse receipt generation + `@veritasacta/verify` round-trip → exercises the sign + verify path

Want to keep this PR focused on the plugin itself rather than changing CI scope.

🔴 Marketplace `files` array — checked, appears not required

I looked carefully before responding and I don't think this change is needed. Two data points:

  1. Anthropic's marketplace schema docs (code.claude.com/docs/en/plugin-marketplaces) list the supported plugin-entry fields: `name`, `source`, `description`, `version`, `author`, `homepage`, `repository`, `license`, `keywords`, `category`, `tags`, `strict`, and component paths (`skills`, `commands`, `agents`, `hooks`, `mcpServers`, `lspServers`). There is no documented `files` field.
  2. None of the 77 existing plugin entries in this marketplace use a `files` array:
    ```
    $ grep -c '"files":' .claude-plugin/marketplace.json
    0
    ```
    If `files` were required, all 77 would be failing to install.

The plugin installs via `source: ./plugins/protect-mcp` — relative-path source, which the docs confirm "clones the entire repository, making relative paths work correctly." I've tested with `claude plugin marketplace add ./` locally and the plugin loads without issues.

If you have an internal tooling/policy that requires a `files` array that isn't reflected in the public docs or the existing entries, I'm happy to add it — just point me at the spec and I'll update this PR immediately. But I didn't want to add a field whose semantics I couldn't confirm, since it could conflict with the existing convention.

Thanks again for keeping the review bar high on this marketplace.

Copy link
Copy Markdown
Owner

@wshobson wshobson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @tomjwxf — huge apologies for the noise on this thread. I was testing a "Hermes" agent integration that went off the rails and posted a bunch of repetitive and factually incorrect reviews under my account (including the bogus "missing files array" request-changes). I've shut that integration down and cleaned up the bad comments.

Your rebuttal was 100% correct — no entry in marketplace.json uses a files array, and it's not in the documented schema. Sorry you had to spend time refuting a hallucination.

The plugin itself looks great:

  • Structure matches #471 exactly
  • governance category addition is a nice touch, keywords help discovery
  • Standards-based design (Ed25519 / JCS / Cedar) with offline-verifiable receipts is genuinely novel for this marketplace
  • Fail-open on missing policy is the right default for backward compatibility

Approving and merging. Thanks for the thoughtful contribution and for your patience with the bot mess.

…ceipts

Addresses wshobson#471. Adds the first cryptographic governance plugin to the
marketplace: every Claude Code tool call is evaluated against a Cedar
policy before running, and every decision produces an Ed25519-signed
receipt that anyone can verify offline.

Contents of plugins/protect-mcp/:
- skills/protect-mcp-setup/SKILL.md — full setup + hook config guide
- agents/policy-enforcer.md — Cedar policy author (opus) with example
  policies for research, development, and production contexts
- agents/receipt-verifier.md — verifier/chain expert (sonnet) that
  diagnoses signature mismatches, chain breaks, and malformed receipts
- commands/verify-receipt.md — /verify-receipt <path>
- commands/audit-chain.md — /audit-chain [--last N]
- hooks/hooks.json — PreToolUse (Cedar evaluate) + PostToolUse (sign)
- README.md + plugin.json

The plugin depends on two published npm packages:
- protect-mcp (10K+ monthly downloads) — the hooks runtime
- @veritasacta/verify — offline receipt verification CLI

Receipts follow IETF draft-farley-acta-signed-receipts, use RFC 8032
Ed25519 signatures, and RFC 8785 JCS canonicalization. Cedar is AWS's
formally-verified authorization engine (the WASM bindings were
upstreamed in cedar-policy/cedar-for-agents#64).

Marketplace entry added under category "security". Category
"governance" does not exist in the marketplace today; happy to propose
one in a follow-up if the maintainer prefers.
Per review feedback on wshobson#484: introducing a new governance category for
better discoverability. This is the first governance-focused plugin in
the marketplace; existing low-count categories (testing, payments,
gaming, finance, blockchain, accessibility) show that niche categories
are acceptable once they have a clear inhabitant.

Also adds a keywords array for searchability.

No changes to plugin contents — this is a marketplace-entry-only update.
@wshobson wshobson force-pushed the feat/protect-mcp-plugin branch from 0f1bb6f to e88aa6f Compare April 16, 2026 16:59
@wshobson
Copy link
Copy Markdown
Owner

Rebased on latest main to resolve the marketplace.json conflict introduced by #480 (qa-orchestra). Conflict was purely positional — both PRs added a new entry after block-no-verify. I kept both: qa-orchestra first, then protect-mcp with the governance category and keywords array from your follow-up commit 0f1bb6f. JSON validated, no other changes. PR is now CLEAN / MERGEABLE.

@wshobson wshobson merged commit 2e04a96 into wshobson:main Apr 16, 2026
tomjwxf pushed a commit to tomjwxf/wshobson-agents that referenced this pull request Apr 17, 2026
Follow-up to wshobson#484 closing the test-plan commitment. Adds a
plugins/protect-mcp/test/ directory with:

  - Six deterministic fixtures covering PreToolUse (allow + deny paths
    on Read / Bash safe / Bash destructive / Write) and PostToolUse
    (receipt signing input)
  - A Cedar test policy exercising both permit and forbid semantics
  - An expected receipt-schema.json (JSON Schema draft-07) pinned to
    draft-farley-acta-signed-receipts required fields
  - run-tests.sh: full round-trip, requires node >= 18 and python3.
    Eight tests covering evaluate (permit/forbid exit codes), sign
    (receipt file produced), schema conformance, verify (valid + tamper
    detection).
  - verify-fixtures.sh: static fixture validation, python3 only, safe
    to run in sandboxed CI without network access.
  - README.md explaining the layout, how to run, and the exit-code
    convention (including 77 = autotools "skip" for missing tools).

The critical regression guard is test 8: flipping the `decision` field
in a signed receipt MUST invalidate the Ed25519 signature, so
`@veritasacta/verify` MUST exit 1. This locks in the tamper-detection
property that the plugin claims.

No changes to the plugin itself. No new runtime dependencies. No
changes to marketplace.json or hooks.json.
@tomjwxf
Copy link
Copy Markdown
Contributor Author

tomjwxf commented Apr 17, 2026

No worries at all @wshobson !

tomjwxf pushed a commit to tomjwxf/wshobson-agents that referenced this pull request Apr 19, 2026
Per review feedback on wshobson#484: introducing a new governance category for
better discoverability. This is the first governance-focused plugin in
the marketplace; existing low-count categories (testing, payments,
gaming, finance, blockchain, accessibility) show that niche categories
are acceptable once they have a clear inhabitant.

Also adds a keywords array for searchability.

No changes to plugin contents — this is a marketplace-entry-only update.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add protect-mcp — Ed25519 receipt signing + Cedar policy enforcement plugin

3 participants