From 9118cd861bcd198f74f26d56c6ab8774d15d294c Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:44:33 +0000 Subject: [PATCH 1/6] docs: document sandbox environment flags Sandbox users had to modify an internal persistent shell file to set custom environment variables. Document the v0.39.0 environment flags, their precedence and lifecycle behavior, and update affected examples to use them. --- .../claude-code-sandbox-model-runner.md | 47 +++++++--------- .../ai/sandboxes/customize/kit-examples.md | 7 +-- content/manuals/ai/sandboxes/faq.md | 54 ++++--------------- content/manuals/ai/sandboxes/usage.md | 43 +++++++++++++++ content/manuals/ai/sandboxes/workflows.md | 5 +- 5 files changed, 79 insertions(+), 77 deletions(-) diff --git a/content/guides/claude-code-sandbox-model-runner.md b/content/guides/claude-code-sandbox-model-runner.md index 8b6e58d7e643..053c025cafe5 100644 --- a/content/guides/claude-code-sandbox-model-runner.md +++ b/content/guides/claude-code-sandbox-model-runner.md @@ -52,7 +52,7 @@ Before you start, make sure you have: - [Docker Desktop](../get-started/get-docker.md) or Docker Engine installed - [Docker Model Runner enabled](../manuals/ai/model-runner/get-started.md#enable-docker-model-runner) -- [Docker Sandboxes (`sbx`) installed and signed in](../manuals/ai/sandboxes/get-started.md#install-and-sign-in) +- [Docker Sandboxes (`sbx`) version 0.39.0 or later installed and signed in](../manuals/ai/sandboxes/get-started.md#install-and-sign-in) If you use Docker Desktop, turn on TCP access in **Settings** > **AI**, or run: @@ -92,38 +92,28 @@ For background on host access from sandboxes, see ## Step 3: Create a Claude Code sandbox -From your project directory, create a sandbox without launching the agent: +From your project directory, create a sandbox without launching the agent. Set +`ANTHROPIC_BASE_URL` so Claude Code uses Docker Model Runner whenever the +sandbox starts: ```console $ cd ~/my-project -$ sbx create claude --name claude-dmr . +$ sbx create --name claude-dmr \ + -e ANTHROPIC_BASE_URL=http://host.docker.internal:12434 \ + claude . ``` -`sbx run` would also work, but it launches Claude Code immediately. Without -`ANTHROPIC_BASE_URL` set, Claude Code points at `api.anthropic.com` and -either prompts for OAuth or errors out before you can fix the endpoint. -Creating the sandbox first lets you write the local endpoint into it before -the agent starts. +`sbx run` would also work, but it launches Claude Code immediately. Creating +the sandbox first gives you a chance to verify the endpoint before the agent +starts. You don't need to set an Anthropic API key or run `sbx secret set anthropic`. Docker Model Runner doesn't authenticate the local endpoint, and the sandbox proxy only injects credentials for requests bound for `api.anthropic.com`. See [Credentials](../manuals/ai/sandboxes/security/credentials.md) for the full -list of services the proxy authenticates. - -## Step 4: Set the local endpoint inside the sandbox - -Append `ANTHROPIC_BASE_URL` to the sandbox's persistent environment file so -Claude Code reads it on every launch: - -```console -$ sbx exec -d claude-dmr bash -c "echo 'export ANTHROPIC_BASE_URL=http://host.docker.internal:12434' >> /etc/sandbox-persistent.sh" -``` - -The `bash -c` wrapper ensures the `>>` redirect runs inside the sandbox, not -on your host. For details on this approach, see -[How do I set custom environment variables inside a sandbox?](../manuals/ai/sandboxes/faq.md#how-do-i-set-custom-environment-variables-inside-a-sandbox). +list of services the proxy authenticates. For more ways to set variables, see +[Set environment variables](../manuals/ai/sandboxes/usage.md#set-environment-variables). To confirm the variable is set, open a shell in the sandbox: @@ -133,7 +123,7 @@ $ echo $ANTHROPIC_BASE_URL http://host.docker.internal:12434 ``` -## Step 5: Verify connectivity to Docker Model Runner +## Step 4: Verify connectivity to Docker Model Runner Still inside the sandbox shell, send a test request to the host endpoint: @@ -152,7 +142,7 @@ Type `exit` to leave the shell. For more details about the request format, see the [Anthropic-compatible API reference](../manuals/ai/model-runner/api-reference.md#anthropic-compatible-api). -## Step 6: Launch Claude Code with the local model +## Step 5: Launch Claude Code with the local model Run Claude Code in the sandbox and pass the model flag through to the agent: @@ -161,11 +151,11 @@ $ sbx run claude-dmr -- --model ai/devstral-small-2 ``` Everything after `--` is forwarded to the Claude Code CLI. Because -`ANTHROPIC_BASE_URL` is set in the sandbox's persistent environment, Claude +`ANTHROPIC_BASE_URL` is stored in the sandbox's environment, so Claude Code routes requests to Docker Model Runner on your host instead of `api.anthropic.com`. -## Step 7: Inspect Claude Code requests +## Step 6: Inspect Claude Code requests To inspect the requests Claude Code sends, run on your host: @@ -176,7 +166,7 @@ $ docker model requests --model ai/devstral-small-2 | jq . This helps you debug prompts, context usage, and compatibility issues without attaching to the sandbox. -## Step 8: Package `gpt-oss` with a larger context window +## Step 7: Package `gpt-oss` with a larger context window `ai/gpt-oss` defaults to a smaller context window than coding-focused models. To use it for repository-scale prompts, package a larger variant on @@ -203,8 +193,7 @@ deleting it: $ sbx stop claude-dmr ``` -To remove the sandbox and everything inside, including the persistent -environment file: +To remove the sandbox and everything inside: ```console $ sbx rm claude-dmr diff --git a/content/manuals/ai/sandboxes/customize/kit-examples.md b/content/manuals/ai/sandboxes/customize/kit-examples.md index a3e06446bd68..3f61d4d5a9ab 100644 --- a/content/manuals/ai/sandboxes/customize/kit-examples.md +++ b/content/manuals/ai/sandboxes/customize/kit-examples.md @@ -120,9 +120,10 @@ available in every shell, append the source line to file. It's sourced before every bash invocation — interactive shells and non-interactive ones, including agents started with `sbx run` and commands run with `sbx exec`. Appending here makes the tool available to -the agent regardless of how its shell is launched. The same file is where -you'd set a custom environment variable; see the -[FAQ](../faq.md#how-do-i-set-custom-environment-variables-inside-a-sandbox). +the agent regardless of how its shell is launched. Use +[`environment.variables`](kit-reference.md#environment) for ordinary variables +declared by a kit. To pass variables when creating a sandbox, use +[`-e` or `--env-file`](../usage.md#set-environment-variables). ```yaml {title="nvm/spec.yaml"} schemaVersion: "2" diff --git a/content/manuals/ai/sandboxes/faq.md b/content/manuals/ai/sandboxes/faq.md index 268e29e3ab4e..c2c67cef7d0b 100644 --- a/content/manuals/ai/sandboxes/faq.md +++ b/content/manuals/ai/sandboxes/faq.md @@ -89,50 +89,16 @@ $ export SBX_NO_TELEMETRY=1 ## How do I set custom environment variables inside a sandbox? -The [`sbx secret`](/reference/cli/sbx/secret/) command only supports a fixed set -of [services](security/credentials.md#built-in-services) (Anthropic, OpenAI, -GitHub, and others). If your agent needs an environment variable that isn't -tied to a supported service, such as `BRAVE_API_KEY` or a custom internal -token, write it to `/etc/sandbox-persistent.sh` inside the sandbox. This -file is sourced on every shell login, so the variable persists across agent -sessions for the sandbox's lifetime. - -Use `sbx exec` to append the export: - -```console -$ sbx exec -d bash -c "echo 'export BRAVE_API_KEY=your_key' >> /etc/sandbox-persistent.sh" -``` - -The `bash -c` wrapper is required so the `>>` redirect runs inside the -sandbox instead of on your host. - -> [!NOTE] -> Unlike `sbx secret`, which injects credentials through a host-side proxy -> without exposing them to the agent, this approach stores the value inside -> 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 for -interactive sessions and for agents started with `sbx run`. - -A variable only takes effect for sessions and agents started *after* it's -added. If an agent is already running when you append to the file, restart -it (or stop and start the sandbox) to pick up the new value. - -Running commands directly with `sbx exec ` does not invoke -a shell, so the persistent environment file is not sourced. Wrap the -command in `bash -c` to load the environment: - -```console -$ sbx exec bash -c "your-command" -``` - -To verify the variable is set, open a shell in the sandbox: - -```console -$ sbx exec -it bash -$ echo $BRAVE_API_KEY -``` +Starting with `sbx` version 0.39.0, use `-e`/`--env` or `--env-file` with +`sbx run` and `sbx create`. See +[Set environment variables](usage.md#set-environment-variables) for syntax, +precedence rules, persistent configuration for an existing sandbox, and +guidance for credentials. + +Variables in `/etc/sandbox-persistent.sh` are available to interactive sessions +and agents started with `sbx run`. A variable only takes effect for sessions +and agents started after it's added. Restart a running agent, or stop and start +the sandbox, to pick up the new value. ## Why do agents run without approval prompts? diff --git a/content/manuals/ai/sandboxes/usage.md b/content/manuals/ai/sandboxes/usage.md index ef4286e39b6b..ca140c5c58d3 100644 --- a/content/manuals/ai/sandboxes/usage.md +++ b/content/manuals/ai/sandboxes/usage.md @@ -96,6 +96,49 @@ Unlike `run`, `create` requires an explicit workspace path. Attach later with $ sbx run --name my-project ``` +## Set environment variables + +> [!NOTE] +> The `-e`/`--env` and `--env-file` flags require `sbx` version 0.39.0 or +> later. + +Pass `-e` or `--env` to `sbx run` or `sbx create` to set an environment +variable in the sandbox: + +```console +$ sbx run -e LOG_LEVEL=debug claude +``` + +Specify a variable name without a value to copy its value from the host +environment: + +```console +$ export API_URL=https://api.example.com +$ sbx run -e API_URL claude +``` + +To load multiple variables, pass one or more environment files: + +```console +$ sbx create --name my-project --env-file .env.sandbox claude . +``` + +The flags follow `docker run` precedence rules. Values passed with `-e` +override values from environment files. When you pass multiple environment +files, a value in a later file overrides the same variable in an earlier file. + +When either command creates a sandbox, the variables are stored with the +sandbox. They are also available to the agent session started by `sbx run`. +When `sbx run` re-attaches to an existing sandbox, the variables apply to that +agent session without changing the sandbox's stored environment. To set +variables for one command instead, use `sbx exec -e` or +`sbx exec --env-file`. + +Environment variables are readable by processes inside the sandbox. For API +keys and other supported credentials, use +[`sbx secret`](security/credentials.md) so the host-side proxy can inject the +credential without exposing its value to the agent. + ## Run commands inside a sandbox To get a shell inside a running sandbox, use [`sbx exec`](/reference/cli/sbx/exec/): diff --git a/content/manuals/ai/sandboxes/workflows.md b/content/manuals/ai/sandboxes/workflows.md index a6548de97f40..b0ae1e29653e 100644 --- a/content/manuals/ai/sandboxes/workflows.md +++ b/content/manuals/ai/sandboxes/workflows.md @@ -515,7 +515,10 @@ at launch and routes them through its proxy — the credential is never stored i sbx's state and never appears inside the sandbox container. This only applies to those specific credential variables. The sandbox does not -forward arbitrary environment variables from the host into the sandbox. +forward arbitrary host environment variables unless you pass them explicitly +with [`-e` or `--env-file`](usage.md#set-environment-variables). Explicitly +passed values are readable by processes inside the sandbox and don't receive +the host-side proxy protection used for supported credentials. For multiple credentials at once, use `--env-file` with a file of `op://` references: From 93a95a5af75ccff014d83c29accb87b534c09fac Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:55:51 +0000 Subject: [PATCH 2/6] docs: consolidate sandbox environment guidance The FAQ duplicated environment-variable instructions that now belong in the command-oriented usage page. Move the persistent-shell guidance there and distinguish ordinary variables from proxy-managed service and custom secrets. --- content/manuals/ai/sandboxes/usage.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/content/manuals/ai/sandboxes/usage.md b/content/manuals/ai/sandboxes/usage.md index ca140c5c58d3..22a9a2fbb635 100644 --- a/content/manuals/ai/sandboxes/usage.md +++ b/content/manuals/ai/sandboxes/usage.md @@ -134,10 +134,25 @@ agent session without changing the sandbox's stored environment. To set variables for one command instead, use `sbx exec -e` or `sbx exec --env-file`. +To persist a variable across future sessions of an existing sandbox, append an +export to `/etc/sandbox-persistent.sh`: + +```console +$ sbx exec -d bash -c "echo 'export INTERNAL_API_URL=https://api.example.com' >> /etc/sandbox-persistent.sh" +``` + +The `bash -c` wrapper ensures the `>>` redirect runs inside the sandbox instead +of on your host. The file is sourced when Bash starts inside the sandbox, +including for interactive sessions and agents started with `sbx run`. A command +passed directly to `sbx exec` doesn't start a shell. Wrap that command in +`bash -c` if it needs variables from the persistent environment file. + Environment variables are readable by processes inside the sandbox. For API -keys and other supported credentials, use -[`sbx secret`](security/credentials.md) so the host-side proxy can inject the -credential without exposing its value to the agent. +keys and other credentials, use [`sbx secret set`](security/credentials.md#store-a-secret) +for a supported service or the experimental +[`sbx secret set-custom`](security/credentials.md#custom-secrets) for a +credential sent to known hosts. The host-side proxy can then inject the real +value without exposing it to the agent. ## Run commands inside a sandbox From 8ff5d28f004046514aeaaba0a8ccf15ce267595f Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Wed, 12 Aug 2026 13:46:21 +0000 Subject: [PATCH 3/6] docs: clarify sandbox environment examples The Model Runner guide contained a grammatical error and an unclear reason for creating before running. Clarify that verification flow and distinguish the 1Password env-file option from the sbx flag while preserving proxy-managed credential behavior. --- content/guides/claude-code-sandbox-model-runner.md | 9 ++++----- content/manuals/ai/sandboxes/workflows.md | 8 ++++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/content/guides/claude-code-sandbox-model-runner.md b/content/guides/claude-code-sandbox-model-runner.md index 053c025cafe5..c65d429da32a 100644 --- a/content/guides/claude-code-sandbox-model-runner.md +++ b/content/guides/claude-code-sandbox-model-runner.md @@ -104,8 +104,8 @@ $ sbx create --name claude-dmr \ ``` `sbx run` would also work, but it launches Claude Code immediately. Creating -the sandbox first gives you a chance to verify the endpoint before the agent -starts. +the sandbox first lets you confirm the variable and test connectivity before +the agent starts. You don't need to set an Anthropic API key or run `sbx secret set anthropic`. Docker Model Runner doesn't authenticate the local endpoint, @@ -151,9 +151,8 @@ $ sbx run claude-dmr -- --model ai/devstral-small-2 ``` Everything after `--` is forwarded to the Claude Code CLI. Because -`ANTHROPIC_BASE_URL` is stored in the sandbox's environment, so Claude -Code routes requests to Docker Model Runner on your host instead of -`api.anthropic.com`. +`ANTHROPIC_BASE_URL` is stored in the sandbox's environment, Claude Code routes +requests to Docker Model Runner on your host instead of `api.anthropic.com`. ## Step 6: Inspect Claude Code requests diff --git a/content/manuals/ai/sandboxes/workflows.md b/content/manuals/ai/sandboxes/workflows.md index b0ae1e29653e..bc9729ac86f7 100644 --- a/content/manuals/ai/sandboxes/workflows.md +++ b/content/manuals/ai/sandboxes/workflows.md @@ -520,8 +520,12 @@ with [`-e` or `--env-file`](usage.md#set-environment-variables). Explicitly passed values are readable by processes inside the sandbox and don't receive the host-side proxy protection used for supported credentials. -For multiple credentials at once, use `--env-file` with a file of `op://` -references: +For multiple credentials at once, pass an environment file of `op://` +references to `op run`. Here, `--env-file` is an `op run` option, not an `sbx` +option. The `op` CLI resolves the references on the host before starting `sbx`. +Because these are built-in service variables, `sbx` handles the resolved +values as proxy-managed credentials, and the real values don't enter the +sandbox: ```console $ cat .sbx-secrets.env From 99eaa39885f0a332451ce7b8ae4bc66d87f2aad8 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Wed, 12 Aug 2026 13:51:29 +0000 Subject: [PATCH 4/6] docs: streamline 1Password sandbox guidance The environment-variable caveat distracted from the 1Password workflow and repeated material from the usage page. Remove the aside and identify the multi-credential example as an op run environment-file workflow. --- content/manuals/ai/sandboxes/workflows.md | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/content/manuals/ai/sandboxes/workflows.md b/content/manuals/ai/sandboxes/workflows.md index bc9729ac86f7..12aa44ea6777 100644 --- a/content/manuals/ai/sandboxes/workflows.md +++ b/content/manuals/ai/sandboxes/workflows.md @@ -514,18 +514,7 @@ $ GEMINI_API_KEY="op://Work/Google/key" op run -- sbx run gemini at launch and routes them through its proxy — the credential is never stored in sbx's state and never appears inside the sandbox container. -This only applies to those specific credential variables. The sandbox does not -forward arbitrary host environment variables unless you pass them explicitly -with [`-e` or `--env-file`](usage.md#set-environment-variables). Explicitly -passed values are readable by processes inside the sandbox and don't receive -the host-side proxy protection used for supported credentials. - -For multiple credentials at once, pass an environment file of `op://` -references to `op run`. Here, `--env-file` is an `op run` option, not an `sbx` -option. The `op` CLI resolves the references on the host before starting `sbx`. -Because these are built-in service variables, `sbx` handles the resolved -values as proxy-managed credentials, and the real values don't enter the -sandbox: +To resolve multiple credentials, pass an environment file to `op run`: ```console $ cat .sbx-secrets.env From f6fd7043c69295d48a1cd7a792b0022f2ed8e151 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Wed, 12 Aug 2026 13:55:46 +0000 Subject: [PATCH 5/6] docs: keep 1Password workflow unchanged The 1Password environment-file example is correct and outside the scope of the sbx environment flag documentation. Restore the section to its original wording. --- content/manuals/ai/sandboxes/workflows.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/content/manuals/ai/sandboxes/workflows.md b/content/manuals/ai/sandboxes/workflows.md index 12aa44ea6777..a6548de97f40 100644 --- a/content/manuals/ai/sandboxes/workflows.md +++ b/content/manuals/ai/sandboxes/workflows.md @@ -514,7 +514,11 @@ $ GEMINI_API_KEY="op://Work/Google/key" op run -- sbx run gemini at launch and routes them through its proxy — the credential is never stored in sbx's state and never appears inside the sandbox container. -To resolve multiple credentials, pass an environment file to `op run`: +This only applies to those specific credential variables. The sandbox does not +forward arbitrary environment variables from the host into the sandbox. + +For multiple credentials at once, use `--env-file` with a file of `op://` +references: ```console $ cat .sbx-secrets.env From 6f1065d7b8a5ada2e1d3bcabf756298c654861cb Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 13 Aug 2026 08:53:49 +0000 Subject: [PATCH 6/6] docs: preserve persistent env restart guidance The rebased FAQ update documented that persisted variables only reach newly started sessions and agents. Keep the FAQ discoverable and add the same operational caveat to the canonical usage procedure. --- content/manuals/ai/sandboxes/usage.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/content/manuals/ai/sandboxes/usage.md b/content/manuals/ai/sandboxes/usage.md index 22a9a2fbb635..8cdd1ca96ddf 100644 --- a/content/manuals/ai/sandboxes/usage.md +++ b/content/manuals/ai/sandboxes/usage.md @@ -147,6 +147,10 @@ including for interactive sessions and agents started with `sbx run`. A command passed directly to `sbx exec` doesn't start a shell. Wrap that command in `bash -c` if it needs variables from the persistent environment file. +A variable added to the file only takes effect for sessions and agents started +afterward. Restart a running agent, or stop and start the sandbox, to pick up +the new value. + Environment variables are readable by processes inside the sandbox. For API keys and other credentials, use [`sbx secret set`](security/credentials.md#store-a-secret) for a supported service or the experimental