Skip to content

fix(mcp-client): refuse a secret variable in mcp.json - #3133

Merged
gold-silver-copper merged 3 commits into
mainfrom
fix/rig24-mcp
Nov 8, 2026
Merged

gold-silver-copper merged 3 commits into
mainfrom
fix/rig24-mcp

Conversation

@gold-silver-copper

@gold-silver-copper gold-silver-copper commented Nov 8, 2026 •

Copy link
Copy Markdown
Collaborator

fix(mcp-client): refuse a secret variable in mcp.json

Description

An mcp.json (project .rig/mcp.json or the user's) could name a rig secret, such as ${RIG_SECRET_CRYPT}, in a server's headers, env, args, command, cwd or url. rig expanded it and sent the secret to that server. A project's mcp.json comes with the checkout, so a cloned repository could ship a server that receives the secret.

Now ${VAR} and ${VAR:-default} whose VAR starts with the harness's secret prefix (rig_harness_protocol::env::SECRET_PREFIX, RIG_SECRET_) are refused by name, in any letter case (Windows reads ${rig_secret_crypt} as RIG_SECRET_CRYPT), whether or not the variable is set. The server does not start, and the error names the field and the variable:

`headers.X`: ${RIG_SECRET_CRYPT} is a secret of rig's, which no server is given

Every other variable expands as before. A lower or mixed-case rig_secret_* name, a distinct variable on Linux and macOS, is refused too.

The README's env row also said a server gets rig's environment "without rig's secrets (API keys)". Only RIG_SECRET_* and agent-only variables are removed; provider API keys from the shell do reach the server. The row now says that.

Item Verdict Test
Audit d-1: a ${RIG_SECRET_*} in mcp.json sends the secret reproduced, fixed config::tests::a_secret_variable_is_refused_by_name_and_never_expanded (fails on the test commit: the variable expands or is reported unset)
Audit d-6: README says provider keys are withheld wrong sentence, corrected docs only

Changelog

  • (mcp-client) A ${RIG_SECRET_*} in an mcp.json is refused, naming the field and the variable, in any letter case, instead of being expanded and sent to the server.

Migration

An mcp.json that named a RIG_SECRET_* variable now fails to start that server; pass the value through a variable of its own instead.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Testing

  • cargo nextest run -p rig-mcp-client a_secret_variable_is_refused_by_name_and_never_expanded: fails on the test commit, passes on the head
  • cargo xtask verify --affected --base origin/main

Checklist:

  • I have updated READMEs and Rust docs affected by this change
  • I have added tests that prove my fix is effective or that my feature works
  • I did not edit CHANGELOG.md or MIGRATING.md (they are generated at release)

Notes

  • The refusal is by name, so it holds whether or not the secret is set in the agent's process, and the test needs no environment.
  • The prefix comes from rig_harness::harness_protocol::env::SECRET_PREFIX, through the existing rig-harness dependency; no new dependency, no public API change.
  • Lines: production +10 −1 (config.rs), README +2 −2, tests +24.
  • Test changed on purpose in the second fix commit: the existing test gains a lowercase ${rig_secret_crypt:-none} case for the letter-case refusal (no new test).
  • Real use: an independent tester ran real rig against logging HTTP and stdio MCP servers on main and this PR (headers, url, env, args, command, user and project scope, /mcp add): leaked on main, refused here; ${HOME} and defaults unchanged.
  • Not verified: a run on Windows (the letter-case refusal is the same code on every platform).

@gold-silver-copper
gold-silver-copper added this pull request to the merge queue Nov 8, 2026
Merged via the queue into main with commit 330d14d Nov 8, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant