用 Claude Code、Codex 写代码,怎么不让 AI 碰到密钥和隐私?

V2EX 有人问:「你们会刻意避免让 AI 接触到自己的任何敏感信息吗?」

楼主的担心很实在:AI 用得越深,账号、服务器信息、各种 Key、真实姓名、证件号、地址,甚至密码,好像都难免一点点被模型看到。这些内容不像密码库里存的是哈希,发出去就收不回来了。

用编程 Agent 的时候,这个问题更具体:它能读你的项目目录、能跑命令,.env、~/.ssh、~/.aws/credentials、环境变量里的 Token,它都可能碰到。

你是怎么处理的?有哪些配置和习惯值得推荐?

楼主把 V2EX 楼里的做法,和 Claude Code、Codex、1Password 的官方文档对了一遍,整理成能直接照做的清单。

一、楼里的几条共识

  • 不管用什么 API,发出去之前先脱敏(#3 docx)。账号、Key、密码这些,本来就没必要告诉 AI(#2 QingXuJiaZhi)。
  • 编程任务里,引导 AI 不去读某些文件;密钥放进环境变量文件,不要贴进聊天窗口;要上传的图片、PDF 先打码(#5 ihenrygoo)。
  • 重要的数字资产,干脆不要放在跑 Agent 的电脑上(#6 JasonYip)。
  • 用 1Password 加环境变量管理密钥(#7 fingerxie)。

二、Claude Code:两层都要配

第一层,权限规则,管内置的读文件工具。 在 ~/.claude/settings.json 里加上:

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  }
}

改完在 Claude Code 里运行 /status,确认配置已经加载。注意两点:

  • 项目里的 .claudeignore 文件不起作用,里面的条目要改写成 Read 拒绝规则。
  • 这条规则能拦住内置的读文件工具,也能拦住 Bash 里能识别出来的 cat、head、tail、sed 等命令;但拦不住不点名文件的命令(比如在目录里跑 grep -r),也拦不住自己去打开文件的 Python、Node 脚本。文档原话是:要在系统层面拦住所有进程,请开启沙箱。

第二层,沙箱,管 Agent 跑的命令。 沙箱默认仍然能读机器上的大部分文件,包括 ~/.ssh 和 ~/.aws/credentials;环境变量也会原样继承,里面的密钥一样。所以要用 sandbox.credentials 把它们点名保护起来:

{
  "sandbox": {
    "enabled": true,
    "credentials": {
      "files": [
        { "path": "~/.aws/credentials", "mode": "deny" },
        { "path": "~/.ssh", "mode": "deny" }
      ],
      "envVars": [
        { "name": "GITHUB_TOKEN", "mode": "deny" },
        { "name": "NPM_TOKEN", "mode": "deny" }
      ]
    }
  }
}
  • 设成 deny 的文件在沙箱里读不到,环境变量会在每条命令执行前被清掉。
  • 没有内置的屏蔽清单,只有你列出来的才受保护。
  • 沙箱只管 Bash 命令,内置的 Read 工具按权限规则走,所以两层要一起配。想让所有子进程都拿不到凭据,文档还给了 CLAUDE_CODE_SUBPROCESS_ENV_SCRUB 这个环境变量。

三、Codex:默认会把带 KEY、TOKEN 的环境变量传下去

  • 默认的 workspace-write 模式能读文件,只能改当前工作区,默认不联网;要联网或改工作区以外的文件,会先问你。不联网这一条,本身就挡住了把数据往外发。
  • 容易忽略的一点:shell_environment_policy.ignore_default_excludes 默认是 true,也就是名字里带 KEY、SECRET、TOKEN 的环境变量,默认会原样传给 Codex 启动的命令。想让它自动过滤,在 ~/.codex/config.toml 里写:
[shell_environment_policy]
ignore_default_excludes = false
  • 有密钥的机器上别用 danger-full-access,这个模式会去掉文件和网络两道边界。

四、密钥本身:别以明文放在项目里

楼里提到的 1Password 做法,官方叫「密钥引用」:

  • .env 里只写引用、不写真实值,比如 AWS_SECRET_ACCESS_KEY="op://development/aws/Access Keys/secret_access_key";
  • 用 op run --env-file="./prod.env" -- 你的命令 启动,真实值只在这个子进程运行期间以环境变量的形式存在;
  • 命令输出里出现的密钥默认会被遮盖,显示成 <concealed by 1Password>。

这样就算 Agent 读到了 .env,看到的也只是引用。但要注意前面说的:程序跑起来以后,密钥就在环境变量里了,Claude Code 的沙箱要配 envVars,Codex 要配 shell_environment_policy。

五、几个小习惯

  • 截图、日志、报错贴给 AI 之前,先把 Token、手机号、证件号打码。
  • Key 万一发进了对话或日志,直接去后台作废、换新的,别抱侥幸心理。
  • 在本站发帖也一样:含 sk-… 这类密钥的帖子会被系统拦下,但最好还是发之前自己检查一遍。

参考来源:

楼主补充(11 月 3 日):存在第三方平台上的环境变量也会泄露

11 月 1 日,任务平台 Trigger.dev 发布安全事件说明:攻击者未经授权,拿到了一部分组织存在平台上的环境变量。官方说已经封堵了被利用的漏洞,并给受影响的账号所有者发了邮件,告诉他们怎么处理。

这提醒我们:除了不让本地的 AI 工具读到密钥,存在 CI、任务平台、托管平台上的密钥也一样有风险。几个习惯:

  • 不同的服务、不同的用途分别用不同的 Key,权限给到够用就行;出了事只作废那一把。灵眸控制台里也可以为不同用途分别建 Key。
  • 收到平台的安全通知后,第一时间轮换相关的 Key,不要等确认受影响了再动。
  • 定期清点一下:你的 API Key 都存在了哪些平台上。