Sandbox Kits & Custom Templates
ជំពូកនេះមិនទាន់ត្រូវបានបកប្រែជាភាសាខ្មែរនៅឡើយទេ — សូមអានជាភាសាអង់គ្លេសខាងក្រោម។
Table of Contents
- What a kit actually is
- Anatomy of a kit
- Mixin kits vs. sandbox kits
- Writing your first kit
- Using a kit
- Sharing, signing, and trusting kits
- Beginner Pitfalls
1. What a kit actually is
Every sandbox you've created so far in this course started from a bare
agent (shell, claude, ...) and got its extra setup — apt-get install,
npm install, environment variables — typed in by hand, every time. A
kit is that setup written down once, as a declarative file, so it can be
applied to any sandbox with a single flag instead of re-typed.
A kit can bundle:
- Tools to install
- Environment variables to set
- Credentials to inject (without ever exposing the raw secret to the agent)
- Network rules to allow or deny
- Files to drop into the sandbox
- Startup commands to run
- Memory instructions to give the agent (project conventions, house style,
"run
ruff checkbefore committing" — that kind of thing)
Note: kits are a newer, explicitly experimental part of
sbx— Docker documents them as subject to change. Everything below matches the documented behavior at the time of writing; if a command errors out, check docs.docker.com/ai/sandboxes/customize/kits for what changed.
2. Anatomy of a kit
A kit is a directory, not a single file:
my-kit/
├── spec.yaml # the kit's declaration
└── files/ # optional: static files to drop into the sandbox
├── home/
│ └── .config/tool/settings.json
└── workspace/
└── .editorconfig
spec.yaml is where everything is declared. A minimal one:
kind: mixin
name: my-kit
setup:
install:
- command: "apt-get update && apt-get install -y jq"
startup:
- command: ["my-daemon"]
background: true
files:
- path: /home/agent/.config/tool/config.json
content: '{"workspace": "${WORKDIR}"}'
onlyIfMissing: true
environment:
variables:
MY_TOOL_WORKSPACE: /home/agent/my-tool
permissions:
network:
allow:
- api.example.com
- "*.cdn.example.com"
deny:
- telemetry.example.com
agentInstructions:
content: |
A linter is installed. Run it before committing.
setup.install commands run once, when the sandbox is created.
setup.startup commands run every time the sandbox starts, so they must be
safe to run more than once (idempotent) — the same discipline you'd apply to
a docker-entrypoint.sh. agentInstructions.content gets appended to the
agent's memory file, the same file claude/CLAUDE.md-style agents already
read on startup.
3. Mixin kits vs. sandbox kits
kind: decides what a kit is allowed to do:
-
kind: mixin— extends an existing agent (claude,codex, a plainshell, ...) with extra tools, files, or permissions. This is what you'll write most often: "give this agent linting" or "give this agent read access to our internal package registry." -
kind: sandbox— defines a complete agent from scratch, including its own container image:kind: sandbox name: my-agent sandbox: image: "my-registry/my-agent:latest" entrypoint: ["my-agent", "--yolo"]A sandbox kit can also
extends: claudeto inherit an existing agent's image, credentials, network permissions, and settings, and layer changes on top rather than starting from zero.
A mixin can't declare a sandbox: block — that's the one thing reserved for
kind: sandbox. Multiple mixins can be applied to the same sandbox at once;
their install/startup/files entries just run one after another, in
order.
4. Writing your first kit
From your host (kits are authored outside a sandbox, then applied to one):
mkdir -p ~/my-kit && cd ~/my-kit
cat > spec.yaml << 'EOF'
kind: mixin
name: ripgrep-and-jq
setup:
install:
- command: "apt-get update && apt-get install -y ripgrep jq"
agentInstructions:
content: |
ripgrep (rg) and jq are installed. Prefer rg over grep for searching
the codebase, and jq for inspecting JSON output.
EOF
Check it's well-formed before trying to use it:
sbx kit validate ~/my-kit
sbx kit inspect ~/my-kit
5. Using a kit
Apply a kit at sandbox creation time with --kit:
sbx run claude --kit ~/my-kit
Or add it to an existing, already-running sandbox:
sbx kit add my-agent-sandbox ~/my-kit
This restarts the sandbox but preserves its state — installed packages,
pulled images, shell history all survive. Adding a kit to a running sandbox
only supports a subset of fields (environment variables, install commands,
and network allow rules) — anything that needs a fresh container (like a
kind: sandbox image swap) has to be applied at creation time instead.
If your kit takes arguments (declared under args: in spec.yaml), pass
them with --kit-arg:
sbx run claude --kit ~/my-kit --kit-arg channel=beta
6. Sharing, signing, and trusting kits
A kit is just files, so it can live anywhere your team already shares code:
sbx run claude --kit ./my-kit # local path
sbx run claude --kit "git+https://github.com/org/kits.git#dir=jq-kit" # Git repo, pinned
sbx run claude --kit ghcr.io/myorg/my-kit:1.0 # OCI registry
Because a kit can run arbitrary install commands, sbx treats "some kit
someone linked you" the same way you should treat "some curl | sh someone
linked you" — worth verifying before you run it. Kits support cosign-style
signing:
sbx kit sign ~/my-kit
sbx kit verify \
--certificate-identity you@example.com \
--certificate-oidc-issuer https://accounts.google.com \
~/my-kit
and a team can require signatures from specific, trusted signers before any kit is allowed to run at all:
sbx settings set kit.trustedSigners \
'[{"identity":"release-bot@example.com","issuer":"https://accounts.google.com"}]'
sbx settings set kit.requireSignature true
7. Beginner Pitfalls
- A kit's
environment.variablesshould never includeHTTP_PROXY,HTTPS_PROXY, orNO_PROXY— the sandbox manages those itself to route traffic through its policy-enforcing proxy. Overriding them routes traffic around that proxy, silently disabling network policy and credential injection for anything that uses them. - If governance (see Part 13)
is active for your organization, a kit's own
permissions.network.allowrules are ignored — only org-level allow rules grant access. A kit can still tighten things withdenyrules, just not loosen them. - Signing covers
spec.yamland thefiles/directory, but not anything referenced by a mutable tag, like a container image tag in akind: sandboxkit. Pin image digests if you need that covered too.
ទិញកាហ្វេជូនខ្ញុំ
ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!