从 Dockerfile 到 Kit:Docker Sandboxes Kit 规范

原文标题:From Dockerfile to Kit: the Docker Sandboxes Kit Specification

作者与来源

为什么容器之外还需要一份权限描述

AI 代理要完成任务,通常需要文件、网络、凭据和工具。开发者可能逐步给它挂载目录、扩大令牌权限、开放防火墙规则。每项授权单独看都像是合理的便利配置,累积起来却可能削弱原本依赖的隔离;而且这些授权散落在命令历史、控制台和个人记忆里,难以复现、审阅或与上周的配置比较。

Dockerfile 解决的是应用软件本身如何构建、打包和启动的问题。OCI 规范标准化了镜像及其分发方式,但 Dockerfile 并未描述应用运行时外部的环境授权,例如网络、凭据、卷、工具和上下文。过去这些信息常被放在 docker run 参数、Compose、CI 配置或运维经验中。Kit 的目标是把这些运行所需声明与内容一起记录并分发。

普通容器共享宿主机内核,通过命名空间和 cgroups 隔离文件系统、网络和进程视图,适合运行行为相对固定的工作负载。代理则会根据观察决定下一步动作,可能安装依赖、请求更高权限、打开端口或尝试访问凭据。文章提出,Docker Sandbox 使用带有独立内核的 microVM,把边界放在模型无法直接改写的层面;这个隔离边界允许在沙箱内给予代理较高权限,同时限制影响范围。

不过,空沙箱并不构成可复现的运行环境:仍然需要声明运行哪个代理、提供哪些工具和 MCP 服务、使用哪些技能与指令,以及它可以触碰什么。Kit 补上了这一层声明。

Kit 是普通 OCI 镜像

规范 v3 将 Kit 定义为普通 OCI 镜像,而不是新的独立制品类型:不需要新的媒体类型,也不需要注册表认识额外的 sidecar 文件。镜像清单通过 vnd.docker.sandbox.kit.descriptor 注解携带声明,镜像层携带内容。因此,Kit 可以沿用 docker buildx build、docker pull、镜像扫描和签名等现有流程,也可以在 Dockerfile 的 FROM 中使用。

将镜像固定到摘要(digest),就同时固定了内容、声明和元数据。规范需要学习的是声明语法和各能力类型的定义,包括 provides、requires 与 kind: set。

Kit 有两种角色:

  • workload 提供根文件系统,并作为实际运行的工作负载。
  • mixin 是叠加层,例如携带网络规则的 CLI、凭据绑定,或提供给代理的上下文。

启动时使用一个 workload,并可组合任意数量的 mixin。

声明表达的是请求,而非自我授权

文章以 GitHub CLI mixin 为例,展示网络策略和凭据声明:

capabilities:
  - type: com.docker.sandbox/network-policy@2
    config:
      runtime:
        allow:
          - github.com
          - hosts: [api.github.com]
            methods: [GET, HEAD, POST, PATCH, PUT, DELETE]
        deny:
          - hosts: [api.github.com]
            methods: [DELETE]
            paths: [/repos/**]

  - type: com.docker.sandbox/credential@1
    optional: true
    config:
      service: github
      phase: runtime
      apiKey:
        name: GH_TOKEN
        proxyManaged: true
        inject:
          - {domain: api.github.com, header: Authorization, format: "Bearer %s"}

这份声明请求访问 GitHub,其中特定 API 主机允许大多数方法,但禁止对 /repos/** 路径执行 DELETE;冲突时 deny 优先。可以创建拉取请求的令牌并不意味着可以删除仓库。凭据标为由代理管理时,符合规范的运行时会将真实值注入发往指定域名的请求;沙箱内部只看到哨兵值。

关键区别在于:Kit 只是提出请求,不会自行授予权限。只有实现了规范行为的运行时才会执行规则,并阻断未列出的主机。若运行时不符合规范,注解本身只是随镜像携带的数据,不能提供强制执行。文章称 Docker Sandboxes 是首个符合规范的运行时。

网络规则、凭据、卷、端口、设备和技能路径等授权能力会计入 Kit 请求获得的权限;生命周期钩子等要求运行时执行动作的条目则不属于这类授权。若一个必需请求无法被宿主满足,符合规范的运行时应拒绝启动,而不是以比声明更少或更多的权限启动代理。

组合规则让结果可预测

容器镜像通常不能通过多个 FROM 直接实现多重继承。Kit 的 mixin 依赖 provides 和 requires 声明依赖图,由解析器按依赖关系排序,而不是按命令行参数输入顺序排序。同一组 Kit 因此会得到相同的组合结果。

解析器采用严格规则:

  1. 每个 requires 都必须由组合集合中的内容满足,否则解析失败,不会偷偷下载缺失项。
  2. 只能有一个 workload。
  3. 两个 Kit 若提供同名能力,组合失败,不会静默覆盖。例如,把 Claude workload 和 Claude mixin 当作可直接叠加的两个提供者,就是规范举出的冲突情形。
  4. 可协调的声明按类型合并:网络规则取并集,钩子按依赖顺序运行,指导内容合成一份文档,许可证取并集。
  5. 不兼容请求会报错,不交给不确定的优先级决定。

kind: set 描述符可以命名一组 Kit。发布 set 时会在构建阶段执行相同的一致性规则,并将其合并为一个普通 Kit。若集合不一致,构建就会失败,而不是把问题留给用户启动代理时才发现。

权限变更应当进入代码审查

文章以 Claude Code Kit 为例:它声明允许访问的主机、凭据、会话间持久化的卷,以及安装和启动钩子。若新版本开始请求额外主机或第二份凭据,这属于权限变化,而不只是软件更新;变更会作为新增声明出现在拉取请求中,供审阅者判断。

规范还定义了不依赖人工阅读差异的第二道门槛:每份描述符都可归一化为运行时需要授予的权限集合。会对更新设门槛的运行时可以记录这份集合,并与新版本比较。新版本权限仍在已批准集合内时可以应用;权限范围扩大就暂停并请求批准。删除一条 deny 规则也属于权限扩大,例如后续版本移除 DELETE /repos/** 限制时,运行时应阻止自动升级。

因此,权限声明要放进制品本身,才能随版本一起比较和审阅。

规范与试用方式

Kit 的目标是让同一份声明在不同符合规范的运行时中保持相同含义,避免格式成为单一产品的锁定机制。规范定义了具有约束力的语法,并为每种能力类型单独说明运行时必须实现的行为;能力类型可以独立演进,例如 network-policy@1 与 network-policy@2 可以并存。

项目提供两套一致性测试:一套判断制品是否符合 Kit 规范,另一套判断运行时是否按规范说明工作。原文称每项规范性要求都由检查或书面豁免覆盖。Docker 目前维护该规范;作者希望它不长期归属单一厂商,并欢迎对无法表达的 Kit 或运行时职责提出问题。

文章给出的试用步骤是先安装 sbx,再从规范仓库的检出目录运行示例:

brew install docker/tap/sbx
cd examples
sbx run ./hello --kit ./gh .

编辑描述符时,只有对应 Kit 需要重建;可以通过 docker buildx build 发布到任意注册表。文章还提到 Docker Cloud Sandboxes 可在弹性算力上运行相同 Kit 并采用相同信任模型。

从代理扩展到普通工作负载

代理让授权问题变得更紧迫,但服务程序同样依赖未写明的运行约定,例如要调用哪些端点、需要什么凭据、重启后必须保留哪个卷。这些知识过去可能存在于 Helm chart、运行手册或同事的经验中。Kit 规范希望让任何软件都能明确记录自己对外围环境的需求。

Dockerfile 让软件构建可复现;Kit 试图让权限也可复现。

来源说明

本文依据 Christian Dupuis 于 2026 年 9 月 24 日发布的 Docker 官方博客文章整理。文章说明 Docker Sandbox Kit Specification v3 以 Apache 2.0 开源,并链接到规范项目。该许可信息指向规范项目;Docker 博客页面页脚同时标示 © 2026 Docker Inc. All rights reserved.

由于三篇稿件合计超过 18,000 字符,本次先完整交付 WWJ-17。尚未在本条回复中交付的编号:WWJ-2187、WWJ-3197。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容