《Claude Code 工程化实战》第 32 讲 企业级 Claude Code 部署清单
📌 本讲摘要 · Claude Code 在企业里落地,真正的难点不是能不能用、而是敢不敢用。安全与治理覆盖三条防线:权限模型决定 Agent 能做什么,凭据管理决定 Agent 能访问什么,审计与可观测决定事后能查清楚什么。本讲给出一份从 0 到生产环境的 12 道关部署清单、settings.json 权限模板、PII 脱敏 Hook、审计日志结构化方案与应急响应 Playbook。学完本讲,你应该能在 1 个工作日内,把团队从几个开发私下用 Claude Code,推进到全员合规接入 SSO + 审计 + 沙箱的企业级状态。
1. 部署清单:从 0 到生产必须过的 12 道关
在企业里推广 Claude Code,常见误区是先让大家用起来、出问题再说。这条路走 3 个月,大概率会因为一次安全事故被一票否决。正确节奏是先建防线、再放使用、最后做优化。
| 阶段 | 关卡 | 必须做到 | 未做后果 |
|---|---|---|---|
| 阶段 1 · 凭据与访问 | 关 1 · 凭据托管 | API key 走 Vault / SSO、不入 .env | 开发离职带走 key、公司持续付费 |
| 关 2 · 团队档位 | 统一企业账户 + inherit 模型档位 | 个人账户混用、无法审计 | |
| 关 3 · 角色权限 | 管理员 / 开发者 / 只读 三档 | 实习生能改全局 settings | |
| 阶段 2 · 工具与文件 | 关 4 · Bash 沙箱 | 默认 allow-list + 危险命令 deny | Agent 误删数据库 |
| 关 5 · 路径白名单 | 限制 Agent 读 / 写哪些目录 | Agent 读到 SSH key / .aws/credentials | |
| 关 6 · 网络出口 | 用代理白名单 / 镜像 | Agent 调任意公网 API 出域 | |
| 阶段 3 · 数据与合规 | 关 7 · PII 脱敏 | Hook 拦截身份证 / 手机号 / 卡号 | 用户数据被发到模型端 |
| 关 8 · 审计日志 | 结构化记录每次工具调用 | 事后无法回溯谁改了什么 | |
| 关 9 · 数据驻留 | 明确数据落在哪、合规区在哪 | 跨境数据传输违规 | |
| 阶段 4 · 应急与运营 | 关 10 · 应急 Playbook | 事前写好出事时怎么止血 | 事故现场 30 分钟内无人决策 |
| 关 11 · 灰度发布 | Skill / Hook 改动先 1 人试用再全量 | 一次 Hook 改动锁住所有 Agent | |
| 关 12 · 定期演练 | 季度做一次模拟 key 泄露演练 | 真正泄露时手忙脚乱 |
这 12 关不是都做完了才能用、而是做多少、决定你能放心让多少人在生产里用。一个 5 人小团队,把阶段 1 的 3 关做掉,基本就能放心跑起来了。
⚠️ 坑 1 · 把安全当一次性的事、等出了事故才补——Claude Code 治理是持续运营、不是上线检查表。建议每季度过一次清单,任何新 Skill / Hook 改动前也都过一遍相关关卡。
2. 权限模型:allow / deny / ask 与 paths 匹配
Claude Code 的权限系统分三层:工具级(允许用哪个工具)、命令级(Bash 允许执行什么命令)、路径级(读 / 写哪些文件)。三层组合起来,基本能覆盖 90% 的安全需求。
实战代码块 1 — 企业级 settings.json 权限配置。这是团队级 .claude/settings.json 的范本,锁死危险操作,放行日常开发。
{
"$schema": "https://docs.claude.com/schema/settings.json",
"permissions": {
"defaultMode": "acceptEdits",
"allow": [
"Bash(pnpm run:*)",
"Bash(git status)",
"Bash(git diff:*)",
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(grep:*)",
"Bash(find:*)",
"Read(src/**)",
"Read(tests/**)",
"Read(package.json)",
"Read(README.md)",
"Edit(src/**)",
"Edit(tests/**)"
],
"deny": [
"Bash(rm -rf:*)",
"Bash(curl:*)",
"Bash(wget:*)",
"Bash(sudo:*)",
"Bash(chmod 777:*)",
"Bash(dd:*)",
"Bash(mkfs:*)",
"Read(.env)",
"Read(.env.*)",
"Read(**/.ssh/**)",
"Read(**/.aws/**)",
"Read(**/.kube/**)",
"Read(**/id_rsa*)",
"Read(**/secrets/**)",
"Edit(.env)",
"Edit(.env.*)",
"Edit(**/secrets/**)",
"Edit(.claude/settings.json)"
],
"ask": [
"Bash(git push:*)",
"Bash(git checkout main)",
"Bash(pnpm install:*)",
"Bash(npm publish:*)",
"Bash(docker:*)",
"Bash(kubectl:*)"
]
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/pii-guard.sh",
"timeout": 5
}
]
}
]
}
}
三个模式的语义:
- allow:直接放行、不弹确认对话框(高频低危)
- deny:直接拒绝、Agent 看不到这个工具/命令/路径(危险操作)
- ask:每次执行前弹确认(低频高危)
注意 deny 里的 Read(.env) 和 Read(**/.ssh/**)——这是把凭据泄露这个最常见的事故场景从根上掐死。即使 Agent 想读 SSH key 来帮我配置部署,也会直接拒绝;开发者看到拒绝提示后,再手动加 allow 一次即可。
⚠️ 坑 2 · 用
defaultMode: "bypassPermissions"跳过所有确认——开发一时爽、出事故火葬场。这个开关只适合完全沙箱化的 CI 环境,不适合本地开发。
3. 凭据管理:API key、OAuth、SSH key 的安全姿态
凭据泄露是 Claude Code 事故里的 No.1。要么是 Agent 误把 .env 写进 git commit,要么是 Agent 读 .ssh/id_rsa 然后用 Bash 把它发出去。三个层级的防护:
| 凭据类型 | 危险做法 | 推荐做法 | 检测手段 |
|---|---|---|---|
| API key | 明文写在 ~/.bashrc / .zshrc | 走 1Password / Vault、Claude Code 通过 op run 注入 |
Hook 扫描内存中的明文 key |
| OAuth token | 放在项目根目录 .token | 走 SSO、Claude Code 走 claude auth login |
定期 rotate + 监控异常调用 |
| SSH key | ~/.ssh/id_rsa 默认 600 权限 | 用 ssh-agent 转发、不要让 Agent 直接读私钥 | deny Read **/.ssh/id_* |
核心原则:让 Agent 用 token / 临时凭证,而不是直接持有长期有效的私钥。Agent 完成工作后、临时凭证就过期,泄露面大大缩小。
4. 审计与可观测:Hook 日志、调用链、合规留痕
实战代码块 2 — PII 脱敏 Hook。这是挂在 PreToolUse: Bash 上的一个真实可用脚本,作用是:Agent 执行 Bash 命令前,先扫描命令字符串,看是否包含手机号、身份证号、银行卡号等 PII,有则拒绝执行。
# .claude/hooks/pii-guard.sh
#!/usr/bin/env bash
# 拦截包含 PII 的 Bash 命令
# Claude Code 通过 stdin 传入 JSON,字段 tool_input.command
set -euo pipefail
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
# 中国大陆手机号
if echo "$CMD" | grep -qE '\b1[3-9][0-9]{9}\b'; then
echo "❌ 拒绝:检测到中国大陆手机号" >&2
echo "💡 提示:请使用脱敏占位符,如 138****1234" >&2
exit 2
fi
# 18 位身份证号
if echo "$CMD" | grep -qE '\b[1-9][0-9]{16}[0-9Xx]\b'; then
echo "❌ 拒绝:检测到身份证号" >&2
exit 2
fi
# 16-19 位银行卡号(简单匹配)
if echo "$CMD" | grep -qE '\b[0-9]{16,19}\b'; then
echo "❌ 拒绝:检测到疑似银行卡号" >&2
exit 2
fi
# AWS Access Key
if echo "$CMD" | grep -qE 'AKIA[0-9A-Z]{16}'; then
echo "❌ 拒绝:检测到 AWS Access Key" >&2
exit 2
fi
exit 0
Hook 的退出码语义:退出 0 = 放行、退出 2 = 拒绝(Claude Code 会把 stderr 作为错误信息反馈给 Agent)。这个 PII 脱敏逻辑非常朴素,生产环境建议接一个真实的 PII 检测服务(如 Microsoft Presidio),准确率会高得多。
实战代码块 3 — 审计日志结构化输出。把每次工具调用落到 JSON Lines 文件,后续可以直接灌进 ELK / Loki 做查询和告警。
# .claude/hooks/audit-log.sh
#!/usr/bin/env bash
# 记录每次工具调用,挂到 PostToolUse
# 输出 .claude/audit.jsonl,每行一条 JSON
set -euo pipefail
INPUT=$(cat)
LOG_FILE=".claude/audit.jsonl"
mkdir -p .claude
# 提取关键字段
TIMESTAMP=$(date -Iseconds)
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // "unknown"')
TOOL_INPUT=$(echo "$INPUT" | jq -c '.tool_input // {}')
TOOL_RESULT=$(echo "$INPUT" | jq -c '.tool_result // {}' | head -c 500)
# 结构化输出(单行 JSON)
jq -nc \
--arg ts "$TIMESTAMP" \
--arg sid "$SESSION_ID" \
--arg tool "$TOOL_NAME" \
--argjson input "$TOOL_INPUT" \
--argjson result "$TOOL_RESULT" \
'{timestamp: $ts, session_id: $sid, tool: $tool, input: $input, result_preview: $result}' \
>> "$LOG_FILE"
exit 0
审计日志的四个查询场景:
- 谁改了 prod 配置? →
jq 'select(.tool=="Edit" and .input.file_path | contains("prod")' audit.jsonl - 昨天 18 点谁在跑 docker? →
jq 'select(.tool=="Bash" and .input.command | contains("docker")' audit.jsonl - 某用户跑了多少工具? →
jq 'select(.session_id=="...") | .tool' audit.jsonl | sort | uniq -c - 是否有 PII 触发了拦截? →
grep "PII 拒绝" pii-guard.log
⚠️ 坑 3 · 把审计日志直接落进 git——审计日志里可能有"谁在跑 rm -rf"这类敏感操作,这种东西只该留在服务器本地,或者独立加密存储。
5. 数据出域防护:敏感信息脱敏、PII 过滤、文件 exclude
三条防线:
- 进 Hook(第 4 节已讲):Agent 要发出去的内容,先扫一遍 PII
- 出 Hook:Agent 的输出如果含敏感路径(如
/Users/xxx/Desktop/xxx),自动打码 - 文件 exclude:在
.claudeignore里把敏感目录排除,Agent 根本看不到
# .claudeignore
# Claude Code 读不到这些路径,跟 .gitignore 语法一致
# 凭据
.env
.env.*
**/.ssh/**
**/.aws/**
**/.kube/**
**/id_rsa*
**/id_ed25519*
**/*.pem
**/*.key
**/secrets/**
# 内部文档
**/internal-docs/**
**/confidential/**
# 大文件(防止 Token 爆炸)
**/*.log
**/*.zip
**/*.tar.gz
node_modules/
dist/
build/
6. 应急响应:出错时如何快速止血
实战代码块 4 — 应急响应 Playbook。把出事时怎么办提前写成 markdown,贴在团队 wiki 第一屏。
# Claude Code 应急响应 Playbook(精简版)
## 等级 1 · Agent 误操作(开发自己发现)
1. /rewind 回到上一步
2. git diff 确认改动范围
3. git checkout / git restore 回退
4. 写一段后见记录:为什么 Agent 误操作?是 prompt 不够明确,还是权限过宽?
## 等级 2 · 凭据可能泄露(怀疑 key 进了 prompt)
1. 立刻 rotate 该 key
2. 查 audit.jsonl 确认 Agent 是否真的发出去了
3. 通知安全团队 + 业务方
4. 检查下游服务是否有异常调用
## 等级 3 · Agent 执行了破坏性命令(如 rm -rf 误打到 /)
1. 立刻 kill 所有 claude 进程:`pkill -f claude`
2. 检查文件系统:`ls -la / | head` 看是否还在
3. 查 audit.jsonl 找到破坏起点
4. 从最近的 git commit / 备份恢复
5. 复盘:为什么 deny 规则没拦住?补 deny 规则
## 等级 4 · PII / 用户数据疑似出域
1. 立刻停用所有 Claude Code 实例
2. 通知 DPO(数据保护官)+ 法务
3. 72 小时内评估是否触发监管报告义务
4. 复盘:为什么 PII 没被脱敏?Hook 配置还是业务逻辑?
## 等级 5 · 大规模 key 泄露(例如 .env 被 commit)
1. 立刻 rotate 所有相关 key
2. git filter-repo 清理历史
3. 强制推送到远端(如果有)
4. 通知所有受影响方
5. 72 小时内提交事故复盘报告
Playbook 的核心是分级 + 动作清单 + 责任人:等级 1 自己搞定,等级 2 找安全团队,等级 3 找运维,等级 4 找 DPO,等级 5 全员。
⚠️ 坑 4 · 出事故现场才写 Playbook——现场手忙脚乱、该 rotate 的 key 没 rotate、该通知的人没通知、该补的 deny 规则没人补。Playbook 必须事前写好,并定期演练。
7. 一句话备忘
🛡️ 安全的反面不是不方便,而是出一次事故就再也用不了。先建防线、再放使用。
更多推荐

所有评论(0)