Skip to content

Add TLS support for incoming MCP server connections#8

Open
dprince wants to merge 1 commit into
openstack-lightspeed:mainfrom
dprince:tls
Open

Add TLS support for incoming MCP server connections#8
dprince wants to merge 1 commit into
openstack-lightspeed:mainfrom
dprince:tls

Conversation

@dprince
Copy link
Copy Markdown
Contributor

@dprince dprince commented May 20, 2026

Summary by CodeRabbit

  • New Features
    • Added full TLS/HTTPS configuration support for the server with certificate and private key options, including optional key passphrase protection and CA validation.
    • Server now accepts configuration for incoming TLS certificates, private keys, optional key passwords, and trusted CA certificate paths.
    • Extended allowed origins to include both HTTP and HTTPS protocols.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

📝 Walkthrough

Walkthrough

This PR enables HTTPS support for the MCP Uvicorn server. A new TLSSettings pydantic model captures certificate, key, password, and CA configuration paths. The server's allowed CORS origins are expanded to include HTTPS. The main entry point conditionally builds and passes TLS kwargs to Uvicorn when cert settings are provided. Configuration documentation is updated with sample TLS fields.

Changes

TLS Server Support

Layer / File(s) Summary
TLS Settings Contract
src/rhos_ls_mcps/settings.py
TLSSettings pydantic class defines paths for certificate, key, password, and CA certs. TransportSecuritySettings.allowed_origins default expands from ["http://*:*"] to ["http://*:*", "https://*:*"]. Main Settings model adds tls: TLSSettings field.
Server TLS Integration
src/rhos_ls_mcps/main.py
main() conditionally builds ssl_kwargs from TLS config fields and passes them to uvicorn.run() to enable HTTPS when certificate settings are present.
Configuration Documentation
config.yaml.sample
Commented-out section documents optional incoming TLS settings with placeholder certificate, key, password, and CA paths.

🎯 2 (Simple) | ⏱️ ~10 minutes

🐰 A hop, a skip, and TLS is done,
The server now speaks in encrypted fun,
With certs in hand and kwargs to pass,
Your Uvicorn's HTTPS, both secure and fast!
Configuration shown, what more can we say?
Trust flows in HTTPS's way! 🔐

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add TLS support for incoming MCP server connections' accurately and concisely summarizes the main changes across all three modified files, which collectively implement TLS configuration and HTTPS support.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@src/rhos_ls_mcps/main.py`:
- Around line 112-118: When config.tls.ssl_ca_certs is provided we currently add
it to ssl_kwargs but never set ssl_cert_reqs, so mutual TLS is not enforced;
update the block that builds ssl_kwargs (the code that reads
config.tls.ssl_certfile, ssl_keyfile, ssl_keyfile_password, ssl_ca_certs) to
also set ssl_kwargs["ssl_cert_reqs"] = ssl.CERT_REQUIRED whenever
config.tls.ssl_ca_certs is present (import ssl if not already), ensuring that
ssl_ca_certs + ssl_cert_reqs=ssl.CERT_REQUIRED are both set to enable mTLS
enforcement.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9795455a-7cd3-4ddc-aa00-469a1658b2a6

📥 Commits

Reviewing files that changed from the base of the PR and between c92b373 and 429bfed.

📒 Files selected for processing (3)
  • config.yaml.sample
  • src/rhos_ls_mcps/main.py
  • src/rhos_ls_mcps/settings.py

Comment thread src/rhos_ls_mcps/main.py
Comment on lines +112 to +118
if config.tls.ssl_certfile:
ssl_kwargs["ssl_certfile"] = config.tls.ssl_certfile
ssl_kwargs["ssl_keyfile"] = config.tls.ssl_keyfile
if config.tls.ssl_keyfile_password:
ssl_kwargs["ssl_keyfile_password"] = config.tls.ssl_keyfile_password
if config.tls.ssl_ca_certs:
ssl_kwargs["ssl_ca_certs"] = config.tls.ssl_ca_certs
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In current Uvicorn docs, does setting ssl_ca_certsalone enforce client certificate verification, or mustssl_cert_reqsalso be set (e.g.,ssl.CERT_REQUIRED)?

💡 Result:

Setting ssl_ca_certs alone does not enforce client certificate verification in current Uvicorn docs; you must also set ssl_cert_reqs (e.g., ssl.CERT_REQUIRED). Uvicorn’s settings documentation describes --ssl-cert-reqs as “Whether client certificate is required” and states the default is ssl.CERT_NONE, i.e., no client cert requirement [1]. The same documentation lists --ssl-ca-certs as the CA certificates file, but it does not say that providing CA certs changes the “required/optional/none” behavior on its own [1]. The Uvicorn CLI options ultimately map to Python’s SSLContext verify mode; ssl_cert_reqs controls ctx.verify_mode, while ssl_ca_certs is used to load trust roots for verification when verification is enabled [2]. Therefore, for mutual TLS enforcement (clients must present valid certificates), set both ssl_ca_certs and ssl_cert_reqs=ssl.CERT_REQUIRED [1][2].

Citations:


🏁 Script executed:

# Check the file exists and read the relevant section
wc -l src/rhos_ls_mcps/main.py

Repository: openstack-lightspeed/rhos-mcps

Length of output: 103


🏁 Script executed:

# Read the TLS configuration section around lines 112-118
sed -n '100,130p' src/rhos_ls_mcps/main.py | cat -n

Repository: openstack-lightspeed/rhos-mcps

Length of output: 1496


🏁 Script executed:

# Check if ssl module is imported
grep -n "^import ssl\|^from ssl" src/rhos_ls_mcps/main.py

Repository: openstack-lightspeed/rhos-mcps

Length of output: 56


🏁 Script executed:

# Check if ssl_cert_reqs is set anywhere in the file
grep -n "ssl_cert_reqs" src/rhos_ls_mcps/main.py

Repository: openstack-lightspeed/rhos-mcps

Length of output: 56


mTLS is not actually enabled when only ssl_ca_certs is provided.

At line 118, CA certs are passed to the SSL configuration, but ssl_cert_reqs is never set. Without this, client certificates are not required or verified. According to Uvicorn's SSL documentation, ssl_cert_reqs controls whether client certificates are enforced (default is ssl.CERT_NONE); providing ssl_ca_certs alone does not change this behavior. Both ssl_ca_certs and ssl_cert_reqs=ssl.CERT_REQUIRED are required for mutual TLS enforcement.

🔧 Proposed fix
+import ssl
...
     if config.tls.ssl_certfile:
         ssl_kwargs["ssl_certfile"] = config.tls.ssl_certfile
         ssl_kwargs["ssl_keyfile"] = config.tls.ssl_keyfile
         if config.tls.ssl_keyfile_password:
             ssl_kwargs["ssl_keyfile_password"] = config.tls.ssl_keyfile_password
         if config.tls.ssl_ca_certs:
             ssl_kwargs["ssl_ca_certs"] = config.tls.ssl_ca_certs
+            ssl_kwargs["ssl_cert_reqs"] = ssl.CERT_REQUIRED
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if config.tls.ssl_certfile:
ssl_kwargs["ssl_certfile"] = config.tls.ssl_certfile
ssl_kwargs["ssl_keyfile"] = config.tls.ssl_keyfile
if config.tls.ssl_keyfile_password:
ssl_kwargs["ssl_keyfile_password"] = config.tls.ssl_keyfile_password
if config.tls.ssl_ca_certs:
ssl_kwargs["ssl_ca_certs"] = config.tls.ssl_ca_certs
if config.tls.ssl_certfile:
ssl_kwargs["ssl_certfile"] = config.tls.ssl_certfile
ssl_kwargs["ssl_keyfile"] = config.tls.ssl_keyfile
if config.tls.ssl_keyfile_password:
ssl_kwargs["ssl_keyfile_password"] = config.tls.ssl_keyfile_password
if config.tls.ssl_ca_certs:
ssl_kwargs["ssl_ca_certs"] = config.tls.ssl_ca_certs
ssl_kwargs["ssl_cert_reqs"] = ssl.CERT_REQUIRED
🤖 Prompt for 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.

In `@src/rhos_ls_mcps/main.py` around lines 112 - 118, When
config.tls.ssl_ca_certs is provided we currently add it to ssl_kwargs but never
set ssl_cert_reqs, so mutual TLS is not enforced; update the block that builds
ssl_kwargs (the code that reads config.tls.ssl_certfile, ssl_keyfile,
ssl_keyfile_password, ssl_ca_certs) to also set ssl_kwargs["ssl_cert_reqs"] =
ssl.CERT_REQUIRED whenever config.tls.ssl_ca_certs is present (import ssl if not
already), ensuring that ssl_ca_certs + ssl_cert_reqs=ssl.CERT_REQUIRED are both
set to enable mTLS enforcement.

Copy link
Copy Markdown
Contributor

@lpiwowar lpiwowar May 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dprince can you please resolve this comment please? You either accept the proposal by the AI or not in such a case you have to provide an explanation (and close the comment). We follow the rule that CodeRabbit comments need to be addressed first before human review.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

@lpiwowar lpiwowar requested review from Akrog, lpiwowar and umago May 20, 2026 14:04
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.

2 participants