From 46e2d331efd3f87fed447be070f325c2fa39d492 Mon Sep 17 00:00:00 2001 From: Ousama Ben Younes Date: Mon, 13 Jul 2026 15:47:01 +0000 Subject: [PATCH] fix: propagate sandbox proxy environment aliases Centralize sandbox subprocess environment setup in build_sandbox_environment() and include lowercase all_proxy/no_proxy aliases alongside the uppercase proxy aliases, plus the CA bundle variables (REQUESTS_CA_BUNDLE, SSL_CERT_FILE) used by common Python and TLS tooling. This keeps subprocesses on the same Caido proxy and trust config while preserving localhost bypass for tools that only read lowercase proxy variables. RED->GREEN: tests/test_session_entries.py imports build_sandbox_environment, which does not exist on the base branch (ImportError = RED); the new test_sandbox_environment_exports_proxy_and_ca_aliases passes with the fix (GREEN). Full suite: 1741 passed, 1 pre-existing unrelated failure (tests/test_pricing.py, also failing on upstream/main). Fixes #430 --- strix/runtime/session_manager.py | 43 +++++++++++++++++++++++--------- tests/test_session_entries.py | 21 ++++++++++++++++ 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/strix/runtime/session_manager.py b/strix/runtime/session_manager.py index a8447ebb..4bf2f481 100644 --- a/strix/runtime/session_manager.py +++ b/strix/runtime/session_manager.py @@ -32,6 +32,12 @@ logger = logging.getLogger(__name__) # In-container Caido sidecar port (matches the image's caido-cli bind). _CONTAINER_CAIDO_PORT = 48080 +_CONTAINER_CAIDO_SCHEME = "http" +_CONTAINER_CAIDO_HOST = "127.0.0.1" +_HOST_GATEWAY_NAME = "host.docker.internal" +_NO_PROXY_VALUE = "localhost,127.0.0.1" +_CA_BUNDLE_PATH = "/etc/ssl/certs/ca-certificates.crt" +_PYTHONUNBUFFERED_VALUE = "1" _SESSION_CACHE: dict[str, dict[str, Any]] = {} @@ -49,6 +55,29 @@ _EXTRA_FILE_EXTRACT_TIMEOUT_S = 120 _EXTRA_FILE_MODE = 0o644 +def _container_caido_url() -> str: + return f"{_CONTAINER_CAIDO_SCHEME}://{_CONTAINER_CAIDO_HOST}:{_CONTAINER_CAIDO_PORT}" + + +def build_sandbox_environment() -> dict[str, str]: + """Return environment variables inherited by sandbox subprocesses.""" + container_caido_url = _container_caido_url() + return { + "PYTHONUNBUFFERED": _PYTHONUNBUFFERED_VALUE, + "HOST_GATEWAY": _HOST_GATEWAY_NAME, + "http_proxy": container_caido_url, + "https_proxy": container_caido_url, + "HTTP_PROXY": container_caido_url, + "HTTPS_PROXY": container_caido_url, + "ALL_PROXY": container_caido_url, + "all_proxy": container_caido_url, + "NO_PROXY": _NO_PROXY_VALUE, + "no_proxy": _NO_PROXY_VALUE, + "REQUESTS_CA_BUNDLE": _CA_BUNDLE_PATH, + "SSL_CERT_FILE": _CA_BUNDLE_PATH, + } + + def _host_identity_env() -> dict[str, str]: # Read the platform through a local so it is not narrowed to whichever OS is # type-checking: comparing sys.platform directly makes one of these branches @@ -301,20 +330,10 @@ async def create_or_reuse( # picks up these env vars automatically. ``NO_PROXY`` keeps the # agent-browser CDP daemon's localhost traffic from looping back # through Caido. - container_caido_url = f"http://127.0.0.1:{_CONTAINER_CAIDO_PORT}" + container_caido_url = _container_caido_url() manifest = Manifest( entries=entries, - environment=Environment( - value={ - "PYTHONUNBUFFERED": "1", - "HOST_GATEWAY": "host.docker.internal", - **_host_identity_env(), - "http_proxy": container_caido_url, - "https_proxy": container_caido_url, - "ALL_PROXY": container_caido_url, - "NO_PROXY": "localhost,127.0.0.1", - }, - ), + environment=Environment(value={**build_sandbox_environment(), **_host_identity_env()}), ) logger.info( diff --git a/tests/test_session_entries.py b/tests/test_session_entries.py index a15e259b..69ad86fd 100644 --- a/tests/test_session_entries.py +++ b/tests/test_session_entries.py @@ -24,9 +24,15 @@ from strix.runtime.session_manager import ( build_bind_mounts, build_extra_file_archive, build_manifest_entries, + build_sandbox_environment, ) +EXPECTED_CAIDO_URL = "http://127.0.0.1:48080" +EXPECTED_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt" +EXPECTED_NO_PROXY = "localhost,127.0.0.1" + + def _source( subdir: str, path: str, *, protect_metadata: bool = False, read_only: bool = False ) -> dict[str, Any]: @@ -552,3 +558,18 @@ def test_only_bind_mount_capable_backends_are_registered_as_such() -> None: finally: _BACKENDS.pop("e2b", None) _BIND_MOUNT_BACKENDS.discard("e2b") + + +def test_sandbox_environment_exports_proxy_and_ca_aliases() -> None: + env = build_sandbox_environment() + + assert env["http_proxy"] == EXPECTED_CAIDO_URL + assert env["https_proxy"] == EXPECTED_CAIDO_URL + assert env["HTTP_PROXY"] == EXPECTED_CAIDO_URL + assert env["HTTPS_PROXY"] == EXPECTED_CAIDO_URL + assert env["ALL_PROXY"] == EXPECTED_CAIDO_URL + assert env["all_proxy"] == EXPECTED_CAIDO_URL + assert env["NO_PROXY"] == EXPECTED_NO_PROXY + assert env["no_proxy"] == EXPECTED_NO_PROXY + assert env["REQUESTS_CA_BUNDLE"] == EXPECTED_CA_BUNDLE + assert env["SSL_CERT_FILE"] == EXPECTED_CA_BUNDLE