Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions content/manuals/ai/sandboxes/configuration/credentials.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
10 changes: 5 additions & 5 deletions content/manuals/ai/sandboxes/customize/build-an-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,18 +256,18 @@ Validate the spec:
$ sbx kit validate ./amp/
```

Launch a sandbox with the kit, passing the kit's `name:` (`amp`) as the
agent argument:
Launch the sandbox by passing the kit directory in place of a built-in agent
name:

```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
Expand All @@ -279,7 +279,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 <name>`) for a clean start.

Flesh out the `agentContext` block as you refine how Amp should behave in the
Expand Down
23 changes: 15 additions & 8 deletions content/manuals/ai/sandboxes/customize/kit-examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 in place of a built-in agent name:

```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
Expand Down Expand Up @@ -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 in place of a built-in agent name:

```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
Expand All @@ -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=<kit>"
```

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=<kit>"
```
57 changes: 56 additions & 1 deletion content/manuals/ai/sandboxes/customize/kit-reference.md
Original file line number Diff line number Diff line change
@@ -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
---
Expand Down Expand Up @@ -88,6 +88,10 @@ locked:
- sandbox.image
security:
privileged: false
args:
channel:
default: stable
enum: [stable, beta]
```

| Field | Required | Description |
Expand All @@ -102,10 +106,61 @@ 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.<name> }}`. 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]
target:
required: true
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. |
| `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.<name> }}` 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`
Expand Down
132 changes: 114 additions & 18 deletions content/manuals/ai/sandboxes/customize/kits.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,35 +302,114 @@ 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. 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, pass the sandbox kit reference
as the first argument:

```console
$ sbx run <sandbox-kit-ref> [PATH...]
$ sbx create <sandbox-kit-ref> [PATH...]
```

The previous form, `sbx run <sandbox-kit-name> --kit <sandbox-kit-ref>`, 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.
> `sbx kit add` restarts the sandbox to apply the updated kit set.
> 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.<name> }}`. Supply a
value with `--kit-arg name=value`:

```console
$ 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 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/ \
--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 in place of the
agent name. 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
Expand All @@ -347,6 +426,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"
```
Expand All @@ -360,6 +447,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
```
Expand All @@ -371,14 +466,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

Expand Down Expand Up @@ -497,16 +593,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
Expand Down
2 changes: 1 addition & 1 deletion content/manuals/ai/sandboxes/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down