Repository navigation
feat(sandbox):Docker 产品准入、网络默认关闭与权限控制(#40) - #62
Merged
Merged
Conversation
…cution, and recovery Compose the v97 recoverable lifecycle and v98 bounded I/O behind one Go DockerSandboxService (schema v99). The CLI, HTTP/OpenAPI, Desktop, and the sandbox_docker_run_propose model tool reuse the same gates: current Profile/permission snapshot, exact per-call approval, Policy, wall/tool budgets, 30-second sandbox.readiness.v1, and a process-local runtime epoch that SQLite cannot restore. Only environment-free, secret-free network=disabled plans are accepted; managed egress stays fail-closed. Independent Start WAL, append-only cancellation, launch binding, and one terminal receipt cover replay and crash recovery. Web capability projection accepts docker_execution_enabled only together with permission control. Real-daemon gates include an in-container IPv4/IPv6/DNS/gateway/proxy bypass probe; daemon architecture names are canonicalized to OCI amd64/arm64.
Bilingual README, usage, HTTP API, architecture, task book, project status, and resume memory now describe the default-disabled network-none Docker Sandbox product entry, its reason/remediation states, the fixed budgets, and the real-daemon acceptance evidence.
This was referenced Aug 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
Issue #40 要求把 v97 的可恢复 Docker 生命周期与 v98 的有界 I/O 合同从“非授权内部边界”提升为真正的产品入口:接入 Run、Policy、Approval、Budget、Tool Gateway 与 CLI/HTTP/Desktop,默认断网,任何网络放宽都必须可解释。此前两代合同刻意不授予产品执行权,Run 的 Policy/Approval/预算/进程权限门虽然齐全,但 Docker 侧没有统一的准入判定,也没有任何入口能安全地触达真实容器。
本次改动
1. 新增 SQLite schema v99 产品账本
新增不可变、非回溯的产品聚合:
迁移不回填准入,不修改 v97/v98 的 false-authority 历史事实;SQLite 记录在重启后不能恢复 start authority。
2. 新增唯一 Go 准入服务 DockerSandboxService
CLI、HTTP/OpenAPI、Desktop 和模型提案都投影同一服务。每次准入/启动都重新读取并精确绑定当前 Run/Profile/权限/审批/Policy/剩余 wall-clock 与 tool budget/未过期 readiness 与进程内 capability;full_access/debug 不能替代精确 per-call 审批,持久权限快照也不是 bearer capability。启动恢复只收敛已经跨过 launch 边界的记录(可检查、终止、清理),admission-only 记录不会在重启后自动变成执行;取消先落盘、再取消活动 context 或接管已过期租约。
3. sandbox.readiness.v1
每次准入和启动对固定本机端点(Unix socket / Docker Desktop Linux-engine NPipe)做新的只读检查,结果有效期固定 30 秒,状态只有 ready|disabled|unavailable,并提供稳定的 reason/remediation 组合。探针不接受 TCP、DOCKER_HOST、调用方 socket、pull 或 Docker CLI。
同时修复一处真实 daemon 才会暴露的契约问题:/info 返回 GOARCH 拼写(x86_64/aarch64)而 /version 与镜像配置使用 OCI 名(amd64/arm64),同一引擎会被误判为平台不支持;现在在只读 HTTP 解析边界统一规范化到 OCI 架构名。
4. 网络默认关闭;allowlist 当前拒绝
只接受 environment-free、secret-free、零 target 的 network=disabled Manifest。create 明确写 NetworkMode=none,并清空端口暴露/绑定、DNS、search domain、ExtraHosts、links、endpoint 与代理字段;inspect 后再次精确复核网络 namespace。现有 Manifest 能表达 allowlist 不等于 enforcement:在 Go-owned host/port/protocol egress guard 实现前,任何 allowlist 或 ManagedEgressEnabled=true 都以 managed_egress_unavailable/use_network_disabled 失败关闭。Docker 不可用时没有宿主 fallback。
5. 入口接线
6. 退出后 I/O、Artifact 与清理顺序
容器进入精确 exited checkpoint 后先采集有界 stdout/stderr;只有 natural exit 0 且 artifact authority 仍精确匹配时才从唯一可写 output mount 暂存、复读、重哈希并原子提交。timeout、取消、非零退出、I/O 失败或 authority 改变均不提交输出;清理不依赖新的 start capability。产品终态 succeeded|timed_out|cancelled|failed 的 receipt 必须证明 cleanup_complete=true。
测试覆盖
新增回归场景包括:Start WAL 使用独立幂等键的崩溃重试、取消先落盘再终止的活动竞态、admission-only 取消的 sticky 收敛、重启不恢复 start authority、终态重放零副作用、超预算/过期/陈旧 authority 拒绝、denial 审计可重放且阻断后续授权,以及 schema v99 不回填历史 authority。
真实 Docker opt-in 门新增容器内断网探测:environment-free scratch 夹具在容器内主动尝试 IPv4/IPv6 拨号、DNS 解析、host.docker.internal、bridge gateway 与代理环境变量,任何一项可绕过都会让测试失败;夹具由 internal/sandbox/testdata/docker-lifecycle-fixture/build-fixture.ps1 可复现构建(该脚本会剥掉构建器注入的默认 PATH,产出严格零环境变量的镜像)。
验证结果
已在只包含本 issue 改动的隔离工作树中完成:
安全边界与非目标
详细设计与不变量记录见 ADR 0099。
Closes #40