Kits
NoteLos kits son experimentales. El formato de archivo de los kits, los comandos de la CLI y la experiencia para crear, cargar y gestionar kits están sujetos a cambios a medida que la característica evoluciona. Comparte comentarios y reportes de errores en el repositorio docker/sbx-releases.
Un kit empaqueta un conjunto de capacidades que un sandbox puede utilizar, tales como:
- Herramientas a instalar
- Variables de entorno a configurar
- Credenciales a inyectar
- Reglas de red para permitir o denegar dominios
- Archivos a incorporar
- Comandos de inicio a ejecutar
- Instrucciones de memoria para el agente
Declaras estas capacidades en un único archivo spec.yaml, apuntas la CLI al directorio (o a un archivo ZIP, artefacto OCI o URL de Git), y el sandbox las aplica y las hace cumplir en tiempo de ejecución. Las credenciales permanecen en el host y pasan a través de un proxy en lugar de entrar en la VM, y el tráfico saliente se restringe a los dominios permitidos por las reglas de red del kit.
Un kit es un mixin o un agente:
- Kits mixin (
kind: mixin): amplían un agente existente con capacidades adicionales. Puedes superponer varios en el mismo sandbox. - Kits de agente (
kind: agent): definen un agente completo desde cero: su imagen, punto de entrada (entrypoint), políticas de red y todo lo demás que el agente necesite.
Qué pueden hacer los kits
Ejecutar comandos
Un kit puede ejecutar comandos dentro del sandbox automáticamente. Los comandos de instalación se ejecutan una vez en la creación; los comandos de inicio se ejecutan cada vez que el sandbox se inicia.
Los comandos de instalación son el lugar idóneo para colocar cualquier elemento que el agente necesite en la imagen, mediante apt, pip, npm, curl | bash o lo que convenga:
commands:
install:
- command: "apt-get update && apt-get install -y jq"Los comandos de inicio cubren tareas como lanzar servicios en segundo plano, calentar cachés o actualizar la configuración en cada inicio. Deben ser idempotentes — consulta la referencia de la especificación de startup:
commands:
startup:
- command: ["sh", "-c", "my-daemon &"]Inyectar archivos
Los kits pueden inyectar archivos en el sandbox de dos maneras: archivos estáticos empaquetados con el kit, e initFiles escritos al inicio con valores en tiempo de ejecución sustituidos.
Los archivos estáticos funcionan bien para contenido que no varía entre sandboxes, como configuraciones de herramientas, reglas de linter compartidas, scripts auxiliares que el agente puede invocar o material de referencia como una guía de estilo o una hoja de referencia de API.
my-kit/
├── spec.yaml
└── files/
├── home/
│ └── .config/my-tool/settings.json
└── workspace/
└── .editorconfigLos initFiles cubren contenido que depende de valores en tiempo de ejecución, como una ruta absoluta del espacio de trabajo que una herramienta necesita integrar en su archivo de configuración al iniciarse:
commands:
initFiles:
- path: /home/agent/.my-tool/config.json
content: '{"workspace": "${WORKDIR}"}'
onlyIfMissing: trueConsulta initFiles en la referencia de la especificación para ver todos los campos.
Configurar variables de entorno
Las variables de entorno configuradas por el kit están disponibles para el agente en tiempo de ejecución:
environment:
variables:
MY_TOOL_WORKSPACE: /home/agent/my-toolPara las credenciales, consulta Autenticación en servicios externos. No coloques valores secretos directamente en environment.variables; de lo contrario, serían visibles dentro de la VM del sandbox.
Controlar el acceso a la red
Las reglas de red definen a qué dominios puede acceder o bloquear el sandbox. Las reglas de red del kit se aplican únicamente a los sandboxes que utilizan el kit:
network:
allowedDomains:
- api.example.com
- "*.cdn.example.com"
deniedDomains:
- telemetry.example.comUsa allowedDomains para los hosts que el agente necesite, como registros de paquetes, puntos de conexión de instalación o APIs externas. Usa deniedDomains para los hosts a los que el agente no deba acceder, como puntos de conexión de telemetría. Si un dominio coincide tanto con una regla de permiso como con una de denegación, la regla de denegación tiene prioridad.
Para servicios autenticados, consulta Autenticación en servicios externos.
Autenticación en servicios externos
Un kit puede adjuntar credenciales a las solicitudes salientes a través del proxy del lado del host. El agente dentro de la VM trabaja con un valor centinela; el proxy lee la credencial real en el host y sobrescribe la cabecera de autenticación antes de que la solicitud salga del sandbox.
El patrón estándar utiliza cuatro bloques vinculados a un identificador de servicio de tu elección (aquí, my-service):
network:
allowedDomains:
- api.example.com
serviceDomains:
api.example.com: my-service # Etiquetar el tráfico a este dominio
serviceAuth:
my-service:
headerName: Authorization # Sobrescribir esta cabecera
valueFormat: "Bearer %s"
credentials:
sources:
my-service:
env:
- MY_SERVICE_API_KEY # Búsqueda de credenciales en el host
environment:
proxyManaged:
- MY_SERVICE_API_KEY # Establece la variable de entorno en la VM como "proxy-managed"El agente se inicia con MY_SERVICE_API_KEY=proxy-managed, envía una solicitud con ese valor en Authorization, y el proxy sobrescribe la cabecera con la credencial real antes de reenviarla. El secreto real nunca llega a la VM.
Consulta Credenciales para saber cómo proporcionar el valor de la credencial en tu host, otros enfoques para casos que no se ajusten al ejemplo anterior, y qué hace el proxy en el momento de la solicitud.
Inyectar memoria al agente
Un kit puede añadir contenido al archivo de memoria del agente, como CLAUDE.md o AGENTS.md. El agente lee este archivo al iniciarse. Utilízalo para proporcionarle al agente convenciones del proyecto, consejos de uso de una herramienta que instale el kit u otras pautas que deban estar en su alcance cuando se ejecute el sandbox.
memory: |
Ruff is installed. Run `ruff check` before committing.
Shared config lives at `/workspace/ruff.toml`.Tanto los kits mixin como los de agentes pueden declarar memory:. El contenido se escribe únicamente cuando el kit de agente activo define agent.aiFilename, el cual determina el nombre del archivo de memoria.
Cuando más de un kit cargado declara un bloque memory:, el contenido de cada kit se escribe en su propio archivo <nombre-kit>.md bajo un directorio hermano kits-memory/ junto al archivo de memoria principal. El archivo de memoria principal recibe una sección ## Kits que apunta a cada archivo de kit:
/Users/you/
├── myproject/ # espacio de trabajo
├── AGENTS.md # archivo de memoria principal con el índice "## Kits"
└── kits-memory/
├── ruff-lint.md
├── vale.md
└── git-ssh-sign.mdConsulta memory en la referencia de la especificación para ver el esquema completo de campos.
Definir un agente
Los kits de agentes declaran un bloque agent: con la imagen en la que se ejecuta el agente y el comando al que se conecta el usuario cuando lanza el sandbox:
agent:
image: "my-registry/my-agent:latest"
entrypoint:
run: [my-agent, "--yolo"]Consulta Kits de agentes para ver casos de uso y un ejemplo.
Kits mixin
Un kit mixin amplía un agente existente con capacidades adicionales. Casos de uso comunes:
- Preinstalar herramientas: linters, bibliotecas u otros programas personalizados.
- Conceder al agente acceso a un nuevo servicio autenticado (una base de datos, una API de proveedor).
- Inyectar configuración compartida del equipo (reglas de linter, ajustes del editor, dotfiles).
Ejemplo: kit de linting de Python
Este kit instala Ruff e inyecta un archivo de configuración compartido, de modo que cada sandbox comience con la misma configuración de linting.
ruff-lint/
├── spec.yaml
└── files/
└── workspace/
└── ruff.tomlschemaVersion: "1"
kind: mixin
name: ruff-lint
displayName: Ruff Linter
description: Python linting with shared team config
network:
allowedDomains:
- pypi.org
- files.pythonhosted.org
commands:
install:
- command: "uv tool install ruff@latest"
user: "1000"
description: Install Ruffline-length = 100
[lint]
select = ["E", "F", "I"]TipLas plantillas para los agentes integrados (
claude,codex, etc.) ya incluyenuv, por lo que este mixin puede usarlo sin tener que instalarlo por separado.
Para iniciar un nuevo sandbox con este mixin:
$ sbx run claude --kit /ruta/a/ruff-lint/
Para aplicar el mixin a un sandbox que ya se está ejecutando, utiliza sbx kit add en su lugar. La bandera --kit solo surte efecto al crear un sandbox.
Kits de agentes
Un kit de agente define un agente completo desde cero: imagen, punto de entrada (entrypoint) y todo lo que el agente necesita. Casos de uso comunes:
- Empaquetar un agente personalizado que hayas creado para que otros puedan ejecutarlo.
- Distribuir un agente interno del equipo con valores predeterminados integrados.
- Ejecutar una bifurcación de un agente existente con tu propia configuración.
- Diseñar prototipos de una nueva integración de agentes.
Los kits de agentes declaran todo lo que puede declarar un kit mixin, además de un bloque agent: que le indica al sandbox cómo lanzar el agente. Para ver un tutorial paso a paso, consulta Construye tu propio kit de agente.
Ejemplo: el agente claude integrado
El agente claude que obtienes con sbx run claude está definido como un kit. Aquí tienes una versión abreviada de su especificación, que muestra cómo se combina el bloque del agente con la red, las credenciales, el entorno y los comandos:
schemaVersion: "1"
kind: agent
name: claude
agent:
image: "docker/sandbox-templates:claude-code-docker"
aiFilename: CLAUDE.md
persistence: persistent
entrypoint:
run: [claude, "--dangerously-skip-permissions"]
network:
serviceDomains:
api.anthropic.com: anthropic
console.anthropic.com: anthropic
serviceAuth:
anthropic:
headerName: x-api-key
valueFormat: "%s"
allowedDomains:
- "claude.com:443"
credentials:
sources:
anthropic:
env:
- ANTHROPIC_API_KEY
environment:
variables:
IS_SANDBOX: "1"
commands:
install:
- command: "curl -fsSL https://claude.ai/install.sh | bash"
user: "1000"
description: Install Claude CodeUso de kits
Los kits se pueden cargar desde una ruta local (un directorio o un archivo ZIP), un repositorio Git o un registro OCI. Pasa --kit más de una vez para superponer varios kits en el mismo sandbox.
Important
--kitsolo surte efecto al crear un sandbox. Pasar esta bandera para el nombre de un sandbox ya existente fallará con el error--kit can only be used when creating a new sandbox. Para aplicar un kit a un sandbox en ejecución, utilizasbx kit adden su lugar.
Local
Apunta --kit a un directorio o archivo ZIP en el disco:
$ sbx run claude --kit ./mi-kit/
$ sbx run claude --kit ./mi-kit-1.0.zip
Mientras iteras en un kit, aplica los cambios a un sandbox en ejecución con sbx kit add en lugar de volver a crearlo:
$ sbx kit add mi-sandbox ./mi-kit/
kit add vuelve a ejecutar los comandos de instalación y a copiar los archivos. Los kits no se pueden eliminar de un sandbox en ejecución: elimínalo y vuélvelo a crear para empezar de cero.
Repositorio Git
$ sbx run claude --kit "git+https://github.com/docker/sbx-kits-contrib.git#ref=v0.1.0&dir=code-server"
#ref=<rama|etiqueta|commit>apunta a una revisión específica. Toma de forma predeterminada la rama por defecto del repositorio.#dir=<ruta>carga un kit desde un subdirectorio.- Las URLs
git+ssh://también funcionan, utilizando tu agente SSH local, auxiliares de credenciales de Git y.netrc. - Envuelve la URL entre comillas en shells donde
&inicie un trabajo en segundo plano.
Registro OCI
$ sbx run claude --kit ghcr.io/miorg/mi-kit:1.0
Para Docker Hub, incluye el prefijo completo docker.io. Consulta Empaquetado y distribución para la publicación.
ImportantLos kits privados solo son compatibles con Docker Hub.
sbxreutiliza tu sesión desbx loginpara descargar artefactos privados de Docker Hub. Otros registros se descargan de forma anónima, por lo que las descargas de kits privados alojados en registros distintos de Docker Hub fallarán.
Empaquetado y distribución
Los subcomandos de sbx kit validan, inspeccionan y publican kits:
sbx kit validate <ruta>— comprueba que un directorio de kit o un archivo ZIP estén bien formados.sbx kit inspect <ruta>— muestra los detalles del kit. Añade--jsonpara obtener una salida legible por máquina.sbx kit pack <ruta> -o <archivo.zip>— empaqueta un directorio como un archivo ZIP para compartirlo.sbx kit push <ruta> <ref>— publica en un registro OCI (por ejemplo,ghcr.io/miorg/mi-kit:1.0).sbx kit pull <ref>— descarga un kit desde un registro como un archivo ZIP en el directorio de trabajo.
Para Docker Hub, incluye el prefijo completo docker.io — sbx no lo añade de forma automática.
Referencia de la especificación
Un directorio de kit tiene un archivo spec.yaml requerido y un árbol files/ opcional:
my-kit/
├── spec.yaml # requerido
└── files/ # opcional — archivos estáticos a inyectar
├── home/
└── workspace/Campos de nivel superior
schemaVersion: "1"
kind: <mixin | agent>
name: <nombre>
displayName: <nombre>
description: <texto>| Campo | Requerido | Descripción |
|---|---|---|
schemaVersion | Sí | Versión del esquema de la especificación. Configúralo en "1". |
kind | Sí | mixin para kits que amplían un agente; agent para kits que definen uno. |
name | Sí | Identificador único. Minúsculas, alfanumérico, guiones. |
displayName | No | Nombre legible por humanos. |
description | No | Breve descripción. |
Las secciones siguientes se aplican a ambos tipos. Los kits de agentes también declaran un bloque agent:.
Credenciales (credentials)
credentials:
sources:
<id-servicio>:
env: [<var-entorno>, ...]
file:
path: <ruta>
parser: <analizador>
priority: <env-first | file-first>| Campo | Descripción |
|---|---|
sources | Mapa de identificador de servicio a la fuente de credenciales. |
sources.<id>.env | Variables de entorno a leer en el host, en orden de prioridad. |
sources.<id>.file.path | Ruta en el host. ~ se expande al directorio de inicio. |
sources.<id>.file.parser | Cómo extraer el valor (por ejemplo, "json:apiKey"). |
sources.<id>.priority | env-first (predeterminado) o file-first. |
Los identificadores de servicio vinculan las credenciales a las reglas de red.
Red (network)
network:
allowedDomains: [<dominio>, ...]
deniedDomains: [<dominio>, ...]
serviceDomains:
<dominio>: <id-servicio>
serviceAuth:
<id-servicio>:
headerName: <cabecera>
valueFormat: <formato>| Campo | Descripción |
|---|---|
allowedDomains | Dominios a los que el sandbox puede acceder. Soporta comodines. |
deniedDomains | Dominios a los que el sandbox no puede acceder. Las reglas de denegación tienen prioridad. |
serviceDomains | Mapa de dominio al identificador de servicio de credentials.sources. |
serviceAuth.headerName | Cabecera HTTP que configura el proxy (por ejemplo, Authorization). |
serviceAuth.valueFormat | Cadena de formato para el valor de la cabecera (por ejemplo, "Bearer %s"). |
Entorno (environment)
environment:
variables:
<NOMBRE>: <valor>
proxyManaged: [<NOMBRE>, ...]| Campo | Descripción |
|---|---|
variables | Pares clave-valor configurados directamente en el contenedor. |
proxyManaged | Nombres de variables de entorno rellenados por el proxy en el momento de la solicitud. Combínalos con credentials.sources. |
Los nombres de las variables deben ser identificadores de shell válidos ([A-Za-z_][A-Za-z0-9_]*).
Comandos (commands)
commands:
install:
- command: <cadena-shell>
user: <uid>
description: <texto>
startup:
- command: [<argv>, ...]
user: <uid>
background: <true | false>
description: <texto>
initFiles:
- path: <ruta>
content: <texto>
mode: <octal>
onlyIfMissing: <true | false>
description: <texto>install
Se ejecuta una vez durante la creación del sandbox. Cadenas de shell pasadas a sh -c.
| Campo | Predeterminado | Descripción |
|---|---|---|
command | — | Cadena de comando de shell. |
user | "0" | Usuario con el que se ejecuta. "0" = root. |
description | — | Descripción legible por humanos. |
startup
Se ejecuta en cada inicio del sandbox. Matriz de cadenas, no interpretada por un shell.
| Campo | Predeterminado | Descripción |
|---|---|---|
command | — | Comando y argumentos como una matriz de cadenas. |
user | "1000" | Usuario con el que se ejecuta. "1000" = agent. |
background | false | Ejecutar en segundo plano. |
description | — | Descripción legible por humanos. |
Los comandos de inicio son no interactivos. Se ejecutan antes de que el agente se acople, sin ninguna terminal conectada, por lo que no pueden pedir datos al usuario (por ejemplo, un inicio de sesión interactivo de aws se bloqueará o fallará). Tampoco retrasan el punto de entrada del agente: el agente se lanza una vez que se han enviado los comandos de inicio, de forma independiente de background. Utilízalos para la preparación no interactiva —lanzar demonios, calentar cachés, actualizar configuraciones— y usa commands.initFiles para cualquier valor que deba guardarse en disco antes de que el agente se ejecute.
Los comandos de inicio deben ser idempotentes. Se ejecutan en cada inicio del sandbox y se vuelven a aplicar en los reinicios del contenedor, por lo que un comando que falle o se comporte incorrectamente en una segunda invocación romperá la ruta de reinicio. Protege las tareas con comprobaciones de existencia, utiliza operaciones de actualización (upserts) en lugar de inserciones y prefiere comandos que converjan en el mismo estado final independientemente de cuántas veces se ejecuten.
initFiles
Archivos escritos al inicio del sandbox, con sustitución en tiempo de ejecución.
| Campo | Predeterminado | Descripción |
|---|---|---|
path | — | Ruta absoluta en el contenedor. |
content | — | Contenido del archivo. ${WORKDIR} se expande a la ruta del espacio de trabajo. |
mode | "0644" | Permisos del archivo en octal. |
onlyIfMissing | false | Omitir si el archivo ya existe. |
Archivos estáticos
my-kit/files/
├── home/ → /home/agent/
└── workspace/ → ruta del espacio de trabajo primario| Ruta en el kit | Destino en el contenedor |
|---|---|
files/home/ | /home/agent/ (archivos de configuración, dotfiles) |
files/workspace/ | La ruta del espacio de trabajo primario |
Los directorios principales se crean automáticamente. Los archivos existentes se sobrescriben. Las rutas absolutas y las secuencias de salto de directorio (../../) son rechazadas.
Memoria (memory)
memory: |
<markdown>Campo de nivel superior. Disponible tanto en kits mixin como en kits de agentes. Fragmento de Markdown que se añade al archivo de memoria del agente al crear el sandbox. El agente lee este contenido al iniciarse. Escríbelo como instrucciones o notas que el agente deba seguir al trabajar en el sandbox. Solo se aplica cuando el kit de agente activo define agent.aiFilename.
El archivo se escribe en el directorio superior de la ruta del espacio de trabajo dentro del sandbox, no en el espacio de trabajo en sí. Para un espacio de trabajo montado en /Users/yo/mi-proyecto, el archivo de memoria se creará en /Users/yo/AGENTS.md (o como se llame el valor de aiFilename). Solo existe dentro del sandbox. No se escribe nada en el host.
Cuando varios kits cargados declaran bloques memory:, el contenido se divide en varios archivos en lugar de concatenarse en el principal:
- La memoria de cada kit se escribe en
<nombre-kit>.mden un directorio hermanokits-memory/junto al archivo de memoria principal. - El archivo de memoria principal recibe una sección
## Kitsque enumera cada kit con un puntero a su archivo. La sección está delimitada por los marcadores<!-- sbx:kits-section start -->y<!-- sbx:kits-section end -->para que pueda regenerarse cuando se añadan o eliminen kits.
Bloque del agente (agent)
Requerido cuando kind: agent.
agent:
image: <ref-imagen>
aiFilename: <nombre-archivo>
persistence: <persistent | ephemeral>
entrypoint:
run: [<argv>, ...]
args: [<arg>, ...]| Campo | Requerido | Descripción |
|---|---|---|
agent.image | Sí | Referencia de imagen de Docker. Consulta Requisitos de la imagen base. |
agent.aiFilename | No | Nombre del archivo de memoria (por ejemplo, AGENTS.md). Añade el campo memory de nivel superior en la creación. |
agent.persistence | No | persistent (volumen con nombre entre reinicios) o ephemeral (predeterminado). |
agent.entrypoint.run | No | Comando y argumentos como una matriz de cadenas. Reemplaza el punto de entrada de la imagen. |
agent.entrypoint.args | No | Argumentos añadidos al punto de entrada existente de la imagen. |
Requisitos de la imagen base
La imagen de contenedor del agente debe proporcionar:
- Un usuario
agentsin privilegios de root con UID 1000 y sudo sin contraseña. - Un directorio de inicio
/home/agent/propiedad deagent. - Las variables de entorno de proxy HTTP (
HTTP_PROXY,HTTPS_PROXY,NO_PROXY) preservadas a través de sudo. - El binario del agente (integrado en la imagen o instalado mediante
commands.install).
Compila sobre docker/sandbox-templates:shell-docker para obtener estas características de forma gratuita.
Depuración
Cuando un kit no se comporte como se espera, comienza con el registro de políticas de red y la inspección directa dentro del sandbox:
sbx policy logmuestra cada solicitud saliente detectada por el proxy del sandbox, la regla con la que coincidió, el contexto adicional disponible y su valor dePROXY, comoforward,forward-bypass,transparentobrowser-open. Utilízalo para diagnosticar fallos de descarga en la instalación, dominios bloqueados e interceptación TLS inesperada. Si las descargas fallan o llegan dañadas después de añadirserviceDomains, comprueba si el mapeo de servicios es demasiado amplio. Mapea únicamente los hosts que realmente requieran inyección de credenciales.sbx exec <sandbox> -- <comando>ejecuta un comando arbitrario dentro de un sandbox existente. Es útil para inspeccionar el estado posterior a la instalación sin tener que volver a crear el sandbox:which mi-herramienta,ls /home/agent/.local/bin/,cat /home/agent/.config/..., etc.
La salida de los comandos de instalación y de inicio solo se emite durante sbx run o sbx create; sbx no la retiene para inspecciones posteriores. Para repetir la configuración y obtener una salida nueva, elimina y vuelve a crear el sandbox: sbx rm <sandbox> && sbx run ....