Docker Sandbox Kit 规范(v3)学习笔记
1痛点:Dockerfile 之后的另一半
事实Dockerfile 完整回答了镜像内部的一切:怎么构建、打包什么、怎么启动(entrypoint、cmd、env、user、workdir)。但它对镜像外部只字未提。
事实Agent 不是静态应用负载,而是行动者(actor):它主动决定下一步做什么,然后对文件系统、网络、数据库、云账号施加操作。这种授权不是缺陷,而是 agent 能干活的前提——不能装依赖、不能调 API、不能持凭据的 agent 无法完成工作。
事实在 Kit 出现之前,"agent 需要哪些权限和资源"分布在:docker run 参数、Compose 文件、CI 配置、入职文档、以及配置者的记忆中——在制品之外、不受版本管理、无法审查。
推理核心问题不是"agent 会越权",而是授权本身不可见、不可版本化。能被审查的前提是信息存在制品内 → 存在制品内才能版本化 → 可版本化才能 diff → 可 diff 才能拦截审批。这条推导链是整个规范的价值基础。
Dockerfiles made software reproducible. Kits make authority reproducible.
(Dockerfile 让软件可复现,Kit 让授权可复现。)
事实规范定位:开放规范(Apache 2.0)而非产品特性,官方宣传语 "Authority as Code"。当前为实验性状态,目标 2026 Q4 定稿。
2Kit 的物理制品模型 ★核心承重墙
一个 Kit 在物理上就是一个普通 OCI 镜像:
- 层(layers)装内容(工具、文件系统)
- manifest 注解
vnd.docker.sandbox.kit.descriptor装声明(descriptor,即申请单)- 一个 digest 把两者钉死在一起
事实没有 Kit 专用 media type、没有 artifactType、没有旁车文件(sidecar)。因此:
docker pull照常拉取,regctl照常检查,任何注册表照常存储- 可以被任何镜像
FROM - 不认识注解的引擎把它当普通镜像运行
- 扫描器、签名器、镜像同步工具零改动
推理"声明与内容同一制品、同一 digest"意味着 Kit 不可能被"半更新":锁 digest 就同时锁定了内容、策略、元数据。分离的描述文件必然漂移(第二事实源问题)。
两类 Kit
| 类型 | 层的内容 | 每次组合的数量 |
|---|---|---|
| workload | 根文件系统;镜像 config 提供入口点/环境 | 恰好一个 |
| mixin | 叠加在 workload 文件系统上的 overlay;可以无内容纯声明 | 零或多个 |
事实descriptor 刻意不重复镜像已能表达的信息:无顶层身份名、无镜像引用、无 entrypoint/env——那些是镜像 config 的职责。重复即产生"一个问题两个答案",其中之一必然过期。
3两个角色:沙箱运行时与 Kit
事实沙箱(Docker Sandboxes / sbx)= microVM,自带独立内核和私有 Docker 引擎,提供"强制而非商量"的隔离边界。
类比沙箱 = 毛坯房 + 门禁系统(运行时提供);Kit = 家具 + 一份"我需要开哪些门"的申请表(内容 + 权限声明)。
边界止于"隔离与内容的分工",不涵盖权限的版本化审查机制。
事实宿主机平台与沙箱内部环境是两个独立概念:
- 宿主机(装 sbx 的机器):macOS Sonoma+(Apple silicon)、Windows 11、Ubuntu 24.04+;本地沙箱还需 Hypervisor Platform / KVM
- 沙箱内部:Linux 用户态(见 §8)
4编写与构建
四种编写形式 事实
| 形式 | 构成 | 特点 |
|---|---|---|
| 伴生对(默认) | <主干>.yaml + 同主干 .dockerfile | Dockerfile 工具链照常工作 |
内联 build: 块 | descriptor 内嵌 Dockerfile 文本 | 单文件 |
| 注释 descriptor | Dockerfile 的 # kit: 注释块携带声明 | 一文件两用 |
| Kit set | kits: 列表引用其他 Kit | 唯一配方不是 Dockerfile 的形式 |
构建命令 事实
# 构建 Kit(Win10 可行,只需 Docker Desktop + buildx)
docker buildx build . -f gh.yaml -t docker.io/me/sbx-kit-gh:2.72.0
docker buildx build . -f gh.yaml --build-arg version=2.99.0 -t gh-kit:2.99.0
.= 构建上下文:整个目录打包发给构建器(伴生文件、contentFile引用的文件都必须在其中)-f gh.yaml= 入口文件(平时放 Dockerfile 的位置)- 首行
# syntax=docker/sandbox-kit:3触发 BuildKit 自动拉取 Kit 前端(docker/sandbox-kit:3镜像) docker build与docker buildx build在现代 Docker 中是同一条命令
前端流水线 事实
- 严格校验 descriptor:任何无法识别的字段直接报错(
KnownFields(true))——拼错的键等于静默缺失的策略,必须失败 - 按文件名主干在上下文中找到伴生 Dockerfile(或在 descriptor 中用
dockerfile:字段显式指定) - 把 Dockerfile 原样交给常规 Dockerfile 构建器(
dockerfile.v0) - 将 guidance 内容(如 agent-context 的
contentFile)staged 进镜像 - 将 descriptor 作为 manifest 注解附加——产出一个普通镜像
推理Kit 前端是"总装工头":调用老工人(Dockerfile 构建器)干活,最后往包装箱上多贴一张单子(注解)。
镜像构建基础(补课要点)
事实OCI 镜像 = ① 一叠只读层(每层是文件系统变化的 tar 包)+ ② config(JSON:入口点/环境/用户)+ ③ manifest(拼装说明,可挂注解)。
事实docker build 逐条执行 Dockerfile 指令;每条 RUN 在临时容器中真实执行,文件系统变化拍成一层;ENTRYPOINT/ENV 写入 config 而非层。多阶段构建中只有最后阶段的层进入最终镜像(FROM scratch + COPY --from 用于丢弃构建工具、只留成品)。
类比Git:层 ≈ commit 的 diff,digest ≈ commit hash,manifest ≈ 仓库元信息。边界镜像层是只读叠加,没有分支/合并语义。
事实mixin 用 FROM scratch 构建纯 overlay(如 gh 示例用 nix 闭包自带全部依赖),可落在任何 workload 上;mixin 也可设 ENTRYPOINT(它仍是可独立运行的镜像),但组合时被忽略——workload 锚定运行时契约。
5capabilities:统一申请模型
事实Kit 对宿主的一切请求都是 capabilities 列表中带类型、带版本的条目。资源授予(卷、端口、设备)与引擎执行的行为(生命周期钩子、agent 上下文)走同一清单——宿主机通过一种机制回答全部请求,或诚实地拒绝无法满足的部分。
capabilities:
- type: com.docker.sandbox/network-policy@1 # 网络申请
config:
runtime:
allow: [github.com, api.github.com, uploads.github.com]
- type: com.docker.sandbox/credential@1 # 凭据申请
optional: true # 给不了则跳过并记录
config:
service: github
apiKey: {name: GH_TOKEN, proxyManaged: true}
- type: com.docker.sandbox/agent-context@1 # 给 agent 的使用说明
config:
contentFile: ./gh-context.md
事实@1 是该类型 config schema 的版本号:类型可独立演进(@2 与 @1 并存),不需要 descriptor 语法升级。知名类型每型一页规范(docs/spec/capabilities/com.docker.sandbox/),未知类型以不透明方式携带(宿主可支持私有类型)。
事实required 无法满足 → 解析失败(fail closed);optional 无法满足 → 跳过并记录。
平台底座(platform floor)事实·规范原文
Kit 内容可以假定符合规范的运行时提供以下底座:
bash和sh、curl、git、已填充的 CA store、以及名为agent(uid1000,home/home/agent)的非 root 默认用户。其余一切 Kit 需要的东西,由它自己安装或携带。
事实Docker 维护了加固模板镜像 dhi.io/sbx-templates:* 预置底座。关键坑:拿裸发行版镜像构建——构建成功、agent 启动失败("能构建 ≠ 能运行")。自建路线必须自行补齐底座:
FROM alpine:3.20
RUN apk add --no-cache bash curl git ca-certificates \
&& adduser -D -u 1000 agent
推理sbx-templates 是便利品而非约束来源:不用它获得的是发行版选择自由(debian/alpine/自制 rootfs),不是操作系统自由(见 §8)。
6组合与发布
组合语义 事实
启动一个集合:一个 workload + 任意多个 mixin。符合规范的运行时将集合视为封闭的:
- 每个
requires必须在集合内满足,否则解析失败;不隐式抓取任何东西 conflicts冲突直接失败- 恰好一个 workload
- 按依赖图排序而非参数输入顺序 → 同一集合永远组合出同一镜像(纯函数)→ 可锁定、可复现、可缓存
| 合并项 | 规则 |
|---|---|
| 文件层 | 各 mixin 依次叠加在 workload 上 |
| 网络规则 | 取并集 |
| 生命周期钩子 | 按依赖顺序拼接 |
| guidance | 合成一份文档 |
| 不兼容请求 | 构建失败(不选赢家) |
kind: set——整套发布 事实
# team-myagent.yaml
# syntax=docker/sandbox-kit:3
schemaVersion: "3"
kind: set
displayName: 我的 Agent 全套环境
version: "1.0.0"
kits:
- ref: docker.io/dockerdev/sbx-kit-shell:1.0.0 # workload
- ref: docker.io/dockerdev/sbx-kit-claude-mixin:2.1.6 # agent 本体
- ref: docker.io/me/sbx-kit-gh:2.72.0
- ref: docker.io/me/sbx-kit-node:22.0.0
kits:列表就是 set 的配方——它没有也不需要 Dockerfile- 成员必须是注册表引用(本地路径 / git URL 被拒绝);发布时每项按 digest 钉死
- 构建时解析每个成员、校验集合一致性、合并成一个普通 Kit 发布
- 消费端一条引用跑全套:
sbx run docker.io/me/team-myagent:1.0.0 .
事实代价:合并产物是钉死的制品(pinned artifact)——升级任何一个成员都要重新发布整个 set。两种消费方式各有位置:固定 set(团队标准环境 / CI,稳定可复现)vs 运行时现场组合(本地开发,灵活)。
文件账本 推理·汇总
| 处境 | 需亲手写的文件 |
|---|---|
| 需要的 Kit 全有人发布 | 0 个(直接 sbx run 引用);固化分享才 +1 个 set.yaml |
| 现成 + 1 个自研工具 | 工具 1 对(yaml+dockerfile)+ 可选 set = 2~3 个 |
| 全套自建 | workload 1 对 + 每工具 1 对 + set 1 个 = (N+1)×2+1 |
| 最小单文件 Kit | 1 个(内联 build: 或 # kit: 注释块) |
推理每个"对"是一次性成本:写一次、发布、全团队复用。类比 package.json——依赖列表里一百个包不等于要写一百个包的代码。
多架构 事实
Kit 是普通 OCI 镜像,multi-arch 原生支持(gh 示例的 nix 构建同时产出 x86_64-linux 与 aarch64-linux)。
7审查与强制:两道门 ★易混点
"agent 新版多要一个域名"不是普通软件升级,而是授权变更——它必然显式可见,可被拦截审批。
为什么"只改一行版本号"就足以触发审查 推理链
老世界里同样"只改版本号"却无法审查:权限活在制品外,版本号变化不携带权限信息,没有可 diff 的对象。能不能审查,取决于信息存在哪。
类比手机 App 更新提示"此应用新增权限:通讯录"——因为权限清单写在 App 清单文件里、随版本走,系统对比新旧清单。Kit 把这套机制搬给 agent 沙箱。边界止于"声明随版本走 + 系统对比";不对应 Kit 的运行时网络强制执行。
门一:升级闸门(SPEC §7.4)事实·规范原文
descriptor 投影为权限面(permission surface):宿主机必须授予的一切的归一化集合(分阶段的网络 allow/deny 列表、各阶段凭据、存储路径、skills 路径、端口、USB 匹配、privileged,以及其他类型的 type+config-digest 条目)。
会拦截更新的消费方把 Kit 的权限面存入 lock,并将候选版本的权限面与之对比:
- 版本变动但权限面未扩大 → MAY 静默应用
- 任何扩大 → MUST 停下等待批准:
- 新增 allow 条目
- 删除 deny 条目(deny 本身是授权可接受的一部分)
- 新凭据、新路径、新端口、新 USB 匹配、privileged
- 对已授予只读的 skills 路径申请写权限
- 其他类型请求的任何 config 变更
optional不改变权限面(它只改变"给不了怎么办",不改变"给得了给什么")resources、lifecycle、agent-context、agent-sessions、sbx、long-running不计入权限面(约束自身或沙箱内行为,不获取访问权)- args 展开后的值计入投影——用参数扩大策略同样过闸门
门二:运行门禁 事实
沙箱内 agent 访问 allow 列表外的域名 → network-policy 由运行时强制执行,直接拦截。声明不是 agent 的自律,是门禁的名单。
两道门对照(防混淆)★
| 升级闸门(§7.4) | 运行门禁 | |
|---|---|---|
| 时机 | 改版本号后启动时 | agent 运行全程 |
| 谁比 | 运行时:新权限面 vs lock 中的旧权限面 | 运行时:实际动作 vs allowlist |
| 结果 | 扩权 MUST 停批;未扩 MAY 静默 | 清单外直接拦截 |
其他可见位置 事实
- 制品对比:两版本都是普通镜像,
regctl/docker buildx imagetools inspect可拉出 manifest 注解做文本 diff - Code Review:按 digest 锁版本时,PR 改一行 digest + 注解 diff 即权限变更审查
- lock 文件 diff:lock 记录权限面,其 diff 天然展示权限变化
8平台边界与约束归属 ★易混点
三层拆解:"仅支持 Linux 生态吗" 推理·分层
| 层 | 结论 | 依据 |
|---|---|---|
| ① 制品格式 | 理论上 OS 中立 | Kit 就是 OCI 镜像 + 注解,未发明新格式;OCI 存在 Windows 镜像先例 |
| ② 规范契约 | 钉在 Linux 用户态 | 平台底座(bash/curl/git/CA/agent 用户)全部是 Linux 惯用语;任何符合规范的运行时都必须提供这套底座 |
| ③ 实现生态 | 今天 100% Linux | sbx = Linux microVM;已发布 Kit、examples、sbx-templates 清一色 Linux 用户态 |
两道锁的归属 ★
| 约束 | 主人 | 层级 |
|---|---|---|
| 底座契约(bash/curl/git/CA/agent 用户)→ Linux 用户态 | Kit 规范 | 制品契约层 |
| 用 Linux 内核的 microVM 实现 | sbx 运行时 | 实现选择层 |
事实规范全文没有"microVM"要求。十大原则之一:
The grammar declares; runtimes behave. descriptor 说要什么,从不说宿主怎么给。实现不了的能力应诚实地拒绝,而不是近似。
推理一致性测试考核行为而非机制——第二个运行时可以完全换掉隔离技术(gVisor、Firecracker、其他),但只要符合规范,服务的仍是 Linux 用户态的 Kit(底座契约推导所致)。逃出 Linux 的唯一途径是规范本身演进,不是换运行时。
类比浏览器:workload Kit ≈ 网页,规范底座 ≈ HTML 标准,sbx ≈ Chrome,microVM ≈ Blink 渲染引擎。写网页满足的是 HTML 标准而非 Chrome 私有行为;换浏览器照样跑,但网页内容仍是 HTML。边界W3C 与 Docker 单一主导方的治理结构不同;"标准中立"目前是架构意图而非多方验证的事实。
现实注脚今天 sbx 几乎是唯一成熟的符合规范的运行时——"满足规范契约"与"能在 sbx 上跑"暂时重合。约束归属是规范级的,但验证手段目前只有 sbx。
异构系统怎么办
| 需求 | 结论 |
|---|---|
| Windows 用户态 workload | ❌ 规范不支持;需走 Kit 之外的产品路线(Windows VM/容器) |
| agent 运行在 Android 里(形态 A) | ❌ Android 用户态(bionic/ART)不是标准 Linux 发行版,底座契约对不上 |
| agent 在 Linux 沙箱里操控 Android(形态 B) | ✅ 可行:com.docker.sandbox/usb-device@1 接 USB 真机 + adb 工具链 mixin;或沙箱内跑 Android 模拟器容器 待核验社区方案(如 dockerify-android)的性能与嵌套虚拟化 |
推理"跑什么"≠"能操作什么":边界画在沙箱墙内侧。Linux 沙箱可作为基地操控异构系统(adb / SSH / 云 API)。
9评估与采用(2026-09 时点)
成熟度 事实
- 状态:实验性(Experimental),Apache 2.0,目标 2026 Q4 定稿
- 演进承诺:增量式——能力类型独立版本化(
@1/@2并存发布),descriptor 级schemaVersion升级是最后手段 - 版本断层:Docker Hub 上
dockerorg 发 v3,sbxorg 是旧 v2 线,官方明言不要混用
采用信号
| 值得上 | 缓一缓 |
|---|---|
| agent 已跑在沙箱且在 Docker 生态(零迁移成本) | 工作站不在 sbx 支持平台(如 Windows 10) |
| 有审计/合规压力(权限变更可 diff 可审批) | 需要规范级稳定(等 Q4 定稿) |
| 多人/多机/多环境复用需求(set 一条引用) | 团队连 Dockerfile 都未铺开(先解决内容复现) |
| 担心供应商锁定(开放规范 + 一致性测试) |
风险清单
- 语法会动:承诺 additive,但
@2出现后有兼容矩阵要管 - 单一参考实现:规范开放,主力运行时只有 sbx;"不是锁定"待第二个实现验证
- 组合即信任传递:组合权限面 = 各成员申请的并集;用别人的 Kit = 信任其申请清单;闸门把关,审批责任在使用方
- v2/v3 并存期:文档、包、教程两代混杂
行动路径(Windows 10 环境)
- 现在可做:构建路径——
docker buildx build -f gh.yaml+docker buildx imagetools inspect看注解(只需 Docker Desktop,产物为普通镜像,不算押注) - 持续观察:Q4 2026 定稿动向;第二个运行时实现是否出现
- 上真沙箱:等 Windows 11 环境,或云模式(
sbx --cloud,同 Kit 引用,不挂载本地工作区)
10易错点辨析(验收沉淀)
- "物理是什么" vs "怎么写":Kit 物理上 = 普通 OCI 镜像(层装内容 + manifest 注解装声明 + 一个 digest);"一工具一 Kit / 伴生文件"是编写粒度与形式。被问"是什么"不要答"怎么写"。
- 两道门不可混:升级闸门比 lock 里的权限面(§7.4,扩权 MUST 停批);运行门禁查 allowlist(清单外拦截)。前者管"版本变化带来的授权变化",后者管"运行时的实际动作"。
- 组合权限 = 并集:多工具组合后权限面是全体成员申请的并集,闸门照常把守——这是"组合即信任传递"的基础。
- "越权" ≠ 问题本质:问题不是 agent 会越权,而是授权不可见、不可版本化;agent 拿权限是特性,散落在外才是缺陷。
- set 没有 Dockerfile:
kits:列表就是配方——四种编写形式中唯一非 Dockerfile 的。 sbx-templates不是平台锁:不用它可换发行版(自己补底座),换不了操作系统(底座契约 + 运行时内核两道锁)。- "仅 Linux"要说准:沙箱内运行环境钉在 Linux 用户态(规范级);宿主机平台无关(sbx 支持 macOS/Win11/Ubuntu);格式理论 OS 中立。
11命令速查
# 构建 Kit(Win10 可行,只需 Docker Desktop + buildx)
docker buildx build . -f gh.yaml -t docker.io/me/sbx-kit-gh:2.72.0
docker buildx build . -f gh.yaml --build-arg version=2.99.0 -t gh-kit:2.99.0
# 查看镜像 manifest(验证声明在注解里)
docker buildx imagetools inspect docker.io/me/sbx-kit-gh:2.72.0
# 安装 sbx(Win11/macOS Sonoma+/Ubuntu 24.04+)
winget install -h Docker.sbx # Windows
brew install docker/tap/sbx # macOS
sbx login # Docker OAuth
# 运行(本地/云同 Kit 引用;云不挂载宿主工作区)
sbx run docker.io/dockerdev/sbx-kit-shell:1.0.0 docker.io/me/sbx-kit-gh:2.72.0 .
sbx --cloud …
浏览已发布 Kit:Docker Hub type=sbx_kit + Verified Publisher(docker org = v3,sbx org = v2,勿混用)。
12类比总录(含边界)
| 类比 | 对应 | 边界 |
|---|---|---|
| 手机 App 权限提示 | 声明随版本走 + 系统对比新旧清单(升级闸门) | 不对应运行时网络强制;App 权限粒度与 capabilities 类型不同构 |
| 浏览器(网页/HTML/Chrome/Blink) | workload/规范/sbx/microVM 的归属分层 | 治理结构不同:HTML 有多方标准组织,Kit 规范目前 Docker 单一主导 |
| Git(commit/diff/hash) | 层/文件系统变化/digest | 镜像层只读叠加,无分支合并语义 |
| 毛坯房 + 家具 + 申请表 | 沙箱隔离 / Kit 内容 / Kit 声明的分工 | 止于分工;不涵盖版本化审查 |
| package.json | 已发布 Kit 引用免费、文件账本趋近于零 | npm 依赖无"权限面"概念 |
| 总装工头 / 装订机 | Kit 前端:调用 Dockerfile 构建 + 贴注解 | 止于编排角色,不含校验细节 |
✓待核验清单
- 待核验
dhi.io/sbx-templates:*的实际标签列表与基础发行版(规范未展开) - 待核验Android 模拟器容器方案(dockerify-android 等)在沙箱 microVM 内的性能与嵌套虚拟化可行性
- 待核验2026 Q4 定稿的实际落地情况与语法变化
- 待核验sbx 在 Windows 10 上 winget 安装的实际行为(官方仅支持 Win11)
- 待核验
sbx run的确切命令行语法细节(本次纸面实践采用 README/kit-intro 可证形式)
✎掌握状态(阶段反馈)
- 已焊牢:痛点推导链、组合模型(workload/mixin/set)、约束归属(规范 vs 运行时)、平台边界
- 验收暴露的薄弱点(已转化为 §10 易错点 1/2/3):物理制品模型的一句话表述、两道门的区分、组合权限并集
- 后续实践里程碑:Win10 构建路径实操(build + inspect,治"物理模型"薄弱点最直接)→ Win11 后 sbx 实操(亲历升级闸门)
🎮延迟反馈自测 · 10 题
规则:每题选择后点击「提交答案」才显示判定与解析(延迟反馈,防提示污染)。答完关注底部进度与得分。