一个只有单文件、九行 Express 代码的仓库,安全扫描该花多少钱?我把新版 Codex Security CLI 指向它,8 分半钟后,扫描在 6.00 美元的预算上限前停下。它消耗了 700 万输入 Token,产出一份 1,605 字的威胁模型,却没有发现任何漏洞。准备把它接入 CI 的人需要先记住这一点:扫描成本取决于 Agent 的推理循环,而不是代码行数。因此,最该优先设置的参数是 --max-cost。
不过,这个工具依然值得研究。它是第一个无需把代码仓库授权给 GitHub App、即可本地运行的 Codex Security 版本。
CLI 能做什么,不能做什么
Codex Security 本身并不是新产品。OpenAI 在 2026 年 3 月以研究预览形式推出了托管服务:连接 GitHub 仓库后,它会构建威胁模型、在隔离环境中扫描提交历史,并在 ChatGPT 工作区报告发现的问题。SecurityWeek 报道称,当时 ChatGPT Pro、Enterprise、Business 和 Edu 用户可以使用该服务。
2026 年 7 月 28 日发布的是另一回事。openai/codex-security 是一个采用 Apache-2.0 协议的 CLI 和 TypeScript SDK,发布在 npm 上。0.1.0 版于 17:09 UTC 发布,同日 23:48 UTC 跟进了 0.1.1 版。截至写作时,它有 1.8k Stars 和 28 个开放 Issue。这是一个刚上线第一天的项目。
安装要求 Node.js 22 或更高版本,以及 Python 3.10 或更高版本,因为扫描引擎以打包的 Python 插件形式提供:
npm install @openai/codex-security
npx codex-security info
执行 info 是确认安装内容最快的方式:
sdkVersion: 0.1.1
bundledPluginVersion: 0.1.14
cliVersion: 0.1.1
codexVersion: 0.144.6
model: gpt-5.6-sol
reasoningEffort: xhigh
最后两行基本决定了成本。在这套安装环境中,扫描默认使用 GPT-5.6 Sol,推理强度为 xhigh。可以通过 --model 覆盖模型选择,但这个插件围绕深度 Agent 循环构建,真正花钱的正是这套循环。
它的命令面比托管产品所呈现的更广:包括 scan、validate、patch、scans(列出、查看、重新运行、匹配、比较)、bulk-scan、导出 CSV、JSON 或 SARIF 的 export、install-hook,以及将工具注册为 MCP Server 的 mcp 模式。还要注意,info 会显示 scanMcp: false,因为扫描无法通过 MCP 传输取消。
认证有两条路,其中一条可能直接卡住你
npx codex-security login 可通过 ChatGPT 账号登录,--device-auth 面向无头机器,而 CI 则使用 OPENAI_API_KEY。如果 API Key 和登录状态同时存在,交互式扫描会询问使用哪一种;非交互式运行则优先使用 API Key。
官方文档里有一项提示需要反复确认:完整仓库扫描可能还需要 Trusted Access for Cyber。登录和设置 API Key 都不会自动获得这项权限。你需要预留的是访问申请流程,而不只是登录步骤。
让 OpenAI Codex Security CLI 对接兼容端点
最容易踩到的坑,是把第三方 Key 填进 OPENAI_API_KEY 后,就以为请求会自动路由到对应服务:
codex-security: Authentication failed using OPENAI_API_KEY.
仅设置 Key 并不会改变路由。内嵌的 Codex 运行时仍然指向 OpenAI 自身的基础 URL,并且忽略 OPENAI_BASE_URL。必须通过接受 TOML 值的 --codex 覆盖供应商配置:
OPENAI_API_KEY=sk-... npx codex-security scan . --auth api-key --max-cost 5 \
--codex 'model_provider="relay"' \
--codex 'model_providers.relay.name="relay"' \
--codex 'model_providers.relay.base_url="https://your-endpoint/api/v1"' \
--codex 'model_providers.relay.env_key="OPENAI_API_KEY"' \
--codex 'model_providers.relay.wire_api="responses"'
有两个细节各让我浪费了一次运行。第一,未加引号的值会报 Invalid --codex TOML value。第二,Codex 0.144.6 会直接拒绝 wire_api="chat",报错会指向讨论 #7782,并要求使用 responses。换句话说,端点必须实现 Responses API,只有 Chat Completions 不够。
模型费用最终落在哪里,也由这项设置决定。无论请求实际发往哪个端点,CLI 都始终按 GPT-5.6 Sol 的 OpenAI 标价估算成本。因此,它显示的运行总额是基于 Token 数量的计算,而不是你的实际账单。若把相同流量路由到价格仅为标价一半的端点,下文那次显示为 6.03 美元的运行,实际花费约为 3 美元,但 CLI 仍会打印 6.03 美元。
一次扫描究竟花多少钱
先明确一个前提:五次测试都通过第三方 OpenAI 兼容端点完成,因为我没有 ChatGPT Business 或 Enterprise 登录账号来测试官方路径。以下结果衡量的是普通开发者今天可实际运行的 CLI,而不是有权限账号下托管服务的表现。
测试仓库有意保持极小,也有意保留缺陷:九行代码,埋了四个问题:
const express = require('express');
const { exec } = require('child_process');
const db = require('./db');
const app = express();
const API_KEY = "sk-live-9f3a2b7c1d4e5f6a8b9c0d1e2f3a4b5c";
app.get('/u', (req, res) => db.query("SELECT * FROM users WHERE id = " + req.query.id, (e, r) => res.json(r)));
app.get('/ping', (req, res) => exec("ping -c 1 " + req.query.host, (e, o) => res.send(o)));
app.get('/f', (req, res) => res.sendFile(__dirname + "/files/" + req.query.name));
app.listen(3000);
问题包括字符串拼接 SQL、将查询参数传给 child_process.exec、未净化的 sendFile 路径,以及硬编码的 Key。测试环境为 macOS、Node v22.17.0、Python 3.14.6、@openai/[email protected]、内置插件 0.1.14;所有运行都发生在 2026-07-29 02:20 至 03:05 UTC 之间。
| 运行 | 扫描目标 | 预算 | 停止时成本 | 耗时 | 缓存输入 | 新增输入 | 输出 | 发现问题 |
|---|---|---|---|---|---|---|---|---|
| 1 | 完整仓库,标准模式 | $1.00 | $1.46 | 3m23s | 1,092,608 | 121,396 | 10,300 | 0 |
| 2 | 完整仓库,标准模式 | $6.00 | $6.03 | 8m33s | 6,654,720 | 331,330 | 34,946 | 0 |
| 3 | 工作树,单行 Diff | $3.00 | $3.06 | 9m46s | 2,035,712 | 240,448 | 28,120 | 0 |
| 4 | 完整仓库,完整项目 | $8.00 | $8.54 | 8m00s | 7,299,840 | 634,419 | 57,223 | 0 |
| 5 | 完整仓库,reasoning_effort=low | $3.00 | $3.20 | 4m13s | 1,749,248 | 366,841 | 16,269 | 0 |
这些金额来自 CLI 自己的估算:扫描过程中会持续打印,也会被存入 scans list。它们是按 OpenAI 标价和 Token 数量计算的,不代表端点实际收费;缓存输入正是 Token 数量很高、总价却相对不高的原因。运行 2 可以精确对上:每百万新增输入 5.00 美元、每百万缓存输入 0.50 美元、每百万输出 30.00 美元:
331,330 x $5.00/M = $1.657
6,654,720 x $0.50/M = $3.327
34,946 x $30.00/M = $1.048
------
$6.032 (CLI 报告为 $6.03239)
用这三档价格计算,五次运行的总额都能精确到分地复现。如果你自己的数字看起来异常,这也是一个实用的校验方法。
五次扫描没有一次完成。它们全都因预算耗尽停止,scans list 将每次都记录为 phase: preflight, status: failed,并显示 coverage: worklistRows 0。这意味着,没有任何一次走到报告漏洞的阶段。
运行 4 是对照组。第一个仓库本来就是刻意不完整的:没有 package.json,而且导入了不存在的 ./db,工具生成的威胁模型也将此明确标为未知项。后来我将它补成一个有四个文件、十三行代码、且声明了依赖的完整项目,成本不降反升:8.54 美元、790 万输入 Token。
成本曲线并不是线性的。前 3 分钟增长缓慢,之后出现两次阶跃式上涨,每次都对应 Agent 扩大工作范围。日志在第 51 秒说明了原因:Preflight: worker delegation supported (up to 8 worker slots)。
输入 Token 中有 95% 是缓存读取,说明同一上下文在一轮又一轮中被重复发送,而非重新读取。单价虽然低,却依然是账单中最大的一项。即使按缓存输入价格计算,700 万 Token 也足以累积出明显成本,更何况目标只是一个九行文件。
这也是常被提及的“每 1,000 行代码约 0.02 美元”估算失效的地方。按这个价格,我的仓库本应只需几分之一美分。
降低推理强度,帮助比预期小得多
运行 5 对与运行 4 相同的项目设置了 model_reasoning_effort="low"。Token 消耗从每分钟约 100 万降至约 50 万,因此同样的钱能换来两倍的实际运行时间。但它仍在同一个 preflight 阶段触及上限,依然没有任何结果可报告。若流水线所需轮次无论如何都超出预算,把消耗速率减半也解决不了问题。
--max-cost 是检查点,不是刹车
官方 CLI 文档说明,已经开始处理的请求可能会在超过上限后结束,但没有说明会超出多少。五次运行中,超支范围为 0.5% 至 46%:1.00 美元的上限在 1.46 美元停止,6.00 美元的上限在 6.03 美元停止,另外三次中等预算运行则超出 2% 至 7%。超出多少,取决于 Agent 临近上限时还有多少请求在执行;若 Worker 扇出恰好在这时落地,成本会更高。上限应设在你绝不能超过的数字之下。
Pre-commit 并不是低成本方案
面对失控的完整扫描,最直观的方案是只扫描改动部分。我提交了一个干净基线,新增一行存在漏洞的代码:用字符串拼接构造 LIKE 子句,然后运行 --working-tree --base HEAD。
结果它比第一次完整扫描更贵:耗时 9m46s,使用 2,276,160 个输入 Token,在 3.00 美元上限下于 3.06 美元停止。它确实比完整扫描走得更远,在预算耗尽前写出了按优先级排列的审查工作清单(rank_input.jsonl、deep_review_input.jsonl),但仍没有任何漏洞发现。Diff 范围缩小,并不会缩小每一轮的上下文:Agent 仍会阅读整个仓库、编写完整威胁模型,并向多个 Worker 分发任务。
install-hook 会将它接入 Git 的 pre-commit Hook:高严重性问题和扫描错误都会阻止提交。在团队中安装前,应该先用自己的代码库为单个 Diff 扫描定价,因为这个 Hook 可能为每次提交增加数分钟和数美元成本。
它目前依然帮不了你的地方
工具为九行代码写出的威胁模型质量不错。它识别出全部四个信任边界,将缺失的 ./db 模块列为明确未知项,也没有在无法验证时默认 Express 提供保护。它还清楚写明了自己的限制:“Controls not present in the repository must not be assumed.”
这正是它的结构性限制。源代码是唯一输入,因此部署阶段才决定的内容对它不可见:CORS 策略、遗留开启的调试模式、弱 TLS、缺失的安全响应头、缓存投毒,以及服务间的运行时授权。特别是对象级授权漏洞,需要使用两个真实身份发起已认证请求才能确认,单靠阅读源码无法做到。
不同语言的分析深度据称也不均衡。关于托管服务的一篇实践者文章认为,它对 Python、JavaScript、TypeScript、Go 和 Java 的覆盖最强,Ruby、PHP 和 Kotlin 则相对靠后。我只测试了 JavaScript,因此这部分只能视为二手信息。
现在值得用吗?
如果你想要威胁模型,可以今天就安装。这是每次运行中我唯一稳定拿到的产物:一份 1,605 字的文档,梳理信任边界、列出攻击者路径,并针对具体服务界定 critical、high、medium 和 low 的含义。它也可以作为其他安全工具的输入,因为 --knowledge-base 支持加入你自己的架构文档,生成的模型也能编辑。
如果你需要可预测的支出,或者真正的漏洞发现列表,那就先等等。五种配置下,我两者都没有得到;面对一个十秒钟就能读完的仓库,单次成本却在 1.46 美元至 8.54 美元之间。流水线后段文档中提到的 findings.json、coverage.json 和 report.md,我一次都没有走到。拥有权限的 ChatGPT Business 账号是否表现不同,是这些测试无法回答的开放问题。
这里两种显而易见的控费手段都没有奏效:缩小 Diff 范围和降低推理强度,最终都撞上同一堵墙。真正改变账目的只有模型单价,因为估算按标价和 Token 数量计算,所以使用价格为标价一半的端点,同一次运行的成本也会减半。预算应以实测运行数据为准,而不是仓库大小;同时,将上限设在实际承受能力之下,并为一轮 Worker 留出余量——我的最坏超支幅度是上限的 46%。
FAQ
Codex Security CLI 免费吗?
CLI 和 SDK 采用 Apache-2.0 协议,安装不收费。但扫描不是免费的。它会消耗通过认证凭据调用的 GPT-5.6 Sol Token,CLI 会按 OpenAI 标价持续打印预估成本。
我需要 ChatGPT Business 或 Enterprise 套餐吗?
对于托管式 GitHub 集成,需要:该路径仅限 Pro、Enterprise、Business 和 Edu。CLI 可以接受普通的 OPENAI_API_KEY,但文档警告,完整仓库扫描仍可能要求 Trusted Access for Cyber,而任何套餐都不会自动授予这项权限。
它能在 CI 中运行吗?
可以。设置 OPENAI_API_KEY,再加入 --fail-on-severity,即可让发现漏洞时返回非零退出码;同时将 CODEX_SECURITY_STATE_DIR 指向仓库外一个可写路径。扫描默认只生成报告,不会修改代码。
它支持第三方 OpenAI 兼容端点吗?
支持,前提是该端点实现了 Responses API。必须通过 --codex 参数覆盖 Codex 供应商配置,因为仅设置 OPENAI_API_KEY 会认证失败。
CLI 与 Codex Security 插件有什么区别?
扫描引擎相同,入口不同。插件运行在 OpenAI 的基础设施中,面向已连接的 GitHub 仓库;CLI 则在你的机器上针对本地路径运行,将扫描历史保存在本地状态目录,并额外支持按 Diff 限定扫描范围、pre-commit Hook、SARIF 导出和 MCP 注册。
相关阅读:GPT-5.6 定价指南 · Codex 自动模式
