摘要

如果把 Claude Code 理解为一个高权限的本地开发 Agent,那么其核心安全问题并不是“模型是否足够聪明”,而是三个更基础的问题:

  1. 在驱动这个 Agent;
  2. 每一个动作是否都经过了足够细粒度的约束;
  3. 系统是否能够区分“用户真实授权的意图”与“模型自行扩张出的执行冲动”。

从最新源码可以观察到,Claude Code 在这些问题上并非采用单一的权限弹窗机制,而是逐步形成了一套更接近零信任 Agent 控制平面的架构:

  • 在身份层面,它尝试把账户、组织、设备、会话绑定成同一条信任链;
  • 在执行层面,它把权限控制下沉到具体 Action / Tool Use,而不是只看会话级开关;
  • 在高风险命令层面,尤其是 Bash,它引入了语法、语义、规则、分类器、人工确认的多阶段判定;
  • 在意图层面,它不再只依赖静态 allowlist,而是引入了基于上下文转录的动作分类器,试图判断动作是否符合用户真实意图。

本文不把这些实现视为零散功能,而将其作为一套 Agent 安全架构进行分析。

一、问题定义:Agent 安全的核心,不是“能不能做”,而是“谁、何时、为何可以做”

传统 CLI 工具的安全边界相对简单:

  • 使用者是明确的人;
  • 操作入口是显式命令;
  • 风险主要由操作系统权限和文件系统边界承担。

Agent 系统则不同。Claude Code 这类工具同时具备如下特征:

  • 能直接读写代码仓库;
  • 能执行 shell / PowerShell;
  • 能启动子 Agent 或远程会话;
  • 能在记忆、计划、调度等状态之间迁移;
  • 能在“用户未逐字指定”的情况下,自主生成中间动作。

因此,其安全问题更接近如下形式:

一个具备高权限执行能力的自治体,如何在不完全牺牲交互效率的前提下,被持续约束在“人类意图可接受”的边界内?

从源码看,Claude Code 的回答不是“做一个更大的 confirmation dialog”,而是把控制拆成四层:

  • 身份绑定层:确认是谁、属于哪个组织、来自哪个设备与会话;
  • 动作授权层:每一次 tool use 都单独判定,而非一劳永逸放权;
  • 高风险语义层:对 Bash 等危险表面做结构化分析;
  • 意图判定层:用分类器判断动作是否符合真实任务意图。

这一点非常关键。它意味着 Claude Code 的安全模型已经从“静态权限管理”转向“运行时零信任判定”。

二、人-Agent 身份绑定:源码中已经出现账户、组织、设备、会话四元绑定的雏形

从研究角度看,Claude Code 安全体系中最值得注意的第一点,是它并未把 Agent 视为“匿名本地进程”。

相反,源码反复强调四类身份信息:

  • 账户身份(account UUID / email);
  • 组织身份(organization UUID);
  • 设备身份(trusted device token);
  • 会话身份(session ingress token / session ID)。

2.1 账户与组织绑定

在认证安装流程中,CLI 会持久化:

  • accountUuid
  • organizationUuid
  • emailAddress
  • displayName

这说明 Claude Code 并不是把“登录成功”当作单一布尔值,而是把人所属的组织上下文也纳入了本地信任状态。

从安全设计上看,这意味着后续很多动作可以不再只问“你有没有 token”,而是问:

  • 这个动作对应哪个账户;
  • 它是否属于正确组织;
  • 跨组织上下文是否被错误复用。

2.2 会话入口绑定

session ingress auth 相关实现表明,会话接入并非裸连。

源码里存在明确的 session ingress token 读取逻辑,且支持:

  • 通过环境变量注入;
  • 通过文件描述符传递;
  • 通过 well-known file 回退;
  • 对不同 token 形态采用不同 header 方式。

尤其值得注意的是:当 token 形态属于 session-key 时,系统会额外注入 X-Organization-Uuid

这意味着“会话可进入”并不是单纯的 bearer token 问题,而是被绑定到组织上下文中的。

2.3 设备绑定

更有研究价值的是 trusted device token

在 bridge / remote-control 相关路径中,源码引入了:

  • trusted device enrollment;
  • 设备 token 持久化;
  • elevated auth enforcement;
  • 设备 token 与 bridge headers 的联动。

换言之,远程控制面并不是只信任“这个用户登录了”,而开始尝试回答:

发起高权限桥接请求的,是否还是那台被登记过的设备?

这一步非常像现代零信任系统中的 device posture 思路。

2.4 一个重要推论

综合这些机制可以推断:Claude Code 正在尝试把 Agent 的“执行人格”从抽象模型,收束到一条更具体的链路上:

人 → 账户 → 组织 → 设备 → 会话

这条链路并不意味着系统已经彻底实现强身份不可抵赖,但至少说明它的设计方向不是“本地 Agent 天然可信”,而是“高权限 Agent 必须被具体身份上下文化”。

三、入向与出向权限检查:Claude Code 的控制点不是会话级,而是 Action 级

在安全系统中,“入向”和“出向”往往对应两个不同问题:

  • 入向:外部请求是否可以进入 Agent 的执行面;
  • 出向:Agent 想要调用工具、发起副作用时,是否应该被允许。

Claude Code 在这两端都已经出现了比较完整的结构。

3.1 入向:远程请求不是直接执行,而是先转译为权限请求对象

在 remote session 相关实现中,来自 CCR / remote side 的控制请求会被识别为 can_use_tool 类型,再进入本地 permission flow。

这意味着一个非常重要的边界被保留了:

远端并不能直接代表本地执行工具,而必须先把请求显式转换成“待授权的工具使用”。

这是一种典型的零信任姿态:

  • 先假定远端执行意图不可信;
  • 再将其转化为本地可审计、可拒绝、可取消的请求对象;
  • 最终由本地控制面决定放行与否。

3.2 出向:每个 Tool Use 都进入 allow / ask / deny 决策机

在本地执行面,权限不是粗粒度地绑定到“本轮对话”或“当前 Agent 实例”,而是围绕每一次 tool use独立判断。

从类型与权限实现看,系统会给每个动作生成三类决策之一:

  • allow
  • ask
  • deny

并伴随:

  • 决策原因;
  • 是否命中规则;
  • 是否来自 classifier;
  • 是否需要后续异步 classifier check;
  • 是否附带建议规则更新。

这说明 Claude Code 的控制模型不是“先信任会话,再在内部自由行动”,而是:

把每次动作都视为一个独立的授权单元。

从零信任角度看,这比 session-level trust 更合理,因为 Agent 风险并不均匀:

  • 读取文件与执行 shell 不是同一风险级别;
  • 创建 task 与写系统目录不是同一风险级别;
  • 调用子 Agent 与发起外部网络访问也不是同一风险级别。

四、Bash 是高风险表面的代表案例:Claude Code 采用了多阶段审查,而不是单点规则匹配

如果要观察 Claude Code 的安全设计最成熟的部分,Bash 是一个典型样本。

从源码看,Bash 权限判断不是一条简单正则,而是至少包含四个阶段。

4.1 第一阶段:危险语法与混淆模式识别

bashSecurity.ts 中存在大量针对 shell 绕过技巧的检测,包括但不限于:

  • command substitution;
  • process substitution;
  • heredoc / quote desync;
  • Zsh equals expansion;
  • 反引号与参数展开;
  • 变量注入、注释错位、控制字符等模式。

这些规则的意义并不在于“覆盖所有 shell 技巧”,而在于它已经承认:

对 Agent 而言,危险不只来自显式的 rm -rf,也来自各种能改变解释语义的 shell 变体与混淆写法。

这是一种明显高于普通命令白名单的安全建模。

4.2 第二阶段:语法 / 语义解析,而不仅是字符串匹配

Bash 权限实现并不只依赖文本模式,而会引入:

  • AST / parser 结果;
  • command prefix 提取;
  • operator 权限检查;
  • path constraints;
  • sed 等特定命令约束。

也就是说,Claude Code 正尝试把 Bash 从“原始字符串”提升为“结构化动作”。

这一点非常重要。因为零信任控制只有在动作被结构化后,才可能做到Action-level,否则永远只能停留在 fragile 的字符串黑名单。

4.3 第三阶段:危险前缀规则剥离

permissionSetup.ts 中对 Bash / PowerShell / Agent 工具的危险规则做了专门清洗。

例如,以下类型的 broad allow 会被视为危险:

  • 整个 Bash 全放行;
  • python:* / node:* / bash:* 这类解释器级 broad prefix;
  • sshenvxargssudo 等可包装任意执行路径的前缀。

其背后的逻辑非常值得注意:

系统不只审查“动作本身”,还审查“用户给出的权限规则是否会让后续判定失效”。

这已经不是传统 ACL,而是一种“对授权机制本身做安全检查”的设计。

4.4 第四阶段:分类器与人工审批兜底

即便经过前述规则与解析,Bash 仍可能进入:

  • 异步 classifier check;
  • 用户交互审批;
  • 远端 / 通道审批竞态;
  • deny tracking 与 fallback 机制。

也就是说,Claude Code 并不假定静态规则足够完备,而是把 Bash 视为一个需要持续判定与人工兜底的风险表面。

从安全研究角度看,这是合理的。因为 shell 语言的表达能力决定了它很难被完全静态封闭。

五、Action 级零信任:其核心不是“默认拒绝”,而是“默认重新验证”

很多系统提到零信任时,会简单地把它概括为“默认拒绝”。

但从 Claude Code 的实现看,更准确的描述是:

默认不把任何一次高风险动作视为可被永久继承的信任。

这一点体现在几个细节上。

5.1 safe allowlist 是严格受限的

在 auto mode classifier 决策中,真正被放进 safe allowlist 的,多为:

  • 只读读取类工具;
  • 搜索类工具;
  • 任务元数据管理;
  • team / message / orchestration 的内部状态操作。

甚至源码里还明确强调:

  • team coordination 不等于安全绕过;
  • subagent 仍然需要各自独立的权限检查。

这说明系统并未因为“这是内部编排动作”就整体放权,而是坚持把执行副作用编排元操作区分开。

5.2 第一响应者获胜(first resolver wins)

在交互权限处理、bridge、channel relay 等路径里,可以看到一个一致思想:

  • hook、classifier、本地 UI、远端桥接、通道审批之间存在竞态;
  • 但系统通过 claim() / resolve-once 机制保证只有第一个合法决策生效

这是一种很典型的分布式安全思路:

在多控制面并存时,必须定义唯一生效的授权提交语义,否则会出现双重批准、状态不同步或被后写覆盖的漏洞。

5.3 远端/通道审批不是对话文本,而是结构化事件

通道权限中最值得肯定的一点,是审批并不是“用户说一句 yes”。

相反,审批回复会被要求经由服务器解析后,转换为特定结构化事件,再由本地匹配 request_id 生效。

这等于把“聊天文本”与“安全指令”分离开来。

从零信任角度,这是必要的:

  • 普通对话文本不应该天然具有授权能力;
  • 授权必须是被明确编码、明确关联请求、明确落到特定 resolver 的控制事件。

六、意图判断:Claude Code 已经开始把“用户真实意图”作为独立安全信号

用户特别关心的“基本意图判断能力”,在 Claude Code 中并不是空白。

yoloClassifier.ts 可以看到,系统已经在做一件很重要的事:

不只检查命令危险性,还试图判断该动作是否符合当前任务与用户真实意图。

6.1 分类对象不是单条命令,而是动作与上下文的组合

formatActionForClassifier、转录构造与工具输入投影表明,分类器输入不是孤立命令,而是由以下信息共同构成:

  • 用户消息;
  • assistant 的 tool_use 历史;
  • 经过投影后的工具输入;
  • CLAUDE.md 配置;
  • auto mode 的 allow / soft_deny / environment 规则。

这意味着 Claude Code 试图回答的问题不是:

rm 危险不危险?

而是:

在当前任务、当前上下文、当前环境约束下,这个动作是否符合用户想让 Agent 做的事情?

这正是意图判断的雏形。

6.2 系统有意识地排除了容易污染分类器的内容

源码里一个很值得注意的细节是:构造 transcript 时,会有意识地排除 assistant 自己的自由文本,主要保留 user 文本与 tool_use 轨迹。

这背后的安全含义很直接:

  • assistant 自己生成的解释文本,可能反过来“说服分类器”批准自己的动作;
  • 若分类器读取了大量模型自述,就有可能形成自我强化回路。

因此,Claude Code 在这里做了一个很重要的隔离:

让意图判定尽量依赖用户输入和客观动作轨迹,而不是模型自我辩护。

6.3 fail-closed 倾向非常明显

无论是 XML 两阶段判定,还是 response parse 路径,都可以看到一个明确倾向:

  • 若 classifier 结果不可解析;
  • 若 classifier 请求中断;
  • 若上下文过长导致异常;
  • 若未拿到预期结构化结果;

系统会偏向 shouldBlock: true 或回退到人工 prompt。

这说明 Claude Code 在意图判定层面采用的是典型的fail-closed / fail-safe策略,而不是“判不清就默认继续做”。

6.4 但这仍然只是“基本意图判断”,不是强语义理解

需要保持克制的是:从源码来看,当前实现更像是安全分类器驱动的风险判定,而非完整意义上的 intent verifier。

原因包括:

  • 它仍以规则模板和启发式上下文为主;
  • classifier 在不同 build / gate 下能力并不一致;
  • 对长链条、多阶段代理目标的语义一致性验证仍较弱;
  • 远不能证明“动作严格等价于用户主观意图”。

因此,更准确的表述是:

Claude Code 已经在实现“面向意图的安全近似判定”,而不是“完备意图理解”。

七、一个值得重视的研究结论:Claude Code 正在形成“身份 + 动作 + 意图”三位一体的 Agent 安全架构

综合前述分析,可以把 Claude Code 当前显露出的安全设计总结为三层耦合结构:

7.1 身份层:谁在驱动系统

  • 账户
  • 组织
  • 设备
  • 会话

这一层解决的是:谁有资格进入 Agent 控制面。

7.2 动作层:系统具体要做什么

  • Tool Use 独立授权
  • Bash / PowerShell 高风险语义检查
  • 规则来源区分(用户、项目、本地、策略、会话等)
  • 远端、通道、本地 UI 的结构化审批

这一层解决的是:每一个副作用动作能否被允许执行。

7.3 意图层:这个动作是否符合人类真实授权边界

  • transcript-based classifier
  • allow / soft_deny / environment 模板
  • fail-closed 输出约束
  • assistant 文本污染隔离

这一层解决的是:为什么这个动作此刻可以被视为合理。

对 Agent 安全而言,这种三层结构比单纯 RBAC 更接近现实需求。因为高权限 Agent 的风险不只来自“没有权限”,还来自:

  • 身份借位;
  • 权限被过度继承;
  • 工具表达能力超出规则粒度;
  • 模型把模糊任务自行扩展成高风险动作。

八、局限与开放问题:它已经有零信任形态,但距离强安全 Agent 仍有距离

从研究视角看,Claude Code 的这些设计值得肯定,但也应看到其边界。

8.1 身份绑定仍然偏平台内闭环

当前身份链条很大程度仍依赖:

  • OAuth 账户体系;
  • Anthropic 自身组织上下文;
  • trusted device token;
  • session token 管理。

这意味着它对第三方企业 IAM、设备姿态、审计总线的原生整合仍有限。

8.2 意图判断仍是概率性,不是形式化验证

无论 classifier 做得多好,本质仍是近似判断器。

它可以降低误操作概率,但不能形式化证明:

  • 用户目标与执行计划完全一致;
  • 子 Agent 行为不会目标漂移;
  • 多步链条组合后仍满足原始授权。

8.3 零信任执行仍主要集中在工具入口,而不是结果约束

目前观察到的控制点大多发生在:

  • tool use 之前;
  • 远端请求进入本地之前;
  • classifier 输出动作建议之前。

但对于“执行结果是否偏离预期”“子步骤组合后是否构成新的高风险状态”,源码层面的结果验证能力仍相对有限。

九、结论:这不是一个简单的权限弹窗系统,而是一套正在成型的 Agent 安全控制平面

如果只从产品表面看,Claude Code 的权限系统容易被理解成:

  • 一些 allow / deny 规则;
  • 一个 Bash 风险检测器;
  • 再加若干确认弹窗。

但从源码整体观察,更准确的描述应当是:

Claude Code 正在构建一套以身份绑定、动作级授权和意图判定为核心的 Agent 安全控制平面。

它的关键特征不是“是否有一个按钮让你点同意”,而是:

  • 将信任从会话级下沉到 action 级;
  • 将授权从静态规则扩展到运行时判定;
  • 将安全边界从“命令是否合法”推进到“动作是否符合用户意图”;
  • 将高权限 Agent 重新置于可审计、可取消、可竞态仲裁的控制结构中。

从安全研究视角看,这一设计方向比“更强的 Agent”本身更值得关注。

因为未来真正决定 Agent 能否进入企业核心工作流的,未必是它会不会写代码,而是它能否被证明:

  • 绑定到具体的人;
  • 约束到具体的动作;
  • 并尽可能忠实于人的真实意图。

Claude Code 至少已经把这件事,当成了一个一等公民问题来处理。

评论