MaydayV/grok-upload-audit
GitHub: MaydayV/grok-upload-audit
这是一款 AI 智能体技能插件,用于取证审计 Grok Build CLI 是否在未经本地同意的情况下上传了用户的代码库和密钥,并生成防篡改证据包和数据删除请求函。
Stars: 2 | Forks: 0
# grok-upload-audit
一个**智能体技能** —— 适用于 [Claude Code](https://claude.com/claude-code)、
[OpenAI Codex](https://github.com/openai/codex) 以及任何其他加载了
`SKILL.md` 技能的编程智能体 —— 它能对 **xAI Grok Build
CLI** 从您的机器上上传的内容进行取证审计,并帮助您采取应对措施。
Grok Build 将其所有的操作记录都存储在 `~/.grok` 目录下。在受影响的版本中,它会将您的工作仓库打包成 `tar.gz` 归档文件,并连同会话状态和插件清单一起,通过 `https://cli-chat-proxy.grok.com/v1/storage` 上传到 xAI 的 Google Cloud Storage bucket 中。上传开关可以 **由 xAI 远程开启,且无需本地用户同意**,而且智能体读取的文件(包括 `.env`)会被原封不动地发送出去。这种行为与 Grok Build 公开宣称的“本地优先”立场相悖。
好消息是:`~/.grok` 保留了所有的记录。本技能会读取这些记录,并将它们转化为针对每一位受影响用户都在问的问题的明确答案 —— *我的代码被上传了吗?里面包含活动的 secret 吗?* —— 此外,还会生成一个防篡改的证据包以及一份随时可发送的数据删除请求。
## 功能
给定一台安装了 Grok Build 的机器,该技能会:
1. **解析 `~/.grok/logs/unified.jsonl`** 以重建每一次上传事件 —— 包括打包了哪些仓库、有多少个快照、总字节数、精确的 GCS 对象路径,以及访问的存储 endpoint。
2. **证明(或反驳)同意情况**,通过读取 `trace.upload.decision` 记录。如果上传是通过 `trace_upload_source: "remote"` 启用的,而每个本地 opt-in 字段都是 `null`,这就是铁证:是 xAI 在服务器端开启了它。
3. **检查 secret 泄露情况**,方法是将您的 `.env` 文件(以及其他 AI 工具的凭证文件)的*值*与本地 Grok 数据进行匹配比对 —— 仅报告**键名和命中次数,绝不包含值本身**。
4. **评估影响范围**,将其诚实划分为三个等级:*确认上传*的仓库、*仅尝试上传*的仓库,以及*触碰过但无上传证据*的仓库(例如,您的主目录或非 git 文件夹)。
5. **生成证据包** —— 包含带有 SHA-256 校验和的提取日志记录 —— 适合作为附件用于投诉。
6. **生成数据删除请求信**(GDPR 第 15/17 条,CCPA/CPRA §1798.105/.110),并预先填入您的账户 ID、每次会话的上传表格以及同意情况的调查结果。
7. **阻止进一步上传**,通过将已知的缓解配置添加到 `~/.grok/config.toml` —— 但仅在您查看调查结果之后进行。
## 设计上的安全性
审计数据外泄问题本身绝不能导致二次数据外泄。本技能正是围绕这一原则构建的:
- **Secret 的值绝不会离开进程。** 它们仅在内存中进行比对,绝不会打印到记录中、写入任何输出文件或发送到任何地方。调查结果仅通过键名和命中次数来识别泄露的凭证 —— 例如 `DATABASE_URL (27 hits)` —— 这样您就能知道*什么*泄露了,而无需重新暴露它。
- **在您决定之前保持只读。** 所有调查操作都是只读的;除非您明确选择应用上传阻止,否则 `~/.grok` 下的任何内容都不会被修改。
- **绝不夸大其词。** “存在于本地会话数据中”与“确认已上传至 xAI”会明确区分开进行报告,并且每一个调查结果都受到日志时间覆盖范围的限制。我们的目标是提供精确、经得起推敲的结果 —— 而不是哗众取宠。
- **主目录防护。** 扫描器拒绝将 `$HOME` 视为仓库,因此它不会扫描您的整个主文件夹。
## 适用范围:这对 Codex 或其他 AI CLI 有效吗?
**不适用 —— 而且这是刻意为之的。** 此工具专门审计 **Grok Build CLI**,因为它检测到的行为是 Grok 特有的:将您的整个仓库打包成 `tar.gz` 归档文件并上传到 xAI 的 Google Cloud Storage bucket,且上传开关可由供应商远程切换。
OpenAI Codex 和 Claude Code 使用**完全不同的数据模型。** 它们是基于 API 的智能体,仅将与任务相关的上下文发送到其模型 endpoint —— 就像任何 LLM API 调用一样 —— 且**绝不会**将您的整个代码库上传到存储 bucket 中。这不仅仅是听信供应商的一面之词:这可以从它们留在磁盘上的内容中得到证实。例如,`~/.codex` 中没有 `unified.jsonl`,没有 `repo_state.upload.*` 事件,其会话文件中也没有存储 bucket 的 endpoint;Codex 的分析数据是匿名的健康指标(无代码,无 PII),且其[收集代码是开源的](https://github.com/openai/codex)。会话历史完全保留在**本地**。
正因如此,将此审计工具指向 `~/.codex` 或 `~/.claude` 不会找到任何上传证据 —— 这不是因为它失败了,而是因为那里根本没有可供查找的此类内容。为了避免捏造出具有误导性的“一切正常”(或者更糟的,虚假警报),该工具会检测到目标并非 Grok 安装目录并如实报告(退出代码 3)。审计 Codex 实际的隐私风险面 —— 本地会话保留、遥测 opt-out —— 需要的是一个真正*不同*的工具和不同的逻辑,而不仅仅是对此工具进行重命名。
该技能*确实*涵盖的一个跨工具角度:它会检查 **Grok** 是否读取了您其他工具的凭证(例如,`~/.codex/auth.json` 中的值是否泄露到了 Grok 上传的会话状态中)。这关乎的是 Grok 拿走了什么,而不是 Codex 发送了什么。
## 环境要求
- 一个加载了 `SKILL.md` 技能的编程智能体 —— [Claude Code](https://claude.com/claude-code)、
[OpenAI Codex](https://github.com/openai/codex) 或类似工具。(您也可以完全脱离智能体独立运行审计工具 —— 请参阅 [独立运行](#standalone-just-the-report)。)
- Python 3.8+(仅使用标准库 —— 无需第三方包)。
- macOS 或 Linux。Grok Build 已安装在 `~/.grok`(或通过传递 `--grok-dir` 指定)。
## 安装
克隆到您智能体的技能目录中。两者使用相同的技能格式,因此唯一的区别在于目标路径:
**Claude Code** —— `~/.claude/skills/`:
```
git clone https://github.com/MaydayV/grok-upload-audit \
~/.claude/skills/grok-upload-audit
```
**OpenAI Codex** —— `~/.codex/skills/`:
```
git clone https://github.com/MaydayV/grok-upload-audit \
~/.codex/skills/grok-upload-audit
```
您的智能体会在下次启动时自动发现它。日后若要更新,只需在该目录下运行 `git pull` 即可。
## 用法
### 通过您的编程智能体(推荐)
只需用自然语言描述您的担忧,该技能就会自动触发 —— 在 Claude Code 或 Codex 中操作方式相同:
- *"Grok 是否将我的代码上传到了 xAI?检查一下我的机器。"*
- *"有新闻说 Grok CLI 会上传项目代码 —— 审计一下我的,并起草一份删除请求。"*
- *"Grok 是否泄露了我的任何 API key?"*
智能体会运行审计,解释调查结果,并且 —— 如果您愿意 —— 还会撰写删除信函并应用上传阻止,逐步指导您完成每一个操作步骤。
### 独立运行(仅获取报告)
您也可以直接运行审计工具,无需任何智能体 —— 它只是一个普通的脚本:
```
# 从你 clone 它的任何位置(~/.claude/skills/…、~/.codex/skills/…,或任何地方)
python3 grok-upload-audit/scripts/grok_audit.py
```
选项:
| Flag | 用途 |
|------|---------|
| `--grok-dir PATH` | 审计非默认的 Grok 目录(默认为 `~/.grok`)。 |
| `--output-dir PATH` | 指定报告/证据的写入位置(默认为 `~/Documents/grok-upload-audit-/`)。 |
| `--no-log-copy` | 跳过将完整的原始日志 gzip 压缩打包到证据包中的步骤。 |
它会在 stdout 打印出 JSON 摘要,并将完整的调查结果写入
`audit_summary.json`。退出代码:`1` = 未安装 Grok;`3` = 目标目录存在但并非 Grok 安装目录(请参阅 [适用范围](#scope-does-this-work-for-codex-or-other-ai-clis))。
## 您将获得
```
grok-upload-audit-/
├── audit_summary.json # machine-readable findings (source of truth)
├── xAI-Data-Deletion-Request.md # pre-filled deletion letter (when generated)
└── evidence/
├── upload_enqueued.jsonl # every upload: timestamp, session, GCS path, size
├── upload_start.jsonl # every packaging pass: repo, phase, turn
├── trace_upload_decisions.jsonl # consent records proving remote activation
├── upload_failures.jsonl # failures naming the storage endpoint + GCS backend
├── gcs_objects.txt # complete list of uploaded object paths
├── unified.jsonl.gz # full unmodified raw log for the window
└── SHA256SUMS.txt # checksums for evidence integrity
```
摘要概览:
```
{
"uploaded": true,
"snapshots": 197,
"megabytes": 33.4,
"repos_uploaded": ["~/Dev/project-a", "~/Dev/project-b"],
"remote_enabled": true,
"secrets_leaked_ROTATE": ["DATABASE_URL (27 hits)", "JWT_SECRET (9 hits)"],
"other_env_values_present": ["API_BASE_URL (140 hits)"],
"prefix_hits_needing_review": []
}
```
## 原理说明
所有代码都位于 `scripts/grok_audit.py` 中(单文件,仅使用标准库)。
它会流式读取追加写入的 `unified.jsonl` 事件日志,并以 Grok 写入的消息类型作为关键线索:
- `repo_state.upload.start` — 一次打包过程已开始(证明有*尝试*)。
- `repo_state.upload.enqueued` — 一个构件已构建并加入队列(证明有*上传*行为;包含 GCS 路径和字节大小)。
- `trace.upload.decision` — 同意决策,包括开关是由 `local`(本地)还是 `remote`(远程)开启的。
- `upload failed: …` — 这些失败记录的错误文本证实了存储代理 endpoint 和 GCS 后端。
secret 检测会根据名称对 `.env` 的键进行分类(与 `*_SECRET`、`*_TOKEN`、`*_KEY`、`*_DSN`、`PASSWORD` 等键关联的值会被视为凭证;而 base URL 或模式标志则被视为配置),并通过匹配值来确认是否泄露 —— 报告时仅显示次数。凭证前缀扫描(`sk-ant-`、`ghp_`、
`AKIA` 等)会标记 `~/.grok` 中任何具有凭证特征的内容,同时会忽略 Grok 自带文档中的占位符,以免引起误报。
有关完整的日志 schema 及各字段的详细含义,请参阅
[`references/log-format.md`](references/log-format.md)。删除信函的
结构和占位符映射位于
[`references/deletion-letter-template.md`](references/deletion-letter-template.md) 中。
## 限制
- **仅限本地证据。** 审计结果反映的是您的机器所记录的内容。它可以证明发生过上传并指出具体的对象;但它无法查看 xAI 的服务器。在日志覆盖时间窗口之前的任何会话都无法在本地重建 —— 删除信函会改为通过账户 ID 将其包含在内。
- **缓解措施仅尽力而为。** 我们认为本地配置的优先级高于 xAI 的远程开关,但这并不是 xAI 给出的保证,而且 `auto_update = true` 意味着未来的更新可能会改变行为。升级后请重新运行审计。卸载 Grok 是唯一能彻底阻止它的方法。
- **字段名可能会变动。** Grok 更新可能会重命名日志字段;脚本会进行优雅降级处理,参考文档中也解释了如何手动进行验证。
## 免责声明
本工具仅用于个人数据保护和安全维护目的。它只读取您自己的本地文件,且不会进行任何网络连接。生成的信函只是一个模板,不构成法律建议 —— 如需针对您所在司法管辖区的问题,请咨询合格的专业人士。本工具不隶属于 xAI,也未获得其认可或与其有任何关联。
## 许可证
[MIT](LICENSE)
标签:AI智能体, StruQ, 取证, 审计工具, 时序数据库, 机密信息检测, 杀软绕过, 逆向工具, 隐私合规