From 7537b3d8ab9ff86a78696fae2e0b83284e7a111a Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 27 Aug 2026 09:57:10 +0000 Subject: [PATCH 1/3] docs: document sandbox kit invocation and arguments Sandbox kit launch examples used the deprecated --kit form, and kit arguments were undocumented. Document positional sandbox kit references, argument declarations and precedence, corrected inheritance, and registry authentication. Co-Authored-By: Codex --- .../ai/sandboxes/configuration/credentials.md | 7 +- .../ai/sandboxes/customize/build-an-agent.md | 9 +- .../ai/sandboxes/customize/kit-examples.md | 23 ++-- .../ai/sandboxes/customize/kit-reference.md | 53 +++++++- .../manuals/ai/sandboxes/customize/kits.md | 128 +++++++++++++++--- content/manuals/ai/sandboxes/faq.md | 2 +- 6 files changed, 186 insertions(+), 36 deletions(-) diff --git a/content/manuals/ai/sandboxes/configuration/credentials.md b/content/manuals/ai/sandboxes/configuration/credentials.md index 9c28102d19aa..b974f77b7964 100644 --- a/content/manuals/ai/sandboxes/configuration/credentials.md +++ b/content/manuals/ai/sandboxes/configuration/credentials.md @@ -495,9 +495,10 @@ To scope the credential to a single sandbox, store it under that sandbox's name: $ gh auth token | sbx secret set --sandbox my-app --registry ghcr.io --password-stdin ``` -`sbx kit pull` also uses these credentials, with the Docker credential -store as a fallback. `sbx kit push` uses only the Docker credential store — -push targets still require a prior `docker login`. +For Docker Hub, `sbx kit pull` and `sbx kit push` use the session from +`sbx login`. For other registries, both commands use these credentials. Both +commands fall back to the Docker credential store, so credentials from +`docker login` also work. ### Remove registry credentials diff --git a/content/manuals/ai/sandboxes/customize/build-an-agent.md b/content/manuals/ai/sandboxes/customize/build-an-agent.md index 1e920b4c11d8..24edf42c24b5 100644 --- a/content/manuals/ai/sandboxes/customize/build-an-agent.md +++ b/content/manuals/ai/sandboxes/customize/build-an-agent.md @@ -256,18 +256,17 @@ Validate the spec: $ sbx kit validate ./amp/ ``` -Launch a sandbox with the kit, passing the kit's `name:` (`amp`) as the -agent argument: +Launch a sandbox with the kit by passing its directory as the agent positional: ```console -$ sbx run --kit ./amp/ amp +$ sbx run ./amp/ ``` The published copy of this kit also runs directly from the contrib repository: ```console -$ sbx run --kit "git+https://github.com/docker/sbx-kits-contrib.git#dir=amp" amp +$ sbx run "git+https://github.com/docker/sbx-kits-contrib.git#dir=amp" ``` ## Iterate @@ -279,7 +278,7 @@ Two loops help: requests, then add their domains to `allowedDomains`. - Add domains to `deniedDomains` when the agent should stay blocked from a host even if another policy permits it. -- Edit the spec and re-run `sbx run --kit ./amp/ amp` to pick up changes. +- Edit the spec and re-run `sbx run ./amp/` to pick up changes. Remove the sandbox first (`sbx rm `) for a clean start. Flesh out the `agentContext` block as you refine how Amp should behave in the diff --git a/content/manuals/ai/sandboxes/customize/kit-examples.md b/content/manuals/ai/sandboxes/customize/kit-examples.md index 90c6504c0e57..0f2c8aeed287 100644 --- a/content/manuals/ai/sandboxes/customize/kit-examples.md +++ b/content/manuals/ai/sandboxes/customize/kit-examples.md @@ -358,11 +358,11 @@ sandbox: Claude Code merges the additional file with the sandbox-managed user settings. Because the file is under `files/home/`, it stays inside the sandbox instead of -being written into a directly mounted host workspace. Launch the sandbox with -the child kit's name: +being written into a directly mounted host workspace. Launch the sandbox by +passing the child kit directory as the agent positional: ```console -$ sbx run claude-sonnet --kit ./claude-sonnet +$ sbx run ./claude-sonnet ``` Proxy-managed OAuth isn't supported for a third-party kit that extends the @@ -451,15 +451,16 @@ sandbox: ``` The child inherits the built-in image, credentials, network permissions, -persistent volumes, settings, MCP integration, and agent instructions. Its -`sandbox.entrypoint` replaces the inherited entrypoint. Proxy-managed OAuth +persistent volumes, settings, MCP integration, agent instructions, setup +entries, and environment variables. Its `sandbox.entrypoint` replaces the +inherited entrypoint. Proxy-managed OAuth isn't supported for the extended agent, so follow the [Anthropic API-key setup](#customize-agent-settings) before launching it. -Launch with the kit's `name:` as the agent argument to `sbx run`: +Launch by passing the sandbox kit as the agent positional to `sbx run`: ```console -$ sbx run claude-safe --kit ./claude-safe +$ sbx run ./claude-safe ``` For a step-by-step walkthrough of building a new sandbox kit from @@ -470,8 +471,14 @@ scratch, see [Build an agent](build-an-agent.md). These patterns are all drawn from working kits in the [sbx-kits-contrib](https://github.com/docker/sbx-kits-contrib) repository, which contains each example as a complete, loadable kit. -Use it to study the full shape of a kit, or load one directly: +Use it to study the full shape of a kit. Load a mixin with `--kit`: ```console $ sbx run claude --kit "git+https://github.com/docker/sbx-kits-contrib.git#dir=" ``` + +For a `kind: sandbox` kit, pass the reference as the agent positional instead: + +```console +$ sbx run "git+https://github.com/docker/sbx-kits-contrib.git#dir=" +``` diff --git a/content/manuals/ai/sandboxes/customize/kit-reference.md b/content/manuals/ai/sandboxes/customize/kit-reference.md index aa3aff28e1d1..9c11b8d5cb70 100644 --- a/content/manuals/ai/sandboxes/customize/kit-reference.md +++ b/content/manuals/ai/sandboxes/customize/kit-reference.md @@ -1,7 +1,7 @@ --- title: Kit spec reference linkTitle: Spec reference -description: Field-by-field reference for a kit's spec.yaml, including credentials, network rules, environment, setup, files, agent instructions, and the sandbox block. +description: Field-by-field reference for a kit's spec.yaml, including arguments, credentials, network rules, environment, setup, files, agent instructions, and the sandbox block. keywords: sandboxes, sbx, kits, spec.yaml, reference, schema, fields weight: 50 --- @@ -88,6 +88,10 @@ locked: - sandbox.image security: privileged: false +args: + channel: + default: stable + enum: [stable, beta] ``` | Field | Required | Description | @@ -102,10 +106,57 @@ security: | `licenses` | No | SPDX license identifiers. | | `locked` | No | Dotted paths child kits may not override. | | `security` | No | Container security settings. `security.privileged: true` runs the container in privileged mode. | +| `args` | No | Arguments supplied when the kit is loaded. Schema v2 only. | A kit also declares behavior blocks such as `agentInstructions`, `permissions`, `ports`, `credentials`, `environment`, `setup`, and `volumes`. +## Arguments + +A schema v2 kit can declare arguments and reference them anywhere in +`spec.yaml` or under `files/` as `${{ kit.args. }}`. Substitution happens +before the spec is decoded. + +```yaml +args: + version: + default: latest + description: Tool version to install + pattern: '^(latest|[0-9]+\.[0-9]+\.[0-9]+)$' + channel: + default: stable + enum: [stable, beta, nightly] + token: + required: true + description: API token + +environment: + variables: + TOOL_VERSION: "${{ kit.args.version }}" +``` + +| Field | Description | +| ------------- | ------------------------------------------------------------------------------------------------------------ | +| Argument name | Starts with a letter or underscore and contains only letters, digits, underscores, and hyphens. | +| `default` | String to use when the caller supplies no value. Mutually exclusive with `required: true`. | +| `required` | Set to `true` when the caller must supply a value. Mutually exclusive with `default`. | +| `description` | Optional help text shown when a required value is missing. | +| `enum` | Optional list of accepted values. Mutually exclusive with `pattern`. | +| `pattern` | Optional Go RE2 regular expression matched against the complete value. Mutually exclusive with `enum`. | + +Each argument must declare either `default`, including an empty-string +default, or `required: true`. A declared default must satisfy its own `enum` or +`pattern`. Every `${{ kit.args. }}` reference must have a matching +declaration. + +Argument values are strings, but substitution happens before YAML decoding. +Quote a placeholder in a string-valued field so a value such as `1.20` isn't +decoded as a number. + +Supply values with `--kit-arg` or `--kit-args-file` when loading the kit. See +[Pass arguments to kits](kits.md#pass-arguments-to-kits) for scoping, +precedence, and validation behavior. + ## Kit kinds ### `kind: mixin` diff --git a/content/manuals/ai/sandboxes/customize/kits.md b/content/manuals/ai/sandboxes/customize/kits.md index 92e5bef2bf87..c5252444704e 100644 --- a/content/manuals/ai/sandboxes/customize/kits.md +++ b/content/manuals/ai/sandboxes/customize/kits.md @@ -302,19 +302,36 @@ agent. For a step-by-step walkthrough, see Use `extends:` to create a variant of a built-in agent without reproducing its configuration. The child kit inherits the parent's image, credentials, network permissions, persistent volumes, settings, MCP integration, and agent -instructions. Use `extends:` for a single parent agent; use a mixin to add an -independent capability that can work with one or more agents. See +instructions. It also inherits the parent's environment variables and all +`setup.install`, `setup.startup`, and `setup.files` entries. Parent setup entries +run before child entries. If both kits set the same environment variable, the +child's value wins. Use `extends:` for a single parent agent; use a mixin to add +an independent capability that can work with one or more agents. See [Fork an existing agent](kit-examples.md#fork-an-existing-agent) for an example that changes Claude Code's permission mode. ## Using kits Kits can be loaded from a local path (a directory or ZIP file), a Git -repository, or an OCI registry. Pass `--kit` more than once to stack -several kits on the same sandbox. +repository, or an OCI registry. Pass a sandbox kit reference as the first +positional argument to `sbx run` or `sbx create`, in the same position as a +built-in agent name. Use `--kit` for mixins, and pass it more than once to stack +several mixins on the same sandbox. + +Starting with Docker Sandboxes version 0.42.0, the sandbox kit reference is the +agent positional: + +```console +$ sbx run [PATH...] +$ sbx create [PATH...] +``` + +The previous form, `sbx run --kit `, is +deprecated. > [!IMPORTANT] -> `--kit` only takes effect when a sandbox is created. Passing it against an +> A mixin passed with `--kit` only takes effect when a sandbox is created. +> Passing it against an > existing sandbox name fails with > `--kit can only be used when creating a new sandbox`. To add a supported > mixin kit to a running sandbox, use [`sbx kit add`](#local) instead. @@ -322,15 +339,73 @@ several kits on the same sandbox. > VM state — installed packages, Docker images, volumes, and agent history > — is preserved across the restart. It supports mixin kits limited to > `environment.variables`, `setup.install`, and `permissions.network.allow`. -> To use other fields, recreate the sandbox with `--kit`. +> To use other fields, recreate the sandbox with the mixin. + +### Pass arguments to kits + +A schema v2 kit can declare inputs in a top-level `args:` block and reference +them in `spec.yaml` or static files with `${{ kit.args. }}`. Supply a +value with `--kit-arg name=value`: + +```console +$ sbx run ./my-agent/ --kit-arg channel=beta +``` + +An argument without a kit-name prefix is offered to every kit that declares it. +When several kits declare the same argument, prefix it with the value of the +kit's `name` field and a period to target one kit: + +```console +$ sbx run ./my-agent/ \ + --kit ./my-mixin/ \ + --kit-arg version=1.2.3 \ + --kit-arg my-mixin.version=2.0.0 +``` + +The kit-specific value takes precedence over the shared value for `my-mixin`. + +Use `--kit-args-file` for a reusable set of `name=value` entries. Blank lines +and lines that start with `#` are ignored: + +```text {title="kit.args"} +version=1.2.3 +my-mixin.channel=beta +``` + +```console +$ sbx create ./my-agent/ . \ + --kit ./my-mixin/ \ + --kit-args-file ./kit.args \ + --kit-arg my-mixin.channel=stable +``` + +When you pass multiple argument files, a value in a later file overrides the +same key in an earlier file. Values passed with `--kit-arg` override every +file. For repeated `--kit-arg` entries with the same key, the last value wins. + +Argument validation happens before the sandbox is created. `sbx` rejects a +missing required value, a value outside its declared `enum` or `pattern`, a +placeholder without a declaration, and a supplied argument that no resolved +kit declares. Pass the same argument flags to `sbx kit validate` or +`sbx kit inspect` when the kit requires values. See +[Kit arguments](kit-reference.md#arguments) for the declaration fields. ### Local -Point `--kit` at a directory or ZIP file on disk: +Launch a local sandbox kit by passing its directory or ZIP file as the agent +positional. Relative paths must start with `./` or `../` so `sbx` can +distinguish them from agent and sandbox names: ```console -$ sbx run claude --kit ./my-kit/ -$ sbx run claude --kit ./my-kit-1.0.zip +$ sbx run ./my-agent/ +$ sbx create ../my-agent-1.0.zip . +``` + +Pass a local mixin with `--kit`: + +```console +$ sbx run claude --kit ./my-mixin/ +$ sbx run claude --kit ../my-mixin-1.0.zip ``` While iterating on a supported mixin kit, apply changes to a running sandbox @@ -347,6 +422,14 @@ remove and recreate it to start clean. ### Git repository +Launch a sandbox kit from a Git repository: + +```console +$ sbx run "git+https://github.com/docker/sbx-kits-contrib.git#ref=v0.1.0&dir=amp" +``` + +Pass a Git-hosted mixin with `--kit`: + ```console $ sbx run claude --kit "git+https://github.com/docker/sbx-kits-contrib.git#ref=v0.1.0&dir=code-server" ``` @@ -360,6 +443,14 @@ $ sbx run claude --kit "git+https://github.com/docker/sbx-kits-contrib.git#ref=v ### OCI registry +Launch a sandbox kit from an OCI registry: + +```console +$ sbx run docker.io/sbx/droid-kit:latest +``` + +Pass an OCI-hosted mixin with `--kit`: + ```console $ sbx run claude --kit ghcr.io/myorg/my-kit:1.0 ``` @@ -371,14 +462,15 @@ For Docker Hub, include the full `docker.io` prefix. See > For Docker Hub, `sbx` reuses your `sbx login` session to pull private > kits. For other registries, store pull credentials with > [`sbx secret set --registry`](../configuration/credentials.md#registry-credentials) -> before running the sandbox: +> before running the sandbox. These credentials take priority over credentials +> in the Docker credential store: > > ```console > $ gh auth token | sbx secret set --registry ghcr.io --password-stdin > ``` > -> Without stored credentials, pulls from non-Docker Hub registries are -> anonymous and private kits fail to pull. +> Without credentials from either store, pulls from non-Docker Hub registries +> are anonymous and private kits fail to pull. ### Restrict kit sources @@ -497,16 +589,16 @@ The `sbx kit` subcommands validate, inspect, and publish kits: For Docker Hub, include the full `docker.io` prefix — `sbx` doesn't add it automatically. -`sbx kit pull` prefers credentials stored with -[`sbx secret set --registry`](../configuration/credentials.md#registry-credentials), -falling back to the Docker credential store. `sbx kit push` only uses the -Docker credential store, so pushing to a private registry requires a prior -`docker login`. +For Docker Hub, `sbx kit pull` and `sbx kit push` use the session from +`sbx login`. For other registries, they prefer credentials stored with +[`sbx secret set --registry`](../configuration/credentials.md#registry-credentials). +Both commands fall back to the Docker credential store, so credentials from +`docker login` also work. ## Spec reference For a field-by-field reference of every `spec.yaml` block — top-level -fields, credentials, network, environment, setup, static files, +fields, arguments, credentials, network, environment, setup, static files, agent instructions, and the sandbox block — see [Kit spec reference](kit-reference.md). ## Debugging diff --git a/content/manuals/ai/sandboxes/faq.md b/content/manuals/ai/sandboxes/faq.md index b02ddfb783a0..8ce178f424e2 100644 --- a/content/manuals/ai/sandboxes/faq.md +++ b/content/manuals/ai/sandboxes/faq.md @@ -129,7 +129,7 @@ sandbox: run: [claude] ``` -Run it with `sbx run claude-safe --kit ./claude-safe/`. See +Run it with `sbx run ./claude-safe/`. See [Sandbox kits](customize/kits.md#sandbox-kits) for the full pattern. ## How do I know if my agent is running in a sandbox? From 4176e1164548dba7fbb1fc583e551ba2271787fb Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 27 Aug 2026 10:46:35 +0000 Subject: [PATCH 2/3] docs: keep secrets out of kit arguments --- content/manuals/ai/sandboxes/customize/kit-reference.md | 8 ++++++-- content/manuals/ai/sandboxes/customize/kits.md | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/content/manuals/ai/sandboxes/customize/kit-reference.md b/content/manuals/ai/sandboxes/customize/kit-reference.md index 9c11b8d5cb70..7ad3f96daba3 100644 --- a/content/manuals/ai/sandboxes/customize/kit-reference.md +++ b/content/manuals/ai/sandboxes/customize/kit-reference.md @@ -126,15 +126,19 @@ args: channel: default: stable enum: [stable, beta, nightly] - token: + target: required: true - description: API token + description: Build target environment: variables: TOOL_VERSION: "${{ kit.args.version }}" ``` +Don't use kit arguments for API tokens, passwords, or other secrets. Use +[Credentials](../configuration/credentials.md) to provide sensitive values to +a sandbox. + | Field | Description | | ------------- | ------------------------------------------------------------------------------------------------------------ | | Argument name | Starts with a letter or underscore and contains only letters, digits, underscores, and hyphens. | diff --git a/content/manuals/ai/sandboxes/customize/kits.md b/content/manuals/ai/sandboxes/customize/kits.md index c5252444704e..300c35ff7c52 100644 --- a/content/manuals/ai/sandboxes/customize/kits.md +++ b/content/manuals/ai/sandboxes/customize/kits.md @@ -351,6 +351,11 @@ value with `--kit-arg name=value`: $ sbx run ./my-agent/ --kit-arg channel=beta ``` +Kit argument values are plain text. Values supplied with `--kit-arg` can remain +in your shell history, and argument files store their values unencrypted. Don't +use kit arguments for secrets. Use [Credentials](../configuration/credentials.md) +instead. + An argument without a kit-name prefix is offered to every kit that declares it. When several kits declare the same argument, prefix it with the value of the kit's `name` field and a period to target one kit: From 47c2b346196b498a28f84fd6c8b14044054b4dc7 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 27 Aug 2026 11:39:14 +0000 Subject: [PATCH 3/3] docs: clarify sandbox kit invocation --- .../ai/sandboxes/customize/build-an-agent.md | 3 ++- .../ai/sandboxes/customize/kit-examples.md | 6 +++--- .../manuals/ai/sandboxes/customize/kits.md | 21 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/content/manuals/ai/sandboxes/customize/build-an-agent.md b/content/manuals/ai/sandboxes/customize/build-an-agent.md index 24edf42c24b5..3d7f111dc308 100644 --- a/content/manuals/ai/sandboxes/customize/build-an-agent.md +++ b/content/manuals/ai/sandboxes/customize/build-an-agent.md @@ -256,7 +256,8 @@ Validate the spec: $ sbx kit validate ./amp/ ``` -Launch a sandbox with the kit by passing its directory as the agent positional: +Launch the sandbox by passing the kit directory in place of a built-in agent +name: ```console $ sbx run ./amp/ diff --git a/content/manuals/ai/sandboxes/customize/kit-examples.md b/content/manuals/ai/sandboxes/customize/kit-examples.md index 0f2c8aeed287..db2251d888b6 100644 --- a/content/manuals/ai/sandboxes/customize/kit-examples.md +++ b/content/manuals/ai/sandboxes/customize/kit-examples.md @@ -359,7 +359,7 @@ sandbox: Claude Code merges the additional file with the sandbox-managed user settings. Because the file is under `files/home/`, it stays inside the sandbox instead of being written into a directly mounted host workspace. Launch the sandbox by -passing the child kit directory as the agent positional: +passing the child kit directory in place of a built-in agent name: ```console $ sbx run ./claude-sonnet @@ -457,7 +457,7 @@ inherited entrypoint. Proxy-managed OAuth isn't supported for the extended agent, so follow the [Anthropic API-key setup](#customize-agent-settings) before launching it. -Launch by passing the sandbox kit as the agent positional to `sbx run`: +Launch by passing the sandbox kit in place of a built-in agent name: ```console $ sbx run ./claude-safe @@ -477,7 +477,7 @@ Use it to study the full shape of a kit. Load a mixin with `--kit`: $ sbx run claude --kit "git+https://github.com/docker/sbx-kits-contrib.git#dir=" ``` -For a `kind: sandbox` kit, pass the reference as the agent positional instead: +For a `kind: sandbox` kit, pass the reference in place of the agent name: ```console $ sbx run "git+https://github.com/docker/sbx-kits-contrib.git#dir=" diff --git a/content/manuals/ai/sandboxes/customize/kits.md b/content/manuals/ai/sandboxes/customize/kits.md index 300c35ff7c52..205084f5ed22 100644 --- a/content/manuals/ai/sandboxes/customize/kits.md +++ b/content/manuals/ai/sandboxes/customize/kits.md @@ -313,13 +313,12 @@ that changes Claude Code's permission mode. ## Using kits Kits can be loaded from a local path (a directory or ZIP file), a Git -repository, or an OCI registry. Pass a sandbox kit reference as the first -positional argument to `sbx run` or `sbx create`, in the same position as a -built-in agent name. Use `--kit` for mixins, and pass it more than once to stack -several mixins on the same sandbox. +repository, or an OCI registry. To launch a sandbox kit, pass its reference in +place of a built-in agent name to `sbx run` or `sbx create`. Use `--kit` for +mixins, and repeat the flag to apply multiple mixins to the same sandbox. -Starting with Docker Sandboxes version 0.42.0, the sandbox kit reference is the -agent positional: +Starting with Docker Sandboxes version 0.42.0, pass the sandbox kit reference +as the first argument: ```console $ sbx run [PATH...] @@ -356,9 +355,9 @@ in your shell history, and argument files store their values unencrypted. Don't use kit arguments for secrets. Use [Credentials](../configuration/credentials.md) instead. -An argument without a kit-name prefix is offered to every kit that declares it. -When several kits declare the same argument, prefix it with the value of the -kit's `name` field and a period to target one kit: +An argument without a kit name prefix applies to every kit that declares it. +To target one kit, prefix the argument with the value of that kit's `name` +field and a period: ```console $ sbx run ./my-agent/ \ @@ -397,8 +396,8 @@ kit declares. Pass the same argument flags to `sbx kit validate` or ### Local -Launch a local sandbox kit by passing its directory or ZIP file as the agent -positional. Relative paths must start with `./` or `../` so `sbx` can +Launch a local sandbox kit by passing its directory or ZIP file in place of the +agent name. Relative paths must start with `./` or `../` so `sbx` can distinguish them from agent and sandbox names: ```console