Claude Code 安全最佳实践完全指南:API密钥管理、权限设置与生产环境保护
安全使用 Claude Code 的实战指南。从 API 密钥管理到权限配置、基于 Hooks 的自动化检查,再到生产环境保护——附带可直接运行的代码示例。
Claude Code 拥有强大的文件操作和命令执行能力,但配置不当可能导致无法挽回的事故。提交 .env 文件、误删生产数据库、将 API 密钥输出到日志——这些都是实际发生过的案例,根源在于没有对 Claude Code 做任何安全防护。
本文从实现层面详细介绍 Claude Code 的安全防护措施,重点不在于概念讲解,而是提供可以直接复制使用的配置和预防代码。
为什么 Claude Code 需要安全措施
与普通文本编辑器不同,Claude Code 具备以下能力:
- 读取、写入、删除任意文件 (
Read/Write/Edit/Bash(rm)) - 执行 Shell 命令 (
Bash) - 网络访问 (
WebFetch/ API 调用) - 向外部服务发布内容 (GitHub、Slack 等)
这些操作只要用户批准就能执行。问题在于:如果机械式地一直点确认,意外操作就会悄然通过。安全措施的本质是从结构上消除出错的空间。
措施1:API 密钥管理——.env + .gitignore 是基础
绝对不能做的事
// ❌ 直接写在源代码里
const client = new Anthropic({ apiKey: "PASTE_REAL_API_KEY_HERE" });
// ❌ 写在 CLAUDE.md 或配置文件里
// ANTHROPIC_API_KEY=PASTE_REAL_API_KEY_HERE
// ❌ 写在 claude -p 的提示词里
// 使用 QIITA_TOKEN=PASTE_REAL_TOKEN_HERE 发布到 Qiita
正确的管理方式
# .env(排除在 git 之外,仅存于本机)
ANTHROPIC_API_KEY=<anthropic-api-key>
QIITA_TOKEN=<qiita-token>
SLACK_BOT_TOKEN=<slack-bot-token>
DATABASE_URL=postgresql://...
# 必须加入 .gitignore
.env
.env.*
.env.local
!.env.example # ← 示例文件可以提交
*.pem
*.key
credentials.json
*-service-account.json
# .env.example(可以提交,值留空)
ANTHROPIC_API_KEY=
QIITA_TOKEN=
SLACK_BOT_TOKEN=
DATABASE_URL=
在代码中读取变量
// ✅ 从环境变量读取
import { config } from "dotenv";
config();
const token = process.env.QIITA_TOKEN;
if (!token) throw new Error("QIITA_TOKEN 未设置,请检查 .env 文件。");
在 CLAUDE.md 中明确禁止事项
## 安全禁止事项
- 不在提示词中包含 API 密钥或 Token
- 不读取并输出 .env 文件的内容
- 不将环境变量的值写入日志或注释
- 不对 process.env 的内容使用 console.log
措施2:提交前扫描敏感信息
即使将 .env 加入 gitignore,也无法防止误写入其他文件或复制粘贴失误。需要引入提交前自动扫描机制。
使用 Hooks 实现提交前检查
.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash(git commit*)",
"hooks": [
{
"type": "command",
"command": "node scripts/secret-scan.mjs"
}
]
}
]
}
}
scripts/secret-scan.mjs:
import { execSync } from "child_process";
// 获取已暂存的变更
const diff = execSync("git diff --cached").toString();
const PATTERNS = [
{ name: "Anthropic API 密钥配置", re: /\b(?:ANTHROPIC_API_KEY|CLAUDE_API_KEY)\s*[:=]\s*["']?[^"'\s]{20,}/i },
{ name: "OpenAI API 密钥配置", re: /\bOPENAI_API_KEY\s*[:=]\s*["']?[^"'\s]{20,}/i },
{ name: "AWS 访问密钥", re: /\bAKIA[0-9A-Z]{16}\b/ },
{ name: "Slack Token", re: /\bxox[baprs]-[0-9A-Za-z-]{10,}\b/ },
{ name: "通用密钥", re: /\b(?:secret|token|api[_-]?key|password)\s*[:=]\s*["'][^"']{10,}["']/i },
];
const found = PATTERNS.filter(({ re }) => re.test(diff));
if (found.length > 0) {
console.error("🚨 发现敏感信息!已中止提交:");
found.forEach(({ name }) => console.error(` - ${name}`));
console.error("\n处理方法:运行 `git reset HEAD <file>` 取消暂存该文件");
process.exit(1); // 退出码 1 → Hook 阻止命令执行
}
console.log("✓ 敏感信息扫描:未发现问题");
process.exit(0);
这样,Claude Code 尝试执行 git commit 的瞬间,自动扫描就会启动,一旦检测到泄露即被拦截。
措施3:权限模式配置
Claude Code 的允许/拒绝设置可以在文件级别进行细粒度控制。
.claude/settings.json 的权限配置
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"defaultMode": "default",
"disableBypassPermissionsMode": "disable",
"allow": [
"Read(**)",
"Glob(**)",
"Grep(**)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(rm -rf*)",
"Bash(git push --force*)",
"Bash(git reset --hard*)",
"Bash(DROP TABLE*)",
"Bash(truncate*)",
"Bash(curl * | bash)",
"Bash(wget * | sh)"
],
"ask": [
"Write(**)",
"Edit(**)",
"Bash(git commit*)",
"Bash(git push*)",
"Bash(npm publish*)",
"Bash(wrangler pages deploy*)"
]
},
"disableAutoMode": "disable"
}
| 设置 | 含义 |
|---|---|
allow | 无需确认,直接执行 |
deny | 完全禁止执行 |
ask | 每次都需要审批 |
要点:破坏性命令放 deny,写入操作放 ask,读取操作放 allow。
用 local 或 managed settings 区分生产与组织策略
官方 Docs 中的设置作用域按 managed、命令行参数、local、project、user 的顺序生效。与其依赖非官方的自定义文件切换方式,不如在个人生产维护机器上使用 .claude/settings.local.json,在组织内使用 managed settings。
.claude/settings.local.json 只用于本机覆盖配置,不提交到 git。
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"defaultMode": "plan",
"disableBypassPermissionsMode": "disable",
"allow": ["Read(**)", "Glob(**)", "Grep(**)", "Bash(git log*)", "Bash(git diff*)"],
"deny": ["Write(**)", "Edit(**)", "Bash(git push*)", "Bash(rm*)", "Bash(*deploy*)"],
"ask": []
},
"disableAutoMode": "disable"
}
如果要在团队或公司层面强制执行,请放入 managed settings。启用 allowManagedPermissionRulesOnly 后,用户和项目仓库无法用自己的 allow / ask / deny 规则绕过组织策略。
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(curl *)"
],
"disableBypassPermissionsMode": "disable"
},
"disableAutoMode": "disable",
"allowManagedPermissionRulesOnly": true
}
措施4:生产环境保护
明确隔离连接目标
## CLAUDE.md — 生产环境规则
## 环境判断
- DATABASE_URL 中包含 'prod' 或 'production' 时,视为**生产环境**
- 在生产环境中,以下操作绝对禁止:
- DROP / TRUNCATE / DELETE(无 WHERE 条件)
- 数据库迁移(需提前确认)
- 批量删除文件
## 确认流程
对生产环境的任何变更,必须:
1. 在预发布环境中先行测试
2. 获得用户确认
3. 执行后报告结果
用环境变量控制连接目标
// scripts/db-query.mjs
const env = process.env.NODE_ENV ?? "development";
const dbUrl = process.env.DATABASE_URL;
if (env === "production" && process.argv.includes("--write")) {
console.error("❌ 向生产环境写入需要 --force-production 标志");
process.exit(1);
}
措施5:文件操作安全装置
自动化删除前备份
// .claude/settings.json 中的 Hooks
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash(rm *)",
"hooks": [
{
"type": "command",
"command": "echo '⚠️ 删除命令即将执行,按 Ctrl+C 可中止。' && sleep 3"
}
]
}
]
}
}
防止重要文件被误编辑
## CLAUDE.md — 禁止修改的文件
以下文件**绝对不得编辑**:
- .env(包含环境变量和密钥)
- wrangler.toml(Cloudflare 生产配置)
- scripts/deploy.sh(部署脚本)
- .github/workflows/*.yml(CI/CD 配置)
如确需修改,请先征得用户同意。
五大常见误区
1. 事后再加 .gitignore 已为时太晚
已经提交过的 .env 即使加入 gitignore,也依然留在 git 历史中。
# 从历史中彻底删除(注意:需要 force push)
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch .env" \
--prune-empty --tag-name-filter cat -- --all
# 或者使用 BFG Repo Cleaner
如果已经推送到 GitHub,请务必先轮换 API 密钥再处理历史记录。
2. 将服务账号 JSON 文件放入代码仓库
Google Cloud 或 AWS 的服务账号密钥通常以 .json 文件形式下发,但存入代码仓库十分危险。请将其转为环境变量,或迁移至 Secret Manager(AWS Secrets Manager / GCP Secret Manager)。
3. 用 Bash 工具执行交互式命令
在 claude -p 无头运行时,如果混入了需要交互输入的命令(如 sudo、vim),进程会挂起。请只使用非交互式命令。
4. 在错误信息中包含凭据
// ❌ 危险:API 密钥会出现在日志中
throw new Error(`认证失败:token=${process.env.TOKEN}`);
// ✅ 安全:不输出具体值
throw new Error(`认证失败:请检查 TOKEN 环境变量`);
5. 所有项目共用同一份权限配置
个人项目和工作项目使用同一份 settings.json,会导致工作项目所需的严格限制被个人项目宽松的配置覆盖。请为每个项目单独管理 .claude/settings.json。
实务中的运行规则
不把秘密信息交给 Claude Code
让 Claude Code “帮我修这个错误”时,不要直接粘贴完整日志或 .env 内容。团队应事先约定:API 密钥、OAuth token、cookie、数据库连接串、客户邮箱、账单 ID、私钥,一律不进入 prompt、issue 评论或聊天记录。
需要上下文时,只保留结构,具体值用 ***REDACTED*** 替换。例如 DATABASE_URL=***REDACTED*** 足以让 Claude Code 理解这里有数据库连接配置,真实值通常不是排查代码问题所必需的。
| 可以交给 Claude Code | 不应交给 Claude Code |
|---|---|
| 错误类型、堆栈中的文件名、复现步骤 | API 密钥、私钥、session cookie、真实 .env 值 |
.env.example、配置项名称、权限规则、失败命令 | 生产数据库 URL、客户数据、内部认证信息 |
| 脱敏日志、测试数据、本地示例值 | 真实 token、服务账号 JSON、含秘密信息的截图 |
建议把这张表写进 CLAUDE.md。对于团队来说,“不暴露秘密信息”应当是明确的操作规则,而不是靠每个人临时判断。
提交前扫描要做两层以上
上面的 PreToolUse Hook 可以拦截 Claude Code 发起的 git commit。但人也可能从另一个终端提交,CI 也可能生成含秘密信息的文件。因此实务中至少叠加三层:Claude Code Hook、本地 pre-commit、CI secret scan。
最低配置是:本地 Hook 先挡一次,CI 再检查一次,发现秘密信息时阻止合并。gitleaks 或 trufflehog 这类专用工具更适合 CI 规模的检测,而本文的脚本适合作为本地早期预警。
具体失败例
失败例1:排查时让 Claude Code 读取 .env
开发者让 Claude Code “确认环境变量”,结果真实值进入会话或工作日志。对策是 deny .env 读取,只提供 .env.example。
失败例2:把 Qiita 发布 token 贴进 prompt
自动发布任务把 QIITA_TOKEN 直接写进 prompt,subagent 或日志可能会保留它。更安全的做法是把 token 放在 .env,命令只引用环境变量名。
失败例3:生产库和测试库 URL 太像
指令只写“整理数据库”,没有确认连接目标。如果实际连接到生产库,删除或迁移就会变成事故。写入前应显示 NODE_ENV、host、database name,并要求用户明确确认。
事故后的初动
怀疑秘密信息泄露时,第一步不是清理历史,而是让凭据失效。
- 立即轮换或撤销相关 API 密钥、token、密码
- 检查 GitHub Actions、Cloudflare、AWS、GCP、SaaS 的审计日志
- 记录谁在何时、哪个仓库、通过什么渠道暴露了什么
- 从 git 历史和日志中删除秘密信息,并同步 force push 的影响
- 更新
deny规则、Hooks、CI 扫描和CLAUDE.md禁止事项
实际试用后可以明显感到,先停用凭据、再清理历史,比一边调查一边改历史更不容易误判。事故处理中最容易再次粘贴原始日志,所以提前准备脱敏日志模板很重要。
教材与咨询的自然衔接
Claude Code 安全不是一个 settings 文件就能解决的。还需要一起检查仓库结构、CI、部署权限和团队审批流程。
ClaudeCodeLab 的个人学习路径会先从 .env 管理和 permission rules 入手;团队咨询则优先确认 managed settings 在哪里强制、CI secret scan 在哪里阻止合并。如果已经在工作中使用 Claude Code,第一步应是梳理谁可能接触哪些秘密信息,再细调权限规则。
安全检查清单
引入 Claude Code 项目时的确认事项:
### 基础配置
- [ ] 已创建 .env 并添加到 .gitignore
- [ ] 已创建 .env.example 并与团队共享
- [ ] 通过 git log 确认现有提交中无敏感信息
### 权限配置
- [ ] 已在 .claude/settings.json 中配置 deny 列表
- [ ] 已将破坏性命令(rm -rf、DROP TABLE 等)加入 deny
- [ ] 已将生产部署命令设置为 ask
### 自动化
- [ ] 已配置提交前敏感信息扫描 Hook
- [ ] 已在 CLAUDE.md 中记录安全禁止事项
### 运维
- [ ] 已制定 API 密钥轮换周期(推荐:90天)
- [ ] 生产作业使用 .claude/settings.local.json 或 managed settings 限制
- [ ] 已将事故响应流程文档化
总结
Claude Code 的安全不是”施加限制”,而是**“构建一个从结构上杜绝事故的体系”**。
| 威胁 | 对策 |
|---|---|
| API 密钥泄露 | .env + .gitignore + 敏感信息扫描 Hook |
| 误删文件 | deny 列表 + 删除前 Hook |
| 误操作生产环境 | local/managed settings + CLAUDE.md 禁止事项 |
| 提交污染 | PreToolUse Hook 提交前扫描 |
配置一次,基本免维护。今天花30分钟完成配置,可以避免未来的重大事故。
相关文章
参考资料
免费 PDF: Claude Code 速查表
输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。
我们会妥善保护你的信息,不发送垃圾邮件。
把 Claude Code 变成真正能带来结果的工作流
先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。
关于作者
Masa
专注 Claude Code 实务流程、团队导入和内容转化的工程师。
相关文章
Claude Code 验证回执工作流:用 build、公开 URL、CTA 和截图证明 AI 修改
Claude Code 修改后的验证回执流程:记录差异、build、公开 URL、CTA、截图和收入路径检查。
Claude Code Permission Budget Loop: 不必每条命令都审批,也能安全推进
为 Claude Code 设计 permission budget,让安全工作快速运行,同时保护 secrets、deploy、billing 与数据。
Claude Code 提示词库维护:把一次性指令变成资产
为 Claude Code 提示词命名、测试、复用,让它从免费 PDF 学习自然连接到付费模板包。