diff --git a/content/manuals/ai/sandboxes/cloud/move.md b/content/manuals/ai/sandboxes/cloud/move.md index 2e2f053846..3b0de88b0a 100644 --- a/content/manuals/ai/sandboxes/cloud/move.md +++ b/content/manuals/ai/sandboxes/cloud/move.md @@ -72,10 +72,12 @@ appear in the cloud destination. When the source has a workspace, the CLI warns and asks for confirmation. The `--force` flag skips the prompt but doesn't include those files. -The destination uses cloud network policy. Local network rules don't transfer. -If the local source has HTTP method or path restrictions, the CLI warns and -asks for confirmation because those restrictions won't apply in the cloud. -`--force` skips the prompt but retains the warning. +The destination uses cloud network policy and the network rules of the +sandbox's kit, or of its built-in agent, as `sbx --cloud create` does. Network +rules you added locally don't transfer. If the local source has HTTP method or +path restrictions, the CLI warns and asks for confirmation because those +restrictions won't apply in the cloud. `--force` skips the prompt but retains +the warning. Published TCP sandbox ports are published on the cloud destination with cloud URLs. Ports that the cloud refuses are skipped with a warning. Host port diff --git a/content/manuals/ai/sandboxes/cloud/network-policy.md b/content/manuals/ai/sandboxes/cloud/network-policy.md index 2f2f6ab2f3..85cf01026e 100644 --- a/content/manuals/ai/sandboxes/cloud/network-policy.md +++ b/content/manuals/ai/sandboxes/cloud/network-policy.md @@ -26,7 +26,8 @@ precedence over allow rules across the applicable policies. Cloud creation uses cloud account policy, network rules passed to the command, and network access declared by the agent or kit. Both `sbx --cloud create` and `sbx --cloud run` leave local network and organization policies on the host. -Moving a local sandbox to the cloud also uses cloud policy. +Moving a local sandbox to the cloud works the same way, except that rules you +added locally don't transfer. Define the intended policy in the cloud store. After creation, inspect the configured rules and [verify connection decisions](#inspect-network-policy). diff --git a/content/manuals/ai/sandboxes/cloud/usage.md b/content/manuals/ai/sandboxes/cloud/usage.md index 2eafc97acb..3f1320f36c 100644 --- a/content/manuals/ai/sandboxes/cloud/usage.md +++ b/content/manuals/ai/sandboxes/cloud/usage.md @@ -201,6 +201,12 @@ $ sbx --cloud ttl cloud-project $ sbx --cloud ttl +30m cloud-project ``` +A stopped sandbox has no running time-to-live, so `sbx --cloud ttl` reports +that it is stopped instead of showing an expiration time. Its time-to-live +starts again when the sandbox resumes. In `--json` output, `stopped` and +`ttl_paused` are `true`, and the expiry fields still hold the previous +deadline. While the sandbox is resuming, only `ttl_paused` is `true`. + ## Stop or remove a sandbox Stop a cloud sandbox while preserving its memory and filesystem: @@ -223,8 +229,9 @@ You can also use `sbx --cloud run claude --name cloud-project`, or run the agent without `--name` and select the sandbox when prompted. Add `--detached` to a named run to resume without attaching. -Resuming keeps the sandbox ID and state. Check its expiration with -`sbx --cloud ttl cloud-project` after resuming. +Resuming keeps the sandbox ID and state, and starts a new time-to-live +period. Check its expiration with `sbx --cloud ttl cloud-project` after +resuming. If stop or resume reports that an existing sandbox was not found, the operation may be disabled for your account. @@ -241,6 +248,20 @@ $ sbx --cloud rm cloud-project Removal asks for confirmation, deletes the cloud sandbox, and can't be undone. Use `--force` to skip the prompt in scripts. +### Remove a sandbox when the agent exits + +Pass `--rm` to an interactive `run` to remove the sandbox when the agent +session ends: + +```console +$ sbx --cloud run --rm claude +``` + +The detach gesture is turned off for that session, and you can't combine +`--rm` with `--detached`. If the session ends without completing, for example +because the connection drops, the sandbox is kept and the CLI prints the +command to remove it. + ## Use persistent volumes Cloud volumes are experimental and preserve data independently of a sandbox. diff --git a/content/manuals/ai/sandboxes/customize/author/_index.md b/content/manuals/ai/sandboxes/customize/author/_index.md index dbf55549fc..e198e547d9 100644 --- a/content/manuals/ai/sandboxes/customize/author/_index.md +++ b/content/manuals/ai/sandboxes/customize/author/_index.md @@ -198,3 +198,34 @@ can override these defaults with `--cpus` and `--memory` when creating a sandbox Put these settings on the workload. `sbx` ignores resource settings on mixins added separately, and it doesn't use the capability's `gpu` field to select GPUs. + +## Keep the sandbox running after sessions end + +By default, a local sandbox stops automatically shortly after its last session +disconnects. A kit that runs a service, such as a development server on a +published port, can ask the sandbox to keep running instead. Declare the +[`long-running@1` capability](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/capabilities/com.docker.sandbox/long-running@1.md), +which takes no `config`: + +```yaml +capabilities: + - type: com.docker.sandbox/long-running@1 +``` + +A sandbox created with this kit behaves like one started with +[`sbx run --detached`](/manuals/ai/sandboxes/usage.md#keep-a-sandbox-running-in-the-background): +it keeps running until someone stops or removes it, including after you attach +to it and disconnect. When a workload, mixin, or set declares the capability, +it applies to the whole sandbox. + +A kit that declares the capability runs only where the runtime can provide it. +If the kit also works when the sandbox stops after its sessions end, set +`optional: true` on the entry. A runtime that can't provide the capability +then skips it instead of refusing the kit. In `sbx`, two cases can't provide +it: + +- Cloud sandboxes can't provide this capability. `sbx --cloud` refuses a kit + that requires it and skips an optional entry. +- `sbx kit add` can't apply the capability to a running sandbox. A required + entry fails, and an optional entry is skipped with a warning. Recreate the + sandbox with the kit to apply it. diff --git a/content/manuals/ai/sandboxes/governance/access-controls/local.md b/content/manuals/ai/sandboxes/governance/access-controls/local.md index 7dfb5024ea..a080ef9702 100644 --- a/content/manuals/ai/sandboxes/governance/access-controls/local.md +++ b/content/manuals/ai/sandboxes/governance/access-controls/local.md @@ -271,6 +271,14 @@ UDP follows the same organization and local policy precedence as TCP. It is refused when the destination requires an HTTP, SOCKS5, system, or PAC-selected proxy, because those proxies can't carry UDP. ICMP remains blocked. +UDP to local-network destinations is blocked before any policy is evaluated, +so no allow rule can permit it, including one that allows all hosts. This +covers multicast, link-local, and unspecified addresses, `255.255.255.255`, +and the broadcast addresses of the host's networks. As a result, discovery +protocols that use multicast, such as mDNS and SSDP, don't work from a +sandbox. UDP to `host.docker.internal` isn't affected. The network log records +these connections under the rule ``. + Inspect UDP rules or check a destination: ```console diff --git a/content/manuals/ai/sandboxes/mcp-gateway.md b/content/manuals/ai/sandboxes/mcp-gateway.md index d65ca5c529..9048d41d48 100644 --- a/content/manuals/ai/sandboxes/mcp-gateway.md +++ b/content/manuals/ai/sandboxes/mcp-gateway.md @@ -339,6 +339,14 @@ If none of these provide a scope set, `sbx` omits the OAuth `scope` parameter so the authorization server applies its default grant. Other advertised scopes aren't included in the fallback. +When `sbx` uses recorded defaults or resource-required scopes, it also +requests `offline_access` if the authorization server advertises it. The +server can then issue a refresh token, so you don't have to authorize again +when the access token expires. Scopes passed to `sbx mcp auth --scope` are +requested exactly as given, without `offline_access`. Existing credentials +issued without a refresh token aren't upgraded; run `sbx mcp auth` again to +request a new grant. + Pass `--no-scope` to suppress the recorded defaults, resource-required scopes, and advertised scope fallback for one authorization, without changing the stored defaults: diff --git a/content/manuals/ai/sandboxes/usage.md b/content/manuals/ai/sandboxes/usage.md index 98578619f2..c525db0acb 100644 --- a/content/manuals/ai/sandboxes/usage.md +++ b/content/manuals/ai/sandboxes/usage.md @@ -67,6 +67,23 @@ such as `168h`, an RFC 3339 timestamp, or a Unix timestamp. The older Run `sbx prune` without flags to confirm and remove all stopped sandboxes. +### Remove a sandbox when the agent exits + +Pass `--rm` to `sbx run` for a throwaway session. The sandbox is removed when +the agent exits, without a confirmation prompt: + +```console +$ sbx run --rm claude +``` + +The sandbox is removed however the agent exits, and `sbx run` exits with the +agent's exit status. If `sbx run` created the sandbox and the agent fails +to start, the sandbox is also removed. If you reattach to an existing sandbox +with `--rm`, that sandbox is removed only after its agent session finishes. + +`--rm` needs an attached agent session to know when to remove the sandbox, so +you can't combine it with `--detached` or `--detach-keys`. + ## Choose a workspace `sbx run` mounts the current directory when you don't pass a workspace path. @@ -133,8 +150,8 @@ $ sbx run claude --name spike ~/my-project ## Create without attaching [`sbx run`](/reference/cli/sbx/run/) creates the sandbox and attaches you to the -agent. To create a sandbox with the current directory mounted in the background -without attaching: +agent. To create a sandbox with the current directory mounted, without +attaching to it: ```console $ sbx create --name my-project claude . @@ -152,6 +169,25 @@ After `sbx create` finishes, the local sandbox stops automatically when no sessions keep it running. Its files and configuration persist. Running `sbx run --name ` starts it again and attaches you to the agent. +### Keep a sandbox running in the background + +To keep a sandbox running after every session ends, for example to serve an +application on a [published port](#publish-ports), start it with +`sbx run --detached` (`-d`). The command starts the sandbox, prints its ID, +and returns without opening an agent session: + +```console +$ sbx run -d --name my-project claude . +``` + +A detached sandbox keeps running until you stop it with `sbx stop` or remove +it with `sbx rm`. You can attach to it with `sbx run --name` or run commands +with `sbx exec`, and it keeps running after those sessions end. + +Running `sbx run -d --name ` against an existing sandbox, such +as one created with `sbx create`, switches it to detached mode permanently. To +return to the default behavior, remove the sandbox and create it again. + ## Set environment variables > [!NOTE] diff --git a/data/sbx_cli/sbx_mcp_add.yaml b/data/sbx_cli/sbx_mcp_add.yaml index fa784bf2d8..e279d979d5 100644 --- a/data/sbx_cli/sbx_mcp_add.yaml +++ b/data/sbx_cli/sbx_mcp_add.yaml @@ -112,6 +112,10 @@ description: |- chosen. --no-scope suppresses all scope fallbacks and requests the server's default grant. + When using recorded defaults or resource scopes, sbx also requests offline_access + if the authorization server advertises it, allowing refresh tokens. To request + an exact set without this addition, use 'sbx mcp auth --scope ...'. + Scopes you name are checked against the union of two documents a server can publish: the authorization server's RFC 8414 scopes_supported and the resource's own RFC 9728 protected-resource metadata (some servers, e.g. diff --git a/data/sbx_cli/sbx_mcp_auth.yaml b/data/sbx_cli/sbx_mcp_auth.yaml index 42761f9874..549f4b120a 100644 --- a/data/sbx_cli/sbx_mcp_auth.yaml +++ b/data/sbx_cli/sbx_mcp_auth.yaml @@ -27,6 +27,10 @@ description: |- flag, and the consent block marks that set as derived rather than chosen. Pass --no-scope to suppress all scope fallbacks and request the server's default grant. + When using recorded defaults or resource scopes, sbx also requests offline_access + if the authorization server advertises it, allowing refresh tokens. An explicit + --scope on this command requests exactly that set, without adding offline_access. + Scopes you choose are checked against both the authorization server's RFC 8414 scopes_supported and the resource's RFC 9728 metadata. A scope present in neither prints a warning but is still requested. If neither document publishes scopes, diff --git a/data/sbx_cli/sbx_move.yaml b/data/sbx_cli/sbx_move.yaml index e0c7f7246d..719432968b 100644 --- a/data/sbx_cli/sbx_move.yaml +++ b/data/sbx_cli/sbx_move.yaml @@ -31,10 +31,12 @@ description: |- - Volumes and environment variables attached to a cloud sandbox, when moving to local. A local sandbox's environment is part of its image and travels to the cloud. - - Network policies. Moving to cloud uses cloud policies; moving to local - starts with the host's default policy. Active local L7 (HTTP) rules - prompt before a move to cloud; --force skips the prompt but keeps - the warning. + - Network rules you added locally. The sandbox's kit network rules do + travel: moving to cloud applies them, as 'sbx create --cloud' does. If + the kit can't be resolved, move warns and the account's cloud policy + applies. Moving to local starts with the host's default policy. Active + local L7 (HTTP) rules prompt before a move to cloud; --force skips the + prompt but keeps the warning. - Cloud URLs and host port bindings. Moving to cloud republishes TCP ports under new cloud URLs; a port the cloud refuses is skipped with a warning. Moving to local saves the published TCP ports and binds them diff --git a/data/sbx_cli/sbx_run.yaml b/data/sbx_cli/sbx_run.yaml index 15eae49b91..3d91534c6a 100644 --- a/data/sbx_cli/sbx_run.yaml +++ b/data/sbx_cli/sbx_run.yaml @@ -124,6 +124,9 @@ options: - name: pull default_value: always usage: Image pull policy (always|missing|never) + - name: rm + default_value: "false" + usage: Remove the sandbox after the agent session exits - name: skills usage: | Shared skills store mode for the agent's skills directory (e.g. ~/.claude/skills): off, readonly (store linked in read-only, directory stays writable), or readwrite (store mounted over it, writes are shared). Default: readonly, or the configured skills.defaultMode setting. Can only be used when creating a new sandbox. diff --git a/data/sbx_cli/sbx_settings_set.yaml b/data/sbx_cli/sbx_settings_set.yaml index acf619f7ba..be8269f1e2 100644 --- a/data/sbx_cli/sbx_settings_set.yaml +++ b/data/sbx_cli/sbx_settings_set.yaml @@ -3,6 +3,8 @@ synopsis: Set a setting override description: |- Set a user override for a setting. + Administrator constraints apply to saved overrides. A conflicting value is rejected. + The value is parsed according to the setting's type: bool "true" or "false" int integer value diff --git a/data/sbx_cli/sbx_settings_unset.yaml b/data/sbx_cli/sbx_settings_unset.yaml index a26570a7b8..87cb58957a 100644 --- a/data/sbx_cli/sbx_settings_unset.yaml +++ b/data/sbx_cli/sbx_settings_unset.yaml @@ -3,7 +3,8 @@ synopsis: Remove a setting override description: |- Remove the user override for a setting. - The setting then evaluates from its environment variable or default value. + Administrator policy remains in effect. Otherwise, the setting evaluates from + its environment variable, remote default, or built-in default. usage: sbx settings unset [flags] options: - name: help