Skip to content

Honor SSL_CERT_FILE and REQUESTS_CA_BUNDLE for TLS verification - #1034

Closed
SachuJames wants to merge 1 commit into
massive-com:masterfrom
SachuJames:ssl-ca-bundle-env-998
Closed

SachuJames wants to merge 1 commit into
massive-com:masterfrom
SachuJames:ssl-ca-bundle-env-998

Conversation

@SachuJames

Copy link
Copy Markdown
Contributor

Both the REST and websocket clients hardcode certifi.where() for TLS verification, so setting SSL_CERT_FILE or REQUESTS_CA_BUNDLE has no effect. Anyone behind a corporate proxy with a custom CA bundle cannot use the SDK.

Fixes #998

What changed:

  • New massive/certs.py with ca_bundle_path(): resolves SSL_CERT_FILE first, then REQUESTS_CA_BUNDLE, falling back to certifi.where().
  • massive/rest/base.py: PoolManager now uses ca_bundle_path() for ca_certs.
  • massive/websocket/__init__.py: extracted the inline SSL context into _ssl_context(), loading ca_bundle_path().

Tests:

  • New test_rest/test_ssl.py (7 tests): env precedence, certifi default, and client-level check via connection_pool_kw["ca_certs"].
  • New test_websocket/test_ssl.py (4 tests): mocked load_verify_locations captures the bundle path; ws:// builds no context.
  • The client-level tests fail on the pre-fix code and pass after. Full suites green: 46 rest + 5 websocket. black and mypy clean on the changed files.

Both clients hardcoded the certifi bundle, so custom CA bundles (common
behind corporate TLS inspection) were silently ignored. Resolve the CA
bundle from SSL_CERT_FILE, then REQUESTS_CA_BUNDLE, falling back to
certifi as before.
justinpolygon added a commit that referenced this pull request Oct 16, 2026
Combines the community PRs that change how the REST client builds its
urllib3 pool (#968, #1008, #1026, #1033, #1034).

- CA bundle: both clients verify TLS with ca_certs if given, then the
  SSL_CERT_FILE or REQUESTS_CA_BUNDLE environment variable, then
  certifi (#998).
- RESTClient(maxsize=10): connections kept per host. urllib3 defaults
  to 1, so threaded clients kept opening new TLS connections.
- RESTClient(connection_pool_kw=...): other urllib3 pool options,
  merged over the defaults (#1009).
- RESTClient(proxy=...): explicit proxy URL, with credentials from the
  URL. Proxy environment variables aren't read, so existing traffic
  doesn't change route. The WebSocket client already uses the system
  proxy via websockets.

Co-authored-by: SACHU JAMES <142034811+SachuJames@users.noreply.github.com>
Co-authored-by: Mohd Quamar Tyagi <104281681+Tyagiquamar@users.noreply.github.com>
Co-authored-by: jakobovski-arb <201493996+jakobovski-arb@users.noreply.github.com>
Co-authored-by: Roman Zydyk <31843161+romanzdk@users.noreply.github.com>
Co-authored-by: Kevin Chiu <2712+kevinchiu@users.noreply.github.com>
justinpolygon added a commit that referenced this pull request Oct 16, 2026
Adds connection options to the clients, combining #968, #1008, #1026,
#1033 and #1034 (contributors are credited as co-authors).

- **Custom CA:** `ca_certs=` on `RESTClient` and `WebSocketClient`,
defaulting to `SSL_CERT_FILE` / `REQUESTS_CA_BUNDLE`, then certifi.
Closes #998.
- **Pool size:** `RESTClient(maxsize=10)`. urllib3 defaults to 1
connection per host.
- **Pool options:** `RESTClient(connection_pool_kw={...})`, merged over
the defaults. Closes #1009.
- **Proxy:** `RESTClient(proxy="http://user:pass@host:port")`. Proxy env
vars aren't read, so nobody's traffic changes route.

The README has a new **Network Configuration** section with examples for
each case (custom CA, proxy, threads, other pool options).

All new parameters are optional and added at the end of the signatures.
The one behavior change: if `SSL_CERT_FILE` or `REQUESTS_CA_BUNDLE`
points to a file, it's now used instead of certifi (as `requests` and
Python do). If it points to a file that doesn't exist, it's skipped with
a warning, so a stale value doesn't break anyone.

Verified against the live API through a local TLS-inspecting proxy
(mitmproxy with auth): REST and WebSocket connect with the proxy's CA
(argument or env var) and fail certificate verification without it;
wrong proxy credentials get 407. Under 16 threads, `maxsize=10` opened
16 TLS connections vs 57–70 with urllib3's default.

---------

Co-authored-by: SACHU JAMES <142034811+SachuJames@users.noreply.github.com>
Co-authored-by: Mohd Quamar Tyagi <104281681+Tyagiquamar@users.noreply.github.com>
Co-authored-by: jakobovski-arb <201493996+jakobovski-arb@users.noreply.github.com>
Co-authored-by: Roman Zydyk <31843161+romanzdk@users.noreply.github.com>
Co-authored-by: Kevin Chiu <2712+kevinchiu@users.noreply.github.com>
@justinpolygon

Copy link
Copy Markdown
Collaborator

Thanks for this! We combined it with a few related PRs in #1040 (you're credited as a co-author), released in v2.9.0. SSL_CERT_FILE / REQUESTS_CA_BUNDLE now work for both REST and WebSocket, and there's also a ca_certs= argument. Closing in favor of #1040.

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.

SDK does not respect SSL_CERT_FILE or REQUESTS_CA_BUNDLE environment variables

2 participants