Truststore
Refs #302.
Switch from certifi to truststore in order to enable system trust stores as our default SSL behavior. Related… https://github.com/encode/httpx/pull/3404#issuecomment-2488009481
Requires us to bump our Python requirement from 3.8 to 3.10.
Looking at PyPI stats we've currently still got fairly significant 3.9 usage.
Perhaps a smart approach here would be...
- Plan on switching from
certifitotruststorewith a release aimed at 2025-10. - At the same time as Python 3.9 becomes EOL.
- And Python 3.14 is released.
(Alternatively we could be more pushy about this with our userbase. 2025-10 seems like a long time to wait for this.)
Maybe it could be done based on python version? certifi for <3.10 and truststore for the rest?
@Secrus - Could phase it in gradually yep. Or eg... support it in Python 3.14. I really don't have enough context to know how to take a call on this one.
I would be uncomfortable dropping support for Python 3.9 before EOL, but it is worth noting there are other ecosystem packages that do this, e.g., numpy has an aggressive Python support schedule and dropped Python 3.9 support earlier this year https://github.com/numpy/numpy/pull/26222
Maybe I am missing something, but according to some experiences made with SSL module of python 3.8 on Windows, ssl.create_default_context() already loads OS level trust stores by calling SSLContext.load_default_certs(), if called without explicit cafile, capath and cadata arguments.
see: https://github.com/python/cpython/blob/39b2f82717a69dde7212bc39b673b0f55c99e6a3/Lib/ssl.py#L750
As of python 3.8 ssl module also performs host name verification by default.
So why struggle with custom cert store libraries?
@deathaxe Behavior of the stdlib ssl module is not consistent across python versions and sources on POSIX systems. For example on ubuntu, installing python through uv will have ssl bundled with webpki-roots and will not load the openssl system certificates by default.
I suggest adding Python 3.14 to the test suite as in:
- #3645