Kits
A Kit is an image that carries a descriptor of what its workload may reach and hold. With kind: kit, Kraft runs the Kit as the whole sandbox, in place of the image, network, resources and credentials keys of kind: docker. This page covers declaring one and what a launch does with it.
Declaring a Kit
repos:
- path: /home/you/code/my-service
sandbox:
kind: kit
runtime: docker
kit: registry.example.com/acme/kraft-worker-claude@sha256:<64 hex>
A Docker Sandbox Kit is an image whose manifest carries the descriptor. Kraft reads Kits written to the spec's v3.0.0-m.7.
Under kind: kit the Kit is the whole sandbox:
runtimeandkitare required.image,network,resourcesandcredentialsare refused.kitmust be pinned by digest (<name>[:<tag>]@sha256:<64 hex>). A tag alone is refused whenrepos.yamlloads.- Like any sandbox, a chain, node or task cannot change it, and a chain's or library's policy can set it too.
Kits you build
Docker's published Kits (docker/sbx-kit-shell, docker/sbx-kit-claude) require capabilities Kraft does not enforce, so Kraft refuses them. Build a Kit for Kraft instead: Build a worker Kit gives one for Claude.
What Kraft enforces
Kraft runs exactly one Kit, a kind: workload, and composes nothing:
| Capability | What Kraft does |
|---|---|
network-policy@1 | Enforced, as the network policy, phase for phase. Required: a Kit without one is refused. |
credential@1 | Enforced for a proxy-managed apiKey with a name and header inject rules, as a credential scoped to its phase. |
resources@1 | Enforced: cpu and memory as the resource limits (2gib is 2g, cpu: 0 is no limit). gpu is not. |
agent-sessions@1 | Accepted and not applied: the harness file builds the command, as for kind: docker. |
| Any other type, or a form above Kraft does not enforce | Refused when required, naming it. Skipped when optional. |
For credential@1, the value is the server's variable that sandbox.yaml's credentials binds to its service. An oauth beside the apiKey is recorded as ignored.
A kind: mixin, a requires, a capability group, a ${{ }} reference in a capability, an args entry exported to env, and a descriptor over 512 KiB are refused too.
What a launch runs
The Kit, lowered to the kind: docker sandbox it describes: the Kit's image by digest, its network lists, its credentials and its limits, and nothing else. The harness's network.requires hosts are not added, so a host the Kit leaves out is refused and recorded like any other.
The image's Entrypoint is kept and the harness's command replaces its Cmd, so a Kit whose entrypoint is the agent CLI itself does not work. The worker session records docker as its backend.
When it is read
Kraft reads the descriptor with your runtime's own CLI and registry login, before an item's worktree is made, and caches it under $KRAFT_HOME/run/kit/ by its digest.
- Docker reads it with
docker manifest inspect. - Podman reads only an index that way, so it pulls a single-manifest Kit and reads its image.
A Kit that cannot be fetched or is refused stops the item and waits for you, naming the Kit and why: see Troubleshooting. Each task dispatched under it records a sandbox_kit_resolved event once per Kit, with what was skipped or ignored.
Doctor
kraft admin doctor fetches and lowers each Kit repository's Kit, fails its sandbox row when it cannot, and runs the sandbox, egress, proxy and credentials rows on what it lowers to. It warns about each harness host the Kit does not allow (kit hosts) and each credential service with no binding (kit credentials).
Related
- Build a worker Kit: a Kit for Claude, step by step.
- Sandboxed workers: the
sandboxkeys, and what reaches the container. - sandbox.yaml: where a Kit's credentials are bound.