第 2 章

权限与信任架构

每一个强大的工具都会产生一种张力:它的能力越强,可能造成的破坏就越大。Claude Code 可以运行 bash 命令、编辑文件、发起网络请求,并在你的整个代码库中编排 subagent。管理这一切的权限系统并非简单的开关。它是一个分层架构,包含五个作用域、三个评估阶段、操作系统级别的 sandbox、基于 hook 的可扩展性,以及一个并不能覆盖你所认为的一切的 checkpoint 系统。

五层作用域层级

Claude Code 的设置遵循严格的优先级顺序。理解这个顺序是配置一个真正生效的设置与配置一个被静默覆盖的设置之间的关键区别。

层级从最高到最低优先级:

  • Managed —— IT 部署在系统目录中的策略。无法被任何配置覆盖。
  • CLI arguments —— 调用时传入的标志。覆盖其下所有层级的配置。
  • Local —— .claude/settings.local.json。每台机器独有,被 gitignore。你的个人覆盖配置。
  • Project —— .claude/settings.json。提交到版本控制。与团队共享。
  • User —— ~/.claude/settings.json。你的全局默认配置。

关键洞察在最顶层。Managed 设置的存在是为了让组织能够强制执行个人开发者无法规避的策略。如果你的 IT 团队部署了一个拒绝访问某个工具的 managed-settings.json,那么任何本地或项目配置都无法重新启用它。这个层级不是建议,而是强制执行。

这创造了两种截然不同的 Claude Code 体验。个人开发者处理个人项目时主要与 User 和 Project 作用域交互。企业内部的工程师可能会发现某些能力在他们看到之前就被锁定了。这两种体验都是有意为之的。

设置文件的位置

User 设置位于 ~/.claude/settings.json——这是你跨所有项目的全局默认配置。Project 设置位于仓库中的 .claude/settings.json 并提交到版本控制,意味着整个团队共享它们。Local 设置放在同一 .claude/ 目录下的 .claude/settings.local.json 中,但按约定被 gitignore,使每个开发者可以在不影响共享配置的情况下拥有机器特定的覆盖。

Managed 设置是个例外。它们位于 IT 控制的系统目录中——普通用户没有写权限的位置。它们是组织的一张王牌,而且设计初衷就是如此。

权限规则评估

在每个作用域内,权限规则遵循三阶段评估,采用首次匹配胜出(first-match-wins)语义。这听起来简单,但暗藏锋芒。

各阶段按以下顺序评估:

  • Deny —— 如果工具调用匹配任何 deny 规则,它将被阻止。就这么简单。不再继续评估。
  • Ask —— 如果匹配 ask 规则,用户将被提示批准。
  • Allow —— 如果匹配 allow 规则,则无需提示直接执行。

如果没有匹配项,则应用工具的默认行为。

规则使用 Tool 或 Tool(specifier) 语法,并支持 glob 模式。你可以写 Bash(npm test) 来匹配特定的 bash 命令,写 Bash(rm *) 来匹配破坏性删除,或写 Write(*.env) 来匹配对环境文件的写入。glob 模式使这个系统富有表现力,但也使其脆弱——deny 规则中一个过于宽泛的模式可能会静默阻止你本打算允许的操作。

首次匹配胜出

这是开发者容易踩坑的地方。如果你有一条 Bash(rm *) 的 deny 规则和一条 Bash(rm -rf node_modules) 的 allow 规则,deny 规则会先触发。你的 allow 规则永远不会执行。每个阶段内的顺序很重要,而阶段排序(deny 在 ask 之前,ask 在 allow 之前)是不可变的。

实际影响:把你的 deny 规则写得窄,allow 规则写得宽。deny 规则是一堵硬墙。确保它只阻止你意图阻止的内容。

敏感文件排除

permissions.deny 配置替代了一个旧的名为 ignorePatterns 的机制。它提供了明确的文件级访问控制,你应该将它用于任何不希望 AI agent 读取或修改的文件。

标准目标:.env 文件、凭据目录、私钥、密钥管理器、API 密钥配置。任何内容出现在向云服务发出的 API 请求中会很危险的文件。Claude Code 通过外部 API 处理文件内容。如果文件包含生产数据库凭据,读取该文件就会将那些凭据发送到 API 端点。permissions.deny 列表就是你对此的防火墙。

Sandbox 隔离

Claude Code 为 bash 命令提供操作系统级别的 sandbox。这不是概念上的边界。它是一种操作系统强制执行机制,限制 Claude Code 生成的进程实际能做什么。

sandbox 将网络访问限制为可配置的域白名单。默认情况下,Claude Code 可以访问其自身运行所需的域,但任意的网络访问被阻止。你可以为你的特定工作流向白名单添加域——你的包注册表、内部 API、云服务提供商端点。

sandbox 还支持 Unix socket 路径白名单、本地端口绑定控制和命令级排除。它足够精细,可以表达"允许 npm install 但阻止 curl 到任意 URL"这样的规则。

Sandbox 下的自动批准

这就是 sandbox 改变信任计算的地方。当 sandbox 处于活跃状态时,Claude Code 可以自动批准 bash 命令,因为爆炸半径已被控制。sandbox 中的 rm -rf / 对本地文件仍然具有破坏性,但无法将数据泄露到外部服务器。sandbox 中的 curl 无法访问白名单之外的域。

这就是 sandbox 背后的设计意图:通过约束环境而非约束 agent 来使自主操作变得安全。它用隔离边界替代了权限提示。对于许多工作流来说,这是正确的权衡。

但 sandbox 有一个逃生舱。默认情况下,如果 Claude Code 需要运行一个非 sandbox 的命令,它可以提示用户。Managed 设置可以完全禁用这个逃生舱,当你需要硬性保证时,这是企业正确的配置。

Checkpoint:有缺口的安全网

在每次文件编辑之前,Claude Code 会快照受影响的文件。如果出了问题,按两次 Escape 键可以将代码和对话回滚到 checkpoint 状态。对于它所覆盖的范围——通过 Claude Code 的 Write 和 Edit 工具进行的直接文件编辑——它是一个很好的撤销系统。

Checkpoint 有显著的缺口,最值得注意的是通过 bash 命令进行的文件更改对系统是不可见的。Checkpoint 限制的完整目录及其影响在第 10 章中涵盖。对你的安全态势的关键影响是:如果你正在通过 bash 修改文件系统,你的安全网是 git,而不是 checkpoint。在开始之前提交。频繁提交。需要时回滚。

Devcontainer 安全

开发容器提供带有默认拒绝防火墙的网络级隔离。devcontainer 配置限制 Claude Code 可以访问的主机,创建一个使 --dangerously-skip-permissions 变得不那么危险的环境,因为容器本身限制了爆炸半径。

这是企业对"如何让 Claude Code 在 CI 中自主运行而无需人工批准每个命令"这个问题的答案。你不是移除权限系统,而是将执行环境包裹在网络隔离中,这样即使不受限制的操作也无法触及不该触及的东西。

Anthropic 提供了一个参考 devcontainer 实现——一个带有自定义防火墙限制网络访问的容器定义,预配置了会话持久性和编辑器集成。它被设计为需要在隔离环境中运行 Claude Code 的组织的起点,无论是用于 CI 管道、安全敏感项目还是无头自主工作流。

泄露注意事项

以下是文档直接承认的严酷事实:devcontainer 无法防止恶意项目的凭据泄露。如果项目代码中包含使 Claude Code 读取凭据并将其编码在输出中的指令,而输出到达了允许的端点,容器的防火墙就无能为力了。数据通过一个已批准的通道流出。

这不是理论上的担忧。在代码注释或 README 文件中嵌入指令的供应链攻击是已知的攻击向量。devcontainer 防止意外的网络访问。它不能防止 agent 执行的项目代码的故意滥用。

缓解措施是分层防御:通过 permissions.deny 进行敏感文件排除以首先防止读取凭据,结合容器隔离限制数据的去向。单独任何一层都不够。但两者结合可以显著提高门槛。

完整的 Hook 事件系统

Hook 是权限系统的可扩展层。它们不仅限于大多数开发者最先发现的两个事件。完整的 hook 事件目录涵盖了 agentic 生命周期中的每个重要时刻,理解所有这些事件可以解锁仅靠权限规则无法实现的控制。

Hook 事件目录

以下是每个 hook 事件、其触发条件以及是否可以阻止操作:

PreToolUse —— 在任何工具执行之前触发。可以阻止工具调用、允许其不提示地执行,或升级给用户。还可以在执行之前修改工具的输入。这是 hook 系统的主力。

PostToolUse —— 在工具成功执行后触发。不能阻止(工具已经运行),但可以向 Claude 提供关于结果的上下文。用于日志记录、代码检查或注入额外信息。

PostToolUseFailure —— 在工具执行失败后触发。接收错误信息以及失败是否由用户中断导致。用于自定义错误报告或触发回退操作。

PermissionRequest —— 当 Claude Code 即将向用户显示权限对话框时触发。与 PreToolUse 不同——这专门在用户将被提示时触发。你的 hook 可以自动批准、自动拒绝、修改工具输入,或应用等同于用户在对话框中看到的"始终允许"选项的权限规则。这实际上用程序化评估替代了交互式提示。

Notification —— 当 Claude Code 发送通知时触发,按通知类型匹配:权限提示、空闲提示、认证事件和 elicitation 对话框。不能阻止通知,但可以向对话注入上下文。

SubagentStart —— 当 subagent 被生成时触发。不能阻止 subagent 创建,但可以向 subagent 的起始状态注入额外的上下文。按 agent 类型匹配:内置 agent 或 .claude/agents/ 目录中的自定义 agent 名称。

SubagentStop —— 当 subagent 完成时触发。可以阻止 subagent 停止,强制其继续工作。用于在接受 subagent 输出之前验证其输出的质量门控。

TeammateIdle —— 当 agent 团队中的队友即将进入空闲状态时触发。退出码 2 阻止队友进入空闲状态,并将你的 stderr 消息作为反馈返回。不支持 matcher——每次触发都会执行。用于强制质量门控,比如在允许队友停止工作之前检查构建产物是否存在。

TaskCompleted —— 当任务被标记为完成时触发,无论是通过显式更新还是当队友完成时仍有进行中的任务。退出码 2 阻止完成并将 stderr 作为反馈返回。用于强制完成标准——运行测试套件、验证 lint 通过、检查任务的可交付成果是否存在。

PreCompact —— 在上下文压缩之前触发。按触发类型匹配:手动(用户运行 /compact)或自动(context window 已满)。接收用户传递给 /compact 的任何自定义指令。不能阻止压缩,但可以执行准备工作——日志记录、保存状态或注入应该在压缩后保留的上下文。

SessionEnd —— 当会话终止时触发。接收一个原因代码:clear、logout、prompt_input_exit、bypass_permissions_disabled 或其他。不能阻止终止,但对清理任务、记录会话摘要或触发会话后工作流很有价值。

三种 Hook 类型

并非所有 hook 都是 shell 脚本。Claude Code 支持三种不同的 hook 处理器类型,每种适合不同的验证需求:

Command hook(type: "command")是默认类型。它们运行一个 shell 命令,通过 stdin 接收事件的 JSON 输入,并通过退出码和 stdout 传达结果。将这些用于确定性检查:模式匹配、文件存在性、命令验证。快速且可预测。

Prompt hook(type: "prompt")使用 LLM 来评估操作。hook 不执行脚本,而是将事件输入连同你的 prompt 一起发送给一个快速模型(默认为 Haiku),并接收一个结构化的 yes/no 决策。这适用于需要判断而非模式匹配的检查——评估代码更改是否遵循架构约定,bash 命令是否适合当前任务,或是否应该允许 Claude 停止工作。

{
  "type": "prompt",
  "prompt": "Evaluate if Claude should stop: $ARGUMENTS. Check if all tasks are complete, no errors remain, and no follow-up is needed."
}

$ARGUMENTS 占位符会被替换为 hook 的 JSON 输入。模型返回 {"ok": true} 来允许,或 {"ok": false, "reason": "..."} 来阻止,原因作为 Claude 的下一条指令反馈给它。

Agent hook(type: "agent")类似 prompt hook,但具有多轮工具访问能力。agent hook 不是单次 LLM 调用,而是生成一个 subagent,可以读取文件、搜索代码和检查代码库来验证条件。subagent 最多运行 50 轮后返回其决策。当验证需要检查实际文件或测试输出,而不仅仅是评估 hook 输入数据时,使用这些。

{
  "type": "agent",
  "prompt": "Verify that all unit tests pass. Run the test suite and check the results. $ARGUMENTS",
  "timeout": 120
}

agent hook 的默认超时为 60 秒(prompt hook 为 30 秒,command hook 为 600 秒)。响应模式与 prompt hook 相同:{"ok": true} 允许,{"ok": false, "reason": "..."} 阻止。

Prompt 和 agent hook 支持以下事件:PreToolUse、PostToolUse、PostToolUseFailure、PermissionRequest、UserPromptSubmit、Stop、SubagentStop 和 TaskCompleted。TeammateIdle 不支持 prompt 或 agent hook。

异步 Hook

默认情况下,hook 会阻塞 Claude 的执行直到完成。对于长时间运行的任务——测试套件、部署、外部 API 调用——这会造成不可接受的延迟。异步 hook 解决了这个问题。

在 command hook 上设置 "async": true 以在后台运行它。Claude 立即继续工作。当后台进程完成时,hook 的 JSON 输出中的任何 systemMessage 或 additionalContext 将在下一轮对话中传递给 Claude。异步 hook 不能阻止或控制行为——当它们完成时,它们本应控制的操作已经完成了。

经典用例:一个在每次文件写入后运行测试套件的 PostToolUse hook。测试在后台运行,而 Claude 继续工作。如果测试失败,失败消息出现在 Claude 下一轮的上下文中,提示它解决问题。

{
  "PostToolUse": [{
    "matcher": "Write|Edit",
    "hooks": [{
      "type": "command",
      "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/run-tests-async.sh",
      "async": true,
      "timeout": 300
    }]
  }]
}

每次异步执行创建一个独立的后台进程。没有去重——如果 Claude 快速连续写入五个文件,hook 会触发五次。

Hook 的输入与输出

每个 hook 通过 stdin 接收一个 JSON 负载,包含公共字段:session_id、transcript_path、cwd、permission_mode 和 hook_event_name。特定于事件的字段根据 hook 类型添加——工具 hook 获取 tool_name 和 tool_input,subagent hook 获取 agent_id 和 agent_type,等等。

hook 的退出码告诉 Claude Code 该做什么:

退出码 0 表示成功。Claude Code 解析 stdout 中的 JSON 输出字段。对于大多数事件,stdout 仅在详细模式下显示。

退出码 2 表示阻止。具体行为取决于事件:PreToolUse 阻止工具调用,PermissionRequest 拒绝权限,Stop 阻止 Claude 停止,TeammateIdle 保持队友工作,TaskCompleted 阻止任务关闭。stderr 消息作为反馈传递给 Claude。

其他退出码 被视为 hook 错误并被忽略。Claude Code 继续执行,就像 hook 没有触发一样。

JSON 输出支持所有事件中的多个字段:continue(布尔值,覆盖退出码决策)、stopReason(用于 Stop hook)、suppressOutput(在详细模式下隐藏 stdout)、systemMessage(在下一轮添加到 Claude 的上下文中)和 additionalContext(立即添加)。

PreToolUse:在执行前修改输入

PreToolUse hook 有一个独特的能力:它们可以在工具执行之前修改工具的输入。hook 的 JSON 输出中的 updatedInput 字段替换工具输入参数中的特定字段。

将 updatedInput 与 "permissionDecision": "allow" 结合使用可以静默重写并自动批准命令。将其与 "permissionDecision": "ask" 结合使用可以将修改后的输入展示给用户审批。

这很灵活,但也恰恰如其听起来那样危险。重写 bash 命令的 hook 可以添加安全标志、前置日志记录或将命令包裹在监控工具中。如果重写逻辑有缺陷,它也可能引入漏洞。对 updatedInput hook 施加的安全审查应与对任何重写可执行命令的代码施加的审查同等严格。

Hook 处理器:"once" 字段

对于在 skill 中定义的 hook(而非在设置文件中定义的),once 字段使 hook 在每个会话中只运行一次,然后自行移除。这适用于 skill 初始化——一个在首次工具调用时运行设置逻辑然后不再干扰的 hook。

/hooks 交互菜单

/hooks 命令打开一个交互菜单,显示所有已配置的 hook,带有指示其来源的标签:[User]、[Project]、[Local]、[Plugin]。从这个菜单你可以查看 hook 详情、添加新 hook、删除现有 hook,以及切换 disableAllHooks 设置。这是审计哪些 hook 处于活跃状态以及它们来自何处的最快方式。

Hook 安全模型

Hook 在启动时被快照。Claude Code 在会话开始时捕获所有已配置 hook 的状态,并在整个会话中使用该快照。如果有人——或什么东西——在会话期间修改了磁盘上的 hook 文件,Claude Code 会检测到更改并显示警告。修改后的 hook 在你在 /hooks 菜单中审查之前不会生效。这防止了恶意或意外的 hook 修改在活跃会话期间静默更改 agent 行为。

Hook 以完整的用户权限运行。hook 是一个在你的机器上以你的凭据、你的文件系统访问权限、你的网络访问权限执行的任意命令。hook 周围没有 sandbox。

这意味着 hook 代码需要与以你的权限运行的任何其他代码同等的安全审查。输入验证很重要。Shell 引用很重要。路径遍历防止很重要。一个将工具输入天真地插入到 shell 命令中的 hook 是一个代码注入漏洞。

对于企业,托管配置中的 allowManagedHooksOnly 设置将 hook 限制为在 managed 作用域中定义的 hook。个人开发者和项目级设置不能添加 hook。这防止了受损项目安装泄露数据或修改工具行为的 hook。

安全导向的 Hook 模式

最常见的安全导向 hook 模式:

阻止破坏性命令

一个 Bash 上的 PreToolUse hook,从 JSON 输入中读取命令,检查危险模式,并返回 deny 决策:

#!/bin/bash
COMMAND=$(jq -r '.tool_input.command')
if echo "$COMMAND" | grep -q 'rm -rf'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Destructive rm -rf blocked by hook"
    }
  }'
  exit 0
fi
exit 0 # allow the command

当 Claude 尝试运行破坏性命令时,hook 拦截它,返回 deny 决策,Claude 在其上下文中看到原因。它要么找到替代方案,要么解释为什么需要该命令。

写入时 Lint

一个 PostToolUse hook,每当 Claude 编辑文件时触发你的 linter:

{
  "PostToolUse": [{
    "matcher": "Edit|Write",
    "hooks": [{
      "type": "command",
      "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/check-style.sh"
    }]
  }]
}

lint 脚本在每次编辑后运行,任何失败出现在 Claude 的上下文中,提示它在继续之前修复样式问题。这将你的 linter 变成 agentic 循环的实时质量门控。

音效作为会话反馈

并非每个 hook 都是关于安全的。一个创意模式使用 hook 在生命周期事件上播放音频提示——会话开始时、提交 prompt 时、Claude 完成时以及上下文压缩时。实现是每个事件上的一行 command hook,在后台运行系统音频播放器(使用 & 以避免阻塞)。在 macOS 上,是 afplay;在 Linux 上,是 aplay 或 paplay。

这听起来很轻浮,但使用它的开发者报告说,音频反馈有助于他们在自主运行期间专注于其他工作时保持对 Claude 状态的感知。你听到它何时完成。你听到上下文何时压缩(一个检查重要指令是否存活的提示)。它将背景感知从切换标签页的繁琐操作转变为被动的感官通道。

安全验证 Skill Hook

Skill 可以在其 frontmatter 中嵌入 hook。一个安全导向的 skill 可能包含一个 PreToolUse hook,在 skill 活跃期间执行的每个 Bash 命令之前运行一个验证脚本:

---
description: Security review workflow
hooks:
  PreToolUse:
  - matcher: "Bash"
    hooks:
    - type: command
      command: "./scripts/security-check.sh"
---

该 hook 限定在 skill 的生命周期内——它仅在 skill 活跃时运行,并在 skill 完成时自行移除。

多条件停止 Prompt Hook

一个 Stop 事件上的 prompt hook,在允许 Claude 完成之前评估三个条件:

{
  "Stop": [{
    "hooks": [{
      "type": "prompt",
      "prompt": "You are evaluating whether Claude should stop working. Context: $ARGUMENTS\n\nAnalyze the conversation and determine if:\n1. All user-requested tasks are complete\n2. Any errors need to be addressed\n3. Any follow-up actions were mentioned but not completed\n\nIf ALL conditions are satisfied, return {\"ok\": true}. If ANY are not met, return {\"ok\": false, \"reason\": \"specific explanation\"}."
    }]
  }]
}

这使用一个快速模型来评估 Claude 的工作是否真正完成,然后才允许它停止。如果评估发现未完成的工作,Claude 收到原因并继续。

审计日志

一个 PreToolUse hook,将每次工具调用及其时间戳、输入和决策记录到文件或监控服务。对开发者零运行时影响,为安全团队提供完全可见性。

文件访问控制

一个 Write 和 Edit 上的 PreToolUse hook,将修改限制在特定目录树中,强制 Claude Code 只能触碰当前项目中的代码。结合用于读取限制的 permissions.deny,这创建了一个全面的文件级访问边界。

MCP 工具门控

匹配 mcp__server__tool 模式的 PreToolUse hook,用于记录或限制对外部服务集成的访问。MCP 工具遵循命名模式 mcp__<server>__<tool>,你可以在 matcher 中使用正则表达式——mcp__memory__.* 匹配内存服务器的所有工具,mcp__.*__write.* 匹配所有 MCP 服务器的写入操作。

设置作用域特性

每个设置作用域具有对团队工作流很重要的独特属性:

User 作用域(~/.claude/settings.json):个人的。随你到处走。适合你的编辑器偏好、个人权限规则、默认模型选择。从不共享。

Project 作用域(.claude/settings.json):通过版本控制共享。团队达成共识的配置。Hook、权限、插件启用、每个人都需要的 environment variable。更改像其他提交文件一样经过代码审查。

Local 作用域(.claude/settings.local.json):每台机器的覆盖。被 gitignore。你在项目配置之上的个人微调。机器特定的路径、开发服务的个人 API 密钥、团队配置中未包含但你想要的工具。

Managed 作用域:IT 控制的。对大多数开发者不可见。强制执行组织策略。不能从 CLI 检查或覆盖。这个作用域的存在就是为什么"在我的机器上能用但在工作机器上不行"是企业 Claude Code 部署中的真实对话。

这些作用域之间的交互是配置变得有趣的地方。一个项目可能允许某个工具。一个托管策略可能拒绝它。托管策略静默地获胜。没有错误消息,没有解释——工具就是不可用。如果你正在调试为什么某个东西在个人项目上能用但在工作中不行,检查是否存在 managed 设置。

MCP 作为安全控制的访问

当 Claude Code 需要与外部服务交互时,有两条路径:通过 bash 运行 CLI 命令,或使用 MCP 服务器。

MCP 路径在安全性上更好。MCP 服务器提供具有定义输入和输出的结构化工具接口。每次调用都通过权限系统,可以被 hook 拦截,并产生结构化日志。一个用凭据运行 curl 的 bash 命令不提供任何那样的可见性——凭据出现在命令字符串中、对话上下文中,以及可能在对模型提供商的 API 调用中。

Claude Code 集成的安全意识方法是:为你的敏感数据源构建 MCP 服务器。不要给 Claude 对你生产数据库的 bash 访问权限。给它一个 MCP 工具,用适当的认证、日志记录和查询限制来包装数据库访问。第 5 章涵盖 MCP 的完整架构和 MCP 优于 CLI 访问的详细安全论证。

Anthropic 的一个法律团队从产品顾问的角度提出了一个重要关切:随着 MCP 集成深入敏感系统,保守的安全态势将制造障碍。工具能力越强,它需要的访问权限越多,安全策略产生的摩擦就越大。组织应该预期这种紧张关系并为之做计划——主动而非被动地构建合规工具,在集成扩散之前建立 MCP 访问治理框架。

安全双用途风险

Agentic 编码工具是双用途技术。帮助安全团队审计代码和生成补丁的同样能力也帮助攻击者发现漏洞和生成利用。Claude Code 读取整个代码库、理解其架构并进行针对性更改的能力,对防御和进攻同样有用。

这不是假设。安全研究人员使用 Claude Code 发现 bug。攻击者可以同样使用它。使 Claude Code 对非安全工程师编写安全代码有价值的专业知识民主化,同样使它对非安全工程师发现不安全代码有价值。

Agentic 网络防御

趋势正同时向两个方向发展。在防御方面,agentic 系统使任何工程师都能执行以前需要专业知识的安全审查、加固和监控。安全知识正在民主化——一个没有安全背景的工程师现在可以使用 Claude Code 审计代码路径、识别常见漏洞模式并生成加固实现。

在进攻方面,威胁行为者将使用相同工具扩展攻击。来自行业分析的预测很明确:自动化 agentic 系统将以机器速度实现安全响应,自动化检测和响应以匹配自主威胁的步伐。为此做好准备的组织——从一开始就将安全嵌入其 agentic 工作流,而不是事后添加——将更有能力抵御使用相同技术的对手。

安全审查作为日常实践

Anthropic 的安全工程团队展示了一个实用模式:将基础设施即代码计划复制到 Claude Code 中,询问"这会做什么,我会后悔吗?"需要安全批准的基础设施变更——部署配置、网络策略更改、访问控制修改——由 Claude 在几秒内审查,而不是在安全团队的队列中等待。这创造了更紧密的反馈循环,消除了开发者在等待安全审查时的阻塞。

这不是取代安全审查。这是使安全审查持续化。安全分析不再只是管道末端的瓶颈,而是在创建时刻就发生了。安全团队仍然审查最终配置,但 Claude 在问题到达安全团队之前就捕获了明显的问题。

组织的回应不是限制 Claude Code——那会放弃防御优势,同时对攻击性使用毫无作用。回应是确保你的安全架构不依赖于对手不成熟。假设你的对手可以访问至少与你同等能力的工具。然后据此构建你的防御。

模拟交易:安全实验边界

模拟交易(paper trading)的概念——在没有真实后果的情况下模拟真实操作——直接适用于 Claude Code 的采用。在给 agent 访问生产系统、生产数据库或生产凭据之前,建立一个它可以自由操作而无风险的安全边界。

这意味着:使用合成数据的 sandbox 环境。镜像生产拓扑但不含任何敏感内容的预发布系统。使用模拟外部服务的本地开发环境。Agent 可以自主运行、犯错、发现边缘情况和崩溃,而不会产生任何后果。

在自主循环中长时间运行 agent 的实践者的模式是一致的:从模拟交易开始。在安全环境中验证行为。逐步扩大边界。信任架构支持这种渐进——你可以从最大限制开始,随着你建立信心而放松约束。

权限系统、sandbox 隔离、hook 和 managed 设置共同创建了一个从"Claude Code 不经询问不能做任何事"到"Claude Code 在这个隔离环境中可以做一切"的梯度。你在该梯度上的正确位置取决于你的上下文、你的风险承受能力以及你首先在安全环境中验证了多少。

要点总结
  • 作用域层级是严格的——Managed 设置覆盖一切,组织策略无法规避。
  • 权限规则按 Deny、Ask、Allow 的顺序评估,采用首次匹配胜出语义,因此 deny 规则写得窄,allow 规则写得宽。
  • Checkpoint 覆盖直接文件编辑,但不覆盖 bash 命令的副作用——git 才是你真正的安全网。
  • Devcontainer 提供网络隔离,但不能防止恶意项目代码的凭据泄露;采用分层防御,并使用 Anthropic 的参考实现作为起点。
  • Hook 系统有十三个事件覆盖整个 agentic 生命周期:PreToolUse、PostToolUse、PostToolUseFailure、PermissionRequest、Notification、SubagentStart、SubagentStop、Stop、TeammateIdle、TaskCompleted、PreCompact、SessionEnd 等。
  • 三种 hook 类型服务不同的验证需求:command hook 用于确定性检查,prompt hook 用于 LLM 评估的判断,agent hook 用于带文件访问的多轮调查。
  • 异步 hook 在后台运行而不阻塞 Claude;将它们用于测试套件和长时间运行的验证。
  • Hook 在启动时被快照——会话中期的修改会触发警告,需要先在 /hooks 菜单中审查才能生效。
  • PreToolUse hook 可以通过 updatedInput 在执行前修改工具输入,实现命令重写、安全标志注入和监控工具包装。
  • MCP 服务器为敏感数据访问提供比原始 bash 命令更好的安全可见性;为你的敏感数据源构建 MCP 服务器。
  • 安全知识正在被 agentic 工具民主化;任何工程师现在都能执行曾经需要专家的审查,但对手也获得了同样的能力。
  • 从最大限制和模拟交易环境开始,然后随着验证 agent 行为逐步放松约束。