From 712d20ee644af60799021c19d30fc90ab06346b8 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 16 Apr 2026 09:59:53 +0200 Subject: [PATCH 1/8] Clarify when persistent environment variables are sourced Variables set in /etc/sandbox-persistent.sh inside a sandbox are only sourced during interactive shell sessions and agent startup. Running a command directly with `sbx exec ` skips the login shell, so the persistent environment file is not loaded. Add a note explaining this distinction and a workaround using a login shell wrapper. Co-Authored-By: Claude Opus 4.6 (1M context) --- content/manuals/ai/sandboxes/faq.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/content/manuals/ai/sandboxes/faq.md b/content/manuals/ai/sandboxes/faq.md index 5c500c2095f..c93f8e8e32b 100644 --- a/content/manuals/ai/sandboxes/faq.md +++ b/content/manuals/ai/sandboxes/faq.md @@ -65,6 +65,17 @@ sandbox instead of on your host. > the sandbox. The agent process can read it directly. Only use this for > credentials where proxy-based injection isn't available. +Variables in `/etc/sandbox-persistent.sh` are sourced automatically during +interactive shell sessions (for example, `sbx exec -it bash`) and by +agents started with `sbx run`. If you run a command directly with +`sbx exec `, the persistent environment file is not sourced +because no login shell is started. To run a command with the persistent +environment loaded, wrap it in a login shell: + +```console +$ sbx exec -it bash -lc "your-command" +``` + To verify the variable is set, open a shell in the sandbox: ```console From c814f89032c413787985bed81e5344f830c5b68c Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 16 Apr 2026 10:00:27 +0200 Subject: [PATCH 2/8] Add FAQ entry explaining why agents skip approval prompts Sandbox agent templates run without approval prompts by default, which can be surprising. Add a FAQ entry explaining that the sandbox isolation layers replace the need for per-action approval, and show how to re-enable approval prompts by passing the agent's own CLI flags after the -- separator. Co-Authored-By: Claude Opus 4.6 (1M context) --- content/manuals/ai/sandboxes/faq.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/content/manuals/ai/sandboxes/faq.md b/content/manuals/ai/sandboxes/faq.md index c93f8e8e32b..7ebae4708d9 100644 --- a/content/manuals/ai/sandboxes/faq.md +++ b/content/manuals/ai/sandboxes/faq.md @@ -83,6 +83,26 @@ $ sbx exec -it bash $ echo $BRAVE_API_KEY ``` +## Why do agents run without approval prompts? + +The sandbox itself is the safety boundary. Because agents run inside an +isolated microVM with [network policies](security/policy.md), +[credential isolation](security/credentials.md), and no access to your host +system outside the workspace, the usual reasons for approval prompts (preventing +destructive commands, network access, file modifications) are handled by the +sandbox isolation layers instead. + +If you prefer to re-enable approval prompts for a specific agent, pass the +agent's own CLI flags after the `--` separator. For example, to run Claude +Code with its default permission checks instead of auto-approve: + +```console +$ sbx run claude --name my-sandbox -- --permission-mode default +``` + +The flags vary by agent. Refer to each agent's own documentation for the +available permission or approval options. + ## How do I know if my agent is running in a sandbox? Ask the agent. The agent can see whether or not it's running inside a sandbox. From 822364e6c336ff14ac250b0320e2846554eacf42 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 16 Apr 2026 10:01:06 +0200 Subject: [PATCH 3/8] Clarify that SSH and non-HTTP protocols are blocked by sandbox networking Users may expect that adding a domain to the allow list unblocks all traffic to that host, including SSH. Add a note to the network policy page stating that allow rules only apply to HTTP/HTTPS, and add a troubleshooting entry for SSH with a workaround (use HTTPS for Git). Co-Authored-By: Claude Opus 4.6 (1M context) --- content/manuals/ai/sandboxes/security/policy.md | 4 +++- content/manuals/ai/sandboxes/troubleshooting.md | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/content/manuals/ai/sandboxes/security/policy.md b/content/manuals/ai/sandboxes/security/policy.md index 18d4d38d47e..187eae0111d 100644 --- a/content/manuals/ai/sandboxes/security/policy.md +++ b/content/manuals/ai/sandboxes/security/policy.md @@ -15,7 +15,9 @@ to all sandboxes on the machine. ## Network policies The only way traffic can leave a sandbox is through an HTTP/HTTPS proxy on -your host, which enforces access rules on every outbound request. +your host, which enforces access rules on every outbound request. Non-HTTP +protocols such as SSH, raw TCP, UDP, and ICMP are blocked at the network +layer and can't be unblocked with policy rules. ### Initial policy selection diff --git a/content/manuals/ai/sandboxes/troubleshooting.md b/content/manuals/ai/sandboxes/troubleshooting.md index 493a640dcaa..14f32879d52 100644 --- a/content/manuals/ai/sandboxes/troubleshooting.md +++ b/content/manuals/ai/sandboxes/troubleshooting.md @@ -34,6 +34,23 @@ To allow all outbound traffic instead: $ sbx policy allow network "**" ``` +## SSH and other non-HTTP connections fail + +Sandbox network isolation only proxies HTTP and HTTPS traffic. Non-HTTP +protocols, including SSH, raw TCP, UDP, and ICMP, are blocked at the network +layer. Adding an allow rule with `sbx policy allow` does not unblock these +protocols because the allow list only applies to HTTP/HTTPS requests routed +through the proxy. + +If `sbx policy log` shows entries with a **PROXY** value of `network`, the +traffic is non-HTTP and is blocked regardless of your allow rules. + +For Git operations over SSH, use HTTPS URLs instead: + +```console +$ git clone https://github.com/owner/repo.git +``` + ## Can't reach a service running on the host If a request to `127.0.0.1` or a local network IP returns "connection refused" From 66e48961e89d0423cc636c3de906a799299b75db Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 16 Apr 2026 10:06:51 +0200 Subject: [PATCH 4/8] Fix approval prompts FAQ with practical workarounds Replace the incorrect --permission-mode flag example with two workarounds that actually work: changing the permission mode inside the session (e.g. /permissions in Claude Code), or building a custom template with different default launch flags. Co-Authored-By: Claude Opus 4.6 (1M context) --- content/manuals/ai/sandboxes/faq.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/content/manuals/ai/sandboxes/faq.md b/content/manuals/ai/sandboxes/faq.md index 7ebae4708d9..f223ed31671 100644 --- a/content/manuals/ai/sandboxes/faq.md +++ b/content/manuals/ai/sandboxes/faq.md @@ -92,16 +92,15 @@ system outside the workspace, the usual reasons for approval prompts (preventing destructive commands, network access, file modifications) are handled by the sandbox isolation layers instead. -If you prefer to re-enable approval prompts for a specific agent, pass the -agent's own CLI flags after the `--` separator. For example, to run Claude -Code with its default permission checks instead of auto-approve: - -```console -$ sbx run claude --name my-sandbox -- --permission-mode default -``` - -The flags vary by agent. Refer to each agent's own documentation for the -available permission or approval options. +If you prefer to re-enable approval prompts, you have two options: + +- **Change the permission mode inside the session.** Most agents let you + switch permission modes after startup. In Claude Code, use the + `/permissions` command to change the mode interactively. +- **Build a custom template.** Create a + [custom environment](agents/custom-environments.md) that launches the + agent with different default flags. This is useful if your team wants a + consistent permission policy across sandboxes. ## How do I know if my agent is running in a sandbox? From 1b096b51b91df92ee502ee953ef4286eb32f31d4 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 16 Apr 2026 10:09:12 +0200 Subject: [PATCH 5/8] Remove misleading policy log diagnostic from SSH troubleshooting Blocked non-HTTP requests look the same as other blocked requests in sbx policy log output, so the advice to check for a PROXY value of "network" was not useful. Simplify the section. Co-Authored-By: Claude Opus 4.6 (1M context) --- content/manuals/ai/sandboxes/troubleshooting.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/content/manuals/ai/sandboxes/troubleshooting.md b/content/manuals/ai/sandboxes/troubleshooting.md index 14f32879d52..f95920fdc57 100644 --- a/content/manuals/ai/sandboxes/troubleshooting.md +++ b/content/manuals/ai/sandboxes/troubleshooting.md @@ -39,11 +39,7 @@ $ sbx policy allow network "**" Sandbox network isolation only proxies HTTP and HTTPS traffic. Non-HTTP protocols, including SSH, raw TCP, UDP, and ICMP, are blocked at the network layer. Adding an allow rule with `sbx policy allow` does not unblock these -protocols because the allow list only applies to HTTP/HTTPS requests routed -through the proxy. - -If `sbx policy log` shows entries with a **PROXY** value of `network`, the -traffic is non-HTTP and is blocked regardless of your allow rules. +protocols because policy rules only apply to HTTP/HTTPS requests. For Git operations over SSH, use HTTPS URLs instead: From a9a5500acd73c48bca5ca221b081c49512b147e5 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 16 Apr 2026 10:12:11 +0200 Subject: [PATCH 6/8] Fix env sourcing workaround: bash -c is sufficient, not bash -lc Verified that sbx exec runs commands without a shell, so the persistent env file is not sourced. Wrapping in bash -c is enough because the file is sourced via BASH_ENV, not login profiles. Co-Authored-By: Claude Opus 4.6 (1M context) --- content/manuals/ai/sandboxes/faq.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/manuals/ai/sandboxes/faq.md b/content/manuals/ai/sandboxes/faq.md index f223ed31671..2dbaf404363 100644 --- a/content/manuals/ai/sandboxes/faq.md +++ b/content/manuals/ai/sandboxes/faq.md @@ -65,15 +65,15 @@ sandbox instead of on your host. > the sandbox. The agent process can read it directly. Only use this for > credentials where proxy-based injection isn't available. -Variables in `/etc/sandbox-persistent.sh` are sourced automatically during -interactive shell sessions (for example, `sbx exec -it bash`) and by -agents started with `sbx run`. If you run a command directly with -`sbx exec `, the persistent environment file is not sourced -because no login shell is started. To run a command with the persistent -environment loaded, wrap it in a login shell: +Variables in `/etc/sandbox-persistent.sh` are sourced automatically when +bash runs inside the sandbox, including interactive sessions and agents +started with `sbx run`. If you run a command directly with +`sbx exec `, the command runs without a shell, so the +persistent environment file is not sourced. Wrap the command in `bash -c` +to load the environment: ```console -$ sbx exec -it bash -lc "your-command" +$ sbx exec bash -c "your-command" ``` To verify the variable is set, open a shell in the sandbox: From 5aac6d4dd1c4cd793c91d89168a291db0559a280 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 16 Apr 2026 15:16:55 +0200 Subject: [PATCH 7/8] Update non-HTTP networking docs: TCP (SSH) can now be allowed Non-HTTP TCP traffic including SSH can be permitted via IP:port policy rules (docker/sandboxes#2329). UDP and ICMP remain blocked. Update the policy page, monitoring table, and troubleshooting entry accordingly. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../manuals/ai/sandboxes/security/policy.md | 19 ++++++++++------- .../manuals/ai/sandboxes/troubleshooting.md | 21 ++++++++++++++----- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/content/manuals/ai/sandboxes/security/policy.md b/content/manuals/ai/sandboxes/security/policy.md index 187eae0111d..40060b61ab0 100644 --- a/content/manuals/ai/sandboxes/security/policy.md +++ b/content/manuals/ai/sandboxes/security/policy.md @@ -15,9 +15,12 @@ to all sandboxes on the machine. ## Network policies The only way traffic can leave a sandbox is through an HTTP/HTTPS proxy on -your host, which enforces access rules on every outbound request. Non-HTTP -protocols such as SSH, raw TCP, UDP, and ICMP are blocked at the network -layer and can't be unblocked with policy rules. +your host, which enforces access rules on every outbound request. + +Non-HTTP TCP traffic, including SSH, can be allowed by adding a policy rule +for the destination IP address and port (for example, +`sbx policy allow network "10.1.2.3:22"`). UDP and ICMP traffic is blocked +at the network layer and can't be unblocked with policy rules. ### Initial policy selection @@ -173,11 +176,11 @@ my-sandbox network registry.npmjs.org transparent policykit 10:15:20 29 The **PROXY** column shows how the request left the sandbox: -| Value | Description | -| ------------- | --------------------------------------------------------------------------------------------------- | -| `forward` | Routed through the forward proxy. Supports [credential injection](credentials.md). | -| `transparent` | Intercepted by the transparent proxy. Policy is enforced but credential injection is not available. | -| `network` | Non-HTTP traffic (raw TCP, UDP, ICMP). Always blocked. | +| Value | Description | +| ------------- | -------------------------------------------------------------------------------------------------------------- | +| `forward` | Routed through the forward proxy. Supports [credential injection](credentials.md). | +| `transparent` | Intercepted by the transparent proxy. Policy is enforced but credential injection is not available. | +| `network` | Non-HTTP traffic (raw TCP, UDP, ICMP). TCP can be allowed with a policy rule; UDP and ICMP are always blocked. | Filter by sandbox name by passing it as an argument: diff --git a/content/manuals/ai/sandboxes/troubleshooting.md b/content/manuals/ai/sandboxes/troubleshooting.md index f95920fdc57..54b0e32f7b7 100644 --- a/content/manuals/ai/sandboxes/troubleshooting.md +++ b/content/manuals/ai/sandboxes/troubleshooting.md @@ -36,12 +36,23 @@ $ sbx policy allow network "**" ## SSH and other non-HTTP connections fail -Sandbox network isolation only proxies HTTP and HTTPS traffic. Non-HTTP -protocols, including SSH, raw TCP, UDP, and ICMP, are blocked at the network -layer. Adding an allow rule with `sbx policy allow` does not unblock these -protocols because policy rules only apply to HTTP/HTTPS requests. +Non-HTTP TCP connections like SSH can be allowed by adding a policy rule for +the destination IP address and port. For example, to allow SSH to a specific +host: -For Git operations over SSH, use HTTPS URLs instead: +```console +$ sbx policy allow network "10.1.2.3:22" +``` + +Hostname-based rules (for example, `myhost:22`) don't work for non-HTTP +connections because the proxy can't resolve the hostname to an IP address in +this context. Use the IP address directly. + +UDP and ICMP traffic is blocked at the network layer and can't be unblocked +with policy rules. + +For Git operations over SSH, you can either add an allow rule for the Git +server's IP address or use HTTPS URLs instead: ```console $ git clone https://github.com/owner/repo.git From e397000b19dc9a246779723be6f6ac1b9815ddb4 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 16 Apr 2026 22:26:57 +0200 Subject: [PATCH 8/8] Remove incorrect custom environments workaround from approval FAQ Custom environments don't let you configure an agent's permission model. The only working way to re-enable approval prompts is to switch permission modes at runtime inside the agent session. Co-Authored-By: Claude Opus 4.7 (1M context) --- content/manuals/ai/sandboxes/faq.md | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/content/manuals/ai/sandboxes/faq.md b/content/manuals/ai/sandboxes/faq.md index 2dbaf404363..ca6917b1438 100644 --- a/content/manuals/ai/sandboxes/faq.md +++ b/content/manuals/ai/sandboxes/faq.md @@ -92,15 +92,10 @@ system outside the workspace, the usual reasons for approval prompts (preventing destructive commands, network access, file modifications) are handled by the sandbox isolation layers instead. -If you prefer to re-enable approval prompts, you have two options: - -- **Change the permission mode inside the session.** Most agents let you - switch permission modes after startup. In Claude Code, use the - `/permissions` command to change the mode interactively. -- **Build a custom template.** Create a - [custom environment](agents/custom-environments.md) that launches the - agent with different default flags. This is useful if your team wants a - consistent permission policy across sandboxes. +If you prefer to re-enable approval prompts, change the permission mode +inside the session. Most agents let you switch permission modes after +startup. In Claude Code, use the `/permissions` command to change the mode +interactively. ## How do I know if my agent is running in a sandbox?