过去一年最常见的 Agent 安全事故模式 过去一年,企业内部 Agent 部署里反复出现的安全事故,有一个高度稳定的模式:Agent 在被提示词注入或被外部内容劫持后,调用了带有真实凭据的外部 API,把内部数据外发到了不该发到的目的地。事后溯源会发现,凭据本身的设计是合规的——它有最小权限、有审计日志、有轮换周期——但凭据一旦交到了 Agent 手里,这套合规设计就等于完全失效。 失效的根本原

过去一年最常见的 Agent 安全事故模式

过去一年,企业内部 Agent 部署里反复出现的安全事故,有一个高度稳定的模式:Agent 在被提示词注入或被外部内容劫持后,调用了带有真实凭据的外部 API,把内部数据外发到了不该发到的目的地。事后溯源会发现,凭据本身的设计是合规的——它有最小权限、有审计日志、有轮换周期——但凭据一旦交到了 Agent 手里,这套合规设计就等于完全失效。

失效的根本原因是凭据持有权被错配。合规设计的逻辑假设是:凭据由人类工程师持有,在工程师主动调用时才生效,凭据泄露可以通过工程师的下一次主动行为被发现。但 Agent 不是工程师——Agent 在被劫持后,会以工程上完全合法的方式调用凭据,凭据系统无法区分"Agent 自主行为"和"Agent 被劫持后的行为",因为两者在 API 调用形态上完全一致。

"凭据交给 Agent"为什么是工程上的最坏设计

在过去一年多份独立工程实践中,把凭据直接交给 Agent 被反复证明是代价最高的设计选择。具体代价有三层。

第一层,凭据失效后没有自然撤销点。一个 Agent 持有 GitHub Personal Access Token,在 30 天有效期内它会反复调用这个 Token;如果某个 prompt injection 攻击让 Agent 把 Token 泄漏到了外部站点,Token 在剩余 28 天里都处于泄露状态,工程侧只有等到下一次定期轮换才能止损。把这种"长时间有效的强凭据"交给 Agent,等于把 Agent 内部的所有脆弱性放大到凭据生命周期的全程。

第二层,凭据粒度不够细。一个 Token 通常对应一组固定的权限,比如"读这个项目的所有 PR、提新 PR、评论 PR"。Agent 在被劫持后,Token 持有的所有权限都被一次性暴露——攻击者不需要逐个攻破,一个 Token 就能拿下所有权限。这与最小权限原则在 Agent 场景下完全错配:Agent 在每次具体任务里只用到 Token 的一部分权限,但剩下没用到的权限全部在 Token 里待命。

第三层,凭据审计无法溯源到操作意图。当 Agent 用 Token 调用某个 API 时,API 侧看到的是"某个 Token 在某个时间点调用了某个端点",看不到调用方是 Agent、Agent 当时在做什么、Agent 的意图是什么。这种"无上下文的凭据"在合规审计时极难定位——事后要查"为什么 Agent 这次发起了 X 调用",只能回到 Agent 日志里找,但 Agent 日志本身可能已经被污染或裁剪过。

从"凭据给 Agent"切换到"凭据留在网关"

把视野拉宽一些,过去半年企业 Agent 安全工程正在发生一个清晰的方向转换:凭据不再交给 Agent,改为留在专门的网关层,Agent 在调用外部 API 时不持有真实凭据。这条转换的工程基础是把凭据持有权和凭据使用权解耦——Agent 持有"使用 API 的权利",但不持有"调用 API 的凭据",网关层在 Agent 调用时临时把真实凭据加上,API 响应到达网关后再脱敏转发给 Agent。

这条转换在工程上有两种主流实现。一种是基于代理拦截的实现:Agent 的所有外部网络请求被一个中间代理(mitmproxy、Envoy、自研网关)拦截,Agent 持有的不是真实凭据,而是看起来像真实凭据的占位符;代理在请求出网时把占位符替换成真实凭据,在响应回传时把响应里的敏感字段剥掉,只把 Agent 实际需要的字段传回去。这种实现的好处是对 Agent 透明,Agent 不知道自己用的是占位符还是真实凭据,代码层不需要修改。

另一种是基于能力令牌的实现:Agent 不持有任何"看起来像凭据"的东西,而是持有结构化的能力令牌——比如 macaroon 这种基于 HMAC 链的加密令牌,令牌本身嵌入了"能用哪个 API、调用频次上限、时间窗口、目标资源范围"等约束;Agent 调用 API 时,网关侧验证令牌的有效性和约束满足情况,满足则放行,不满足则拒绝。Agent 拿到的是一个"调用授权",不是凭据本身。

代理拦截方案:Airut 的 masked secrets 设计

代理拦截方案在工程上落地最完整的一个案例,出现在 2026 年 2 月公开的一个开源项目里。该项目的核心设计是:把 Agent 跑在 rootless Podman 容器里,容器持有的是"surrogate tokens"——形态和真实凭据一致、但不携带任何实际权限的占位符;容器的所有出网请求被一个 mitmproxy 实例强制拦截,代理在请求即将出网时按预设白名单替换占位符为真实凭据;真实凭据只在请求头里存在一瞬间,响应回传后立即剥掉。

这套设计在工程上有几个关键不变量值得专门讲清楚。第一,Agent 进程从头到尾没见过真实凭据——surrogate tokens 是按真实凭据的形态构造的,但里头携带的是不可解密的随机数据,即便 Agent 想把 surrogate 泄漏出去,泄漏的也是无效数据。第二,真实凭据只活在代理的内存里,从不落盘、不写入 Agent 容器、不写进任何持久化存储;代理进程重启时,真实凭据需要从外部密钥管理服务(KMS)重新加载,而不是从本地缓存恢复。第三,代理按"目的域名"决定凭据替换策略——Agent 请求的是 GitHub,代理就注入 GitHub 真实凭据;Agent 请求的是内部数据库,代理就注入数据库真实凭据;Agent 请求的是任意未在白名单内的域名,代理直接 RST。

这套设计的工程价值在于,它把"凭据保护"和"网络隔离"两件事合并成了一个组件。一个 Agent 即使被完全劫持,它能调用的所有外部目的地都是代理白名单内的、它能发出的所有请求凭据都是真实凭据的合法使用、它能看到的响应都经过代理脱敏。攻击者能做的最多是在白名单内的合法操作里反复触发,而不是把数据外发到任意可控地址。

能力令牌方案:SatGate 的 macaroon caveat 设计

能力令牌方案在工程上落地最完整的一个案例,出现在 2026 年 2 月公开的另一个项目里。该项目的核心设计是:Agent 不持有任何"看起来像凭据"的东西,而是持有 macaroon 能力令牌——一种基于 HMAC 链的加密令牌,令牌本身嵌入了 caveat(限制条件);每个 caveat 是一条形如"这个令牌只能用于工具 X、调用频次上限 Y、时间窗口 Z"的硬约束;Agent 调用 API 时,网关侧验证令牌上的 caveat 是否满足,满足则放行,Agent 拿到 API 响应所需的代理调用,不满足则直接返回错误。

macaroon 这套设计的工程特性有几个关键点。第一,令牌可以层级签发——一个父令牌可以签发一个子令牌,子令牌继承父令牌的所有 caveat,再加自己的 caveat;Agent 可以把子令牌委托给 sub-agent,sub-agent 只能看到比自己更严格的约束,看不到父令牌的原始权限。第三,caveat 是加密绑定的——攻击者拿到一个 macaroon 令牌后,无法去掉任何 caveat,因为去掉 caveat 需要令牌签发者的私钥,签名验证会立即失败。第三,caveat 可以是动态约束——比如"这个令牌在调用 search_database 工具时,单次成本不能超过 50 cents",这类约束由网关在每次调用前实时验证,不依赖 Agent 自觉。

这套设计的工程价值在于,它把"凭据保护"和"成本治理"两件事合并成了一个组件。Agent 不再持有任何静态凭据,而是每次任务开始前从网关申请一个针对本次任务的 macaroon 令牌,任务结束立即撤销。攻击者即便劫持了 Agent,能拿到的也只是任务期内一个受限的令牌,任务结束后令牌自动失效,没有任何"长生命周期凭据"可以泄漏。

两种方案的工程取舍

两种方案在工程取舍上各有侧重。代理拦截方案适合"Agent 已经持有代码、需要最小改动"的场景——把 Agent 的网络请求强制走代理,代码不需要改一行,就能把凭据从 Agent 进程里隔离出去。代价是必须部署一个中间代理,代理本身成为新的信任边界;代理一旦被攻破,所有 Agent 的真实凭据都会暴露。

能力令牌方案适合"Agent 从设计阶段就考虑安全"的场景——Agent 持有的是结构化的能力描述而不是凭据,网关验证能力而不是验证凭据;整套系统的信任边界清晰,Agent 进程被攻破不影响任何真实凭据。代价是 Agent 代码需要重写,适配能力令牌的申请、持有、撤销流程;现有 Agent 产品(Claude Code、Cursor 等)需要专门的适配层。

在企业落地的工程实操上,通常的取舍是"代理拦截优先、能力令牌跟进"。第一阶段用代理拦截把现有 Agent 全部包起来,凭据先不交到 Agent;第二阶段逐步把现有 Agent 改造成能力令牌持有者,把代理拦截慢慢退役。这条路径在工程上是渐进式的,不要求企业停下所有 Agent 业务去重写一遍。

企业 Agent 凭据治理的工程新基线

把上述工程实践汇总,可以画出企业 Agent 凭据治理的工程新基线。这条基线由五条构成,缺一不可。

第一条,任何 Agent 都不持有长期静态凭据。Agent 持有的所有访问外部资源的权利,必须以临时能力令牌或代理拦截的形式存在,而不是以长期 API Key、长期 Token、长期密钥的形式存在。长期凭据只允许存在于密钥管理服务(KMS)、外部身份服务(OAuth IdP)、硬件安全模块(HSM),Agent 进程本身不持有任何长期凭据。

第二条,任何 Agent 调用外部 API 都必须经过可审计的网关。Agent 不直接访问外部 API,所有外部访问都走一个独立的网关层;网关层记录每一次调用的 Agent ID、时间戳、目标端点、调用结果,审计日志不可篡改可回放。即便 Agent 被劫持,劫持者也只能触发网关已经记录的调用类型,任何偏离历史模式的调用都会被网关拒绝。

第三条,凭据替换必须在网关层完成,Agent 进程从不见真实凭据。任何真实凭据都只活在网关层的内存里,从网关层到外部 API 的链路是直连的,不经过 Agent 进程;Agent 进程能看到的最多是脱敏后的响应数据,看不到任何能直接用于二次调用的字段。

第四条,能力令牌必须按任务周期签发和撤销。每次 Agent 任务开始前申请一个针对本次任务的能力令牌,任务结束立即撤销;令牌在 Agent 进程内不持久化,跨任务不重用。这条机制把"凭据生命周期"和"任务生命周期"对齐,任务结束等于凭据失效,没有"凭据残留"的窗口期。

第五条,所有凭据策略必须在外部策略文件中定义,不写在 Agent 代码或提示词里。凭据替换规则、能力令牌 caveat、外部 API 白名单,这些都必须由治理侧在外部 YAML/JSON 文件里集中定义,Agent 代码和提示词不能修改这些规则;Agent 在运行时只能读取这些规则、不能改写这些规则。这条机制确保策略变更不需要重新部署 Agent,治理侧独立完成策略迭代。

把这条基线推到企业多 Agent 系统

把视野再拉宽一些,凭据治理的工程基线在多 Agent 系统里尤其关键。多 Agent 协作时,凭据使用的主体从一个 Agent 变成一组 Agent,如果凭据仍然按"每个 Agent 各持一份"的模式分配,凭据管理复杂度会爆炸式增长,凭据泄露的窗口期也会按 Agent 数量增长。

正确做法是把"凭据持有"和"凭据使用"分离到网关层,所有 Agent 都不直接持有任何凭据,所有外部调用都走同一个网关;网关层按 Agent 群体身份、任务类型、调用频次统一做凭据分配和能力令牌签发。这样无论企业内部有多少台 Agent,凭据管理的复杂度都是网关层一个组件的复杂度,而不是 N 个 Agent 的复杂度。

更往前一步,网关层还可以承担"跨 Agent 凭据协调"的职责——当 Agent A 需要调用 Agent B 已经通过网关验证的某项能力时,Agent A 不需要重新走一遍凭据申请,而是通过网关层直接调用 Agent B 的能力接口,网关层记录这次"跨 Agent 能力调用"并对 Agent A 进行二次身份验证。这套机制把多 Agent 系统的凭据治理从"分散管理"切换到"集中治理",在工程上是质的简化。

企业 Agent 治理负责人现在必须回答的三个问题

面对上述基线,企业 Agent 治理负责人现在至少要直接回答三个问题。第一个问题:你企业内部现在有多少 Agent 持有长期静态 API Key / Token / 凭据?每个 Agent 持有哪些外部服务的凭据、这些凭据的有效期是多长、凭据的轮换周期是多长?这个问题不回答,所有"凭据隔离"都是空谈——凭据已经在 Agent 手里了,再多的工程治理都是事后追溯。

第二个问题:你的 Agent 调用外部 API 时,有没有一道统一的网关层负责凭据替换和审计?如果没有,Agent 持有真实凭据,凭据泄露就是常态;如果有,网关层的策略变更能不能在不重新部署 Agent 的前提下完成?

第三个问题:你的 Agent 持有的任何访问权利,能不能在任意时刻被审计和撤销?如果你的 Agent 持有的是长期 Token,撤销只能在轮换周期时自然发生;如果走的是临时能力令牌,任何一次策略更新都能立刻切断 Agent 的访问路径。

结语

Agent 的能力边界在过去一年被显著推前,从"按 prompt 调用一个外部 API"演化到"按 prompt 自主发现并调用多个外部 API"。每推前一步,工程侧的凭据治理基线就必须同步推前一步。把"长期静态凭据交给 Agent"作为主要工程模式的部署,在过去一年的多起 Agent 安全事故里被反复证明不够。把"凭据留在网关、Agent 持有临时能力"作为基线,按代理拦截或能力令牌的方式重新设计 Agent 的凭据体系,是当下能落地的工程基线。

任何企业 Agent 项目,只要涉及 Agent 调用外部 API 或持有访问权限,工程基线就必须做到这五条——Agent 不持有长期静态凭据、所有外部调用走可审计网关、真实凭据只在网关层内存、能力令牌按任务周期签发撤销、策略变更不重新部署 Agent——否则,今天不是某次凭据泄露的主角,也会是下一次的主角。