具体问题与边界
“用户点了允许”不能让进程读取任意密钥;“命令在沙箱里”也不能判断用户是否愿意删除仓库文件。 安全链至少包含威胁识别、策略分类、具体授权和系统强制执行。Codex 把 Permission Profile、Exec Policy/Guardian、Approval 与平台 Sandbox/Network Proxy 放在不同层,因为它们回答的问题不同。
本节不把 Hook 或路径检查宣传为安全边界,也不评价未公开云端内部实现。
四层责任
| 层 | 主要问题 | 决策/状态 | 不能替代 |
|---|---|---|---|
| Permission Profile | 本次 Turn 可请求哪些资源 | cwd、读写根、网络、附加权限 | 用户对具体动作的同意 |
| Policy/Guardian | 这个具体动作风险如何 | allow、prompt、forbid/review | 内核级资源限制 |
| Approval | 用户/Host 是否授权这次请求 | once/session scoped decision | 缩小过宽的系统能力 |
| Sandbox/Proxy | 进程实际上能触碰什么 | OS profile、ACL/token、network rules | 理解用户意图 |
Pre Hook 可以加入组织规则,但它运行在应用协议边界;Post Hook 更不具备撤销已经发生副作用的能力。
正常决策链
- TurnContext 从配置、受管要求和临时附加权限物化 Permission Profile。
- Handler 把模型参数解析为具体 argv、cwd、路径和网络意图,避免审批抽象描述。
- Exec Policy/Guardian 根据规则输出 allow、prompt 或 forbid;不可询问的拒绝不会伪装成审批。
- Prompt 分支用稳定 key 注册 waiter,批准只覆盖声明的作用域。
- 执行器把 Permission Profile 编译成平台 Sandbox/Proxy 约束,然后启动进程。
- 若检测到 SandboxDenied,只有政策允许时才能提出升级并以新权限重试一次。
官方公开说明同样把 sandbox mode 与 approval policy 区分:前者限制技术能力,后者决定何时必须询问。 这一产品概念与源码分层一致,但平台具体实现仍由锁定源码证明。
Python 风格伪代码
async def authorize_and_run(request: ExecRequest, context: TurnSnapshot) -> ExecResult:
concrete = validate_and_resolve(request, cwd=context.cwd)
permission = context.permissions.restrict_to(concrete.required_resources)
verdict = exec_policy.classify(concrete)
if verdict is Forbid:
return ExecResult.denied("policy forbids this action")
if verdict is Prompt:
decision = await approval_waiters.request(concrete, context.cancellation)
if decision is not Approved:
return ExecResult.denied("approval not granted")
environment = execution_environment.for_profile(permission)
try:
return await environment.spawn(concrete, context.cancellation)
except SandboxDenied as denial:
escalation = permission.minimal_escalation_for(denial)
if not context.approval_policy.may_escalate(escalation):
return ExecResult.denied(denial.explanation)
await approval_waiters.request(escalation, context.cancellation)
return await execution_environment.for_profile(escalation).spawn(concrete, context.cancellation)
这里 environment.spawn 不是万能黑箱:它代表由平台实现的进程启动和强制边界;应用策略不能假装
完成了这部分工作。
失败和绕过路径
| 单层依赖 | 遗漏威胁 | 典型结果 |
|---|---|---|
| 只用 Tool description/Hook | 模型输入可绕过说明 | 越界请求进入执行器 |
| 只用 Exec Policy | 规则不强制 syscall/path | 子进程仍可访问系统资源 |
| 只用 Approval | 用户难以审查隐含资源范围 | 一次批准覆盖过宽能力 |
| 只用 cwd/路径检查 | 命令内部可自行打开其他路径 | 应用检查被解释器绕过 |
| 只用 OS Sandbox | 不理解业务意图与破坏性 | 合法范围内仍可做用户不想要的事 |
| 失败后无限升级重试 | 逐步扩大权限 | 策略被错误循环消解 |
设计判断
分层会造成同一请求在多个模块中被表示,也需要把拒绝理由反馈给模型和用户。收益是各层可以使用 适合自己的证据和强制机制,并能单独测试。安全审计应问“每层的输入、输出和不可替代性”,而不是 只问“有没有沙箱”。
小型本地 Agent 即使不实现 Guardian,也至少应把应用 allowlist、人工确认和 OS 隔离分开;若没有 真实沙箱,必须像 Mini Codex 一样明确标记 Local Adapter 无隔离。
证据与 Mini Codex
生产锚点为 protocol/src/permissions.rs、core/src/exec_policy.rs、core/src/tools/sandboxing.rs、
sandboxing/src/manager.rs 和平台后端。6.72—6.82 给出各层及 macOS/Linux/Windows/Network 分支。
Mini Codex 只实现 ExecPolicy、Approval、WorkspacePolicy 与可替换 Adapter:
cd examples/mini-codex
uv run pytest -q -k 'policy or approval or sandbox or workspace'
默认 LocalSandboxAdapter 没有 OS isolation,测试通过只证明决策顺序。
本节边界
已经证明:意图分类、授权和强制执行不可合并。下一节转向另一种常被错误合并的层次——持久化权威。 详细源码映射由研究仓库中的配套索引维护。
评论
登录后即可评论