feat(mcp): add secret allowlist to limit agent access#358
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a significant security enhancement by allowing users to define an explicit allowlist for secrets accessible by AI agents through the MCP server. This prevents unintended exposure of sensitive information and streamlines the agent's environment by only providing necessary credentials, thereby reducing unnecessary authentication prompts and improving overall system security posture. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a valuable security feature by adding an allowlist for secrets exposed through the MCP server. The implementation is solid, correctly filtering secrets before they reach the server and adding helpful warnings for misconfigurations. I have one minor suggestion to improve the warning logic to avoid duplicate messages. Overall, this is a great addition.
| for name in allowlist { | ||
| if !all_secrets.contains_key(name) { | ||
| tracing::warn!( | ||
| "mcp.secrets allowlist contains '{name}' which is not a configured secret" | ||
| ); | ||
| } | ||
| } |
There was a problem hiding this comment.
The current implementation iterates through the allowlist directly. If the allowlist contains duplicate secret names that are not configured, it will produce a warning for each occurrence. To improve the user experience by avoiding duplicate warnings, consider checking each name only once. You can achieve this by converting the allowlist to a HashSet before iterating.
let allowlist_set: std::collections::HashSet<_> =
allowlist.iter().map(|s| s.as_str()).collect();
for name in allowlist_set {
if !all_secrets.contains_key(name) {
tracing::warn!(
"mcp.secrets allowlist contains '{name}' which is not a configured secret"
);
}
}
Greptile SummaryThis PR adds an optional Key changes:
All prior review concerns have been addressed: the empty-allowlist warning was added, the merge semantics are commented, unit tests cover the four Confidence Score: 4/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[fnox mcp startup] --> B[get_secrets for profile]
B --> C{mcp.secrets set?}
C -- None --> D[all secrets available]
C -- Some allowlist --> E{allowlist empty?}
E -- Yes --> F[warn: no secrets will be available]
E -- No --> G[warn: unknown entries in allowlist]
G --> H[warn: missing provider dependency secrets]
F --> I[filter_secrets: keep only allowlisted]
H --> I
D --> I
I --> J[profile_secrets passed to FnoxMcpServer]
J --> K{MCP tool called}
K -- get_secret --> L{name in profile_secrets?}
L -- No --> M[return not found]
L -- Yes --> N[resolve and return value]
K -- exec --> O[ensure_resolved: batch resolve env=true secrets]
O --> P[inject only allowlisted env=true vars into subprocess]
Last reviewed commit: 8f71f60 |
Add `mcp.secrets` config option that restricts which secrets the MCP server exposes. When set, only listed secrets are resolved and available via get_secret/exec. Unlisted secrets are never resolved, avoiding unnecessary auth prompts and reducing exposure to AI agents. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a warning when mcp.secrets is set to an empty list, since this silently disables all secrets for the MCP server. Also add a comment explaining why overlay replaces (not appends) the allowlist. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cover the security-critical filtering logic: no allowlist returns all secrets, empty allowlist returns empty, subset filtering, and unknown allowlist entries are silently ignored. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add tests verifying that overlay mcp.secrets replaces (not appends) the base allowlist, and that omitting secrets in the overlay preserves the base. Also warn at startup when an allowlisted secret's provider depends on another fnox-managed secret that is excluded from the allowlist (e.g., OP_SERVICE_ACCOUNT_TOKEN needed by 1Password but missing from mcp.secrets), which would cause silent auth failure at runtime. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
e2eacd6 to
8f71f60
Compare
Summary
mcp.secretsconfig option to restrict which secrets the MCP server exposes to AI agentsget_secret/exec; unlisted secrets are never resolved (no unnecessary auth prompts)Example:
Closes discussion #350
Test plan
mcp.secretsto a subset, verify only those are accessible viaget_secretexeconly injects allowlisted secretsmcp.secretsexposes all secrets (backward compat)🤖 Generated with Claude Code
Note
Medium Risk
Changes how the MCP server selects and resolves secrets, which can affect agent workflows and provider authentication (especially when providers require dependent env secrets). Scope is contained to MCP config parsing/merging plus startup validation and docs/schema updates.
Overview
Adds an optional
mcp.secretsallowlist to restrict which profile secrets the MCP server exposes, soget_secretandexeconly resolve/inject the listed names (default remains all secrets when omitted).On
fnox mcpstartup, it now logs warnings for empty allowlists, unknown secret names, and allowlisted secrets whose provider depends on other configured secrets not included in the allowlist. Config merging is updated so an overlaymcp.secretsreplaces the base allowlist (to avoid accidentally re-exposing secrets), with unit tests added for filtering and merge behavior; docs and the public JSON schema are updated accordingly.Written by Cursor Bugbot for commit 8f71f60. This will update automatically on new commits. Configure here.