Thomas Piacentini
← Atelier

Chapitre

com.docker.sandbox/ capabilities

Texte original · anglais

A kit grants itself nothing: each capability is typed and versioned, the resolver unions one workload with its mixins, and any widening on update stops for approval.

The gh mixin a colleague published reaches api.github.com with your token. You want to know exactly which requests it can make with that token, and what changes when version 2 arrives. Both answers are in its capabilities list.

When you finish this section, you can read that list, predict the merged grant set, and say which update will stop and ask.

Typed, versioned requests

Capability: one typed request in the capabilities list of a kit, for something that the kit needs and cannot supply itself {{kitspec §7}}. The host answers each one: granted, refused, or prompted.

Each entry has a type of the form <namespace>/<name>@<version>, an optional display name, and an optional flag {{kitspec §7}}. Its config is decoded strictly for the types the specification defines, so an unknown key is an error {{kitspec §7}}. The version names the config schema, so network-policy@1 and @2 both exist and a descriptor states one of them {{kitspec §7.1}}. A type that describes a policy appears once {{kitspec §7.1}}, while instance-shaped types repeat once per thing requested, such as credential@1 per service and phase.

Unknown types are allowed by design, because new types are how the format grows {{kitspec §7.3}}. A required unknown type fails resolution, and an optional one is skipped and recorded.

The nineteen types at the pin

Type Shape What it asks for
network-policy@1 singleton hosts the sandbox can reach, per phase
network-policy@2 singleton, exclusive with @1 hosts plus HTTP methods and paths
credential@1 per service and phase one service the workload authenticates to
ssh-agent@1 per phase what the forwarded SSH agent signs
volume@1 per path persistent or tmpfs storage
host-mount@1 per path a host directory, sharing the storage key with volume@1
port@1 per container port and transport a published port
usb-device@1 instance a USB device match
resources@1 singleton CPU, memory, and GPU limits, a constraint rather than a grant
privileged@1 singleton, no config a privileged container
long-running@1 singleton, no config keep running with no session attached
lifecycle@1 singleton install hooks, startup hooks, files, the interactive argv
agent-context@1 singleton the instruction file for the agent
agent-sessions@1 singleton headless prompt and resume verbs
agent-skills@1 per path where the agent reads skills
agent-skill@1 per effective name one bundled skill
git-identity@1 singleton, no config the runtime's git name and email
kit-registry@1 singleton, no config reach the runtime's own kit registry, where builds push and pull
sbx@1 singleton, no config launch the workload a particular way, with the identity the image states

The table is kitspec §7.2 at the v3.0.0-m.8 tag. The main branch adds a twentieth, com.docker.sandbox/agent-interactive-sessions@1, as a singleton {{kitspec-main §7.2}}, unreleased at the pin. The newest type in sbx itself arrived with the pinned release. A kit can declare com.docker.sandbox/long-running@1 to keep a local sandbox running after all its sessions disconnect {{rel-sbx v0.47.0}}.

network-policy@2 and credential@1

A network-policy@2 entry is a plain host string or an object with hosts, methods, and paths {{kitcap network-policy@2}}. A host string grants the connection for any protocol, as @1 did. An entry with methods or paths is bounded: it grants those HTTP requests and nothing else on that host. Deny entries list what to refuse, and a deny wins {{kitcap network-policy@2}}. A refused request gets a status, because a runtime must answer it with HTTP status 403 {{kitcap network-policy@2}}. The proxy that enforces this is the one in the policy log section.

A credential@1 entry names a service and a phase, and never the place where the secret is kept {{kitcap credential@1}}. With apiKey.proxyManaged, the real value stays on the host {{kitcap credential@1}}. Every inject domain must appear in the allow list of the same phase {{kitcap credential@1}}. The binding that answers it is the one the secret section stores.

Resolution and the merged set

A runtime must include exactly one workload kit in each composition {{kitspec §5.3}}. It must fail when two kits provide the same normalized name {{kitspec §5.3}}, so claude plus claude-mixin is refused. Across the set, allow entries union per phase, deny entries union per phase, and deny wins on the result {{kitcap network-policy@2}}. When one kit allows a host outright, another kit's bounded entry for that host is dropped, because the union is the unbounded grant {{kitspec §9.5}}. Figure runs that arithmetic on three kits.

Fig. 4.2three kits resolve into one grant settree
One workload and two mixins merge into one grant set where allows union, deny wins, and a removed deny on the next version stops for approval.
One workload and two mixins merge into one grant set where allows union, deny wins, and a removed deny on the next version stops for approval. Read top down. The three kits are the captured hello-kit, the gh example of kitspec §2, and the network-policy@2 config example of its capability page. The teal block is the lock. From capture/fixtures/kits/hello-kit/kit.yaml, kitspec §5.3, §7.4, §9.5, and the kitcap pages.

Original SVG

Original source
id: fig-4-2
kind: tree
title: three kits resolve into one grant set
claim: One workload and two mixins merge into one grant set where allows union, deny wins, and a removed deny on the next version stops for approval.
caption: Read top down. The three kits are the captured hello-kit, the gh example of kitspec §2, and the network-policy@2 config example of its capability page. The teal block is the lock. From capture/fixtures/kits/hello-kit/kit.yaml, kitspec §5.3, §7.4, §9.5, and the kitcap pages.

What a grant looks like inside sbx

The recording host ran a v2 mixin, so the captured rows come from permissions.network.allow rather than a v3 entry. The daemon stores the grant as a policy rule the sandbox owner cannot edit:

the kit's allow rule on sandbox m101-kitjsonFull source
      "name": "kit:m101-kit",
…
      "scope": "sandbox:m101-kit",
…
      "resource_type": "network",
      "decision": "allow",
      "resources": [
        "example.com"
      ],
…
      "editable": false,
…
        "created_via": "provisioned",
The rules array has one element, cut to the fields named in the text.
Original source
title: the kit's allow rule on sandbox m101-kit
source: capture/out/12-policy-kit.json
lang: json
note: The rules array has one element, cut to the fields named in the text.
---
      "name": "kit:m101-kit",
…
      "scope": "sandbox:m101-kit",
…
      "resource_type": "network",
      "decision": "allow",
      "resources": [
        "example.com"
      ],
…
      "editable": false,
…
        "created_via": "provisioned",

sbx policy check network example.com --sandbox m101-kit --json then answers "allowed": true (the capture). The rule carries created_via: provisioned and answers to --source kit, which is how the policy section tells a kit rule from one you added.

Updates and the lock

Every grant maps onto one normalized set. A consumer that controls updates stores that set in its lock file and compares each candidate against it {{kitspec §7.4}}. A new version whose set stays inside the stored one can apply silently. Any widening must stop for approval.

The list is explicit. It holds a new allow entry, a removed deny entry, and a new credential, path, or port. Write access over a read-only skills path is also on it. A removed deny counts, because the deny was part of what made the grant acceptable {{kitspec §7.4}}. optional does not change the set {{kitspec §7.4}}. Six types contribute nothing to it: resources@1, lifecycle@1, agent-context@1, agent-sessions@1, sbx@1, and long-running@1 {{kitspec §7.4}}.

Original source
- Read a kit's `capabilities` list before you run it, and treat each entry as a request you answer.
- Expect allows to union across kits, and write a `deny` when another kit must not widen a host.
- Review every update that adds an allow, a credential, a path, or a port, or removes a deny.

Sources: kitspec §5.3, §7, §7.1, §7.2, §7.3, §7.4, §9.5 (research/sources/SPEC-v3-at-v3.0.0-m.8.md); kitspec-main §7.2 (research/sources/SPEC-v3.md, unreleased); kitcap network-policy@2, credential@1 (research/sources/kit-capabilities.md); rel-sbx v0.47.0 (research/sources/sbx-releases.md); capture/fixtures/kits/hello-kit/kit.yaml; capture/out/12-policy-kit.json, 12-policy-kit.txt, 12-check-kit.json

Code et livrables 1
Ce que vous en retenez

Enregistré dans votre carnet sur cet appareil.

Sources et limites

Les repères de lecture sont déclaratifs. Les résultats de tests sont enregistrés séparément ; ils valent pour les cas exécutés.

AI Engineering from Scratch · 3f9715c · MIT

Télécharger ce fichier ↓