fix: stamp virtual key tool allowlist when include-clients filter bypasses autoInjectDisabled - #4297
Conversation
|
|
|
Caution Review failedPull request was closed or merged during review No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughTwo pre-request hook functions record whether include-tools were caller-provided and update the auto-injection gate so include-clients filters can trigger stamping of ChangesMCP Include-Tools Auto-Injection Logic
Sequence Diagram(s)sequenceDiagram
participant Client
participant GovernancePlugin
participant Context
Client->>GovernancePlugin: send request (with/without include-tools)
GovernancePlugin->>GovernancePlugin: prune include-tools -> set includeToolsProvided
GovernancePlugin->>Context: read disableAutoToolInject
GovernancePlugin->>Context: read MCPContextKeyIncludeClients
GovernancePlugin->>Context: stamp MCPContextKeyIncludeTools (if !includeToolsProvided && (autoInjectAllowed || includeClientsPresent))
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.12.2)level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies" Comment |
Confidence Score: 5/5Safe to merge — the change is a minimal two-line guard fix applied consistently in both code paths that call The compound condition No files require special attention. Important Files Changed
Reviews (3): Last reviewed commit: "fix: mcp allowed clients governance fixe..." | Re-trigger Greptile |
|
Re P1 (empty slice bypasses the allowlist stamp): This is based on a misreading of the guard. computeMCPIncludeTools initializes its result with make([]string, 0) and only appends — it never returns nil. A non-nil empty slice satisfies tools != nil, so the zero-grant case is stamped onto MCPContextKeyIncludeTools, and downstream shouldSkipToolForRequest treats an empty list as deny-all (len == 0 → every tool skipped). The scenario described (zero-grant VK + include-clients + disableAutoToolInject=true) injects zero tools, not all of them. This is covered by TestPreRequestHookMCP_NoGrants_IncludeClients_StampsDenyAll, which asserts the stamped value is a non-nil empty list on exactly this path. The suggested remediation ("stamp on an empty return value too") is what the code already does. Re P2 (missing test coverage): Covered in prerequesthookmcp_test.go. Both requested cases exist — TestPreRequestHookMCP_AutoInjectOff_IncludeClientsOnly_StampsGrant (a) and TestPreRequestHookMCP_AutoInjectOff_NoFilters_StampsNothing (b) — plus the same pair for the large-payload runPreRequestRouting site and the full include-tools × include-clients × toggle matrix for both call sites. |
|
You're right on both counts, and I appreciate the thorough walkthrough. P1: The nil-vs-empty-slice distinction is the crux, and I got it wrong. Since P2: I'll take your word on the test coverage — naming specific test functions ( Both original comments were incorrect. The implementation and test coverage are solid — happy to see this merge. |
9c77480 to
1ee84a3
Compare
21ace8c to
25f7aaa
Compare
Merge activity
|
25f7aaa to
7099ba4
Compare
…ypasses `autoInjectDisabled` (#4297) ## Summary When a request includes an `include-clients` filter, `ParseAndAddToolsToRequest` in `core/mcp` opts the request into tool injection even if auto-injection is globally disabled. Previously, the virtual key's tool allowlist was only stamped onto the context when auto-injection was enabled, meaning requests that bypassed the auto-injection gate via `include-clients` could run without the key's tool restrictions applied. ## Changes - Renamed `callerProvided` to `includeToolsProvided` in both `runPreRequestRouting` and `PreRequestHook` for clarity. - Added a check for `MCPContextKeyIncludeClients` in the context. When this key is present, the virtual key's tool allowlist (`computeMCPIncludeTools`) is stamped onto the context regardless of whether auto-injection is disabled, ensuring the key's grants are enforced on every code path where injection can occur. ## Type of change - [x] Bug fix - [ ] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [ ] Providers/Integrations - [x] Plugins - [ ] UI (React) - [ ] Docs ## How to test Send a request with an `include-clients` filter set and `disableAutoToolInject` enabled on the governance plugin. Verify that the virtual key's tool allowlist is applied and that tools outside the key's grant are not injected. ```sh go test ./plugins/governance/... ``` ## Breaking changes - [ ] Yes - [x] No ## Security considerations This fix closes a gap where a caller could use an `include-clients` filter to trigger tool injection while bypassing the virtual key's tool allowlist. The key's grants are now enforced on all injection paths, preventing potential privilege escalation through MCP tool access. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed tool injection so filters that request client-specific tools still trigger tool availability even when automatic injection is disabled. * Ensured previous pruning/default behavior remains unchanged while correctly honoring explicit client-filter requests for tool inclusion. <!-- end of auto-generated comment: release notes by coderabbit.ai -->

Summary
When a request includes an
include-clientsfilter,ParseAndAddToolsToRequestincore/mcpopts the request into tool injection even if auto-injection is globally disabled. Previously, the virtual key's tool allowlist was only stamped onto the context when auto-injection was enabled, meaning requests that bypassed the auto-injection gate viainclude-clientscould run without the key's tool restrictions applied.Changes
callerProvidedtoincludeToolsProvidedin bothrunPreRequestRoutingandPreRequestHookfor clarity.MCPContextKeyIncludeClientsin the context. When this key is present, the virtual key's tool allowlist (computeMCPIncludeTools) is stamped onto the context regardless of whether auto-injection is disabled, ensuring the key's grants are enforced on every code path where injection can occur.Type of change
Affected areas
How to test
Send a request with an
include-clientsfilter set anddisableAutoToolInjectenabled on the governance plugin. Verify that the virtual key's tool allowlist is applied and that tools outside the key's grant are not injected.go test ./plugins/governance/...Breaking changes
Security considerations
This fix closes a gap where a caller could use an
include-clientsfilter to trigger tool injection while bypassing the virtual key's tool allowlist. The key's grants are now enforced on all injection paths, preventing potential privilege escalation through MCP tool access.Checklist
docs/contributing/README.mdand followed the guidelinesSummary by CodeRabbit