Codex 安全 · Windows Windows

在 Windows 上更安全地使用 Codex。

限制 Codex 能读取、修改和发送的内容,然后验证配置,并在出错时恢复。

工作原理

社区项目 · 与 OpenAI 无关联

审批不是安全边界。

面对删除命令,很多人的第一反应是:"我在指令里写清楚,重要操作让我亲自审批。"但审批有效的前提,是你能看懂每一条命令——在 Windows 上,引号规则、编码、注册表、一大串参数,让这件事远比想象中难。

命令会越来越长,审批一天重复几十次,时间一长总会有看累、看漏、只看前半段的时候;审查 Agent 也一样会判断错。当审批是唯一的防线,一次误判就等于把全部权限交出去。

先试试看 · 最可怕的错误:语义错误

先通读整段脚本,再看下面的答案。里面没有一行恶意代码——但它会删掉一个你从未想删除的目录。

Set-Location "C:\Users\you\projects\webapp"
$ErrorActionPreference = "SilentlyContinue"
if (-not (Test-Path "C:\Users\you\projects\webapp\node_modules")) {
  npm ci --no-audit --no-fund --loglevel=error
}
$config = Get-Content "C:\Users\you\projects\webapp\tools\build-config.json" -Raw -ErrorAction SilentlyContinue | ConvertFrom-Json
$base = $config.outputDirectory
npm run build -- --outDir "$base" --minify
Copy-Item -Path "$base\*" -Destination "C:\Users\you\projects\webapp\release\latest" -Recurse -Force -Confirm:$false
Remove-Item -Path "$base\data" -Recurse -Force -Confirm:$false
git add -A; git commit -m "sync build output"; git push origin main

一段常规的构建 + 发布脚本。

读到最后一几行时,第 7 行看起来毫无问题:$base 从配置里取值。但配置读取已经悄悄失败——$base 是 $null。整段脚本没有一行是为了制造事故而写的。

答案 $config = Get-Content "C:\Users\you\projects\webapp\tools\build-config.json" -Raw -ErrorAction SilentlyContinue | ConvertFrom-Json$base = $config.outputDirectoryRemove-Item -Path "$base\data" -Recurse -Force -Confirm:$false

PowerShell 把以 \ 开头的路径解析为当前驱动器的根目录——这里是 C:。配置文件不存在,读取悄悄失败,$base 是 $null:"$base\data" 变成 \data,"$base\*" 变成 \*。Copy-Item 先把 C:\ 下能读到的东西复制进 release\latest,Remove-Item 指向 C:\data。删除是否真的发生,取决于 C:\data 是否存在、当前身份是否有权限。危险不来自任何一条危险的行——两个看起来合理的局部行为组合出了一个你从未想过的路径。

风险一 · Agent 事故——不需要恶意

正确完成任务不等于安全完成任务。这些命令没有一行是恶意的,只是结果错了。

同步即清空
git fetch origin main --quiet
git reset --hard origin/main
git clean -fdx -e ".env.local" -e "node_modules"

一个普通的需求:把仓库恢复成远程 main 的干净状态。

它从不确认工作树里有没有你唯一的副本。reset --hard 丢弃已跟踪的改动,clean -fdx 连被忽略的文件也清掉。任务是对的,完成方式是危险的。

风险二 · 权限大于任务所需

这些不是 Agent 的理解事故,而是权限本身允许的事情:无法审计的代码,以及把一次授权扩展到未来的执行入口。

不可审计执行
powershell.exe -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -EncodedCommand JABFAHIAcgBvAHIAQQBjAHQAaQBvAG4AUAByAGUAZgBlAHIAZQBuAGMAZQA9ACcAUwBpAGwAZQBuAHQAbAB5AEMAbwBuAHQAaQBuAHUAZQAnADsAIABHAGUAdAAtAEMAaABpAGwAZABJAHQAZQBtACAAIgAkAGUAbgB2ADoAVQBTAEUAUgBQAFIATwBGAEkATABFAFwALgBhAHcAcwAiACwAIgAkAGUAbgB2ADoAVQBTAEUAUgBQAFIATwBGAEkATABFAFwALgBzAHMAaAAiACAALQBSAGUAYwB1AHIAcwBlACAALQBGAG8AcgBjAGUAIAAtAEUAcgByAG8AcgBBAGMAdABpAG8AbgAgAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAIAB8ACAARgBvAHIARQBhAGMAaAAtAE8AYgBqAGUAYwB0ACAAewAgAEMAbwBwAHkALQBJAHQAZQBtACAAJABfAC4ARgB1AGwAbABOAGEAbQBlACAAIgBDADoAXABVAHMAZQByAHMAXAB5AG8AdQBcAHAAcgBvAGoAZQBjAHQAcwBcAHcAZQBiAGEAcABwAFwALgBzAGMAYQBuAC0AbwB1AHQAcAB1AHQAIgAgAC0ARgBvAHIAYwBlACAAfQA=
解码后是: $ErrorActionPreference = 'SilentlyContinue'Get-ChildItem "$env:USERPROFILE\.aws", "$env:USERPROFILE\.ssh" -Recurse -Force |ForEach-Object { Copy-Item $_.FullName "C:\Users\you\projects\webapp\.scan-output" -Force }

一种常见的引号规避写法——也可能是把真正执行的内容藏起来。

在 Full Access 下,prompt 注入和恶意仓库指令就是这个样子:Hidden、NonInteractive、ExecutionPolicy Bypass,加上没人能审计的 payload。

跨登录持久化
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "WebAppUpdater" -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File C:\Users\you\AppData\Local\Temp\upd.ps1" -PropertyType String -Force | Out-Null

注册一个开机启动的更新程序。

Run 键指向的是可变文件 upd.ps1:今天审的是 A 版本,下次登录执行的可能是被替换后的 B 版本。一次授权变成持续生效的执行入口,超出了这次审批的语义范围。

社区调研中的个案

一位使用 Full Access 的用户发现:中转站把注入的脚本伪装成"环境监测"混进了执行流程,最后因为思维链里能看到执行的代码才被发现——SSH 密钥和各种 API key 差一步就被打包带走了。

脚本伪装得完全无害,所以审批根本不是问题所在。工作区边界可以做到:注入的代码无论伪装得多好,都读不到项目之外的 SSH 和 API key。

每一条新命令都是一场必须满分的考试,而失败一次就交出全部权限。Codex Safe Setup 的思路相反:让审批成为边界内的可选工作流,让边界本身成为不可越过的防线。

看看实际边界如何工作

它限制什么

它限制什么

三道能力边界,作为一份最小权限配置一次安装。

文件

Codex 不应默认拥有整个文件系统。

安装的权限配置从工作区出发,而不是从整台机器出发。写入只允许在已登记的工作区根目录内,其余路径默认拒绝。

Codex 对 .git、.codex、.agents 的保护同样保留。凭据一旦进入模型上下文或日志,即使没有执行破坏命令也等于泄露。

  • 工作区写入 — 仅限已登记的工作区根目录。
  • 最小运行时读取 — 仅保留运行时必需的最小读取集。
  • 文件系统根目录 — 默认拒绝,包括临时目录。
  • 常见凭据 — 即使在工作区内也拒绝:.env、私钥、npm 与云凭据文件。

联网

命令联网是独立的边界。

批准命令和允许数据离开你的机器是两个不同的问题。安装器把联网作为一项独立、明确的选择。

没有启用代理的域名表不是真正生效的白名单。

  • Off 关闭 — 默认。命令无法访问网络。
  • Allowlist 白名单 — 仅明确列出的公开域名可通过命令代理。
  • Unrestricted 不受限 — 高风险。命令直接出网,需单独确认风险。

恢复

安全也意味着可以恢复。

限制用于阻止错误,恢复用于承受错误。每个受管理文件都会先备份,可选的检查点桥接器保存工作进度而不动你的分支。

检查点不包含被忽略或拒绝的文件。恢复请使用独立工作树:git worktree add <新空目录> <提交>。

  • 写入前备份 — 安装器触碰的每个文件都会先备份,并提供精确回滚命令。
  • Git 检查点 — 可选,保存在 refs/codex-safe/checkpoints/* 隐藏引用。当前分支、真实索引和工作树保持不变。
  • 敏感未跟踪文件 — 拒绝纳入检查点:.env、私钥、.npmrc、云凭据文件。
  • 自动破坏性恢复 — 绝不自动执行 reset --hard、clean、替换分支或原地恢复。
  • Git 被替换 — 固定 Git 路径的 SHA-256 校验不通过时拒绝运行。

前后对比

自主与隔离并不对立。

好的权限边界让 Agent 在允许范围内自主工作——你不需要成为每几秒一次的守门人。

Full Access

一切读取、写入和发送默认允许。
  • agent
  • 工作区
  • 主目录
  • 凭据
  • 整个文件系统
  • 网络

有边界的自主

Agent 在边界内自主工作,越界操作直接失败。
  • agent
  • 工作区
  • 必需的运行时读取
  • 明确的联网策略
  • 其余一切 → 拒绝

推荐模式 BoundedAutonomy 在边界内没有审批弹窗——权限限制替代了原来靠审批维持的安全。

处理边界跨越的三种方式

审批方式和命令联网是两个彼此独立的决定。三种模式共用同一份最小权限文件配置——只有「谁来审批」不同。

BoundedAutonomy 推荐 没有审批弹窗。越界操作直接在权限边界处失败。
AskMe 符合条件的越界请求交给你本人审批。
AutoReview 符合条件的越界请求交给审查 Agent——沙箱并不会因此变强。

验证

安装不等于验证。

写入配置不等于证明它生效。验证会如实报告实际检查了什么,以及哪些无法检查。

codex-safe-setup / 验证 已检查
PASS 已经直接检查并符合预期。
PARTIAL 配置证据存在,但缺少必要的运行时或 CLI 检查。
FAIL 必要条件缺失或互相冲突。
NOT CONTROLLED 属于其他控制面——如实报告,不暗示受保护。
静态配置和 codex execpolicy check 是证据,不是对所有未来运行时行为的证明。Codex 升级后请重新验证。

安装后请重启 Codex,再进行运行时探测。

验证实际检查什么
  • 工作区之外的写入
  • 工作区之外的读取
  • 工作区内的敏感文件
  • 受保护的元数据(.git、.codex、.agents)
  • 删除恢复(检查点)
  • 命令联网出口
  • 回滚与备份
  • 外部控制面——如实报告,绝不暗示

工作区外会放置一个合成 canary 文件,用于在做出任何结论前实际探测边界。

安装

安装 Codex Safe Setup

两条命令,一句指令——之后插件会先审计、解释取舍,只有在你确认后才写入配置。

PowerShell
PS> codex plugin marketplace add QianQIUlp/codex-safe-setup --ref v0.1.0
codex plugin add codex-safe-setup@codex-safe-setup

新建一个 Codex 任务或 CLI 会话,然后输入:

使用 $secure-codex-setup 审计我当前的 Codex 权限,并安装推荐的安全配置。

要求 需要 Codex CLI 0.138.0 或更高版本 · Windows 上推荐 PowerShell 7

推荐 marketplace 安装方式,因为 Codex 能记录来源和版本。

每个 Release 都附带可安装 ZIP 和 .sha256 文件。可在 PowerShell 中用 Get-FileHash -Algorithm SHA256 <压缩包> 核对。

查看安装详情

两条命令之后会发生什么
  1. 01 只读评估——此时不会改动任何东西。
  2. 02 边界与取舍逐一解释,不做隐藏。
  3. 03 前置依赖(PowerShell 7、Codex CLI)单独征求同意。
  4. 04 先以 Plan-only 预览确切的配置内容。
  5. 05 只有在你明确确认后才写入。
  6. 06 静态与 execpolicy 验证;之后请重启 Codex。
  7. 07 备份已记录——精确回滚随时可用。

边界之外

认清边界。

可信的安全工具会明确说明它不能保护什么。以下能力属于其他控制面——每一项都会标记为 NOT CONTROLLED,绝不暗示已经受控。

  • Web Search
  • Browser
  • Computer Use
  • App 与 Connector
  • 其他 Plugin
  • MCP 服务器
  • 云端任务
  • Git 远程
  • CI 凭据
  • 安装前已暴露的凭据
  • 主机恶意软件
  • 操作系统失陷

以上每一项都会在验证报告中标记为 NOT CONTROLLED。

阅读威胁模型

如果凭据可能已经暴露
  • 立即吊销或轮换凭据。
  • 检查服务商的用量、会话与账单记录。
  • 清除文件、日志、shell 历史与仓库历史中的残留。
  • 时间上的巧合不能证明因果。

开源

开放构建。

社区维护,Apache-2.0 许可。源码、可复现构建与私有安全报告都在 GitHub。

  • CI 在 Windows 上运行隔离集成测试与包校验。
  • Release 从经过校验的 tag 构建,并附带 SHA-256 校验文件。
  • 每个 Release 都通过了官方 Skill 与 Plugin 验证器。
  • 通过 GitHub Security Advisories 私下报告安全漏洞。
在 GitHub 上查看源码