Repository navigation
Description
Please read this first
- Have you read the docs? Agents SDK docs
- Yes. I reviewed the Sandbox client documentation and the current
DockerSandboxClientimplementation.
- Yes. I reviewed the Sandbox client documentation and the current
- Have you searched for related issues? Others may have had similar requests
- Yes. I searched open and closed issues and pull requests for
network_mode,network_disabled,DockerSandboxClientOptions,DockerSandboxClient+network, andallow_internet_access. I did not find an existing request covering this functionality.
- Yes. I searched open and closed issues and pull requests for
Describe the feature
I would like DockerSandboxClientOptions to support creating a Docker sandbox with networking completely disabled.
This is useful for agents that execute model-directed shell commands but do not require network access inside the sandbox.
Today, DockerSandboxClientOptions exposes the Docker image and optional exposed ports, but _create_container() does not pass a network configuration to docker_client.containers.create(). As a result, Docker uses its normal default networking behavior.
Docker's Python SDK already supports:
client.containers.create(
...,
network_mode="none",
)The proposed Agents SDK API is:
DockerSandboxClientOptions(
image="python:3.14-slim",
network_mode="none",
)with a deliberately narrow type:
network_mode: Literal["none"] | None = NoneNone preserves the existing behavior exactly, while "none" passes network_mode="none" to Docker.
The public option intentionally supports only "none" rather than an arbitrary str. The purpose of this change is specifically to allow callers to disable networking. Exposing unrelated Docker networking modes such as host, bridge, or container:<id> would unnecessarily broaden a security-sensitive public API.
Production / security use case
A common architecture is:
application / worker
|
| Docker API
v
sandbox container
|
+-- local input files
+-- shell commands
+-- preinstalled dependencies
+-- no network required
The application may need network access for model/API calls while the model-controlled sandbox should have no IP network path to:
- the public Internet;
- host network services;
- other containers;
- private or LAN services;
- metadata services.
For workloads such as document processing, code analysis, and other untrusted-input workflows, this provides a useful defense-in-depth boundary.
This is stronger and simpler than attempting to restrict only Internet egress, because the sandbox does not require networking at all. Docker's network_mode="none" directly represents that requirement.
The option remains opt-in. Some Docker sandbox users legitimately require networking, including workloads that use network-dependent tools or in-container remote storage/mount strategies, so changing the default behavior would be backwards incompatible.
Resume semantics
The setting also needs to be persisted in DockerSandboxSessionState.
DockerSandboxClient.resume() can recreate a missing container from serialized session state. If the network setting existed only in DockerSandboxClientOptions, a sandbox originally created with networking disabled could later be recreated with Docker's default networking.
The session state therefore includes:
class DockerSandboxSessionState(SandboxSessionState):
...
network_mode: Literal["none"] | None = Noneand replacement-container creation reuses state.network_mode.
This also preserves compatibility with older serialized session states because the new field defaults to None.
Compatibility
Existing callers remain unchanged.
For example:
DockerSandboxClientOptions(
image="python:3.14-slim",
exposed_ports=(8080,),
)retains the current behavior.
The new network_mode argument is optional and keyword-only, so the existing positional meaning of:
DockerSandboxClientOptions(image, exposed_ports)is preserved.
When network_mode is omitted, _create_container() does not add a network_mode entry to the Docker create kwargs. This preserves the existing Docker container creation behavior rather than explicitly selecting a different Docker network mode.
The current minimum Docker SDK dependency is docker>=6.1, which already supports network_mode="none", so this does not require a Docker SDK dependency change.
Exposed ports
network_mode="none" and exposed_ports remain independent Docker configuration inputs at the SDK layer.
This change does not introduce an additional Agents SDK validation rule for that combination. When networking is disabled, Docker remains authoritative for the resulting container configuration and behavior.
This keeps the feature focused on exposing the existing Docker no-network capability without introducing additional policy around port configuration.
Implementation scope
The change is intentionally focused:
- Add
network_mode: Literal["none"] | None = NonetoDockerSandboxClientOptions. - Persist the setting in
DockerSandboxSessionState. - Pass
network_mode="none"to Docker container creation when explicitly configured. - Omit the Docker
network_modekwarg entirely when the option is not configured. - Reapply the persisted setting when
resume()needs to recreate a missing container. - Preserve compatibility with serialized session states that predate the new field.
- Add focused regression coverage for configuration, Docker container creation, serialization, backwards compatibility, and resume/recreation.
API shape
The API is intentionally:
network_mode: Literal["none"] | None = Nonerather than a generic Docker network-mode string.
This maps directly to Docker's existing network_mode="none" semantics while keeping the Agents SDK surface limited to the capability this feature is intended to provide: explicitly creating a Docker sandbox without networking.
None means that the SDK does not specify a Docker network mode and therefore preserves the existing behavior. "none" explicitly requests a sandbox with networking disabled.
A focused implementation with regression coverage is available and follows this API shape, including preservation of the setting across container recreation during DockerSandboxClient.resume().
Activity