PYTHON-5930 Fix SSL_CERT_FILE/SSL_CERT_DIR trust store handling - #2965
Open
blink1073 wants to merge 14 commits into
Open
PYTHON-5930 Fix SSL_CERT_FILE/SSL_CERT_DIR trust store handling#2965blink1073 wants to merge 14 commits into
blink1073 wants to merge 14 commits into
Conversation
Honor SSL_CERT_FILE/SSL_CERT_DIR as the exclusive trust source across platforms instead of merging them with the OS/certifi certificate store.
…+PyOpenSSL Only bypass load_default_certs() where it actually merges an OS/certifi store (win32, and darwin with PyOpenSSL). Everywhere else, load_default_certs() already honors these env vars correctly, including falling back to the platform default for whichever of the two is left unset -- calling load_verify_locations() unconditionally dropped that fallback, silently narrowing the trust store e.g. on Linux when only one var was set. Adds regression tests covering both branches.
…g host create_pyopenssl_variants() never passed host=host to create_variant(), unlike create_encryption_variants(). The win64 case worked by accident via create_variant()'s display-name-based win64 special case, but pyopenssl-macos silently fell back to the rhel87-small default and never actually ran on macOS, so it couldn't validate macOS-specific PyOpenSSL behavior.
Addresses review feedback: the darwin+PyOpenSSL bypass path had no direct test coverage, only the win32 bypass and the non-Windows fallback were exercised.
Co-authored-by: Noah Stapp <noah@noahstapp.com>
Addresses review feedback: rename the Linux fallback test to name the platform it actually covers, and drop the redundant macOS+PyOpenSSL mention from the Windows test's comment since a dedicated test now covers that case.
Addresses review feedback: the tests in TestClientSSL are pure unit tests (mocked or manual asyncio.run()) with no dependency on the async/sync test class machinery, so they were needlessly duplicated by synchro. Moved them to test/test_ssl_support.py, following the existing test_pyopenssl_context.py precedent for standalone test files that aren't generated/mirrored.
Co-authored-by: Noah Stapp <noah@noahstapp.com>
… file" This reverts commit 9e55d86.
The three new SSL_CERT_FILE/SSL_CERT_DIR regression tests are pure unit tests with no async/sync variants, so mirroring them via synchro adds duplicated code. Move just those tests to a new non-mirrored test/test_ssl_support.py, following the test_pyopenssl_context.py precedent. The rest of TestClientSSL is left in place; refactoring the existing suite is follow-up work.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes TLS trust store selection when SSL_CERT_FILE and/or SSL_CERT_DIR are set, ensuring they replace (rather than get merged with) the OS/certifi trust store on Windows and on macOS when using PyOpenSSL. It also corrects an Evergreen variant configuration so the macOS+PyOpenSSL path is actually exercised in CI.
Changes:
- Update
get_ssl_context()to bypassload_default_certs()on Windows and macOS+PyOpenSSL whenSSL_CERT_FILE/SSL_CERT_DIRare present, and instead load only the env-provided trust roots. - Add unit regression tests covering the platform/backend-specific behavior.
- Fix Evergreen variant generation so
pyopenssl-macosruns onmacos-14, and update the generated variants config accordingly.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
test/test_ssl_support.py |
Adds targeted unit tests validating env var trust store replacement vs default cert loading across platforms/backends. |
pymongo/ssl_support.py |
Implements the conditional bypass of load_default_certs() when it would incorrectly merge OS/certifi trust roots. |
doc/changelog.rst |
Documents the bug fix for Windows and macOS+PyOpenSSL trust store handling. |
.evergreen/scripts/generate_config.py |
Ensures the PyOpenSSL macOS variant passes host=host so it schedules on macOS. |
.evergreen/generated_configs/variants.yml |
Updates the generated variant to run on macos-14 (reflecting the generator fix). |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Member
Author
|
Failures are pre-existing ECS and backoff timing flakes. |
blink1073
marked this pull request as ready for review
July 29, 2026 13:31
|
Assigned |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PYTHON-5930
Replaces #2925, which GitHub auto-closed when
masterwas deleted during the rename tomain. Prior review history is there.Changes in this PR
Fixes
SSL_CERT_FILE/SSL_CERT_DIRbeing merged with the OS/certifi certificate store instead of replacing it, on Windows and on macOS with PyOpenSSL. Other platforms already behave correctly and are unaffected.Also fixes an Evergreen config bug found while validating this: the
pyopenssl-macosvariant was never running on macOS, so this fix could not otherwise have been verified in CI.Test Plan
Added regression tests in a new
test/test_ssl_support.py.just typingandjust lintpass. Passing patch build withtest-win64,pyopenssl-win64, andpyopenssl-macos.Checklist
Checklist for Author
test_ssl_support.py).Checklist for Reviewer