权限与执行边界
所有入口使用同一个信任档案工厂,审批规则和 OS 沙箱各自解决不同问题。
入口一致,工作目录独立
TUI、Print、Remote、Worker、子 Agent 和 Skill fork 都通过 build_trust_profile 构造信任状态,避免某个入口漏挂路径校验或沙箱。工作树和 Worker 按自己的工作目录重建档案,不能修改父 Agent 共享的 Bash 对象。
权限检查组合危险命令检测、显式规则、路径范围和权限模式。系统沙箱约束实际命令可访问的资源,交互审批决定某次工具调用是否获得允许,两者不能互相替代。
从模型意图到系统能力
| 层次 | 判断内容 | 作用范围 |
|---|---|---|
| 工具注册与启用 | 该工具是否存在、当前入口是否可用 | 模型可调用的能力集合 |
| 前置 Hook | 项目流程是否允许该次调用 | 执行前的业务与流程规则 |
| 权限检查 | 危险命令、显式规则、文件路径与模式 | 此次工具是否允许或需确认 |
| 参数校验 | 输入是否符合工具模型 | 避免执行非法或不完整参数 |
| OS 沙箱 | 命令实际能访问哪些资源 | Bash 执行的操作系统边界 |
模型提出“修改这个文件”只是请求,不是授权事实。即使提示词要求只读,也需要执行层拒绝写入;即使用户允许某次写入,也不能由此推断后续任意命令都获得了许可。
规则来自用户、项目和本地层,构造档案时明确相应路径。命令类会检查危险命令和显式拒绝或询问规则,文件类会检查目标路径及受保护文件。不同工具应按实际作用检查,而不是仅凭工具名称包含“读取”或“执行”决定。
请求沙箱不等于沙箱已生效
沙箱先创建,再检查 available(),随后执行 prepare(config),准备后还会检查可用性。只有请求开启、后端可用、准备完成且配置允许自动放行时,才设置相应授权标记。
def attach_profile_to_bash(
registry: Any, profile: TrustProfile, *, clone: bool = False
) -> Any:
"""把档案里的 OS 沙箱与 work_dir 挂到注册表的 Bash 工具上。
clone=True 时浅拷贝 Bash 并注册回 registry(worktree / 队友必须用克隆,
避免污染父 Agent 共享的 Bash 对象与其 deny 路径,P10)。
"""
bash = registry.get("Bash")
if bash is None:
return None
if clone:
bash = copy.copy(bash)
registry.register(bash)
bash.sandbox = profile.sandbox
bash.sandbox_config = profile.sandbox_config
bash.work_dir = profile.work_dir
return bash
请求了沙箱但准备失败时,Bash 会拒绝裸执行,不会静默降级为不受约束的命令。Linux 使用 bwrap,macOS 使用 Seatbelt;能否运行仍取决于本机环境与真实准备结果。
| 请求与准备结果 | 有效含义 |
|---|---|
| 未请求 OS 沙箱 | 仍执行权限规则,但没有该层系统隔离 |
| 请求后端不可用或准备失败 | 不开启沙箱自动放行,执行路径应失败关闭 |
| 后端准备成功、未启用自动放行 | 沙箱约束与审批规则分别生效 |
| 后端准备成功且允许自动放行 | 只有对应有效档案支持相应放行 |
sandbox_requested、sandbox_available 和 sandbox_enabled 表示不同事实。前两者描述请求与运行环境,最后一个还受自动放行配置影响;界面或日志只显示“配置已开启”容易掩盖准备失败。
路径范围也必须随工作目录重建。若父 Agent 在主工作树、Worker 在另一个 worktree,共享并改写同一个 Bash 实例会让父任务意外使用子任务路径。当前通过克隆 Bash 并挂载独立档案避免这种对象污染。
非交互路径的 ask
没有人能响应的 Print 或后台路径,遇到 ask 默认拒绝。允许某个工具不能等同于自动允许后续所有 Worker、所有路径或所有命令,审批需要保留作用范围。
用户明确选择绕过审批的权限模式,是另一种有效档案状态;它不会凭空创建 OS 隔离。文档和界面应同时能说明权限模式及沙箱是否真正可用。
只读规划与实际执行
Plan Mode 用于先分析和生成方案,写入能力受当前模式约束;退出规划后再恢复执行所需权限。计划批准、工具批准和 OS 沙箱准备是三个不同判断,批准一份计划不能代替执行时的参数和路径检查。
在 Worker 场景中,审批还要同时匹配当前运行和有效审批 ID。计划已经结束、取消或被替换后,旧的允许响应必须失效。这种关联约束保护的是时间上的授权范围,文件路径约束保护的是空间上的范围。
已完成机制与开放边界
当前实现统一了各入口档案和主要授权路径,但不能据此宣称已通过所有平台、所有命令形式的完整安全审计。尤其真实 macOS Seatbelt 需要对应系统验收;文件与命令工具也有各自的实现约束,不能把 Bash 沙箱概括成所有扩展工具都天然运行于同一 OS 隔离中。
本站展示了什么
“修改文档”场景展示允许、拒绝、后续同类操作不再询问以及取消后的审批失效。这里的文件完全位于浏览器本地存储,不是 OS 沙箱的替代品,也不证明真实终端命令在任意系统上都受隔离。
可观察的重点是拒绝后文件不变、批准后读取得到修改内容、停止后旧审批不起作用。浏览器内虚拟 README 的变化只是验证交互与状态,真实受保护路径和命令边界应通过运行时测试确认。
