04 进阶篇:权限、Hooks 与自动化
精细控制 Claude Code 的行为边界,让 AI 安全地为你工作。
4.1 分层权限系统
Claude Code 的权限系统分为三层:
权限模式(粗粒度) → allow/deny 规则(细粒度) → 沙盒(隔离层)
权限模式回顾
| 模式 | 读取 | 编辑 | 命令 | 切换方式 |
|---|---|---|---|---|
| 普通模式 | 自动 | 需确认 | 需确认 | Shift+Tab |
| 自动接受编辑 | 自动 | 自动 | 需确认 | Shift+Tab |
| 计划模式 | 自动 | 不执行 | 不执行 | Shift+Tab |
4.2 allow/deny 规则配置
配置文件位置
| 文件 | 作用范围 | 优先级 |
|---|---|---|
~/.claude/settings.json |
全局(所有项目) | 低 |
.claude/settings.json |
项目(团队共享) | 中 |
.claude/settings.local.json |
项目(个人) | 高 |
规则语法
json
{
"permissions": {
"allow": [
"Read",
"Glob",
"Grep",
"Bash(npm run test)",
"Bash(npm run build)",
"Bash(git status)",
"Bash(git diff)",
"Bash(git log*)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force)",
"Bash(curl * | bash)",
"Read(./.env*)",
"Read(./**/secrets/*)"
]
}
}
规则匹配模式
| 模式 | 含义 | 示例 |
|---|---|---|
Read |
允许/拒绝所有读取 | 读取任意文件 |
Write |
允许/拒绝所有写入 | 修改任意文件 |
Bash(npm run test) |
精确匹配命令 | 仅匹配 npm run test |
Bash(npm run:*) |
前缀匹配(冒号分隔) | 匹配 npm run test、npm run build 等 |
Bash(git *) |
通配符匹配 | 匹配所有 git 命令 |
Read(./.env*) |
Glob 匹配文件路径 | 匹配 .env、.env.local 等 |
实战配置示例
前端项目:
json
{
"permissions": {
"allow": [
"Read",
"Glob",
"Grep",
"Bash(npm run:*)",
"Bash(npx:*)",
"Bash(git *)",
"Bash(node *)"
],
"deny": [
"Bash(npm publish*)",
"Bash(git push --force*)",
"Read(./.env*)"
]
}
}
Python 项目:
json
{
"permissions": {
"allow": [
"Read",
"Glob",
"Grep",
"Bash(python *)",
"Bash(pytest *)",
"Bash(pip install *)",
"Bash(git *)",
"Bash(poetry *)"
],
"deny": [
"Bash(pip install --user *)",
"Bash(git push --force*)",
"Read(./**/credentials*)"
]
}
}
最佳实践:
- 先用普通模式观察 Claude 常用哪些命令,再逐步添加 allow 规则
- 始终添加 deny 规则保护危险操作(
rm -rf、git push --force)- 敏感文件用
Read(./path*)deny 规则保护- 不要使用
--dangerously-skip-permissions,除非在 CI 等受信环境
4.3 Hooks 系统
Hooks 是 Claude Code 的自动化引擎,在特定生命周期事件触发时执行自定义命令。
8 大生命周期事件
| 事件 | 触发时机 | 可用变量 | 能否阻断 | 典型用途 |
|---|---|---|---|---|
SessionStart |
会话开始 | 无 | 否 | 环境初始化 |
UserPromptSubmit |
用户按回车前 | prompt |
是 | 危险指令过滤 |
PreToolUse |
工具执行前 | tool_name, tool_input |
是 | 权限审计 |
PostToolUse |
工具执行后 | tool_name, tool_input, tool_output |
否 | 自动格式化 |
Notification |
Claude 需要用户输入 | notification_text |
否 | 桌面通知 |
Stop |
响应完全结束 | 无 | 否 | 摘要日志 |
SubagentStop |
子代理任务结束 | subagent_name, result |
否 | 子任务统计 |
PreCompact |
对话压缩前 | 无 | 否 | 备份历史 |
Hook 配置结构
json
{
"hooks": {
"事件名": [
{
"matcher": "匹配模式(正则)",
"hooks": [
{
"type": "command",
"command": "要执行的 shell 命令"
}
]
}
]
}
}
可用环境变量
| 变量 | 含义 | 适用事件 |
|---|---|---|
$CLAUDE_TOOL_NAME |
被调用的工具名 | PreToolUse, PostToolUse |
$CLAUDE_TOOL_INPUT |
工具输入(JSON) | PreToolUse, PostToolUse |
$CLAUDE_TOOL_INPUT_FILE_PATH |
文件路径 | 文件操作工具 |
$CLAUDE_TOOL_OUTPUT |
工具输出(JSON) | PostToolUse |
$CLAUDE_PROMPT |
用户提示文本 | UserPromptSubmit |
4.4 Hook 实战示例
示例一:自动格式化(PostToolUse)
每次 Claude 编辑文件后自动运行 Prettier:
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write \"$CLAUDE_TOOL_INPUT_FILE_PATH\" 2>/dev/null || true"
}
]
}
]
}
}
示例二:ESLint 检查(PostToolUse)
编辑 JS/TS 文件后自动 lint:
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npx eslint \"$CLAUDE_TOOL_INPUT_FILE_PATH\" --fix 2>/dev/null || true"
}
]
}
]
}
}
示例三:安全审计(PreToolUse)
阻止 Claude 读取敏感文件:
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Read",
"hooks": [
{
"type": "command",
"command": "echo \"$CLAUDE_TOOL_INPUT\" | jq -r '.file_path' | grep -qE '\\.(env|key|pem)$' && echo 'BLOCK: 不允许读取敏感文件' && exit 1 || exit 0"
}
]
}
]
}
}
示例四:桌面通知(Notification)
Claude 需要输入时发送系统通知:
json
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code 需要你的输入\" with title \"Claude Code\"'"
}
]
}
]
}
}
Linux 替代方案:
json
{
"command": "notify-send 'Claude Code' '需要你的输入'"
}
Windows 替代方案:
json
{
"command": "powershell -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code 需要你的输入', 'Claude Code')\""
}
示例五:会话日志(Stop)
每次会话结束记录摘要:
json
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "echo \"[$(date '+%Y-%m-%d %H:%M')] Session ended in $(pwd)\" >> ~/.claude/session-log.txt"
}
]
}
]
}
}
示例六:Python 自动格式化(PostToolUse)
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "echo \"$CLAUDE_TOOL_INPUT\" | jq -r '.file_path' | grep -qE '\\.py$' && black \"$CLAUDE_TOOL_INPUT_FILE_PATH\" 2>/dev/null || true"
}
]
}
]
}
}
4.5 自动化工作流
工作流一:代码质量门禁
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "FILE=\"$CLAUDE_TOOL_INPUT_FILE_PATH\"; case \"$FILE\" in *.py) black \"$FILE\" && flake8 \"$FILE\";; *.ts|*.tsx) npx prettier --write \"$FILE\" && npx eslint \"$FILE\" --fix;; *.go) gofmt -w \"$FILE\";; esac 2>/dev/null || true"
}
]
}
]
}
}
工作流二:自动测试
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "FILE=\"$CLAUDE_TOOL_INPUT_FILE_PATH\"; case \"$FILE\" in *test*.py) pytest \"$FILE\" -q;; *test*.ts) npx jest \"$FILE\";; esac 2>/dev/null || true"
}
]
}
]
}
}
工作流三:Git 安全防护
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo \"$CLAUDE_TOOL_INPUT\" | jq -r '.command' | grep -qiE '(push --force|reset --hard|clean -f|rm -rf /)' && echo 'BLOCK: 危险 Git 操作被阻止' && exit 1 || exit 0"
}
]
}
]
}
}
4.6 沙盒模式
在隔离环境中运行命令,防止意外损害:
json
{
"security": {
"sandbox": true
}
}
沙盒模式下,Claude 执行的命令被限制在安全范围内。
最佳实践:生产环境或共享服务器上建议开启沙盒模式。
4.7 Hook 注意事项
| 注意事项 | 说明 |
|---|---|
| 保持轻量 | Hook 在每次工具调用时执行,慢 Hook 会严重拖慢体验 |
| 错误容忍 | 用 `2>/dev/null |
| matcher 是正则 | `"Write |
| 阻断返回非零 | PreToolUse Hook exit 1 会阻断工具执行 |
| 配置位置 | 全局 ~/.claude/settings.json 或项目 .claude/settings.local.json |
4.8 小结
| 概念 | 关键要点 |
|---|---|
| 权限模式 | 三种模式,Shift+Tab 切换 |
| allow/deny | 细粒度控制,支持精确匹配和通配符 |
| Hooks | 8 大生命周期事件,实现自动化 |
| 常用 Hook | 格式化、lint、安全审计、通知 |
| 沙盒 | 生产环境建议开启 |
| Hook 原则 | 轻量、容错、正则匹配 |
下一篇 :05 实战篇:MCP 服务器与技能扩展