Skip to content

v1.12.0 — MCP audit/approval + policy hardening (8 High + 3 Medium)#16

Merged
wyckit merged 1 commit into
masterfrom
fix/v1.12-mcp-policy-hardening
Jun 21, 2026
Merged

v1.12.0 — MCP audit/approval + policy hardening (8 High + 3 Medium)#16
wyckit merged 1 commit into
masterfrom
fix/v1.12-mcp-policy-hardening

Conversation

@wyckit

@wyckit wyckit commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Closes a sixth external review. Every finding verified against current master first. 245 passing + 3 env-gated skipped; 10 new tests.

High — fixed

  • MCP side effects need a durable signed auditGateAndForward (wired with an IRunArtifactStore + key provider) persists a signed TraceBundle before forwarding and fails closed if it can't (McpProxy_persists_a_signed_audit_before_forwarding).
  • MCP approvals are challenge-bound — server-issued challenge bound to {call fingerprint, tenant, expiry}; raw n1 no longer approves (McpProxy_approvals_must_be_challenge_bound_to_the_call).
  • Pinned, non-option npxConnectNpx requires name@1.2.3; rejects leading-dash + floating specs (ConnectNpx_requires_a_pinned_non_option_package). Call sites pin @modelcontextprotocol/server-filesystem@2026.1.14.
  • CI isolates the API key from npx — live-LLM test and the FS-E2E (npx) step now have disjoint environments.
  • Production auth boundaries — trusted-proxy mode requires INTENTMESH_PROXY_SECRET; legacy WEB_TOKEN no longer satisfies the prod guard (removed from quickstart).
  • /readyz probes persistence — write + atomic-move + delete in the runs dir.
  • Direct run-query row capRunQueryAction bounded by db.RowCap (A_direct_run_query_is_bounded_by_the_row_cap).
  • Per-file delete verificationpc-deletion-matches-approval: deleted set == approved refs (Verification_proves_deleted_files_match_the_approved_refs).

Medium — fixed

  • Rate-limit key trusts X-Forwarded-For only behind the trusted proxy (matching X-Proxy-Secret); else socket IP.
  • NormalizeForForward rewrites custom-mapper path args to the canonical in-root path.
  • NuGet package signing: documented residual (needs a code-signing certificate); provenance attestation + SHA256SUMS ship today.

🤖 Generated with Claude Code

…h + 3 Medium)

High:
- MCP side effects require a durable signed audit: McpProxy.GateAndForward, when
  wired with an IRunArtifactStore + key provider, persists a signed TraceBundle
  BEFORE forwarding and fails closed if it can't be written.
- MCP approvals are challenge-bound: with an ApprovalChallengeService, an approval
  is a server-issued challenge bound to {call fingerprint, tenant, expiry} — a raw
  "n1" no longer approves, and a challenge for one call can't approve another.
- ConnectNpx requires a pinned, non-option package (name@1.2.3); call sites pin
  @modelcontextprotocol/server-filesystem@2026.1.14.
- CI splits the live-LLM test (ANTHROPIC_API_KEY) from the npx FS-E2E step so the
  secret and untrusted npm execution never share an environment.
- Production auth: trusted-proxy mode requires INTENTMESH_PROXY_SECRET; legacy
  WEB_TOKEN no longer satisfies the prod auth guard (removed from quickstart).
- /readyz performs a real write + atomic-move + delete probe of the runs dir.
- Direct RunQueryAction is bounded by db.RowCap at execution.
- New pc-deletion-matches-approval postcondition: deleted files == approved refs.

Medium:
- Rate-limit key trusts X-Forwarded-For only behind the trusted proxy (matching
  X-Proxy-Secret); otherwise the socket IP — a direct client can't rotate XFF.
- NormalizeForForward rewrites custom-mapper path args to the canonical in-root path.
- NuGet package signing remains a documented residual (needs a code-signing cert).

10 new tests; 245 passing + 3 env-gated skipped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@wyckit wyckit merged commit b84ae6e into master Jun 21, 2026
2 checks passed
@wyckit wyckit deleted the fix/v1.12-mcp-policy-hardening branch June 21, 2026 18:35
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.

1 participant