来源:https://academy.claude.com/courses/ai-native-sdlc-playbook/hooks-as-approval-gates 读这篇之前:可直接读;06 已区分劝告性 skill 和确定性 hook 不确定:ZH 是 Clint 译官方英文课体,不是 Anthropic 中文。
本课词汇
| English | 中文 | 怎么记 |
|---|---|---|
| hook | 钩子 | Claude 动手前允许 / 询问 / 拦住 |
| managed settings | 托管设置 | MDM 或管理控制台下发,工程师关不掉 |
| PreToolUse | 用工具前 | 例子里匹配 Bash,再跑 production-gate.sh |
| sandbox | 沙箱 | 操作系统级文件系统和网络隔离 |
| allowManagedHooksOnly | 只跑托管 hooks | 项目里的 .claude/settings.json 会被拦住 |
| requiredMinimumVersion | 最低版本 | 低于批准下限拒绝启动 |
对照正文
EN The build phase used hooks as guardrails, allowing or blocking actions with no human involved (Stage 3: Build). A hook can also ask, pausing the action until a specific person approves, which is what release gating needs.
ZH 构建阶段把 hooks 当护栏,允许或拦住动作,不经过人(Stage 3: Build)。Hook 也可以问:动作暂停,直到特定的人批准——发布闸需要的就是这个。
EN The play sits in Stage 5: Deploy because the release gate is the clearest case, but hooks are not deploy-specific: they run wherever Claude acts. For example, hooks can block edits to migrations and infra without a change ticket during Stage 3: Build, and stop the agent editing test files during a fix task in Stage 4: Test.
ZH 这条打法放在 Stage 5: Deploy,因为发布闸最清楚,但 hooks 不是发布专用:Claude 动手的地方它都跑。例如构建阶段(Stage 3: Build)没有变更单就不准改 migrations 和基础设施;测试阶段(Stage 4: Test)修缺陷时不准 agent 改测试文件。
怎么起步 / Getting started
EN - Prerequisites: None.
- Infrastructure: A written list of the approvals the change process requires.
ZH 先决条件:无。
- 基础设施:一份写下来的、变更流程必须留下的批准清单。
怎么做 / How to execute it
EN 1. Engineering leadership, with change management and compliance, lists the human approval gates that must survive, such as change management sign-off, release authorization, and edits to protected paths.
2. The platform engineer expresses each gate as a hook, a script that runs before Claude acts that can allow, ask, or block.
3. Team hooks go in .claude/settings.json in Git, and non-negotiable hooks go in managed settings owned by the platform or IT admin, where individual engineers cannot switch them off.
4. A block should explain itself, so when a hook stops an action, the reason and the route to approval appear in Claude’s output.
ZH 1. 工程领导层会同变更管理和合规,列出必须活下来的人批准闸:例如变更管理签字、发布授权、改受保护路径。
2. 平台工程师把每扇闸写成 hook:Claude 动手前跑的脚本,可以允许、询问、或拦住。
3. 团队 hooks 放 Git 里的 .claude/settings.json;不能谈的 hooks 放平台或 IT 管理员的托管设置,个别工程师关不掉。
4. 拦住要自己解释:hook 停下一个动作时,原因和怎么走批准,应出现在 Claude 的输出里。
长什么样 / What it looks like
EN A standalone example in the project’s .claude/settings.json:
ZH 项目 .claude/settings.json 里的独立例子:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/production-gate.sh" }
]
}
]
}
}
ZH 官方示例,保持英文。
EN And the gate itself (.claude/hooks/production-gate.sh):
ZH 闸本身(.claude/hooks/production-gate.sh):
#!/bin/bash
# Production deploys require a named release authorization
cmd=$(jq -r '.tool_input.command' < /dev/stdin)
if [[ "$cmd" == *"deploy"* && "$cmd" == *"production"* ]]; then
if [ -z "$RELEASE_APPROVAL" ]; then
echo "Production deploys need a release authorization." >&2
exit 2 # exit 2 blocks the action; the message goes to Claude
fi
fi
exit 0
ZH 官方示例,保持英文。
治理 / Governance considerations
EN Hooks are the approval gates. The gate condition is enforced every time, for everyone. Allow and block decisions are logged with a timestamp. The gate also defines what counts as approval, whether that’s an approved change ticket or the release manager’s sign-off.
ZH Hooks 就是审批闸门。闸门条件每次、对每个人都强制。允许和拦住的决定带时间戳记下。闸还定义什么算批准:已批的变更单,或发布经理签字。
受监管企业的 managed settings / Managed settings for a regulated enterprise
EN Managed settings for a regulated enterprise, deployed by the platform team via mobile device management (MDM) or the admin console. Engineers cannot edit or override any of the settings therein. See below:
ZH 受监管企业的托管设置,由平台团队经移动设备管理(MDM)或管理控制台下发。其中任何设置工程师都不能改、不能覆盖。见下:
{
"permissions": {
"deny": [
"Read(.env*)", "Read(./secrets/**)",
"WebFetch", "Bash(curl *)", "Bash(wget *)"
],
"allow": [
"Bash(git *)", "Bash(make build)",
"Bash(make test)", "Bash(make lint)"
],
"disableBypassPermissionsMode": "disable"
},
"allowManagedPermissionRulesOnly": true,
"sandbox": {
"enabled": true,
"failIfUnavailable": true,
"allowUnsandboxedCommands": false,
"network": { "allowedDomains": ["git.internal.example.com", "registry.npmjs.org"] },
"credentials": {
"files": [
{ "path": "~/.ssh", "mode": "deny" },
{ "path": "~/.aws/credentials", "mode": "deny" }
],
"envVars": [ { "name": "GITHUB_TOKEN", "mode": "deny" } ]
}
},
"allowManagedHooksOnly": true,
"disableSideloadFlags": true,
"allowManagedMcpServersOnly": true,
"strictKnownMarketplaces": [
{ "source": "github", "repo": "example-corp/approved-plugins" }
],
"requiredMinimumVersion": "2.1.193"
}
ZH 官方示例,保持英文。
EN What the settings do, in control terms:
ZH 这些设置在控制上做什么:
EN - permissions.deny keeps secrets out of the agent’s context and blocks arbitrary network egress through tools. permissions.allow pre-approves the safe inner loop so the deny list doesn’t turn into prompt fatigue.
disableBypassPermissionsModeplusallowManagedPermissionRulesOnlymeans no engineer, project file, or command-line flag can widen the rules.sandboxcovers what permissions cannot. A tool-level deny on WebFetch doesn’t stop a shell command reaching the network, whereas the OS-level domain allowlist blocks egress outright, so the two enforce one objective at different layers.failIfUnavailableandallowUnsandboxedCommandsturn the sandbox into a precondition, meaning Claude Code refuses to start when the sandbox cannot initialize and a command that fails inside the sandbox cannot be retried outside it.credentialshandles a case the deny rules miss.permissions.denygoverns Claude’s file tools, but a sandboxed shell command could still read~/.sshor~/.aws/credentialsby default. This block denies those reads and strips the listed secrets from the environment of sandboxed commands.allowManagedHooksOnlymeans only hooks defined in managed settings run; hooks in user, project, and local settings are blocked, including the standalone.claude/settings.jsonexample above. To keep this play’s approval gate enforced, define it in the managed file’s ownhooksblock.disableSideloadFlagsandstrictKnownMarketplacesmean that any skill, agent, hook, or MCP server on an engineer’s machine came through the organization’s approved plugin marketplace and not from a home directory. The marketplace allowlist controls what can be installed, and the flags that would sideload a plugin, agent, or MCP config for a single run are rejected at startup.allowManagedMcpServersOnlymakes the agent’s tool surface an allowlist owned by the platform team.requiredMinimumVersionrefuses to start on a version below the approved floor, so the controls are enforced by a build the organization has actually assessed.
ZH - permissions.deny 不让秘密进 agent 上下文,并拦住经工具的任意出网。permissions.allow 预批安全的内环,免得拒绝名单变成提示疲劳。
disableBypassPermissionsMode加上allowManagedPermissionRulesOnly意味着没有工程师、项目文件或命令行旗标能把规则放宽。sandbox补权限补不到的。工具级拒绝 WebFetch 挡不住一条 shell 出网;操作系统级域名允许名单则直接拦住出网,两层执行同一目标。failIfUnavailable和allowUnsandboxedCommands把沙箱变成前提:沙箱初始化不了 Claude Code 拒绝启动,沙箱里失败的命令也不能拿到外面重试。credentials补拒绝规则漏掉的情况。permissions.deny管的是 Claude 的文件工具,但沙箱 shell 默认仍可能读~/.ssh或~/.aws/credentials。这块拒绝这些读取,并从沙箱命令环境里剥掉列出的秘密。allowManagedHooksOnly意味着只有托管设置里定义的 hooks 会跑;用户、项目、本地设置里的 hooks 被拦住,包括上面独立的.claude/settings.json例子。要让本打法的审批闸真正强制,把它定义在托管文件自己的hooks块里。disableSideloadFlags和strictKnownMarketplaces意味着工程师机器上的 skill、agent、hook 或 MCP 服务器,都得经过组织批准的插件市场,不能从家目录来。市场允许名单控制能装什么;为单次运行侧载插件、agent 或 MCP 配置的旗标,启动时拒绝。allowManagedMcpServersOnly让 agent 的工具面成为平台团队拥有的允许名单。requiredMinimumVersion低于批准下限的版本拒绝启动,于是控制由组织真正评估过的构建来强制。
EN Treat the example as a starting point to customize to your own environment. Each deny rule removes some capability, and the right balance depends on the data classification of the repo. The settings reference documents all keys, including the managed-only ones.
ZH 把例子当起点,按自己的环境改。每条拒绝规则都拿掉一些能力,合适的平衡取决于仓库的数据分级。设置参考 记录了所有键,包括仅托管的。
怎么衡量 / How to measure it
EN For the hooks themselves:
ZH 就 hooks 本身:
EN - Leading indicator: Time spent waiting on each approval gate. Every hook decision is written to the OpenTelemetry export with a timestamp and an allow or block verdict, so the wait is visible per gate.
- Lagging indicator: Gate violations reaching production before and after hooks, from the incident tracker.
ZH 领先指标:每扇审批闸上等待的时间。每个 hook 决定都写进 OpenTelemetry 导出,带时间戳和允许/拦住裁决,所以等待按闸可见。
- 滞后指标:上 hooks 前后到达生产的闸门违规,来自事故追踪。
读完能记住的三句话
EN A hook can allow, ask, or block. Release gating needs the ask. ZH Hook 可以允许、询问、或拦住。发布闸需要「询问」。
EN Non-negotiable hooks go in managed settings. Engineers cannot switch them off. ZH 不能谈的 hooks 放托管设置。工程师关不掉。
EN Treat the managed-settings example as a starting point. Each deny removes capability. ZH 托管设置例子当起点。每条拒绝都拿掉能力。