From 14a7442eebcceb0e404f3ab568c4d5d9cc2d5ddb Mon Sep 17 00:00:00 2001 From: Taylor Steinberg Date: Wed, 8 Apr 2026 23:08:06 -0400 Subject: [PATCH] fix: warn when TLS verification is disabled in Client Emit a UserWarning at Client construction time when `verify=False` is passed, to alert users that disabling TLS certificate verification is insecure and should not be used in production. Co-Authored-By: Claude Sonnet 4.6 --- src/posit/connect/client.py | 14 ++++++++++++ tests/posit/connect/test_client.py | 36 +++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/posit/connect/client.py b/src/posit/connect/client.py index cb71f41c..44297a6d 100644 --- a/src/posit/connect/client.py +++ b/src/posit/connect/client.py @@ -2,8 +2,16 @@ from __future__ import annotations +import warnings + from typing_extensions import TYPE_CHECKING, Optional, Union, overload +_TLS_VERIFY_DISABLED_WARNING = ( + "TLS certificate verification is disabled. This is insecure and should " + "not be used in production. Pass a path to a CA bundle via `verify=` " + "instead." +) + from . import hooks, me, urls from .auth import Auth, BootstrapAuth from .config import Config @@ -169,6 +177,12 @@ def __init__(self, *args, **kwargs) -> None: >>> Client(url="https://connect.example.com", verify="/path/to/ca-bundle.crt") """ verify = kwargs.pop("verify", True) + if verify is False: + warnings.warn( + _TLS_VERIFY_DISABLED_WARNING, + UserWarning, + stacklevel=2, + ) api_key = None url = None if len(args) == 1 and isinstance(args[0], str): diff --git a/tests/posit/connect/test_client.py b/tests/posit/connect/test_client.py index 5d73fd9b..12a4a640 100644 --- a/tests/posit/connect/test_client.py +++ b/tests/posit/connect/test_client.py @@ -85,9 +85,43 @@ def test_verify_false( MockConfig: MagicMock, MockSession: MagicMock, ): - Client(url="https://connect.example.com", api_key="12345", verify=False) + with pytest.warns(UserWarning, match="TLS certificate verification is disabled"): + Client(url="https://connect.example.com", api_key="12345", verify=False) assert MockSession.return_value.verify is False + def test_verify_false_emits_warning( + self, + MockAuth: MagicMock, + MockConfig: MagicMock, + MockSession: MagicMock, + ): + with pytest.warns(UserWarning, match="TLS certificate verification is disabled"): + Client(url="https://connect.example.com", api_key="12345", verify=False) + + def test_verify_true_no_warning( + self, + MockAuth: MagicMock, + MockConfig: MagicMock, + MockSession: MagicMock, + ): + import warnings as _warnings + + with _warnings.catch_warnings(): + _warnings.simplefilter("error") + Client(url="https://connect.example.com", api_key="12345", verify=True) + + def test_verify_ca_bundle_no_warning( + self, + MockAuth: MagicMock, + MockConfig: MagicMock, + MockSession: MagicMock, + ): + import warnings as _warnings + + with _warnings.catch_warnings(): + _warnings.simplefilter("error") + Client(url="https://connect.example.com", api_key="12345", verify="/path/to/ca.crt") + def test_verify_ca_bundle( self, MockAuth: MagicMock,