Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion src/claude_agent_sdk/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,32 @@ class SandboxSettings(TypedDict, total=False):
- Filesystem write restrictions: Use Edit allow/deny rules
- Network restrictions: Use WebFetch allow/deny rules

**Known issue -- ``/etc/hosts`` missing inside Docker containers:**

When running inside a Docker container with ``sandbox.enabled=True`` and
``enableWeakerNestedSandbox=True``, the ``bubblewrap`` (``bwrap``) sandbox may
not expose the host's ``/etc/hosts`` file to sandboxed processes. This breaks
resolution of ``localhost`` inside the sandbox, which in turn breaks any tool
that connects through a proxy at ``http://localhost:<port>`` -- for example,
``botocore`` credential fetching in AWS Bedrock AgentCore runtimes where
outbound traffic is routed through ``localhost:3128``.

**Workaround:** Disable the sandbox when running in Docker environments that
depend on ``/etc/hosts`` for local name resolution::

sandbox_settings: SandboxSettings = {"enabled": False}

Alternatively, use ``excludedCommands`` to exempt the affected commands from
sandboxing::

sandbox_settings: SandboxSettings = {
"enabled": True,
"excludedCommands": ["python", "aws", "curl"],
}

The permanent fix requires a CLI update to explicitly bind-mount ``/etc/hosts``
inside the bwrap sandbox. See https://github.com/anthropics/claude-agent-sdk-python/issues/861.

Attributes:
enabled: Enable bash sandboxing (macOS/Linux only). Default: False
autoAllowBashIfSandboxed: Auto-approve bash commands when sandboxed. Default: True
Expand All @@ -892,6 +918,12 @@ class SandboxSettings(TypedDict, total=False):
ignoreViolations: Violations to ignore.
enableWeakerNestedSandbox: Enable weaker sandbox for unprivileged Docker environments
(Linux only). Reduces security. Default: False
bwrapExtraBinds: Additional ``--ro-bind`` source paths for the Linux
bubblewrap sandbox. Each path is bound into the sandbox at the same
location (e.g., ``["/etc/hosts", "/etc/resolv.conf"]``). This is useful
when running inside containers where the sandbox's default root bind
mount does not propagate certain files managed by the container runtime.
Requires CLI support (CLI 2.2+); silently ignored by older CLI versions.

Example:
```python
Expand All @@ -902,7 +934,9 @@ class SandboxSettings(TypedDict, total=False):
"network": {
"allowUnixSockets": ["/var/run/docker.sock"],
"allowLocalBinding": True
}
},
# Ensure /etc/hosts is available inside the sandbox (CLI 2.2+)
"bwrapExtraBinds": ["/etc/hosts", "/etc/resolv.conf"],
}
```
"""
Expand All @@ -914,6 +948,7 @@ class SandboxSettings(TypedDict, total=False):
network: SandboxNetworkConfig
ignoreViolations: SandboxIgnoreViolations
enableWeakerNestedSandbox: bool
bwrapExtraBinds: list[str]


# Content block types
Expand Down
24 changes: 24 additions & 0 deletions tests/test_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -1593,6 +1593,30 @@ def test_sandbox_network_config(self):
assert network["httpProxyPort"] == 8080
assert network["socksProxyPort"] == 8081

def test_sandbox_with_bwrap_extra_binds(self):
"""Test sandbox with bwrapExtraBinds for additional container mounts."""
import json

from claude_agent_sdk import SandboxSettings

sandbox: SandboxSettings = {
"enabled": True,
"bwrapExtraBinds": ["/etc/hosts", "/etc/resolv.conf"],
}

transport = SubprocessCLITransport(
prompt="test",
options=make_options(sandbox=sandbox),
)

cmd = transport._build_command()
settings_idx = cmd.index("--settings")
settings_value = cmd[settings_idx + 1]

parsed = json.loads(settings_value)
assert parsed["sandbox"]["enabled"] is True
assert parsed["sandbox"]["bwrapExtraBinds"] == ["/etc/hosts", "/etc/resolv.conf"]

def test_build_command_with_tools_array(self):
"""Test building CLI command with tools as array of tool names."""
transport = SubprocessCLITransport(
Expand Down