安全自审计

English

这是一份 maintainer 自审计,面向正在判断是否把 Codex Quota Monitor 接到敏感 CLIProxyAPI 和 Codex OAuth 状态上的用户。它不是第三方审计,也不是“部署后 没有风险”的保证;它说明 monitor 会读什么、数据可能到哪里、项目承诺不持久化 或暴露什么,以及用户如何本地复现检查。

如果需要更结构化的资产、边界和 abuse path 视图,见 威胁模型

威胁模型

monitor 面向可信 operator,在已有 CPA 部署附近运行自托管 dashboard。这是运维型安全 模型,不是公网 SaaS 安全模型:项目依赖本地监听、最小权限运行时、secret 脱敏和 共享 dashboard 时的外部鉴权访问层。它不实现内置用户登录、RBAC、多租户隔离或用户 访问审计日志。核心资产是:

纳入范围:

不纳入范围:

数据流

输入 用途 目的地 持久化
managementBaseUrl 读取 CPA management endpoint 中的 auth inventory、usage、routing、logs 和 health。 operator 配置的本地 CPA endpoint。 派生出的状态和计数可能进入 API/UI/history。
CPA management key 给 CPA management 请求加 Authorization: Bearer <key>;旧的 manual_quota_refresh_auth = "management-key" 部署也用它鉴权受保护的手动 direct quota refresh。 operator 配置的 CPA management URL,以及旧模式下的入站 /api/v1/quota/refresh 校验。 key 值不应进入 API/UI/history/metrics/logs。浏览器保存默认关闭,只在旧的 management-key refresh 模式且启用 allow_browser_key_storage 后可用。
手动刷新 UI token 鉴权默认浏览器 POST /api/v1/quota/refresh 动作,避免暴露 CPA management key。 页面 bootstrap 和入站 /api/v1/quota/refresh 校验。 进程启动时在内存中生成,只嵌入返回的 HTML 页面;不会由 print-config、API JSON、history、metrics 或日志打印。
Codex auth 文件 可选 direct quota sampling,从 auth 文件读取 access_token 和 account id。 https://chatgpt.com/backend-api/wham/usage token 值不应进入 API/UI/history/metrics/logs。
SQLite state DB 保存 dashboard snapshot 派生出的 Trends、ETA、Audit 和 Stats 时间序列输入。 --state-db 或 NixOS module 配置的本地路径。 账号标签、状态、quota 和 usage 元数据会被持久化。
Benchmark summary 在 Trends 中展示校准结果。 本地 summary.json 路径。 summary 字段会显示在 dashboard 中。

HTTP API 基本是只读的,但它不是鉴权边界。HostOrigin 检查能减少误连或跨源暴露, 但不会识别用户,也不能替代登录或 access layer。默认 POST /api/v1/quota/refresh 会校验页面内 refresh token 后才排队触发 provider-facing refresh,因此浏览器用户不需要 CPA management key。设置 manual_quota_refresh_auth = "none" 会移除这层动作校验,只适合可信本地部署。即使 secret value 已脱敏,也应把 /api/v1/status/api/v1/stats/api/v1/recommendations/api/v1/diagnostics/api/v1/alerts/metrics 当作敏感运维元数据。LAN 或 reverse-proxy 部署必须通过 --allowed-host 或 NixOS module 的 allowedHosts 选项明确列出浏览器访问用的域名/IP。

安全声明

这些声明应当能用仓库里的测试和验证命令复现:

本地验证

信任某个改动前,先跑常规测试:

nix develop -c python3 -m unittest discover -s tests -v
nix develop -c python3 -m build

确认 resolved config 和 doctor 输出不会打印 secret 值:

codex-quota-monitor print-config \
  --management-base-url http://127.0.0.1:8317 \
  --management-key-file /path/to/management-key \
  --gateway-health-url http://127.0.0.1:8317/healthz \
  --state-db off

codex-quota-monitor doctor --json \
  --management-base-url http://127.0.0.1:8317 \
  --management-key-file /path/to/management-key \
  --gateway-health-url http://127.0.0.1:8317/healthz \
  --auth-dir /path/to/auth-files \
  --state-db off

启动服务后,用只存在于测试 key 或 auth 文件里的精确 secret 字符串检查只读输出:

secret='replace-with-a-test-only-secret-string'
curl -fsS http://127.0.0.1:4515/api/v1/status > /tmp/cqm-status.json
curl -fsS http://127.0.0.1:4515/api/v1/recommendations > /tmp/cqm-recommendations.json
curl -fsS http://127.0.0.1:4515/api/v1/diagnostics > /tmp/cqm-diagnostics.json
curl -fsS http://127.0.0.1:4515/api/v1/alerts > /tmp/cqm-alerts.json
curl -fsS http://127.0.0.1:4515/metrics > /tmp/cqm-metrics.txt
grep -R --fixed-strings "$secret" /tmp/cqm-status.json /tmp/cqm-recommendations.json /tmp/cqm-diagnostics.json /tmp/cqm-alerts.json /tmp/cqm-metrics.txt

grep 应该没有任何匹配。这个检查要用一次性测试 secret;不要把真实 auth token 或 management key 粘到 issue 里。

共享 support artifact 前,生成脱敏副本,不要直接改原始文件:

codex-quota-monitor redact /tmp/cqm-status.json --secret "$secret" >/tmp/cqm-status-redacted.json
codex-quota-monitor redact /path/to/history.sqlite3 --output /tmp/history-redacted.sqlite3 --secret "$secret"
codex-quota-monitor redact /path/to/benchmark/summary.json --output /tmp/summary-redacted.json --secret "$secret"

如果已经把 support artifact 复制到一个 staging 目录,先跑 dry-run summary。目录和多路径 脱敏只有在传入 --apply 时才会改写文件:

codex-quota-monitor redact /tmp/cqm-support --secret "$secret"
codex-quota-monitor redact /tmp/cqm-support --secret "$secret" --apply

dry-run JSON 会报告有多少受支持的 JSON、JSONL、CSV、text/Markdown 和 SQLite 文件会变化。只在复制出来的 support artifact 上使用 --apply,不要对正在使用的 auth 目录、live history database 或仍在写入的 benchmark directory 原地执行。

新用户部署规则

残余风险

monitor 按设计会接触敏感材料。能读取 monitor 进程内存、auth 目录、management key 文件,或能控制配置的 CPA / proxy endpoint 的本地攻击者,可以窃取 secret。即使没有 原始 token,暴露的 dashboard endpoint 仍可能泄露账号标签、plan 档位、quota 时间、 最近 model 活动和服务健康。保持 runtime 本地化和最小权限,并把 API、metrics、 history、benchmark 或日志里的每一个新增字段都当作 privacy change 复查。