Skip to content

fix(ssl): present mTLS client cert when no custom CA is configured - #6772

Open
Meekohi wants to merge 2 commits into
IBM:mainfrom
Meekohi:fix/mtls-client-cert-without-custom-ca
Open

Meekohi wants to merge 2 commits into
IBM:mainfrom
Meekohi:fix/mtls-client-cert-without-custom-ca

Conversation

@Meekohi

@Meekohi Meekohi commented Sep 10, 2026 •

Copy link
Copy Markdown

Summary

MCP gateways omit configured mTLS client credentials when their server certificate uses system CA trust. Present client credentials without requiring a custom CA.

Reproduction Steps

Register an HTTPS MCP gateway that requires a client certificate. Configure client_cert and client_key, and leave ca_certificate unset. Registration, health checks, or tool calls fail because the upstream receives no client identity.

Closes #6771.

Root Cause

Five outbound paths create an SSL context only when a custom CA exists. They therefore ignore configured client credentials with system trust.

Fix Description

Use build_client_ssl_context() for health checks, SSE and Streamable HTTP connections, handshakes, and tool calls. Decrypt stored handshake keys, reject incomplete credential pairs, and preserve candidate-only credential isolation.

Verification

Updated against main@85dabf0be.

  • make ruff interrogate pylint passes.
  • make test: 24,544 passed, 974 skipped, and two expected failures.
  • Live regression tests and candidate credential-isolation tests pass.
  • Coverage is 98% overall. Doctests: 1,242 passed. Changed-line coverage is 100%.
  • make docker-prod-rust builds the production image successfully.
  • make test-e2e: 129 passed and 14 feature-specific cases skipped against a fresh three-replica gateway stack.
  • make detect-secrets-scan passes.

Coverage waiver: one validator-cache test-order failure occurs during coverage on this branch.
Both observed failure variants reproduce on main when schema-validator mock tests precede structured-content tests.
The affected tests pass independently, and the ordinary full suite passes.
This existing test-isolation failure remains outside this PR.

Container gate waiver: fresh isolated Compose stacks replace host-wide docker-nuke and shared-port testing-up.
The stacks use the rebuilt production images, fresh PostgreSQL volumes, Redis, nginx, and the MCP test upstream.
This preserves existing local services while exercising production gateway behavior.

GitHub Actions requires maintainer approval for the latest fork update. Reviewer approval also remains required.

@Meekohi

Meekohi commented Sep 14, 2026

Copy link
Copy Markdown
Author

Hi @a-effort — a quick process note, since this is my first PR to the repo:

  • CI hasn't run. All 13 workflows are sitting at "action required" pending first-time-contributor approval. Could someone approve the runs so reviewers can see the checks?
  • [BUG]: mTLS client certificate ignored unless a custom CA certificate is also configured #6771 hasn't picked up a priority label yet. Happy to hold until it's triaged, but flagging it because it's a silent mTLS misconfiguration (client cert is never presented unless a custom CA is also set), which I'd guess lands as a bug rather than a feature.

I'll turn review feedback around quickly. Thanks!

Also refreshed the Verification table in the description: make lint / make test / make coverage now run end to end locally (23,214 passed, 0 failed; coverage 98%; pylint 10.00 with the CI flags; branch merges cleanly into current main and passes there too).

@a-effort

Copy link
Copy Markdown
Collaborator

Thanks for contributing! 🙌
I ran the checks, added labels to #6771, and will flag this PR for review from backend folks.

Build outbound SSL contexts whenever custom trust or client credentials exist.
Apply the rule to health checks, connection helpers, handshakes, and tool calls.
Decrypt stored handshake keys and preserve candidate-only credential isolation.

Cover real TLS registration, handshakes, and MCP tool calls without gateway CA configuration.
Reject untrusted servers, missing client identities, and incomplete credential pairs.

Closes IBM#6771

Signed-off-by: Michael Holroyd <meekohi@gmail.com>
Signed-off-by: Michael Holroyd <michael.holroyd@ga-ccri.com>

{"fundingSource": "RD1191", "team": "CTO", "fshGit": "d3463a9a", "fshDocker": "sha256:62e82fe2"}
@Meekohi
Meekohi force-pushed the fix/mtls-client-cert-without-custom-ca branch from 248ebc0 to 5402f05 Compare October 22, 2026 22:02
@Meekohi

Meekohi commented Oct 22, 2026

Copy link
Copy Markdown
Author

Updated this PR to sync with the latest main branch.

Signed-off-by: Michael Holroyd <michael.holroyd@ga-ccri.com>

{"fundingSource": "RD1191", "team": "CTO", "fshGit": "d3463a9a", "fshDocker": "sha256:62e82fe2"}

This branch has not been deployed

No deployments
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.

[BUG]: mTLS client certificate ignored unless a custom CA certificate is also configured

2 participants