diff --git a/strix/runtime/session_manager.py b/strix/runtime/session_manager.py index cdc6d9558..3e7d57154 100644 --- a/strix/runtime/session_manager.py +++ b/strix/runtime/session_manager.py @@ -21,6 +21,11 @@ # 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" _SESSION_CACHE: dict[str, dict[str, Any]] = {} @@ -29,6 +34,29 @@ _WORKSPACE_ROOT = "/workspace" +def _container_caido_url() -> str: + return f"{_CONTAINER_CAIDO_SCHEME}://{_CONTAINER_CAIDO_HOST}:{_CONTAINER_CAIDO_PORT}" + + +def build_sandbox_environment() -> dict[str, Any]: + """Return environment variables inherited by sandbox subprocesses.""" + container_caido_url = _container_caido_url() + return { + "PYTHONUNBUFFERED": "1", + "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 build_session_entries( local_sources: list[dict[str, Any]], ) -> tuple[dict[str | Path, BaseEntry], list[dict[str, Any]], list[Path]]: @@ -91,19 +119,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", - "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()), ) backend_name = load_settings().runtime.backend diff --git a/tests/test_session_entries.py b/tests/test_session_entries.py index e08c59aa1..830c49175 100644 --- a/tests/test_session_entries.py +++ b/tests/test_session_entries.py @@ -6,13 +6,18 @@ from agents.sandbox.entries import LocalDir -from strix.runtime.session_manager import build_session_entries +from strix.runtime.session_manager import build_sandbox_environment, build_session_entries if TYPE_CHECKING: from pathlib import Path +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, *, mount: bool = False) -> dict[str, Any]: return {"source_path": path, "workspace_subdir": subdir, "mount": mount} @@ -85,3 +90,18 @@ def test_symlink_tree_is_staged(tmp_path: Path) -> None: assert entry.src == staged_dirs[0] assert not (staged_dirs[0] / "link.txt").is_symlink() assert (staged_dirs[0] / "link.txt").read_text() == "content" + + +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