diff --git a/data/sbx_cli/sbx_create.yaml b/data/sbx_cli/sbx_create.yaml index df9925ad00..0175c8e627 100644 --- a/data/sbx_cli/sbx_create.yaml +++ b/data/sbx_cli/sbx_create.yaml @@ -88,6 +88,9 @@ options: - name: on-timeout usage: | What happens when --ttl lapses: 'stop' stops the sandbox in place so it can be started again later, 'restart' keeps it running by stopping and immediately starting it, or 'delete' removes it. Omit the flag and the server stops the sandbox when it can be started again later, and deletes it otherwise. With 'restart' a supplied --ttl must be at least 1h (cloud only). + - name: platform + usage: | + Target platform: linux/amd64 or linux/arm64 (cloud only). With --image-ref, omitting it lets the server resolve the platform from the image and the CLI sends the local CPU as a hint for multi-platform images. With --template, omitting it inherits the template platform. With a sandbox kit, the kit's template is built for this platform and cached apart from other platforms; omitting it keeps the server's choice. - name: publish shorthand: p default_value: '[]' diff --git a/data/sbx_cli/sbx_create_claude.yaml b/data/sbx_cli/sbx_create_claude.yaml index 027eda0a4d..f9f9dd0754 100644 --- a/data/sbx_cli/sbx_create_claude.yaml +++ b/data/sbx_cli/sbx_create_claude.yaml @@ -95,6 +95,9 @@ inherited_options: - name: on-timeout usage: | What happens when --ttl lapses: 'stop' stops the sandbox in place so it can be started again later, 'restart' keeps it running by stopping and immediately starting it, or 'delete' removes it. Omit the flag and the server stops the sandbox when it can be started again later, and deletes it otherwise. With 'restart' a supplied --ttl must be at least 1h (cloud only). + - name: platform + usage: | + Target platform: linux/amd64 or linux/arm64 (cloud only). With --image-ref, omitting it lets the server resolve the platform from the image and the CLI sends the local CPU as a hint for multi-platform images. With --template, omitting it inherits the template platform. With a sandbox kit, the kit's template is built for this platform and cached apart from other platforms; omitting it keeps the server's choice. - name: publish shorthand: p default_value: '[]' diff --git a/data/sbx_cli/sbx_create_codex.yaml b/data/sbx_cli/sbx_create_codex.yaml index 3a82068080..a9d9290877 100644 --- a/data/sbx_cli/sbx_create_codex.yaml +++ b/data/sbx_cli/sbx_create_codex.yaml @@ -95,6 +95,9 @@ inherited_options: - name: on-timeout usage: | What happens when --ttl lapses: 'stop' stops the sandbox in place so it can be started again later, 'restart' keeps it running by stopping and immediately starting it, or 'delete' removes it. Omit the flag and the server stops the sandbox when it can be started again later, and deletes it otherwise. With 'restart' a supplied --ttl must be at least 1h (cloud only). + - name: platform + usage: | + Target platform: linux/amd64 or linux/arm64 (cloud only). With --image-ref, omitting it lets the server resolve the platform from the image and the CLI sends the local CPU as a hint for multi-platform images. With --template, omitting it inherits the template platform. With a sandbox kit, the kit's template is built for this platform and cached apart from other platforms; omitting it keeps the server's choice. - name: publish shorthand: p default_value: '[]' diff --git a/data/sbx_cli/sbx_create_cursor.yaml b/data/sbx_cli/sbx_create_cursor.yaml index 1d814e0de3..24a097f387 100644 --- a/data/sbx_cli/sbx_create_cursor.yaml +++ b/data/sbx_cli/sbx_create_cursor.yaml @@ -95,6 +95,9 @@ inherited_options: - name: on-timeout usage: | What happens when --ttl lapses: 'stop' stops the sandbox in place so it can be started again later, 'restart' keeps it running by stopping and immediately starting it, or 'delete' removes it. Omit the flag and the server stops the sandbox when it can be started again later, and deletes it otherwise. With 'restart' a supplied --ttl must be at least 1h (cloud only). + - name: platform + usage: | + Target platform: linux/amd64 or linux/arm64 (cloud only). With --image-ref, omitting it lets the server resolve the platform from the image and the CLI sends the local CPU as a hint for multi-platform images. With --template, omitting it inherits the template platform. With a sandbox kit, the kit's template is built for this platform and cached apart from other platforms; omitting it keeps the server's choice. - name: publish shorthand: p default_value: '[]' diff --git a/data/sbx_cli/sbx_create_devin.yaml b/data/sbx_cli/sbx_create_devin.yaml index 88eba38d54..bc76d62859 100644 --- a/data/sbx_cli/sbx_create_devin.yaml +++ b/data/sbx_cli/sbx_create_devin.yaml @@ -95,6 +95,9 @@ inherited_options: - name: on-timeout usage: | What happens when --ttl lapses: 'stop' stops the sandbox in place so it can be started again later, 'restart' keeps it running by stopping and immediately starting it, or 'delete' removes it. Omit the flag and the server stops the sandbox when it can be started again later, and deletes it otherwise. With 'restart' a supplied --ttl must be at least 1h (cloud only). + - name: platform + usage: | + Target platform: linux/amd64 or linux/arm64 (cloud only). With --image-ref, omitting it lets the server resolve the platform from the image and the CLI sends the local CPU as a hint for multi-platform images. With --template, omitting it inherits the template platform. With a sandbox kit, the kit's template is built for this platform and cached apart from other platforms; omitting it keeps the server's choice. - name: publish shorthand: p default_value: '[]' diff --git a/data/sbx_cli/sbx_create_docker-agent.yaml b/data/sbx_cli/sbx_create_docker-agent.yaml index 1f76b59c3a..f336967fe1 100644 --- a/data/sbx_cli/sbx_create_docker-agent.yaml +++ b/data/sbx_cli/sbx_create_docker-agent.yaml @@ -95,6 +95,9 @@ inherited_options: - name: on-timeout usage: | What happens when --ttl lapses: 'stop' stops the sandbox in place so it can be started again later, 'restart' keeps it running by stopping and immediately starting it, or 'delete' removes it. Omit the flag and the server stops the sandbox when it can be started again later, and deletes it otherwise. With 'restart' a supplied --ttl must be at least 1h (cloud only). + - name: platform + usage: | + Target platform: linux/amd64 or linux/arm64 (cloud only). With --image-ref, omitting it lets the server resolve the platform from the image and the CLI sends the local CPU as a hint for multi-platform images. With --template, omitting it inherits the template platform. With a sandbox kit, the kit's template is built for this platform and cached apart from other platforms; omitting it keeps the server's choice. - name: publish shorthand: p default_value: '[]' diff --git a/data/sbx_cli/sbx_create_gemini.yaml b/data/sbx_cli/sbx_create_gemini.yaml index 649feb769f..22d2afa7f2 100644 --- a/data/sbx_cli/sbx_create_gemini.yaml +++ b/data/sbx_cli/sbx_create_gemini.yaml @@ -95,6 +95,9 @@ inherited_options: - name: on-timeout usage: | What happens when --ttl lapses: 'stop' stops the sandbox in place so it can be started again later, 'restart' keeps it running by stopping and immediately starting it, or 'delete' removes it. Omit the flag and the server stops the sandbox when it can be started again later, and deletes it otherwise. With 'restart' a supplied --ttl must be at least 1h (cloud only). + - name: platform + usage: | + Target platform: linux/amd64 or linux/arm64 (cloud only). With --image-ref, omitting it lets the server resolve the platform from the image and the CLI sends the local CPU as a hint for multi-platform images. With --template, omitting it inherits the template platform. With a sandbox kit, the kit's template is built for this platform and cached apart from other platforms; omitting it keeps the server's choice. - name: publish shorthand: p default_value: '[]' diff --git a/data/sbx_cli/sbx_create_opencode.yaml b/data/sbx_cli/sbx_create_opencode.yaml index 257906ed7a..4365a06f8a 100644 --- a/data/sbx_cli/sbx_create_opencode.yaml +++ b/data/sbx_cli/sbx_create_opencode.yaml @@ -95,6 +95,9 @@ inherited_options: - name: on-timeout usage: | What happens when --ttl lapses: 'stop' stops the sandbox in place so it can be started again later, 'restart' keeps it running by stopping and immediately starting it, or 'delete' removes it. Omit the flag and the server stops the sandbox when it can be started again later, and deletes it otherwise. With 'restart' a supplied --ttl must be at least 1h (cloud only). + - name: platform + usage: | + Target platform: linux/amd64 or linux/arm64 (cloud only). With --image-ref, omitting it lets the server resolve the platform from the image and the CLI sends the local CPU as a hint for multi-platform images. With --template, omitting it inherits the template platform. With a sandbox kit, the kit's template is built for this platform and cached apart from other platforms; omitting it keeps the server's choice. - name: publish shorthand: p default_value: '[]' diff --git a/data/sbx_cli/sbx_create_shell.yaml b/data/sbx_cli/sbx_create_shell.yaml index b3f08809dd..4f50e5ce11 100644 --- a/data/sbx_cli/sbx_create_shell.yaml +++ b/data/sbx_cli/sbx_create_shell.yaml @@ -95,6 +95,9 @@ inherited_options: - name: on-timeout usage: | What happens when --ttl lapses: 'stop' stops the sandbox in place so it can be started again later, 'restart' keeps it running by stopping and immediately starting it, or 'delete' removes it. Omit the flag and the server stops the sandbox when it can be started again later, and deletes it otherwise. With 'restart' a supplied --ttl must be at least 1h (cloud only). + - name: platform + usage: | + Target platform: linux/amd64 or linux/arm64 (cloud only). With --image-ref, omitting it lets the server resolve the platform from the image and the CLI sends the local CPU as a hint for multi-platform images. With --template, omitting it inherits the template platform. With a sandbox kit, the kit's template is built for this platform and cached apart from other platforms; omitting it keeps the server's choice. - name: publish shorthand: p default_value: '[]' diff --git a/data/sbx_cli/sbx_env.yaml b/data/sbx_cli/sbx_env.yaml index 69d20c3f29..b7056de720 100644 --- a/data/sbx_cli/sbx_env.yaml +++ b/data/sbx_cli/sbx_env.yaml @@ -2,224 +2,33 @@ name: sbx env synopsis: | Manage sandboxes declaratively from an sbxenv.yaml file experimental: true -description: | - Manage a sandbox environment declared in an sbxenv.yaml file. +description: |- + Manage a sandbox declared in an sbxenv.yaml file. The file selects the agent, + kits, workspace mounts, environment variables, secrets, and credential bindings. - The file describes the agent, optional mixin kits, workspace mounts, - environment variables, secrets to provision, and per-service credential - bindings. Secrets are provisioned at the environment's sandbox scope so - `sbx env rm` can remove everything it created. + Use create to provision the sandbox, run to start or join its agent session, + exec to run a command, and rm to remove it and its provisioned secrets. + Use plan to preview changes. Changes require approval; --force skips the prompt. - A secret with `command` or `ref` can set `snapshot: true` to resolve on - the host after approval and store the result as a literal. This works locally - and with --cloud. Snapshots do not refresh; recreate the environment to rotate - them. A snapshot cannot set refresh or noVerify. + Lifecycle commands and command-based secrets execute on the host with your + permissions. Keep secret helpers and their dependencies outside writable + sandbox mounts, and use absolute helper paths. - Command secrets run from a fresh temporary directory on the host during - verification and refresh. The host temporary directory must be absolute and must - remain outside writable sandbox mounts. Relative references such as ./helper or - cat token no longer resolve against the project or daemon working directory. Use an absolute - helper path outside shared workspaces. sbx does not copy helpers, inspect their - dependencies, or confine their execution. Helpers and any code or configuration - they load must remain outside writable sandbox mounts. Explicit paths into shared - workspaces and broad mounts exposing host configuration or the host temporary - directory remain unsafe, including mounts added later with sbx mount. + The environment file is mounted read-only by default when shared with the + sandbox. Set sandboxOptions.writableEnvFiles only when you trust the agent + to change what future invocations run on the host. - secrets: - github: - command: gh auth token - snapshot: true + With --cloud, manage a cloud sandbox from the same file. Host workspace mounts, + host port bindings, MCP definitions, registry credentials, and unsnapshotted + dynamic secret sources are unsupported. Clone the project inside the sandbox instead. - A file may declare its own inputs in an `args:` block, each with a default or - `required: true` and an optional description, enum, or pattern. Reference one - as `${{ env.args.NAME }}` anywhere a value appears and supply it with - `--env-arg NAME=VALUE`. + Secrets and bindings are provisioned at creation; changes require recreating + the sandbox. Removal deletes secrets provisioned by this environment; bindings + are retained unless --prune-bindings is passed. Use the same cloud target, + identity, and ordered files for subsequent commands. - A `kits:` entry is either a bare reference or a mapping carrying the - arguments that kit declares, which `--kit-arg` overrides per invocation: - - kits: - - ./mixins/base - - source: ./mixins/tool - args: - version: ${{ env.args.channel }} - - A kit source written as an explicit relative path — `./…`, `../…`, `.`, `..`, or one - ending in `.zip` — is resolved against the directory of the file that declares - it, so a checked-in file reaches the same kits from wherever `sbx` is run. Write a - local kit that way: a bare `kits/tool` is as much a registry reference as a - directory, so it is left as written and resolves from the current directory. - - A `workspace:` names the directory mounted read/write into the sandbox. A - relative path resolves against the directory of the file that declares it — as - a relative kit source does — so `workspace: .` mounts the directory the file - sits in. ${{ env.projectDir }} names the project directory (the one holding the - first PATH, or the current directory when none is named) and ${{ env.fileDir }} - the declaring file's own, for a value that spells its anchor out. Declaring - none mounts nothing — as omitting PATH does for `sbx create` — and the agent - works in the container's own filesystem instead of on your files. Unless the file sets `name:` or --name overrides it, - the sandbox is named after the mounted directory, or after the project directory - when nothing is mounted, so an environment that mounts nothing is still the same - sandbox every time. - - A `lifecycle:` block declares commands that run on the host — outside - the sandbox, with your own privileges — around the sandbox's life: - - lifecycle: - initialize: - - command: test -d app || git clone https://github.com/acme/app - postCreate: - - command: ./scripts/seed-fixtures.sh - preRemove: - - command: ./scripts/archive-state.sh - - Each runs through your shell from the project directory — the one holding the - first PATH, or the current directory when none is named; ${{ env.projectDir }} - names the same place, and commands merged in from a file elsewhere share it. - Change it per command with `workdir:`, and cap a command's runtime with - `timeout:`. - - "initialize" runs on every "create" and every "run", including one that only - attaches, so it can produce the workspace the sandbox mounts; write it to be - repeatable. "postCreate" runs once the sandbox exists, and "preRemove" after - "sbx env rm" is confirmed but before it deletes anything. Whatever stops - preRemove is only a warning, so a teardown that cannot run still cannot make an - environment unremovable; what one adds to the environment instead — a stored - credential, an approved domain — stops the removal, since what follows would - delete it without a plan row ever naming it. "sbx env exec" runs no commands at - all. - - Commands appear in the environment plan with the directory each runs in, and are - approved with it before the invocation does any work. An environment that declares - any of them asks on every invocation, whether or not this one is what runs them, - since approving a command also trusts whatever it invokes, including a script - whose contents change after the answer. Use --skip-host-commands to run none of - them. - - Everything an environment sets up — host commands, credentials, bindings, MCP - registrations, directories, published ports, the sandbox itself and the - variables it runs with — is shown as a plan and approved before anything runs: - - ENVIRONMENT - Name: claude-proj - File: /Users/me/proj/sbxenv.yaml - - SECRETS - + anthropic - ref: op://vault/anthropic/key - refresh: 55m - - LIFECYCLE - ~ initialize: make setup && make seed - command: make setup -> make setup && make seed - workdir: /Users/me/proj - - 1 to add · 1 to change · 0 to destroy - - Approve this plan? (y/N) - - The plan groups resources by the block of the file that declares them, in the - order the blocks are declared, so a row is looked up where it was written. The - mark in front of a row is what applying does to the resource, and the totals - name every mark a plan can carry: "+ to add" and "~ to change" above, - "- to destroy" for what "sbx env rm" takes away, "> to run" for a command that - runs again — a command converges to nothing, so it runs on every apply that - reaches it — and "! to forget" for a resource this environment applied and no - longer declares. Where the file has nothing to say, the text after the row's name does: - that a resource is missing, or that the work waits for the next create, since a - port, a credential, a kit or a postCreate command comes with the sandbox, so - attaching to one that already exists leaves it for the next one that is built. A - resource that is as it was, and already approved, is left out: what is on screen - is what there is to read. - - The lines under a row are the attributes the environment declares, so an edited - kit argument or variable reads as what it was against what it becomes, and a - "command:" or "ref:" secret shows where the credential comes from — a command - that resolves one runs on this machine. A secret's literal "value:" is the one - exception: a plan is both shown here and written to state, so it is named and - stands in as a "sha256:" digest. - - KITS - ~ ./mixins/tool - args.version: 1.2.3 -> 1.2.4 - - ENV - ~ GOFLAGS - value: -mod=mod -> -mod=readonly - - What an attribute was is what this environment last applied here, or — for one it - approved and never applied, such as a binding or a port answered for while - attaching to a sandbox that already exists — what was approved. Either way an - edit shows the value the question is about, whatever the row itself does. - - An environment file that a mount would hand over read-write — which is what - mounting the project directory holding it does — is bound read-only at its own - path inside that mount, leaving the rest of it writable. The file decides what a - later invocation runs on this machine, so an agent able to edit it decides what - the next plan asks about. Declare "sandboxOptions.writableEnvFiles: true" where an - agent is meant to edit it; the plan then says the file is writable, as it says - when a file sits below a mount's own directory, where renaming that directory - reaches it again. - - What was approved is recorded per environment under sbx's state directory, not - next to the file, so a later invocation asks only about what moved — and applies - silently when nothing did. An environment that declares commands running on this - machine is asked about on every invocation, changed or not: the answer is about - the invocation, and what a command does depends on what the project holds when it - runs rather than on the text approved before. "sbx env plan" prints the plan and - changes nothing. - - Use --force (-f) where there is no terminal to answer on. Where an - environment's commands are your own and run many times a day, - "sbx settings set env.rememberHostCommands true" asks about them only when - they change. - - With --cloud, create, run, exec, rm and plan manage a cloud sandbox from the same - file. Supported declarations are agents and kits, sandbox environment variables, - CPU and memory sizing, literal or snapshot secrets and bindings for supported providers, and - host lifecycle commands. Kits can publish TCP ports through cloud endpoints. - Stored cloud secrets are inherited as with cloud create/run; sandbox-scoped secrets - override account defaults, and secrets declared in the file override both. The plan - shows inherited credentials. Removal deletes only secrets provisioned by this environment. - - Bindings merge into the same global credentials.yaml as local environments and - are retained on removal unless --prune-bindings is passed. Cloud must advertise - kit credential support. Third-party kit domains must be approved by the binding; - creation refuses implicit provider-default routing for a bound secret. Bindings - and secrets are provisioned at creation; editing them requires recreating the sandbox. - - Snapshot references use the host's supported CLI resolvers (such as op:// and AWS - Secrets Manager ARNs); the sdk backend is unsupported. An interrupted secret - upload reuses the saved value in the host credential store. If that value is - unavailable, resolution is not repeated: follow the recovery error before cleanup. - - workspace, additionalWorkspaces and clone name host directories, which a cloud - sandbox cannot mount; remove them and clone the project inside the sandbox from a - kit instead. Host port bindings, registry credentials, MCP definitions, custom - credential providers, local sandbox options and dynamic secret sources are also - rejected before host commands or provisioning. Initialize commands may prepare - local kit sources; kit validation follows initialization and precedes cloud baking. - - State belongs to this machine, the selected cloud endpoint, Docker identity and - ordered environment files. Use the same target and files for subsequent commands. - DOCKER_ACCESS_TOKEN uses a token-specific state scope: changing the token starts - with separate state. Use sbx login for state that survives token refresh. - - If creation is interrupted, retry the same command and declaration within 23 hours. - Removal waits for unresolved writes to be recovered. Older unresolved attempts - retain their journal; the error names its path. Before deleting that journal, - confirm the original requests have finished and remove their sandbox and secrets - using ordinary cloud commands in the same account and endpoint. If the outcome - cannot be confirmed, retain the journal and contact support. - - Lifecycle commands inherit the cloud endpoint and expose SBX_SANDBOX_ID after - creation. Sandbox env values apply to new sessions; rejoining a live agent keeps - that process's existing environment. - - sbx --cloud env plan ./sbxenv.yaml - sbx --cloud env run --force --detach ./sbxenv.yaml - sbx --cloud env exec ./sbxenv.yaml -- git status - sbx --cloud env rm --force ./sbxenv.yaml + For file syntax and workflows, see: + https://docs.docker.com/ai/sandboxes/configuration/environment-files/ usage: sbx env COMMAND options: - name: help diff --git a/data/sbx_cli/sbx_env_create.yaml b/data/sbx_cli/sbx_env_create.yaml index cecba3496c..6d5aa1c4e0 100644 --- a/data/sbx_cli/sbx_env_create.yaml +++ b/data/sbx_cli/sbx_env_create.yaml @@ -13,23 +13,10 @@ description: |- supplied by --env-arg, plus ${{ env.projectDir }} and ${{ env.fileDir }}. Nothing else is expanded, so a "$" is literal text. - A directory resolves to the sbxenv.yaml in it and to no other name; any - other file is read only when a PATH names it. The hidden .sbxenv.yaml was once - read as a directory's own environment too, so a project still holding one now - reads as having none. - - With no PATH, an existing .sbxenv.yaml in your home directory is merged - underneath as a base layer for defaults shared across projects; naming any - PATH skips the layer. It may not set "name:", which identifies a single - project, and its "workspace:" must be rooted at ${{ env.projectDir }} — for - the base that is always the directory the invocation runs from, since naming - any PATH skips it — so the base mounts each project's own directory rather - than one directory under all of them. Changing its "agent:" - changes the derived - sandbox name, leaving - sandboxes created under the previous name for "sbx env rm" to miss. - - A list such as "ports" or "mcp.servers" concatenates across layers rather - than overriding, so an entry declared in both appears twice. + A directory PATH selects sbxenv.yaml; a file PATH selects that file. + With no PATH, ~/.sbxenv.yaml supplies shared defaults when present. + Explicit PATHs skip those defaults. Later files override earlier values; + lists such as ports and mcp.servers are concatenated. usage: sbx env create [PATH...] [flags] options: - name: clone diff --git a/data/sbx_cli/sbx_env_exec.yaml b/data/sbx_cli/sbx_env_exec.yaml index 36c7ee012c..7820785b42 100644 --- a/data/sbx_cli/sbx_env_exec.yaml +++ b/data/sbx_cli/sbx_env_exec.yaml @@ -13,23 +13,10 @@ description: |- argument forms the command and the environment file is read from the current directory. - A directory resolves to the sbxenv.yaml in it and to no other name; any - other file is read only when a PATH names it. The hidden .sbxenv.yaml was once - read as a directory's own environment too, so a project still holding one now - reads as having none. - - With no PATH, an existing .sbxenv.yaml in your home directory is merged - underneath as a base layer for defaults shared across projects; naming any - PATH skips the layer. It may not set "name:", which identifies a single - project, and its "workspace:" must be rooted at ${{ env.projectDir }} — for - the base that is always the directory the invocation runs from, since naming - any PATH skips it — so the base mounts each project's own directory rather - than one directory under all of them. Changing its "agent:" - changes the derived - sandbox name, leaving - sandboxes created under the previous name for "sbx env rm" to miss. - - A list such as "ports" or "mcp.servers" concatenates across layers rather - than overriding, so an entry declared in both appears twice. + A directory PATH selects sbxenv.yaml; a file PATH selects that file. + With no PATH, ~/.sbxenv.yaml supplies shared defaults when present. + Explicit PATHs skip those defaults. Later files override earlier values; + lists such as ports and mcp.servers are concatenated. Flags match the behavior of "sbx exec". usage: sbx env exec [flags] [PATH...] -- COMMAND [ARG...] diff --git a/data/sbx_cli/sbx_env_plan.yaml b/data/sbx_cli/sbx_env_plan.yaml index 67a2a37a42..043fc49c66 100644 --- a/data/sbx_cli/sbx_env_plan.yaml +++ b/data/sbx_cli/sbx_env_plan.yaml @@ -17,23 +17,10 @@ description: |- path to the environment file itself. Passing more than one PATH deep-merges them in order, matching the other "sbx env" subcommands. - A directory resolves to the sbxenv.yaml in it and to no other name; any - other file is read only when a PATH names it. The hidden .sbxenv.yaml was once - read as a directory's own environment too, so a project still holding one now - reads as having none. - - With no PATH, an existing .sbxenv.yaml in your home directory is merged - underneath as a base layer for defaults shared across projects; naming any - PATH skips the layer. It may not set "name:", which identifies a single - project, and its "workspace:" must be rooted at ${{ env.projectDir }} — for - the base that is always the directory the invocation runs from, since naming - any PATH skips it — so the base mounts each project's own directory rather - than one directory under all of them. Changing its "agent:" - changes the derived - sandbox name, leaving - sandboxes created under the previous name for "sbx env rm" to miss. - - A list such as "ports" or "mcp.servers" concatenates across layers rather - than overriding, so an entry declared in both appears twice. + A directory PATH selects sbxenv.yaml; a file PATH selects that file. + With no PATH, ~/.sbxenv.yaml supplies shared defaults when present. + Explicit PATHs skip those defaults. Later files override earlier values; + lists such as ports and mcp.servers are concatenated. usage: sbx env plan [PATH...] [flags] options: - name: clone diff --git a/data/sbx_cli/sbx_env_rm.yaml b/data/sbx_cli/sbx_env_rm.yaml index 1375731667..6a9ca0e422 100644 --- a/data/sbx_cli/sbx_env_rm.yaml +++ b/data/sbx_cli/sbx_env_rm.yaml @@ -13,23 +13,10 @@ description: |- in order (docker-compose `-f` semantics), so the same set used to create the environment resolves to the same sandbox on removal. - A directory resolves to the sbxenv.yaml in it and to no other name; any - other file is read only when a PATH names it. The hidden .sbxenv.yaml was once - read as a directory's own environment too, so a project still holding one now - reads as having none. - - With no PATH, an existing .sbxenv.yaml in your home directory is merged - underneath as a base layer for defaults shared across projects; naming any - PATH skips the layer. It may not set "name:", which identifies a single - project, and its "workspace:" must be rooted at ${{ env.projectDir }} — for - the base that is always the directory the invocation runs from, since naming - any PATH skips it — so the base mounts each project's own directory rather - than one directory under all of them. Changing its "agent:" - changes the derived - sandbox name, leaving - sandboxes created under the previous name for "sbx env rm" to miss. - - A list such as "ports" or "mcp.servers" concatenates across layers rather - than overriding, so an entry declared in both appears twice. + A directory PATH selects sbxenv.yaml; a file PATH selects that file. + With no PATH, ~/.sbxenv.yaml supplies shared defaults when present. + Explicit PATHs skip those defaults. Later files override earlier values; + lists such as ports and mcp.servers are concatenated. usage: sbx env rm [PATH...] [flags] options: - name: env-arg diff --git a/data/sbx_cli/sbx_env_run.yaml b/data/sbx_cli/sbx_env_run.yaml index 95b7e7e9c9..28328857d7 100644 --- a/data/sbx_cli/sbx_env_run.yaml +++ b/data/sbx_cli/sbx_env_run.yaml @@ -14,23 +14,10 @@ description: |- supplied by --env-arg, plus ${{ env.projectDir }} and ${{ env.fileDir }}. Nothing else is expanded, so a "$" is literal text. - A directory resolves to the sbxenv.yaml in it and to no other name; any - other file is read only when a PATH names it. The hidden .sbxenv.yaml was once - read as a directory's own environment too, so a project still holding one now - reads as having none. - - With no PATH, an existing .sbxenv.yaml in your home directory is merged - underneath as a base layer for defaults shared across projects; naming any - PATH skips the layer. It may not set "name:", which identifies a single - project, and its "workspace:" must be rooted at ${{ env.projectDir }} — for - the base that is always the directory the invocation runs from, since naming - any PATH skips it — so the base mounts each project's own directory rather - than one directory under all of them. Changing its "agent:" - changes the derived - sandbox name, leaving - sandboxes created under the previous name for "sbx env rm" to miss. - - A list such as "ports" or "mcp.servers" concatenates across layers rather - than overriding, so an entry declared in both appears twice. + A directory PATH selects sbxenv.yaml; a file PATH selects that file. + With no PATH, ~/.sbxenv.yaml supplies shared defaults when present. + Explicit PATHs skip those defaults. Later files override earlier values; + lists such as ports and mcp.servers are concatenated. usage: sbx env run [PATH...] [flags] options: - name: clone diff --git a/data/sbx_cli/sbx_kit_inspect.yaml b/data/sbx_cli/sbx_kit_inspect.yaml index 431f89bb7d..b5728d9081 100644 --- a/data/sbx_cli/sbx_kit_inspect.yaml +++ b/data/sbx_cli/sbx_kit_inspect.yaml @@ -8,6 +8,11 @@ description: |- Pass --kit-arg to preview how the kit resolves with a given set of arguments; the output shows the substituted content. + + --offline skips the daemon-backed kit policy (kit.allowedSources, + kit.allowLocalKits, kit.requireSignature) so the command needs neither + sandboxd nor a signed-in session; it only accepts a local directory or + ZIP reference, since those are the only ones this check applies to. usage: sbx kit inspect REFERENCE [flags] options: - name: format @@ -29,6 +34,10 @@ options: experimental: true usage: | File of name=value kit arguments, one per line (can be repeated); --kit-arg overrides + - name: offline + default_value: "false" + usage: | + Skip the daemon-backed kit policy check; local directory or ZIP references only inherited_options: - name: cloud default_value: "false" @@ -44,5 +53,8 @@ example: |4- # Machine-readable output sbx kit inspect ghcr.io/myorg/my-kit:1.0 --format json + + # Inspect without sandboxd running or a Docker sign-in + sbx kit inspect ./my-kit --offline see_also: - sbx kit - (Experimental) Manage kit artifacts diff --git a/data/sbx_cli/sbx_kit_pull.yaml b/data/sbx_cli/sbx_kit_pull.yaml index 2524e3ef71..59c29cf943 100644 --- a/data/sbx_cli/sbx_kit_pull.yaml +++ b/data/sbx_cli/sbx_kit_pull.yaml @@ -2,18 +2,15 @@ name: sbx kit pull synopsis: Pull a kit artifact from an OCI registry experimental: true description: |- - Pull a kit artifact from an OCI registry and save its layer payload to a file. + Pull a kit artifact from an OCI registry and save its payload to a file. + Use a registry/repo:tag or registry/repo@sha256:digest reference. - The reference should be in the format "registry/repo:tag" or - "registry/repo@sha256:digest" (e.g., "ghcr.io/myorg/my-plugin:1.0"). - - The file extension is chosen automatically based on the kit's format: - schemaVersion: "1" → .zip (legacy ZIP archive) - schemaVersion: "2" → .tar.gz (standard OCI tar+gzip layer) + The output extension follows the resolved artifact format: .zip for v1, + or .tar.gz for v2. Use --output to choose the file path. + For Docker Hub, the sbx login session takes priority. Other registries use + secrets set with sbx secret set --registry. Both fall back to Docker credentials. The registry must support HTTPS. - - Authentication: sbx registry secrets (sbx secret set --registry) take priority, falling back to the Docker credential store. usage: sbx kit pull REFERENCE [flags] options: - name: help diff --git a/data/sbx_cli/sbx_kit_push.yaml b/data/sbx_cli/sbx_kit_push.yaml index a3c1d6f4a0..973600b4d7 100644 --- a/data/sbx_cli/sbx_kit_push.yaml +++ b/data/sbx_cli/sbx_kit_push.yaml @@ -2,31 +2,15 @@ name: sbx kit push synopsis: Push a kit artifact to an OCI registry experimental: true description: |- - Package and push a kit artifact directory to an OCI registry. + Package a kit directory containing spec.yaml and push it to an OCI registry. + Use a registry/repo:tag reference. The kit's schema selects the artifact format. - The directory must contain a valid spec.yaml. The reference should be - in the format "registry/repo:tag" (e.g., "ghcr.io/myorg/my-plugin:1.0"). + Every push attaches provenance. Use --sign to also sign the manifest and + provenance; signing is keyless unless --key is supplied. - The OCI artifact format is selected from the kit's spec.yaml: - schemaVersion: "1" → legacy ZIP-based artifact - schemaVersion: "2" → v2 tar+gzip layer with the spec in the manifest - config blob and standard OCI annotations (so - distribution tooling can read kit metadata - without pulling layers) - - With --sign, the pushed manifest is signed and the Sigstore bundle is - attached to the kit as an OCI referrer. Signing is keyless (Fulcio + - Rekor) unless --key is given for key-based signing. - - Every push also attaches a SLSA provenance attestation as an OCI - referrer, recording the kit's content digests, the declared sandbox - image, and the source git commit when the directory is a working tree. - The provenance is unsigned unless --sign is given, in which case it is - signed as a DSSE in-toto attestation with the same identity or key. - - Authentication: the Docker Hub session from sbx login and sbx registry - secrets (sbx secret set --registry) take priority, falling back to the - Docker credential store. + For Docker Hub, the sbx login session takes priority. Other registries use + secrets set with sbx secret set --registry. Both fall back to Docker credentials. + The registry must support HTTPS. usage: sbx kit push DIRECTORY REFERENCE [flags] options: - name: help diff --git a/data/sbx_cli/sbx_kit_validate.yaml b/data/sbx_cli/sbx_kit_validate.yaml index cf727cabac..034fabe05a 100644 --- a/data/sbx_cli/sbx_kit_validate.yaml +++ b/data/sbx_cli/sbx_kit_validate.yaml @@ -9,6 +9,11 @@ description: |- A kit that declares required arguments is invalid until they are supplied, so pass the same --kit-arg values you would pass to sbx create. + + --offline skips the daemon-backed kit policy (kit.allowedSources, + kit.allowLocalKits, kit.requireSignature) so the command needs neither + sandboxd nor a signed-in session; it only accepts a local directory or + ZIP reference, since those are the only ones this check applies to. usage: sbx kit validate REFERENCE [flags] options: - name: format @@ -30,6 +35,10 @@ options: experimental: true usage: | File of name=value kit arguments, one per line (can be repeated); --kit-arg overrides + - name: offline + default_value: "false" + usage: | + Skip the daemon-backed kit policy check; local directory or ZIP references only inherited_options: - name: cloud default_value: "false" @@ -45,5 +54,8 @@ example: |4- # Supply the arguments a kit declares sbx kit validate ./my-kit --kit-arg region=eu + + # Validate without sandboxd running or a Docker sign-in + sbx kit validate ./my-kit --offline see_also: - sbx kit - (Experimental) Manage kit artifacts diff --git a/data/sbx_cli/sbx_mcp.yaml b/data/sbx_cli/sbx_mcp.yaml index bc1c640729..ba01b1da79 100644 --- a/data/sbx_cli/sbx_mcp.yaml +++ b/data/sbx_cli/sbx_mcp.yaml @@ -22,7 +22,7 @@ see_also: - sbx mcp add - Register an MCP server - sbx mcp auth - Authorize MCP servers - sbx mcp inspect - Show MCP server details - - sbx mcp load - Load an already-registered MCP server into a running sandbox + - sbx mcp load - Load an already-registered MCP server into a sandbox - sbx mcp ls - List MCP servers - sbx mcp rm - Remove a registered MCP server - sbx mcp unload - Unload an MCP server from a running sandbox diff --git a/data/sbx_cli/sbx_mcp_add.yaml b/data/sbx_cli/sbx_mcp_add.yaml index ab196933c5..92b3d1352c 100644 --- a/data/sbx_cli/sbx_mcp_add.yaml +++ b/data/sbx_cli/sbx_mcp_add.yaml @@ -1,220 +1,25 @@ name: sbx mcp add synopsis: Register an MCP server description: |- - Register an MCP server by name. The server is validated and its - specification is stored for use with sbx create/run --static-mcp. + Register an MCP server for use with sbx create/run --static-mcp. + To attach a registered server to a running sandbox, use sbx mcp load. - This command only registers the server. To attach an already-registered - server to a running sandbox, use 'sbx mcp load'. + Use --url for a remote MCP endpoint, a community-registry or server-manifest + URL, or a Docker Hardened Image reference. Other image references are unsupported. + Use --command for a local stdio server. Local servers run on the host with your + full permissions; use only trusted executables. - The --url flag accepts four input formats; the type is auto-detected: + OAuth metadata is discovered automatically for remote endpoints. Use --client-id + for a pre-registered client, or --oauth-authorization-server when the server + publishes no discovery metadata. Confidential clients need a secret stored as + mcp:NAME:client_secret; use sbx secret set without -t to read it from stdin. - - Remote MCP endpoint URL (https://host/mcp — talks MCP at the URL; - OAuth metadata is discovered via RFC 9728/8414). - - MCP community-registry URL (https://registry.modelcontextprotocol.io/v0/servers/...) - — fetches the registry envelope and resolves the OCI image. - - Server-manifest URL (any URL returning a server.json or server.yaml - body shaped like the MCP community-registry schema — GitHub raw URLs, - internal HTTP servers, ad-hoc CDN links all work). - - Docker Hardened Images (DHI) image ref (dhi.io/: or - dhi.io/@sha256:... — the server.json manifest is extracted - from the image's in-toto attestation via the OCI Referrers API). + Use --header for custom headers on remote endpoints. Header values can reference + stored secrets; see the examples below. Header secrets come from this host's + secret store and require a locally connected server. - Other image refs (inputs without "://" that are not dhi.io, e.g. - docker.io/foo:tag) are no longer accepted. Use a server manifest instead. - - SSRF guard and --skip-ssrf-check: - A --url whose host resolves to a private/RFC1918, loopback, link-local, or - cloud-metadata address is fetched anyway, but flagged: the add proceeds and - a warning naming the resolved address is printed (this protects against - manifest URLs that reach internal services, cloud metadata, or - DNS-rebinding targets by making them visible, not by blocking them). Some - legitimate servers live on private networks (split-horizon DNS, internal - load balancers, VPN-only endpoints, PrivateLink), so their public hostname - resolves to a private address and the warning is expected noise for them. - OAuth authorization-server metadata has a separate SSRF guard with the same - warn-and-proceed posture: a disallowed address is logged, not blocked. Pass - --skip-ssrf-check to disable both checks for this add, including OAuth - metadata redirects (silencing the warning too), when you trust the provider - and its discovery destinations; use it only for URLs you control. - - OAuth for remote endpoints (--oauth-authorization-server / --client-id): - Two related options configure OAuth for a remote --url server (both are - only valid with --url): - - --oauth-authorization-server hand-supplies the authorization-server - metadata for a server that publishes no well-known RFC 9728/8414 metadata - (e.g. Gmail). It is a local file path or an http(s) URL to a JSON document - conforming to the RFC 8414 oauth-authorization-server shape - (authorization_endpoint and token_endpoint are required). --client-id is - required alongside it UNLESS the metadata document itself advertises a - registration_endpoint, in which case a client is registered dynamically - (RFC 7591) and --client-id may be omitted. - - --client-id supplies a PRE-REGISTERED OAuth client. It may be given WITHOUT - --oauth-authorization-server: the server's authorization metadata is then - discovered normally and the supplied client is attached to it. This is the - right mode for a server whose discoverable metadata exposes no - registration_endpoint (so Dynamic Client Registration is impossible) but - which accepts a client id the operator registered ahead of time. - - Client secrets (confidential clients): - There is no --client-secret flag. The secret for a confidential client - lives in the secret store in the global scope under the - service name "mcp::client_secret", and is read from there - whenever the server is used: - - sbx secret set mcp::client_secret - - Run it with no -t so the value is read from stdin instead of landing in - your shell history. The secret is never written to the MCP registration - on disk. Remove it later with 'sbx secret rm mcp::client_secret'. - - The stored secret is bound to the OAuth identity (client id, issuer and - token endpoint) that first used it. Re-registering the same server name - against a different client or authorization server therefore does NOT - reuse it — store the secret again for the new client. To let a new - identity claim the existing secret, drop the recorded binding with - 'sbx secret rm mcp::client_secret:identity'. - - Two rules apply on the discovered path (they do not affect a server that - advertises a registration_endpoint, the hand-supplied - --oauth-authorization-server path, or --command servers): - - - If the discovered authorization metadata has NO registration_endpoint, - Dynamic Client Registration is impossible, so --client-id is REQUIRED; - the add fails without it. This is the Slack shape (discoverable metadata, - no DCR, a pre-registered client). - - A stored client secret is REQUIRED when the server's advertised - token_endpoint_auth_methods_supported (RFC 8414) does NOT include "none" - — i.e. it accepts only confidential clients (client_secret_basic / - client_secret_post). Registration still succeeds without one, but the - add-time authorization is skipped; store the secret and run - 'sbx mcp auth ' to finish. When the list includes "none" a - public/PKCE client is allowed and --client-id alone is enough. If the - server advertises no token_endpoint_auth_methods_supported at all (the - field is optional in RFC 8414), the requirement cannot be determined and - the add proceeds as usual. - - Default OAuth scopes (--scope / --no-scope): - --scope records the DEFAULT set of scopes to request at consent time for a - remote --url OAuth server (repeatable). Precedence at authorization time is - --no-scope > an explicit 'sbx mcp auth --scope' > the set recorded here > the - scope set the RESOURCE itself says it requires (from its RFC 9728 - protected-resource metadata or its WWW-Authenticate challenge) > whichever of - openid, email, profile, and offline_access are advertised. Other advertised - scopes are excluded from this fallback. If no scopes are selected, the scope - parameter is omitted so the authorization server can apply its own default - grant (RFC 6749 §3.3). - - A resource that publishes a required set therefore gets it requested with no - flag at all, and the consent block marks that set as derived rather than - 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. - GitHub, document their real scopes on the resource and advertise almost - nothing over RFC 8414). A scope in neither prints a warning naming the - offender but is still requested — a mismatch is often the server's own - documentation gap, not a typo, and either document is allowed to be - non-exhaustive. This is a recognition check, not a promise: a recognized - scope can still be refused at consent time. - - Scope values may be URN-shaped (urn:ietf:params:oauth:scope:mail) or - URL-shaped (https://www.fastmail.com/dev/mcp). Neither needs quoting — a scope - token cannot contain a space or a quote — and both are percent-encoded - normally on the wire. --scope applies both to a hand-supplied override and to - a plain --url server whose OAuth metadata is discovered. - - RFC 8707 resource indicator (--resource): - Every authorization request, code exchange and token refresh names the server - the token is for, in the 'resource' parameter the MCP authorization - specification requires (RFC 8707). That value is normally DERIVED, and you do - not need this flag: it comes from the server's own RFC 9728 protected-resource - metadata when it publishes some, and otherwise from the --url endpoint - (lowercased scheme/host, path kept, fragment dropped). - - --resource replaces that derivation with a value you supply. Use it when the - derived one is wrong — most often a server whose published identifier is its - bare origin (https://api.example.com) while its endpoint has a path - (https://api.example.com/mcp), which is indistinguishable from publishing - nothing, so the endpoint URL is what gets sent. An authorization server - entitled to reject an unknown target answers 'invalid_target'. - - The value must be an absolute URI with a scheme and a host, and RFC 8707 §2 - forbids a fragment; a bad value fails the add rather than being repaired or - dropped later. It is sent VERBATIM — nothing is lowercased and no path or - trailing slash is adjusted, because the string names a server and changing it - could name a different one. Only one value is accepted: a gateway backend - connects to exactly one MCP endpoint. - - It outranks both the published value and the URL derivation, and also an - authorization server advertising resource_indicators_supported=false (the add - says so when that happens). It is recorded on the registration, so there is no - 'sbx mcp auth --resource': one value is used by the add-time authorization, - every later 'sbx mcp auth', and every token refresh — a resource that differed - between them is the audience mismatch this parameter exists to prevent. To - change it, 'sbx mcp rm' the server and add it again; the existing token was - minted for the old resource anyway. - - Not 'audience': RFC 8707 'resource' is what the MCP specification requires, and - an 'audience' parameter on an authorization-code request is an Auth0/Okta - vendor extension that sbx does not send. See 'sbx mcp inspect ' for the - effective value and where it came from. - - Scope limit: this governs the OAuth flow sbx itself runs — a local data plane - (SBX_MCP_URL=none), and any server registered with - --oauth-authorization-server/--client-id. For a plain remote in hosted mode the - control-plane gateway is the OAuth client and does not carry the field yet, so - the value is recorded and the add warns that it is not sent for that server. - - Custom request headers for remote endpoints (--header): - --header adds an HTTP header to every request sent to a remote --url - endpoint, written in the curl convention 'Header-Name: header value'. - Repeat the flag for more headers; each header name may be given once. - Headers the transport owns (Host, Content-Length, Connection, Proxy-*, …) - are rejected. - - Only a remote endpoint can carry them: --header is refused with --command - and --local, and an add whose --url resolves to a stdio server (a registry - or manifest URL naming an OCI image) fails rather than dropping them. - - A header value may reference a secret with ${placeholder}. The placeholder is - stored in the registration exactly as typed and the secret itself never is; - the value is read from the encrypted secret store and substituted when a - sandbox connects to the server. Store it with: - - sbx secret set mcp:: - - For example: - - sbx mcp add acme --url https://mcp.acme.com/mcp --header 'Authorization: Bearer ${api-key}' - sbx secret set mcp:acme:api-key - - On an OAuth-protected server an explicit Authorization header takes - precedence over the OAuth access token. - - Header secrets are read from the LOCAL secret store, so a header-bearing - server only works where this host connects it. Adding one while your MCP - gateway is the hosted (SaaS) one is rejected rather than registered with - headers that would be silently dropped — unless the server carries a - hand-supplied OAuth override (--oauth-authorization-server), which this - host connects directly in every gateway mode. - - Alternative input — local stdio command (--command + --args): - The command runs as a subprocess on the HOST, outside the sandbox. - - WARNING: Local servers are for ad-hoc development only. They have - no identity, no verifiable supply chain, and no sandboxing. The - process runs with your host user's full permissions — it can read - your filesystem, access your network, and call any API your user - can. Do not use --command with untrusted executables. + For registration and authorization workflows, see: + https://docs.docker.com/ai/sandboxes/mcp-gateway/ usage: sbx mcp add NAME (--url URL | --command COMMAND) [flags] options: - name: args diff --git a/data/sbx_cli/sbx_mcp_load.yaml b/data/sbx_cli/sbx_mcp_load.yaml index b16ef630f4..cae021dcf2 100644 --- a/data/sbx_cli/sbx_mcp_load.yaml +++ b/data/sbx_cli/sbx_mcp_load.yaml @@ -1,9 +1,10 @@ name: sbx mcp load -synopsis: Load an already-registered MCP server into a running sandbox +synopsis: Load an already-registered MCP server into a sandbox description: |- - Attach a previously-registered MCP server to a running sandbox's gateway. - Connected agents see the new server's tools immediately via the standard MCP - tools/list_changed notification — no agent restart required. + Attach a previously-registered MCP server to a sandbox's gateway. + In a running sandbox, connected agents see the new server's tools immediately + via the standard MCP tools/list_changed notification — no agent restart + required. A stopped sandbox gets the server the next time it starts. The server must already exist in the local MCP store (register first with 'sbx mcp add'). Both remote/hosted and local-stdio servers are supported. diff --git a/data/sbx_cli/sbx_policy.yaml b/data/sbx_cli/sbx_policy.yaml index cbd73a20c0..a6a76d1a6f 100644 --- a/data/sbx_cli/sbx_policy.yaml +++ b/data/sbx_cli/sbx_policy.yaml @@ -30,5 +30,6 @@ see_also: - sbx policy inspect - Show policy or rule details - sbx policy log - Show sandbox policy logs - sbx policy ls - List sandbox policies + - sbx policy refresh - Force an immediate policy refresh - sbx policy reset - Reset policies to defaults - sbx policy rm - Remove a policy rule diff --git a/data/sbx_cli/sbx_policy_init.yaml b/data/sbx_cli/sbx_policy_init.yaml index 5d15960c9c..16bddc6492 100644 --- a/data/sbx_cli/sbx_policy_init.yaml +++ b/data/sbx_cli/sbx_policy_init.yaml @@ -1,23 +1,18 @@ name: sbx policy init synopsis: Initialize the global network policy description: |- - Initialize the global network policy that applies to all sandboxes. + Initialize the global network policy before starting a sandbox or adding + custom rules. Per-sandbox rules apply on top of this policy. - This sets the initial global network policy and must be run before adding - custom allow/deny rules or starting a sandbox for the first time. It is a - one-time setup: once initialized, use "sbx policy reset" to start over. + Choose a policy: - This is the initial global policy, not a per-sandbox default; you can change - it later. Per-sandbox rules, including those added by kits such as the - built-in agent kits, apply on top for individual sandboxes. + - allow-all: Allow all outbound network traffic. + - balanced: Allow typical development traffic, including AI services and package registries. + - deny-all: Block all outbound network traffic. - Available policies: - allow-all All outbound network traffic is allowed - balanced Typical development traffic is allowed, such as AI services and package registries - deny-all All outbound network traffic is blocked - - After initializing, use "sbx policy allow/deny/rm" to change the global policy. - Use "sbx policy reset" to clear all policies and start over. + After initialization, use sbx policy allow/deny/rm to change the rules. + Initialization is a one-time setup. Use sbx policy reset to clear all policies + and start over. With --cloud: Set the default network mode of the cloud policy. diff --git a/data/sbx_cli/sbx_policy_ls.yaml b/data/sbx_cli/sbx_policy_ls.yaml index 8f3a4cac8f..491d9b8328 100644 --- a/data/sbx_cli/sbx_policy_ls.yaml +++ b/data/sbx_cli/sbx_policy_ls.yaml @@ -37,6 +37,10 @@ options: usage: Output in JSON format - name: protocol usage: 'Filter network rules by protocol: tcp or udp' + - name: quiet + shorthand: q + default_value: "false" + usage: Only display rule IDs (network patterns with --cloud) - name: source usage: 'Filter policies by source: "local", "org", or "kit"' - name: type @@ -68,6 +72,9 @@ example: |4- # Output filtered rules as JSON sbx policy ls --json + # List only rule IDs + sbx policy ls -q + # List only network policies sbx policy ls --type network diff --git a/data/sbx_cli/sbx_policy_refresh.yaml b/data/sbx_cli/sbx_policy_refresh.yaml new file mode 100644 index 0000000000..601cf2e075 --- /dev/null +++ b/data/sbx_cli/sbx_policy_refresh.yaml @@ -0,0 +1,32 @@ +name: sbx policy refresh +synopsis: Force an immediate policy refresh +description: |- + Force sandboxd to fetch and apply governance policy immediately. + + The daemon normally polls for policy changes on a regular interval. Use this + after changing an org policy setting (for example, toggling AI Governance) so + the change takes effect without waiting for the next poll. This also + invalidates the cached registry credential; it never restarts the daemon or + stops running sandboxes. + + The refreshed policy applies to new connections only. Connections a sandbox + opened while the previous policy allowed them stay open even if the new + policy denies them; restart the sandbox to drop them. +usage: sbx policy refresh [flags] +options: + - name: help + shorthand: h + default_value: "false" + usage: help for refresh +inherited_options: + - name: cloud + default_value: "false" + usage: | + Dispatch to Docker Cloud Sandboxes API instead of local sandboxd (supported by a growing set of verbs — run 'sbx --cloud --help' for the current list) + - name: debug + shorthand: D + default_value: "false" + usage: Enable debug logging +example: ' sbx policy refresh' +see_also: + - sbx policy - Manage sandbox policies diff --git a/data/sbx_cli/sbx_run.yaml b/data/sbx_cli/sbx_run.yaml index 0b9b1bb7c0..6c331411d0 100644 --- a/data/sbx_cli/sbx_run.yaml +++ b/data/sbx_cli/sbx_run.yaml @@ -116,6 +116,9 @@ options: - name: on-timeout usage: | What happens when --ttl lapses: 'stop' stops the sandbox in place so it can be started again later, 'restart' keeps it running by stopping and immediately starting it, or 'delete' removes it. Omit the flag and the server stops the sandbox when it can be started again later, and deletes it otherwise. With 'restart' a supplied --ttl must be at least 1h (cloud only). + - name: platform + usage: | + Target platform: linux/amd64 or linux/arm64 (cloud only). With --image-ref, omitting it lets the server resolve the platform from the image and the CLI sends the local CPU as a hint for multi-platform images. With --template, omitting it inherits the template platform. With a sandbox kit, the kit's template is built for this platform and cached apart from other platforms; omitting it keeps the server's choice. - name: publish shorthand: p default_value: '[]' diff --git a/data/sbx_cli/sbx_settings_ls.yaml b/data/sbx_cli/sbx_settings_ls.yaml index cea45a6c1d..35edf79352 100644 --- a/data/sbx_cli/sbx_settings_ls.yaml +++ b/data/sbx_cli/sbx_settings_ls.yaml @@ -22,6 +22,10 @@ options: - name: no-trunc default_value: "false" usage: Show full values and descriptions, one setting per block + - name: quiet + shorthand: q + default_value: "false" + usage: Only display setting keys inherited_options: - name: cloud default_value: "false" @@ -37,5 +41,8 @@ example: |4- # List settings as JSON sbx settings ls --format json + + # List only setting keys + sbx settings ls -q see_also: - sbx settings - Manage Docker Sandboxes settings diff --git a/data/sbx_cli/sbx_settings_set.yaml b/data/sbx_cli/sbx_settings_set.yaml index 4fccea06c8..574d40a6cb 100644 --- a/data/sbx_cli/sbx_settings_set.yaml +++ b/data/sbx_cli/sbx_settings_set.yaml @@ -1,21 +1,14 @@ name: sbx settings set 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 - float floating-point value - string plain text - json raw JSON + Set a user override for a setting. Values are parsed according to the + setting's type: bool (true or false), int, float, string, or raw JSON. + Administrator constraints apply; conflicting values are rejected. Environment variables take precedence over user overrides. - Most changes take effect within about five seconds. If a daemon restart is - required, this command tells you to run 'sbx daemon restart'. + Most changes take effect within about five seconds. This command reports + when a daemon restart is required. usage: sbx settings set KEY VALUE [flags] options: - name: help diff --git a/data/sbx_cli/sbx_skills_import.yaml b/data/sbx_cli/sbx_skills_import.yaml index 5619d31a39..cf266c5eac 100644 --- a/data/sbx_cli/sbx_skills_import.yaml +++ b/data/sbx_cli/sbx_skills_import.yaml @@ -2,29 +2,19 @@ name: sbx skills import synopsis: Import skills from supported agent directories experimental: true description: |- - Import skills already installed for supported coding agents on this - machine. + Import skills installed for supported coding agents on this machine. + Directories are checked in order: - The following directories are checked in order: - ~/.agents/skills - ~/.claude/skills - ~/.config/opencode/skills - ~/.copilot/skills - ~/.cursor/skills - ~/.factory/skills + 1. ~/.agents/skills + 2. ~/.claude/skills + 3. ~/.config/opencode/skills + 4. ~/.copilot/skills + 5. ~/.cursor/skills + 6. ~/.factory/skills - When the same skill appears in more than one directory, the first copy is used - and the others are skipped with a warning. - - Importing a skill that is already installed replaces it completely, including - removing files that are no longer present. You will be prompted before a skill - is replaced; use --force to skip all prompts. - - Symlinks at the top level are followed if they point to a directory. Symlinks - within skill folders and loose files at the top level are skipped. - - Imported skills are available to Claude, Codex, Copilot, Cursor, Droid, and - OpenCode. + The first copy of each skill is used. Importing replaces an existing skill + completely, including removing obsolete files; --force skips confirmation. + Top-level directory symlinks are followed; symlinks within skills are skipped. usage: sbx skills import [flags] options: - name: dry-run diff --git a/data/sbx_cli/sbx_template_load.yaml b/data/sbx_cli/sbx_template_load.yaml index 4cb424c1c1..2857b18814 100644 --- a/data/sbx_cli/sbx_template_load.yaml +++ b/data/sbx_cli/sbx_template_load.yaml @@ -7,22 +7,19 @@ description: |- Tar files are typically created with: sbx template save SANDBOX TAG --output FILE With --cloud: - The tar is uploaded to the cloud template registry as a new template. - Takes two arguments (FILE, NAME). NAME must be unique per account. - --cpus and --memory-mib are required, and together must name one of the - billable sandbox shapes: - micro (1 vCPU / 2048 MiB) - small (2 vCPU / 4096 MiB) - medium (4 vCPU / 8192 MiB) - large (8 vCPU / 16384 MiB) - xl (16 vCPU / 32768 MiB) - --capture-mode controls what gets captured for the template: "disk" (default) - is faster to load and cold-boots from the filesystem; "all" captures memory + - disk + microVM checkpoint so subsequent runs resume in sub-second time at the - cost of a slower load. + Upload a tar file as a cloud template. Takes FILE and NAME; NAME must be + unique per account. Uploads can take several minutes. - Cloud loads upload your full tar to the registry; multi-GB uploads can - take several minutes. See https://docs.docker.com/ai/sandboxes/ for the snapshot/load model. + --cpus and --memory-mib are required and must match a billable sandbox shape: + + - micro (1 vCPU / 2048 MiB) + - small (2 vCPU / 4096 MiB) + - medium (4 vCPU / 8192 MiB) + - large (8 vCPU / 16384 MiB) + - xl (16 vCPU / 32768 MiB) + + Use --capture-mode disk for a filesystem snapshot, or all to capture memory, + disk, and the microVM checkpoint for faster resume. usage: sbx template load FILE [NAME] [flags] options: - name: capture-mode diff --git a/data/sbx_cli/sbx_template_save.yaml b/data/sbx_cli/sbx_template_save.yaml index 87eca96a03..20ad4a3a23 100644 --- a/data/sbx_cli/sbx_template_save.yaml +++ b/data/sbx_cli/sbx_template_save.yaml @@ -1,16 +1,11 @@ name: sbx template save synopsis: Save a snapshot of the sandbox as a template description: |- - Save a snapshot of the sandbox as a template. + Save a sandbox snapshot as a template in the local image store. + Use --pull never when creating a sandbox from the saved template. - The saved image is stored in the sandbox runtime's image store and can be - used as a template for new sandboxes with: - sbx run --pull never -t TAG AGENT [WORKSPACE] - - Use --pull never to use the saved image without trying to pull it from a registry. - - Use --output to also export the image to a tar file that can be shared - and loaded on another host with: sbx template load FILE + Use --output to export a tar file for loading on another host with + sbx template load. With --cloud: Snapshot a running cloud sandbox into a cloud-managed template. The @@ -52,6 +47,9 @@ example: |4- # Save as a template for new sandboxes on this host sbx template save my-sandbox myimage:v1.0 + # Create a sandbox from the saved template + sbx run --pull never -t myimage:v1.0 claude ./project + # Also export to a shareable tar file sbx template save my-sandbox myimage:v1.0 --output /tmp/myimage.tar