Skip to content

fix(agent): pass docker_network config to backend-probe container - #62023

Open
sagitario-jpn wants to merge 1 commit into
NousResearch:mainfrom
sagitario-jpn:fix/docker-network-backend-probe
Open

fix(agent): pass docker_network config to backend-probe container#62023
sagitario-jpn wants to merge 1 commit into
NousResearch:mainfrom
sagitario-jpn:fix/docker-network-backend-probe

Conversation

@sagitario-jpn

Copy link
Copy Markdown

The backend probe in prompt_builder.py builds its own container_config dict but omitted docker_network, so the probe container always launched with the default bridge network regardless of the operator's docker_network: false setting (issue #46358 introduced the toggle but only wired it through terminal_tool.py/code_execution_tool.py/file_tools.py).

Also extends test_sibling_container_config_sites_carry_docker_network to cover agent.prompt_builder, closing the gap that regression guard was meant to catch.

What

Fixes a docker_network config gap in the backend probe (agent/prompt_builder.py). When terminal.docker_network: false is set, the probe container spawned by _probe_remote_backend() still launched with the default NetworkMode: bridge, ignoring the operator's egress lockdown.

Why

#46358 introduced terminal.docker_network and wired it through tools/terminal_tool.py, tools/code_execution_tool.py, and tools/file_tools.py. The backend probe in agent/prompt_builder.py builds its own container_config dict for _create_environment(...) but was never updated to include docker_network, so it silently falls back to DockerEnvironment's default (network=True).

In practice this means an operator running with docker_network: false for a fully air-gapped Docker sandbox still gets one bridged, internet-reachable container per model backend on disk (labeled hermes-task-id:prompt-backend-probe). The probe itself only runs a fixed uname/whoami/pwd command today, so there's no immediate exploit path, but it breaks the operator's stated intent and the existing regression guard (test_sibling_container_config_sites_carry_docker_network) didn't catch it because it didn't check agent.prompt_builder.

Changes

  • agent/prompt_builder.py: add "docker_network": config.get("docker_network", True) to the probe's container_config dict, matching the pattern already used in terminal_tool.py / code_execution_tool.py / file_tools.py.
  • tests/tools/test_docker_network_config.py: extend test_sibling_container_config_sites_carry_docker_network to also walk agent.prompt_builder, so this asymmetry can't reappear silently.

How to test

  1. Set terminal.backend: docker and terminal.docker_network: false.
  2. Remove any existing hermes-* containers.
  3. Trigger a normal turn that uses execute_code — its container correctly gets NetworkMode: none.
  4. Before this fix: the sibling container labeled hermes-task-id:prompt-backend-probe still comes up as NetworkMode: bridge. After this fix: it comes up as none too.

Automated:

pytest tests/tools/test_docker_network_config.py -v   # 8 passed
pytest tests/agent/test_prompt_builder.py -v           # 160 passed, 1 skipped (unrelated, filesystem-case-sensitivity skip)

Platforms tested

Windows 11 (PowerShell), Python 3.12.

Related

Follow-up to #46358, closing the gap flagged in that PR's own regression-guard test docstring ("the probe/exec asymmetry reported on issue #46358").

The backend probe in prompt_builder.py builds its own container_config
dict but omitted docker_network, so the probe container always launched
with the default bridge network regardless of the operator's
docker_network: false setting (issue NousResearch#46358 introduced the toggle but
only wired it through terminal_tool.py/code_execution_tool.py/file_tools.py).

Also extends test_sibling_container_config_sites_carry_docker_network
to cover agent.prompt_builder, closing the gap that regression guard
was meant to catch.
@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint area/docker Docker image, Compose, packaging backend/docker Docker container execution sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data P2 Medium — degraded but workaround exists labels Jul 10, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for tracing the remaining backend-probe path. Current main still omits docker_network from the probe container_config at agent/prompt_builder.py:982-996; _create_environment consequently defaults it to True at tools/terminal_tool.py:1421 and forwards that to Docker at tools/terminal_tool.py:1444.

The added propagation matches the established terminal-path pattern, and extending tests/tools/test_docker_network_config.py's sibling-site guard covers this exact omission class. No blocking correctness or completeness issue was identified in the two-file diff.

Automated hermes-sweeper review.

@teknium1 teknium1 added the sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users label Jul 11, 2026

@GottZ GottZ left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was generated by AI during triage.

Summary

Two PRs address the Docker egress-lockdown configuration: #46358 introduced the operator-facing docker_network toggle and propagated it through the primary container paths, while #62023 fixes the remaining backend-probe path that still defaulted to bridged networking.

Related pull requests

  • #46358 [closed] related — (+94/-0) — foundational, already superseded by merged #59149: it exposed terminal.docker_network, bridged it through CLI and gateway configuration, forwarded it to DockerEnvironment, and added regression coverage; #59149 cherry-picked and widened this implementation to additional container paths and safe container reuse.
  • #62023 related — (+3/-1) — merge: it propagates docker_network into agent.prompt_builder's backend-probe container_config, preventing that container from silently falling back to network=True, and extends the sibling-site regression guard to cover this path.

Suggested consolidation

Merge #62023: it is a small, complementary fix for a concrete propagation gap left after the #46358 implementation was integrated and widened through #59149, and its diff matches the visible keep_open review with no identified blocker. No PRs should be closed as duplicates; #46358 remains relevant as the superseded source of the foundational implementation.

Cross-PR triage: Reviewed 2 pull requests and 0 issues in this complex. Each diff was read against this issue; Assessment working set: 9 kB of PR diffs, 5 kB of issue/PR text, 4 kB of discussion (4 comments), 0 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docker Docker image, Compose, packaging backend/docker Docker container execution comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants