feat(docker): terminal network toggle with full-path coverage and reuse guard - #59149
Merged
Conversation
Port from nanocoai/nanoclaw#2713: expose Hermes' existing Docker network isolation primitive through terminal config so operators can opt out of container egress.
…tainer reuse Follow-up to the salvaged toggle commit: - file_tools.py / code_execution_tool.py: carry docker_network in their container_config dicts so those environment-creation paths honor the lockdown instead of silently defaulting back to bridge (the probe/exec asymmetry class reported on #46358). - docker.py: cross-process reuse now inspects HostConfig.NetworkMode when docker_network=false and removes a mismatched (networked) container before starting a fresh air-gapped one. Fails closed when inspect fails. Default-network config never churns containers, so operators using docker_extra_args --network=none are unaffected. - tests: AST invariant that every container_config site carrying docker_run_as_host_user also carries docker_network, plus three reuse guard tests (reject bridge under lockdown / keep matching none / no inspect when network enabled). - docs: configuration.md gains terminal.docker_network + env var row.
This was referenced Jul 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
terminal.docker_network: falsenow air-gaps the Docker sandbox (--network=none) across every environment-creation path, and container reuse can no longer silently hand back a networked container under lockdown.Salvages #46358 (the toggle itself) and widens it per review: the original only threaded the toggle through
terminal_tool.py, so thefile_tools/code_executioncontainer paths fell back to bridge networking — the same exec/probe asymmetry class @ignasivegas reported on the issue. Label-only cross-process reuse also ignored the toggle entirely.Changes
hermes_cli/config.py(terminal.docker_network, defaulttrue), env bridge incli.py/gateway/run.py, wiring intools/terminal_tool.py, 4 teststools/file_tools.py,tools/code_execution_tool.py: carrydocker_networkin their container_config dictstools/environments/docker.py: reuse path inspectsHostConfig.NetworkModewhen lockdown is requested; mismatched (networked) containers are removed and replaced with a fresh--network=nonecontainer, warning logged. Fails closed on inspect failure. Default-network config never churns containers (docker_extra_args --network=noneusers unaffected)tests/tools/test_docker_network_config.py: +4 tests — AST invariant (every container_config site withdocker_run_as_host_usermust carrydocker_network) and three reuse-guard behaviorswebsite/docs/user-guide/configuration.md:docker_networkkey + env-var table rowValidation
scripts/run_tests.sh tests/tools/test_docker_network_config.pyscripts/run_tests.sh(docker_network + env_sync + docker_environment)network=False→NetworkMode=none, egressNET_BLOCKED (Errno 101), local exec OKdocker_network: false→ old container removed, freshnonecontainer, egress blockedSource
Infographic