Skip to content

fix(mcp): the path audit finds path options by type and by name #3480

Closed

Description

@dan-petty

Problem

The audit of MCP path parameters finds a parameter by words in its name. PR #3467 added this audit for #3300. _path_parameters in tests/ai/mcp/test_path_confinement.py:41 filters by _PATH_PARAM_KEYWORDS (src/devops_cli/core/paths.py:106): path, file, dir, dest, target, filename, filepath, uri. So a published option that holds a path under another name passes the audit with no decision. A new tool with such an option also passes.

Census at origin/main 46cf288: for each row of CONST_MCP_EXPOSURE_TABLE, a read-only script compares the params of resolve_click_command with the published schema, PATH_CONFINEMENTS and NOT_A_FILE_PATH. 10 published Path parameters have no decision:

  • ai_harness_offload.repo, ai_read.repo
  • docker_sandbox.workspace, sandbox_deploy.workspace
  • k8s_diff_helm.values
  • review_export_feedback.output, tf_plan.out
  • roadmap_refine.source
  • scan_injection.sarif, scan_injection.suppress

scan_sast.config also has no decision. Its type is a string (src/devops_cli/commands/scan.py:380), and its help says "a local path, or a registry id".

docker_sandbox.workspace and sandbox_deploy.workspace do have a check. _check_sandbox_preconditions (src/devops_cli/ai/mcp/generator.py:341) runs validate_sandbox_workspace. That check refuses listed roots, sockets and traversal, but it does not confine a path to the work tree.

The risk is limited, so this is defense in depth. _JOB_ROLE_TOOLS holds none of these tools, and the ops role is never served over the network (src/devops_cli/ai/mcp/roles.py). The evaluation ran no exploit.

Expected

  • The audit reads the type of each parameter in the test, as well as its name. A Path option under any name needs a decision.
  • Each parameter above is confined, dropped from the schema, or exempt with a reason. The decision for each workspace says whether validate_sandbox_workspace is enough.
  • scan_sast.config has a named decision in a table, because a type check cannot find a string.
  • The change does not widen _PATH_PARAM_KEYWORDS without a check of validate_path_parameter (core/paths.py:158), which reads the same list at runtime through src/devops_cli/ai/agents/context.py:18.

The type at this version is typer.models.TyperPath, and isinstance(param.type, click.Path) is False.

tf_plan, review_export_feedback and scan_injection have read_only True in the exposure table, and their out, output and sarif options write a file. That is the defect class of #3235. This item does not change the flag unless #3235 is folded in.

Acceptance criteria

  • A test: the audit fails on a fixture tool with a Path option under a name with no keyword and no decision.
  • A test: the audit passes on the published catalogue, and each of the 10 parameters above has a decision or is not published.
  • A test holds the decision for scan_sast.config.
  • A test: for each parameter that this change confines, a traversal value is refused before a command runs.
  • The tests that refuse a stale table entry still pass, and they accept each new entry.
  • validate_path_parameter gives the same result for the present keyword names.

Existing tool considered

The parameter types through resolve_click_command. safe_resolve_subpath and confine_tool_paths for a confined value. validate_sandbox_workspace for a sandbox mount. The change adds no library.

Related

Related: #3300, #3236, #3235

Activity

  1. added
    type/bugDefect, regression, or incorrect runtime behavior
    scope/mcpModel Context Protocol tools, system resources, and prompts
    status/newStatus New: the item is not ready yet
    on Nov 4, 2026
  2. dan-petty commented on Nov 4, 2026

    @dan-petty
    OwnerAuthor

    Intake placed this item to the backlog: intake puts every new item in the backlog. A person plans the milestones.

    • Type: type/bug. The fix prefix of the title gives the type.
    • Scope: scope/mcp. The (mcp) scope of the title gives the scope.
    • Priority: P2-Medium. The candidate states the risk is limited and this is defense in depth, but 10 published parameters have no path decision.
    • Value: Medium. Closes a gap where 10 published Path parameters bypass the audit, but the tools are not served over the network.
    • Effort: Medium. Requires changing the audit to read parameter types, adding decisions for 10 parameters, handling the string-typed scan_sast.config, and writing multiple new tests.
    • Related: fix(mcp): the ops role publishes 60 tools with unconfined path parameters #3300, which asks for a different change. Both items work on the MCP path parameter audit; #3300 delivered the name-based audit, this candidate fixes the audit to also detect by parameter type.
  3. added
    priority/p2-mediumStandard priority feature work and architectural improvements
    on Nov 4, 2026
  4. added
    status/in-progressActively being designed or implemented by developer or agent
    status/in-reviewPull request open and undergoing multi-persona review or CI gates
    and removed
    status/newStatus New: the item is not ready yet
    status/in-progressActively being designed or implemented by developer or agent
    on Nov 5, 2026
  5. removed
    status/in-reviewPull request open and undergoing multi-persona review or CI gates
    on Nov 5, 2026
  6. devops-cli-service commented on Nov 5, 2026

    @devops-cli-service
    Contributor
  7. devops-cli-service commented on Nov 5, 2026

    @devops-cli-service
    Contributor

    Live since 2026-11-05 20:49 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    effort/mediumEffort Mediumpriority/p2-mediumStandard priority feature work and architectural improvementsscope/mcpModel Context Protocol tools, system resources, and promptssource/agentFiled by an agenttype/bugDefect, regression, or incorrect runtime behaviorvalue/mediumValue Medium

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions