Repository navigation
fix(mcp): enforce read-only policy and session scope on plugin tool dispatch - #10537
Merged
Merged
Conversation
…ispatch Plugin tool calls were gated only by the flat tool allowlist and the connection binding: the read-only execution policy, and the scoped-session connection boundary that the flat tools/list enforces, both stopped at the lazy/meta surface. A read_only deployment could be bypassed through any installed plugin tool that does not declare readOnlyHint (e.g. a topic delete), and a scoped session could call and enumerate plugins whose connections are entirely out of scope. - shared ensure_plugin_tool_policy check on both call paths (dbx_<prefix>__<tool> dispatch and dbx_plugin_call): rejects undeclared writes under a read-only policy (MCP_READ_ONLY) and out-of-scope plugins (PLUGIN_OUT_OF_SCOPE), before the backend is reached - dbx_plugin_list/catalog skips scope-hidden plugins entirely (no row, no allowlist-hidden count); dbx_plugin_tools answers a scoped-out plugin with the same out-of-scope error and no tool schema - dbx_plugin_tools now answers a nonexistent plugin and an all-allowlist-hidden one identically so the meta tool cannot fingerprint installed plugin ids
Owner
|
Thanks for the contribution! Merged in 1b6b003, will be released in the next version. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The plugin-tool surface introduced by the flat/lazy meta tools is gated by the flat tool allowlist, but it skips the rest of the execution policy stack that every native
dbx_*tool enforces:annotations.readOnlyHintis displayed (tools/list) but never enforced, so a tool such asdbx_kafka__kafka_topics_deleteexecutes writes in a deployment the operator configured as read-only.DBX_MCP_SCOPE_*), the flattools/listfilters out plugins without in-scope connections, but the lazy/meta surface still lets callers enumerate every installed plugin (dbx_plugin_list,dbx_plugin_toolswith full argument schemas) and call their connection-less tools.dbx_plugin_toolsanswers "all tools hidden" differently from "plugin does not exist", which lets a client fingerprint installed plugin ids.Fix
ensure_plugin_tool_policycheck on both call paths (dbx_<prefix>__<tool>dispatch anddbx_plugin_call), before the backend is reached:read_only, reject tools the plugin does not declarereadOnlyHintwithMCP_READ_ONLY;PLUGIN_OUT_OF_SCOPE.dbx_plugin_list/catalog skip scope-hidden plugins entirely (no row, no hidden-count disclosure);dbx_plugin_toolsanswers a scoped-out plugin with the same out-of-scope error and no tool schema.dbx_plugin_toolsnow answers a nonexistent plugin and an all-allowlist-hidden one identically.Credentials stay bound to the owning plugin as before; this only closes the policy gap.
Testing
plugin_tools_enforce_read_only_policy: undeclared write rejected on both dispatch paths, backend never reached; declared read-only tool still runs.plugin_tools_enforce_session_scope: out-of-scope plugin rejected, disappears fromdbx_plugin_list/dbx_plugin_tools, in-scope plugin keeps working.plugin_tool_wildcards_match_only_the_plugin_namespace(companion PR) and the existing allowlist tests still pass; fullcargo test -p dbx-mcp --lib(186 tests) green on my fork's CI run of the equivalent branch.