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

stacklok / toolhive / 29572789470
69%

Build:
DEFAULT BRANCH: main
Ran 17 Jul 2026 10:20AM UTC
Jobs 1
Files 801
Run time 2min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

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

Coverage Regressions

Lines Coverage ∆ File
6
72.15
-1.9% pkg/runner/config.go
3
71.85
-1.11% pkg/ignore/processor.go
3
81.26
0.0% pkg/transport/proxy/httpsse/http_proxy.go
3
62.21
0.35% pkg/workloads/manager.go
2
96.05
0.0% pkg/authserver/storage/memory.go
2
82.29
-0.21% pkg/vmcp/composer/workflow_engine.go
Jobs
ID Job ID Ran Files Coverage
1 29572789470.1 17 Jul 2026 10:20AM UTC 801
68.26
GitHub Action Run
Source Files on build 29572789470
  • Tree
  • List 801
  • Changed 19
  • Source Changed 8
  • Coverage Changed 16
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #29572789470
  • 748ddd8d on github
  • Prev Build on main (#29572703451)
  • Next Build on main (#29575224164)
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