Repository navigation
fix: isolate candidate credential handshakes - #6877
Conversation
6ffbc71 to
a03a1f1
Compare
msureshkumar88
left a comment
There was a problem hiding this comment.
blocking | tests/unit/mcpgateway/routers/test_mcp_servers_router.py:1347 | Candidate-only tests call the handler directly, bypassing FastAPI validation and @require_permission. Add a live-gateway black-box POST /v1/mcp-servers/test-handshake test for successful candidate credentials plus hidden/mismatched gateway denial.
|
920b045 to
f049eb6
Compare
|
@msureshkumar88 Added two @ja8zyjits Updated |
msureshkumar88
left a comment
There was a problem hiding this comment.
The schema descriptions are fixed, and CI passes. The previous live-gateway coverage requirement remains unresolved.
blocking | tests/unit/mcpgateway/routers/test_mcp_servers_router.py:2183 | The new TestClient tests mock authentication, permissions, and upstream calls; they do not provide the requested live-gateway coverage. | Add a black-box test against a running gateway for candidate credential success and hidden/mismatched gateway denial.
The tests mount the router on a separate FastAPI app and override get_current_user_with_permissions. The autouse fixture grants permissions through MockPermissionService. Both tests replace ResilientHttpClient with a mock. These tests exercise request validation and response serialization, but they do not verify the complete gateway authentication and upstream handshake paths. Add coverage under tests/live_gateway/ with authenticated HTTP requests and an upstream that checks candidate credentials. Verify that hidden and URL-mismatched gateway requests send no upstream probe.
1e15617 to
9d8703f
Compare
|
msureshkumar88
left a comment
There was a problem hiding this comment.
The backend changes fit #6876, and the schema descriptions are corrected. The requested live-gateway verification remains incomplete at 86f84e1aa6cbc314e1e36485c4ff9743aab79ce4.
blocking | tests/live_gateway/e2e/test_candidate_credential_handshake.py:157 | The success test fails URL policy before candidate credentials reach the upstream. | Permit the loopback stub in the isolated subprocess configuration and verify successful candidate authentication.
Edit the environment configuration near lines 154–159. Add SSRF_PROTECTION_ENABLED=false only to this isolated test subprocess. Keep the explicit localhost allowlist and production SSRF protection unchanged. SSRF_ALLOW_LOCALHOST=true alone does not bypass the resolved-loopback rejection in validate_gateway_test_url().
Edit the upstream handler near lines 97–103 to return 401 for an incorrect X-Candidate value. Strengthen assertions near lines 349–358 to check the exact candidate value and exclude stored credentials from every recorded handshake request. Verify that a valid candidate succeeds with credentialSource=form; an invalid candidate must fail even when a stored credential is valid.
blocking | tests/live_gateway/e2e/test_candidate_credential_handshake.py:398 | The hidden-gateway test returns HTTP 401 before gateway authorization, so it does not verify cross-team isolation. | Create an authenticated caller with gateways.read and a valid team-scoped token before requesting the hidden gateway.
Replace the caller setup near lines 393–404. Create a persisted team-A user, establish team-A membership, and grant a role containing gateways.read. Generate a valid token for that user with teams=[team_a_id]. The current teams=[] token names an uncreated user and does not represent team-A membership.
Before the hidden request near lines 406–422, prove that the same caller can handshake with a visible gateway. Clear the upstream recorder after that control request. Then request the team-B gateway and retain the assertions for success=false, failureClass=transport, and zero upstream requests. Do not relax authentication or permission enforcement to make the test pass.
blocking | tests/live_gateway/e2e/test_candidate_credential_handshake.py:451 | The mismatch test passes through URL-policy rejection without exercising the new exact-gateway URL comparison. | Replace the disallowed hostname with a permitted reachable URL that differs from the registered gateway URL.
Edit the setup near lines 437–445 to start two localhost upstreams on different ports and register their URLs. Replace base_url at line 451 with the second upstream URL while retaining the first gateway ID. First prove that each matching ID/URL pair succeeds. Clear both recorders, then verify that the mismatched pair fails and contacts neither upstream.
Keep this regression sensitive to the comparison in mcpgateway/services/gateway_service.py:8712: removing that comparison must make the test fail.
Validation at this head:
rtk proxy .venv/bin/python -m pytest tests/unit/mcpgateway/routers/test_mcp_servers_router.py tests/live_gateway/e2e/test_candidate_credential_handshake.py -q --tb=short -o addopts=
Result: 100 passed, 2 failed. Repeating the live module independently produces 1 passed, 2 failed. The success test reports URL-policy rejection; the hidden-gateway test reports HTTP 401. The passing mismatch test does not establish the requested URL-match denial.
e3a6004 to
dad9c48
Compare
|
@msureshkumar88 Addressed the live-gateway coverage findings in commit
Validation: |
msureshkumar88
left a comment
There was a problem hiding this comment.
All previous requested changes are implemented at dad9c483a2237814dde6dc29e8127cd02a6e9b49.
Verified commit patches and independently ran the focused unit and live-gateway modules: 102 passed.
The live tests prove valid candidate success, invalid candidate failure, authenticated cross-team denial, and exact gateway URL mismatch without upstream probes.
Focused unit coverage covers all 20 added executable production lines.
The backend fix matches #6876 and preserves existing defaults. No UI or database migration changes are required.
No blocking or functionally-impacting findings remain. Current CI has no failing checks.
Optional follow-ups: add a user-facing request example, broaden live TLS/SSE coverage, and improve internal exact-gateway denial diagnostics.
Signed-off-by: Rakhi Dutta <rakhibiswas@yahoo.com>
Signed-off-by: Rakhi Dutta <rakhibiswas@yahoo.com>
Signed-off-by: Rakhi Dutta <rakhibiswas@yahoo.com>
Signed-off-by: Jitesh Nair <jiteshnair@ibm.com>
dad9c48 to
1b45b7a
Compare
Signed-off-by: Jitesh Nair <jiteshnair@ibm.com>
Picks up four commits, including #7079 (standardize error response format) and #6877 (isolate candidate credential handshakes). One textual conflict, in .secrets.baseline, resolved from main per AGENTS.md and left for the hook to regenerate. #7079 also changed behaviour this branch asserted on, with no conflict marker to signal it. update_gateway's catch-all handler now routes through unexpected_error_detail(), which keeps project exception messages and replaces anything else with a correlation reference. The shared key validator raises a bare ValueError, so its text is now sanitized by design. The deny-path test asserted that text; it now asserts the outcome -- the update is refused, rollback runs, nothing is committed -- and records why the message is deliberately not pinned. Verified all three blocking findings still hold after the merge: a masked update cannot switch signing algorithms, a mask at create is refused, a ciphertext wrapping malformed PEM is refused, 1024-bit RSA is refused while 2048-bit passes, and empty or whitespace methods still resolve to client_secret_post. Signed-off-by: Mohan Lakshmaiah <mohan.economist@gmail.com>
Restore permission decorators for HTTP-stack checks. Add type hints to recovered live tests. Correct the temporary database description. Refs #6877 Signed-off-by: Jitesh Nair <jiteshnair@ibm.com>
* test: add HTTP-stack tests for candidate-only handshake and fix field descriptions Signed-off-by: Rakhi Dutta <rakhibiswas@yahoo.com> (cherry picked from commit 9dd5764) Signed-off-by: Jitesh Nair <jiteshnair@ibm.com> * test: add live-gateway e2e tests for candidate-only credential handshake Signed-off-by: Rakhi Dutta <rakhibiswas@yahoo.com> (cherry picked from commit 4bd2ce0) Signed-off-by: Jitesh Nair <jiteshnair@ibm.com> * test: fix handler state isolation and defensive id extraction Signed-off-by: Rakhi Dutta <rakhibiswas@yahoo.com> (cherry picked from commit 817b209) Signed-off-by: Jitesh Nair <jiteshnair@ibm.com> * test: strengthen candidate-only handshake e2e coverage Signed-off-by: Rakhi Dutta <rakhibiswas@yahoo.com> (cherry picked from commit dad9c48) Signed-off-by: Jitesh Nair <jiteshnair@ibm.com> * test: adapt restored candidate handshake fixtures Restore permission decorators for HTTP-stack checks. Add type hints to recovered live tests. Correct the temporary database description. Refs IBM#6877 Signed-off-by: Jitesh Nair <jiteshnair@ibm.com> --------- Signed-off-by: Rakhi Dutta <rakhibiswas@yahoo.com> Signed-off-by: Jitesh Nair <jiteshnair@ibm.com> Co-authored-by: Rakhi Dutta <rakhibiswas@yahoo.com>
Summary
Closes #6876