• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stacklok / toolhive / 29572789470

17 Jul 2026 10:14AM UTC coverage: 68.265% (+0.04%) from 68.221%
29572789470

push

github

web-flow
Return HTTP 403 for authz-denied vMCP calls (#5827) (#5841)

Return HTTP 403 for authz-denied vMCP calls

On the vMCP Serve path a Cedar-denied direct tools/call returned HTTP
200 with JSON-RPC -32602 "tool not found" — the denied tool is filtered
out of the session's advertised set, so the call reaches the SDK as an
unknown tool. That is indistinguishable from a typo, invisible to audit
(which keys the outcome off the HTTP status), and inconsistent with the
single-server proxy path, which returns 403. The registered-but-denied
case (an argument-conditional policy) was worse still: HTTP 200 with a
tool-result error, audited as success.

Add pre-flight admission checks on the core — CheckToolCall,
CheckResourceRead, CheckPromptGet — extracted from the existing
CallTool/ReadResource/GetPrompt admission blocks into shared helpers so
the pre-check and the call path enforce one decision and cannot drift.
Wire them to the mcpcompat CallGate seam: a pre-dispatch gate maps an
admission denial to HTTP 403 plus a JSON-RPC error with code 403 and a
kind-specific message, installed only when authorization is configured.
The denial message depends only on the capability kind, never the name,
so it is not a tool-existence oracle. The three kind messages are shared
exported constants (vmcp.DenyMessage*) referenced by every emitter — the
gate, the tool-result conversion, the resources/read handler, and the
code-mode closure — so the wording cannot drift apart. Audit now records
the denial for free via the existing 403 -> denied mapping.

Code mode overrides CheckToolCall to admit execute_tool_script (the
feature flag is the grant; each inner call is still authorized), and the
rate-limit decorator deliberately does not intercept the pre-flight
checks so a denied call consumes no tokens. CallTool's own admission
check is retained as defense-in-depth.


Claude-Session: https://claude.ai/code/session_01UthZzKery5m7GBNcXYKALe

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

119 of 119 new or added lines in 8 files covered. (100.0%)

19 existing lines in 6 files now uncovered.

74154 of 108627 relevant lines covered (68.26%)

63.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.26
/pkg/transport/proxy/httpsse/http_proxy.go


Source Not Available

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc