一句 `grep . .env`,你的密钥就喂给 AI 了——readignore 堵上这个缺口

你让 Claude Code/Codex 等智能体 改个项目。它为了理解上下文,顺手 cat .env------你的数据库密码就这么进了模型上下文。而你浑然不觉。

用了 .gitignore 就安全了?不。

.gitignore 只挡住 git 提交,挡不住 AI 编程智能体在运行时读取文件。Claude Code、Cursor、Codex、opencode......这些智能体可以读你仓库里的任何 文件------包括密钥.env*.pemid_rsacredentials.json

你可能会说:我在 Claude Code 里配了 permissions.deny: Read(.env)

还不够。它只挡住了 Read 工具。智能体可以用 GrepGlobBash 绕过:

bash 复制代码
grep . .env      # 走的是 Bash,不是 Read
cat id_rsa

Read 这条路堵了,Bash 那条路还敞着------grep 也是一次工具调用,照样把密钥塞进上下文。

这就是 readignore 要补的缺口。

readignore 是什么

AI 编程智能体的 .gitignore

你写一份 .readignore(100% gitignore 语法,零学习成本),声明哪些文件 AI 智能体禁止读取。readignore 把这一份声明,适配成每个智能体**当前真正支持的最强防御机制。

gitignore 复制代码
# readignore ------ 本仓库 AI 智能体禁止读取的文件

# 密钥
.env
.env.*
!.env.example            # ! 取反:放行模板
*.pem
*.key

# SSH / 云凭证
**/id_rsa
.aws/
.gcp/

# 敏感目录
secrets/
credentials.json

关键在于:它不假装跨智能体等价 。每个智能体能做到的强度不一样,readignore 适配到各自实际能强制 的那个点,并诚实标注

能力矩阵:强度诚实分级

智能体 强度 机制 状态
Claude Code hard PreToolUse 钩子------在工具调用执行前拦截 Read / Grep / Glob / Bash ✅ 已发布
codex CLI hard .codex/hooks.json,Claude-style PreToolUse 钩子 ✅ 已发布
pi hard .pi/extensions/readignore.ts 覆写内置 read 工具 ✅ 已发布
opencode config opencode.jsonpermission.read deny / allow glob ✅ 已发布
Cursor soft .cursor/rules 自然语言建议(模型可能遵守) 🗺 路线图
kilo code --- 机制待定 🗺 路线图

"强度"到底是什么意思

  • hard :代码在工具执行前 (或输出到达模型前)运行,能直接拒绝这次调用。三种形态:
    • Claude Code / codex :一个 PreToolUse 钩子脚本返回 permissionDecision: "deny",工具根本不会执行
    • pi :一个 TypeScript 扩展,以与内置 read 工具同名 注册从而覆写 它;匹配的路径返回 Access denied,文件根本不会被读取。
  • config :写出原生 deny 配置(如 opencode 的 permission.read)。能否生效取决于智能体是否忠实加载它。opencode 的 permission.ask 程序化钩子目前在运行时是空操作(opencode issue #7006),所以暂时到不了 hard。
  • soft :一条自然语言规则,请求模型遵守,无强制力。Cursor 风格工具的未来适配器会落在这里。

同一份 .readignore,在不同智能体上落到的防线强度不同。

工作原理

你只维护一份 .readignore,readignore 翻译成每个目标智能体的原生机制。

快速开始

bash 复制代码
# 安装(任选其一)
npm i -g readignore
# 或(Linux / macOS,无需 Go / npm)
curl -fsSL https://raw.githubusercontent.com/0xByteBard404/readignore/main/install.sh | sh
# 或(有 Go 1.25+ 环境)
go install github.com/0xByteBard404/readignore/cmd/readignore@latest

# 在你的仓库里
cd your-repo
readignore init                       # 生成 .readignore,内置常见密钥模式
# 编辑 .readignore 使之匹配你的项目,然后:
readignore install claude-code        # 单个智能体
readignore install --all              # 或:为本仓库检测到的全部智能体

init 拒绝覆盖已有的 .readignore(除非 --force);install 遇到已有配置文件会跳过 并提示手动合并(除非 --force),避免覆盖你已有的 .claude/settings.jsonopencode.json

各适配器到底生成了什么

Claude Code(hard)

bash 复制代码
.claude/hooks/readignore.sh   (0755)   # 提取目标路径,调 readignore match
.claude/settings.json                  # 在 PreToolUse 上注册钩子

钩子在 Read | Grep | Glob | Bash 时触发,调用 readignore match <path> 做权威匹配,路径命中(exit 1 = deny)时在执行前拒绝 。Claude Code 的 settings 监听器会实时感知变更,无需重启

codex CLI(hard)

bash 复制代码
.codex/hooks/readignore.sh    (0755)
.codex/hooks.json                      # Claude-style PreToolUse 钩子

codex 的钩子协议与 Claude Code 一致(permissionDecision: "deny"),共用同一套 bash 钩子。

一个诚实的平台说明 :codex 没有独立的 Read / Grep / Glob 工具,agent 读文件一律走 shell 命令(cat .envgrep pattern file)。所以 PreToolUse 钩子原生只在 tool_name="Bash" 时触发,readignore 的匹配器从该 command 字符串里抽取路径参与匹配。原生「读文件」调用始终是 Bash 命令,而这条路径钩子确实会拦。项目级钩子首次运行需通过 codex 的信任提示。

pi(hard)

lua 复制代码
.pi/extensions/readignore.ts   (0644)   # 覆写 pi 内置 read 工具

pi 启动时自动加载 .pi/extensions/*.ts。该扩展注册一个名为 read 的工具------与内置工具同名 ------从而覆写 它:匹配的路径在文件被读取前返回 Access denied,其余情况委托给正常读取。不引入任何 pi 类型,文件可独立通过类型检查。

opencode(config)

json 复制代码
{
  "permission": {
    "read": {
      ".env": "deny",
      ".env.*": "deny",
      ".env.example": "allow"
    }
  }
}

opencode 启动时读取。注意 opencode 的 glob 引擎没有 gitignore 的顺序 / 取反语义,readignore 用「更具体的 allow 击败更宽泛的 deny」来近似 ! 取反------常见场景正确,复杂取反链可能与 gitignore 不一致。若依赖复杂取反,优先用 Claude Code 适配器(完整 gitignore 语义)。

核心价值:改完立即生效

这是我最想强调的一点。

所有钩子现在统一调用 readignore match 子命令(基于 go-git 的 format/gitignore 引擎,权威匹配)。钩子每次工具调用都实时重读 cwd/.readignore

意味着什么?.readignore 立即生效,无需重新 install ------和 .gitignore 一样改完即用。

以前改 .readignore 后必须重跑 install,把模式重新冻结进生成的钩子文件。现在这层去掉了:.readignore 是唯一真相,钩子只是个调用 readignore match 的薄壳。

为什么不直接用现有方案

方案 漏掉什么
.gitignore 智能体运行时仍会读取文件(gitignore 只挡提交)
Claude Code permissions.deny: Read(.env) Grep / Glob / Bash(grep . .env)可绕过
每个智能体单独手配 5+ 个智能体间重复劳动,容易失同步

readignore 用一份声明替代逐个手配,每个智能体落到自己能做到的最强防线。

项目状态

三个 hard 适配器(Claude Code、codex CLI、pi)+ 一个 config 适配器(opencode)。Cursor、kilo code 在路线图上。许可证 MIT。

如果你在用 Cursor、kilo code 或其他智能体,欢迎来开 issue 讨论适配器设计------每个适配器实现一个小的 Adapter 接口,并在 init() 中自注册。


如果你也担心 AI 智能体读到不该读的文件,花一分钟试试:

bash 复制代码
npm i -g readignore && readignore init && readignore install --all

📦 项目地址github.com/0xByteBard4...

Star / Issue / PR 都欢迎。如果觉得有用,点赞 + 收藏支持一下,关注我追后续 Agentic 系列👇

相关推荐
Token炼金师1 小时前
梯度的呼吸:激活、归一化、反传与残流 —— 深度网络的四道命门
人工智能·深度学习·llm
Svan L1 小时前
文献综述工具比较:沁言学术与 ChatGPT Plus 的可用性分析
人工智能·chatgpt
今心上1 小时前
关于安装李沐深度学习d2l包【2026.7可用版】
人工智能·深度学习
forestsea1 小时前
GLM-4-9B-Chat-1M 模型在 openEuler 系统上的完整部署文档
人工智能·ai·语言模型
voidmort1 小时前
3. 理解 RoPE
人工智能·深度学习·机器学习·transformer
Kel1 小时前
万物皆 Runnable:LangChain 如何用一个接口统一模型、链与图
人工智能·设计模式·架构
科技圈快迅1 小时前
解决续费痛点,轻量化AI订阅替代方案深度解读
大数据·人工智能
Tbisnic1 小时前
23.大模型开发:深度学习----CNN 卷积神经网络 与 RNN 循环神经网络
人工智能·python·rnn·深度学习·cnn·ai大模型
灵机一物1 小时前
2026算力推荐进入专业化阶段:超互联品牌如何构建企业AI选型能力矩阵
服务器·人工智能·决策树·云平台