0xByteBard404/readignore

GitHub: 0xByteBard404/readignore

readignore 通过生成 .readignore 文件并将其适配为各 AI 编码代理的原生防护机制,防止代理在运行时读取仓库中的敏感文件和密钥。

Stars: 0 | Forks: 0

# readignore readignore **English** | [中文](README.zh-CN.md) **AI 编码代理的 `.gitignore` —— 声明你的 AI 代理绝对不能读取的文件。** [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/39/39faa54be350a1dab8afd3b2fb8c1c83e4d9cff84abfef2374d19a18053687c4.svg)](https://github.com/0xByteBard404/readignore/actions/workflows/ci.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/0xByteBard404/readignore)](https://goreportcard.com/report/github.com/0xByteBard404/readignore) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/0xByteBard404/readignore/blob/main/LICENSE) [![Go Version](https://img.shields.io/badge/go-1.25-00ADD8?logo=go&logoColor=white)](https://go.dev/) 🌐 **网站**: [readignore.vercel.app](https://readignore.vercel.app) AI 编码代理(Claude Code, Cursor, Codex, opencode, kilo code, …)在运行时可以读取仓库中的 任何文件——**包括机密信息**,如 `.env`、`*.pem`、 `id_rsa`、`credentials.json`。现有的防御机制存在漏洞: - `.gitignore` 仅能阻止 **git** 进行提交;代理依然能读取该文件。 - Claude Code 的 `permissions.deny: Read(.env)` 仅拦截了 **Read** 工具—— 代理可以通过 `Grep`、`Glob` 或 `Bash` 绕过(执行 `grep . .env` 即可奏效)。 **readignore** 通过一个 `.readignore` 文件(使用 gitignore 语法)填补了这一漏洞,该文件会被适配转化为每个代理的原生防御机制——并作用于该代理实际支持的最高强度级别。 ## 工作原理 How readignore works: .readignore → readignore CLI → per-agent defenses 你只需编写一个声明式的 `.readignore` 文件。readignore 会将其转化为每个目标代理**可用的最强机制**——并**如实标注**各自的执行强度,因为各个代理的能力并不对等。 ## 能力矩阵 readignore 会将 `.readignore` 适配为每个代理最强的*真实*机制。 强度等级是**真实的**,而非营销噱头: | 代理 | 强度 | 机制 | 状态 | |---|---|---|---| | **Claude Code** | **hard** | `PreToolUse` hook——在工具运行**之前**拦截调用(Read, Grep, Glob, Bash)。运行时的程序化拦截。 | ✅ 已发布 | | **codex CLI** | **hard** | `.codex/hooks.json` Claude 风格的 `PreToolUse` hook(bash,调用 `readignore match`)。与 Claude Code 采用相同的运行时拦截机制;首次运行时需要信任 hook。详情见下方的 [codex 说明](#codex-platform-note)。 | ✅ 已发布 | | **pi** | **hard** | `.pi/extensions/readignore.ts` TypeScript 扩展,该扩展会**重写**内置的 `read` 工具——调用 `readignore match`,并在读取文件之前对匹配的路径返回 `Access denied`。在启动时自动加载。 | ✅ 已发布 | | **opencode** | **config** | `opencode.json` 中的 `permission.read` 拒绝/允许通配符;在 opencode 加载配置时生效。 | ✅ 已发布 | | **Cursor** | soft | `.cursor/rules` 自然语言建议(模型可能会遵从)。 | 🗓 路线图 | | **kilo code** | config | `kilo.json` 中的 `permission.read` 拒绝/允许通配符;在 kilocode 加载配置时生效。 | ✅ 已发布 | ### “强度”的含义 - **hard** —— 代码在工具执行*之前*(或在其输出到达模型之前)运行,并且可以拒绝调用。 目前有三种形式,均在运行时被切实执行: - **Claude Code / codex** —— 一个 `PreToolUse` hook 脚本返回 `permissionDecision: "deny"`,随后该工具**永远不会执行**。 - **pi** —— 一个注册了与内置 `read` 工具同名的 TypeScript 扩展会*重写*它;匹配的路径将返回 `Access denied`,且文件永远不会被读取。 - **config** —— readignore 写入原生的拒绝配置(如 opencode 的 `permission.read`)。其执行取决于代理是否能如实地加载它。 opencode 的程序化 `permission.ask` hook 目前在运行时是不起作用的([opencode #7006](https://github.com/anomalyco/opencode/issues/7006)),因此我们暂时还无法在此达到 `hard` 级别。 - **soft** —— 一条要求模型*遵守*的自然语言规则。无强制执行力。针对 Cursor 类工具的未来适配器将归入此类。 readignore **并不**承诺跨代理的等效性。它会自动适配为每个代理实际能够强制执行的机制。 ## 快速开始 ``` # 1. 安装(npm —— 无需 Go;其他选项见下文的 Installation) npm i -g readignore # 2. 在你的 repo 中: cd your-repo readignore init # generates .readignore with common secret patterns # 3. 编辑 .readignore 以匹配你的项目,然后为你的 agent(s) 安装: readignore install claude-code # single agent readignore install codex # codex CLI (Claude-style PreToolUse hook) readignore install pi # pi (.pi/extensions/ TS override, auto-loaded) # 或者为在此 repo 中检测到的每个 agent 安装: readignore install --all ``` 除非你传递 `--force` 参数,否则 `init` 会拒绝覆盖现有的 `.readignore` 文件。 ## 命令 ``` # 生成 .readignore 模板(包含 .env, *.pem, id_rsa, .aws/, … 等模式) readignore init [--force] # 列出已注册的 adapter 及其强度,以及在此 repo 中的检测状态 readignore adapters # Dry-run:解析 .readignore 并打印 adapter 将会生成的内容(stdout) readignore generate claude-code readignore generate codex readignore generate pi readignore generate opencode # 将 adapter 的输出写入磁盘 readignore install claude-code # one adapter readignore install --all # all adapters detected here readignore install claude-code --force # overwrite existing files # 将 adapter 的文件刷新至当前的 readignore 版本(= install --force) readignore update # all adapters detected (default = --all) readignore update claude-code # one adapter # 移除 adapter 生成的文件(install 的逆操作) readignore uninstall claude-code # one adapter readignore uninstall --all # all adapters detected here readignore uninstall claude-code --dry-run # preview only, don't delete # 验证 .readignore 语法并报告每个 adapter 的安装状态 readignore check # 检查某个路径是否被 .readignore 拒绝(exit 0=允许,1=拒绝) # 这就是 hooks 在 runtime 调用的内容 —— 你可以直接用它进行 debugging readignore match .env ``` 如果目标文件已存在,除非你传递 `--force` 参数,否则 `install` 会**跳过它**(并提示你手动合并)。这可以避免覆盖你现有的 `.claude/settings.json` 或 `opencode.json`。 ## `.readignore` 语法 100% 兼容 gitignore。零学习成本: ``` # readignore —— 此 repo 的 AI agent 禁止读取的文件 # Secrets & keys .env .env.* !.env.example # ! un-ignores (negation): allow the template through *.pem *.key # SSH / cloud credentials **/id_rsa .aws/ .gcp/ # Sensitive directories secrets/ credentials.json # 末尾的 / 仅锚定到目录 build/ ``` 支持:`*`、`**`、`?`、`[abc]` 字符匹配、`!` 取反 (最后匹配生效,与 gitignore 完全相同)、用于锚定目录的尾部 `/`、 `#` 注释。请参阅 [gitignore 规范](https://git-scm.com/docs/gitignore)。 ## 生成的内容 ### Claude Code (`readignore install claude-code`) 在 `.claude/` 目录下生成两个文件: ``` .claude/hooks/readignore.sh (0755) # extracts target path, calls `readignore match` .claude/settings.json # registers the hook on PreToolUse ``` 该 hook 会在 `Read | Grep | Glob | Bash` 时触发,调用 `readignore match ` (gitignore 匹配的 **go-git 权威标准**),并在路径匹配时**在执行前拒绝**(`exit 1` = 拒绝)。Claude Code 的设置监听器会实时获取更改——**无需重启**。 **编辑 `.readignore` 会立即生效**——hook 会在每次调用时通过 `readignore match` 重新读取 `cwd/.readignore`,因此在编辑规则后你永远无需重新运行 `install`。与 `.gitignore` 一样提供即编即用的体验。 ### opencode (`readignore install opencode`) 生成一个包含 `permission.read` 拒绝/允许通配符的 `opencode.json`: ``` { "$schema": "https://opencode.ai/config.json", "permission": { "read": { ".env": "deny", ".env.*": "deny", ".env.example": "allow" } } } ``` opencode 会在启动时读取此配置。 ### codex CLI (`readignore install codex`) 在 `.codex/` 目录下生成两个文件,镜像映射了 Claude Code 的目录结构: ``` .codex/hooks/readignore.sh (0755) # extracts target path, calls `readignore match` .codex/hooks.json # registers the hook (Claude-style PreToolUse) ``` codex 的 hook 协议采用 [Claude 风格](https://github.com/openai/codex) (`PreToolUse` + `permissionDecision: "deny"`),因此可以运行相同的 bash hook——它 调用 `readignore match`(go-git 权威标准)并在工具执行前拒绝调用。与 Claude Code 一样,**编辑 `.readignore` 会立即生效** (无需重新安装)。 #### codex 平台说明 —— 仅限 Bash 的 hook 触发器 与 Claude Code 不同,**codex 没有独立的 `Read` / `Grep` / `Glob` 工具**。 codex 代理完全通过 **shell 命令**(`cat .env`、 `head -n 50 file`、`grep pattern file`)来读取文件。因此,`PreToolUse` hook *原生*仅会在 `tool_name="Bash"` 时触发(目标路径包含在 `tool_input.command` 中),并且 readignore 的匹配器会从该 `command` 字符串中提取路径。 `hooks.json` 中的 `matcher: "Read|Grep|Glob|Bash"` 是刻意为之的,并不是 bug: - 它保持了 codex 适配器与 Claude Code 适配器的**对称性**(相同的 共享 bash hook,均调用 `readignore match`); - 它涵盖了安装了向 codex 暴露 `Read`/`Grep`/`Glob` 的 **MCP 工具**的用户——这些 MCP 工具也会被拦截。 但对于 codex 的**原生**工具集,只有 `Bash` 分支会被触发。原生 的“读取此文件”调用始终是一个 Bash 命令,而该 hook 确实可以拦截它。 ### pi (`readignore install pi`) 生成一个单一的 TypeScript 扩展: ``` .pi/extensions/readignore.ts (0644) # overrides pi's built-in `read` tool ``` pi 在启动时[自动加载 `.pi/extensions/*.ts`](https://github.com/earendil-works/pi-coding-agent)。 该扩展注册了一个名为 `read` 的工具——与 pi 的 内置工具同名——从而**重写**它:它会调用 `readignore match `(go-git 权威标准),并且匹配的路径在文件被读取前就会返回 `Access denied`;其他所有操作则委派给正常的读取流程。由于未导入任何 pi 类型,因此该 文件可以独立进行类型检查。与 hook 适配器一样,**编辑 `.readignore` 会立即生效**。 ## 安装 **npm(推荐——无需 Go):** ``` npm i -g readignore # or: npx readignore ``` npm 包装器的 `postinstall` 脚本会从 [GitHub Releases](https://github.com/0xByteBard404/readignore/releases) 为你的平台下载相应的 Go 二进制文件。 **`go install`(如果你使用的是 Go 1.25+):** ``` go install github.com/0xByteBard404/readignore/cmd/readignore@latest ``` **二进制下载:**从 [Releases](https://github.com/0xByteBard404/readignore/releases) 获取适用于你平台的压缩包,解压,并将 `readignore` 放入你的 PATH 中。 **`curl | sh` 一键脚本(Linux / macOS,无需 Go 或 npm):** ``` curl -fsSL https://raw.githubusercontent.com/0xByteBard404/readignore/main/install.sh | sh ``` 该脚本会检测你的操作系统/架构,从最新版本中获取相应的二进制文件和 `checksums.txt`,验证 SHA256,并将 `readignore` 安装到 `/usr/local/bin`(如果失败则回退到 `~/.local/bin`,并在需要时提供 PATH 提示)。 Windows 用户:请使用 npm、Scoop 或 Releases 中的 `.zip` 文件。 **Homebrew:** ``` brew tap 0xByteBard404/tap brew install readignore ``` (需要 `0xByteBard404/homebrew-tap` 仓库。) **即将推出:** Scoop (Windows)。 ## 为什么不直接用 `.gitignore` 或 `permissions.deny`? | 方案 | 无法拦截的情况 | |---|---| | `.gitignore` | 代理在运行时读取文件(gitignore 仅拦截提交)。 | | Claude Code `permissions.deny: Read(.env)` | `Grep`、`Glob`、`Bash`(`grep . .env`)均可绕过。 | | 按代理手动配置 | 在 5 个以上的代理中重复工作;容易产生不同步。 | readignore 采用**一次声明,按代理适配**的方式,作用于每个代理最强的 执行点。 ## 项目状态 v0.3.0 —— 三个 **hard** 适配器(Claude Code、codex CLI、pi)+ 一个 **config** 适配器。所有 hook 现在都会调用 `readignore match`(go-git 权威标准), 因此**编辑 `.readignore` 会立即生效**——无需重新安装。 通过 npm、`curl | sh` 或 Homebrew 安装。Cursor 和 kilo code 适配器已列入 路线图。 有关版本历史,请参阅 [CHANGELOG.md](./CHANGELOG.md)。 ## 许可证 [MIT](./LICENSE) © 2026 0xByteBard404
标签:AI编程助手, EVTX分析, Go, Ruby工具, SOC Prime, Streamlit, StruQ, 密钥保护, 开发工具, 日志审计, 暗色界面, 访问控制