fix: Bind inherited MCP credentials to configured REST origin#3499
fix: Bind inherited MCP credentials to configured REST origin#3499kfelternv wants to merge 3 commits into
Conversation
Signed-off-by: Kyle Felter <kfelter@nvidia.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
Summary by CodeRabbit
WalkthroughThe MCP server now validates per-call destinations against a trusted configured base URL, restricts inherited credential forwarding, applies explicit token precedence, and blocks cross-origin redirects while allowing same-origin redirects. CLI, Helm, Makefile, README, and tests document and validate these rules. ChangesMCP destination and credential policy
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant MCPClient
participant MCPToolHandler
participant HTTPClient
participant NICoREST
MCPClient->>MCPToolHandler: call tool with config and credentials
MCPToolHandler->>MCPToolHandler: resolve destination and token precedence
MCPToolHandler->>HTTPClient: send approved REST request
HTTPClient->>NICoREST: request trusted destination
NICoREST-->>HTTPClient: response or redirect
HTTPClient->>HTTPClient: allow only same-origin redirects
HTTPClient-->>MCPToolHandler: return REST response or error
MCPToolHandler-->>MCPClient: return tool result
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
🔍 Container Scan Summary
Per-CVE detail lives in the per-service |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@rest-api/cli/README.md`:
- Around line 387-391: Clarify the README description of unpinned per-call
destinations: when no --base-url is configured, a per-call base_url may proceed
without credentials or with an explicit per-call token. State that only
inherited credentials—the inbound Authorization header or server default
token—are rejected rather than forwarded.
In `@rest-api/mcp/internal/server/config.go`:
- Around line 77-109: Update resolvedConfig.FromCallConfig to canonicalize the
parsed configuredBaseURL and callBaseURL components before comparing them,
including scheme and host casing while preserving path and other relevant URL
components. Use the canonical comparison for the mismatch check, while retaining
the existing normalized values for assignment and validation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 5133d5a2-7f69-41fe-a173-6d226a475951
📒 Files selected for processing (11)
helm/rest/nico-mcp/values.yamlrest-api/Makefilerest-api/cli/README.mdrest-api/cli/pkg/mcp.gorest-api/mcp/cmd/nico-mcp/main.gorest-api/mcp/internal/server/config.gorest-api/mcp/internal/server/config_test.gorest-api/mcp/internal/server/schema.gorest-api/mcp/internal/server/server.gorest-api/mcp/internal/server/server_test.gorest-api/mcp/internal/server/transport_test.go
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@rest-api/mcp/internal/server/util.go`:
- Around line 31-45: The sameBaseURL function currently compares serialized
URLs, so equivalent default-port destinations are rejected. Update sameBaseURL
to reuse sameOrigin’s origin comparison and effectivePort handling, then
separately compare the parsed base-path components while preserving invalid-URL
rejection.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: b8f098c1-3808-40bb-a141-284f2a031730
📒 Files selected for processing (4)
rest-api/cli/README.mdrest-api/mcp/internal/server/config.gorest-api/mcp/internal/server/config_test.gorest-api/mcp/internal/server/util.go
🚧 Files skipped from review as they are similar to previous changes (3)
- rest-api/mcp/internal/server/config_test.go
- rest-api/mcp/internal/server/config.go
- rest-api/cli/README.md
🔐 TruffleHog Secret Scan✅ No secrets or credentials found! Your code has been scanned for 700+ types of secrets and credentials. All clear! 🎉 🕐 Last updated: 2026-07-14 22:17:33 UTC | Commit: 9ef8b43 |
What this PR does
Pins inherited MCP credentials to the REST origin configured when
nico-mcpstarts.base_urlmust match the configured REST origin when one is set.How we verified it
Revision:
b45d6b3b1e3c6446a9cc8f54ba24ff01677450aaEnvironment: macOS 26.5.1 on arm64 with Go 1.26.4. The standalone
nico-mcpbinary was built from both the PR revision and base revision536bb264fa599d4085da8fdb66de27c953c08bd4, then exercised over real localhost HTTP connections with sentinel credentials.Hands-on verification:
Authorization: Bearer inherited-baseline-sentinel.refusing to forward inherited credentials to a per-call base_url; the receiving service observed no request.token: explicit-head-sentinelsucceeded, and the receiving service observed only that explicit token.configured-inherited-sentinelto the matching origin.per-call base_url does not match the configured server base URLbefore any connection to that origin.baseline-redirect-sentinel. The PR binary returnedrefusing cross-origin redirect; the redirect destination observed no request from the PR binary.Supporting checks:
go test ./mcp/... -count=1 go vet ./mcp/... git diff --check 536bb264fa599d4085da8fdb66de27c953c08bd4..b45d6b3b1e3c6446a9cc8f54ba24ff01677450aaAll three commands passed.
How to reproduce the verification
Prerequisites: Go 1.26.4 or newer, Python 3, and
curl.nico-mcpwithout a configured REST origin:Expected result: the MCP response contains
refusing to forward inherited credentials to a per-call base_url, and terminal A prints no new request.Expected result: the MCP result contains
[], and terminal A prints/v2/org/test-org/nico/site?pageNumber=1 Bearer explicit-sentinel.Call it without a per-call origin:
Expected result: the MCP result contains
[], and terminal A prints/v2/org/test-org/nico/site?pageNumber=1 Bearer configured-origin-sentinel.Now supply a different origin:
Expected result: the response contains
per-call base_url does not match the configured server base URL; no connection to port 19081 is attempted.