下一个动作由推理决定
CI job 和微服务的行为可以预先枚举并白名单化。AI agent 的下一个动作由 LLM 在运行时决定。策略不能只写「允许调用 X」,必须能对运行时的意图做判断。
Token Ladder · RFC 8693
TTL 阶梯是非对称的,而且是故意的:Ts 有 DPoP 绑定和逐调用的策略检查,被窃后没有私钥就是废纸,所以可以活得久一点;Tup 是一份没有绑定的上游凭据,谁拿到谁能用 —— 所以它必须最短命。 看完整的 claim 设计 →
The empirical argument
没有服务端补丁可打,因为 PAT 的 scope 本身就是漏洞。
把这些事件排在一起,会得到一个反直觉但一致的结论:它们都不是内存安全漏洞,也都不是「少了一个批准弹窗」。每一起里,那次工具调用都在 agent 的授权范围内。变成灾难的原因,是那份凭据的范围太宽、寿命太长。
这决定了控制点的位置。提示注入防护、工具描述固定、审批弹窗 —— 全都坐在凭据之上。它们能阻止 agent 提出请求,阻止不了那份凭据继续有效。一个被污染的工具描述、一个被投毒的 npm 版本、一个读取 ~/.claude.json 的信息窃取器,抵达的是同一个静态 PAT,而没有一个会经过 PreToolUse 钩子。
反过来说:如果凭据从未落到笔记本上,工具投毒就从「外泄整个私有仓库」降级为「做一次被授权的、有日志的、可撤销的调用」。
—— 这一句就是 AgentPAM 的全部设计前提The problem
今天一个 AI agent 访问敏感 API 的全部身份材料,是一个躺在点文件里的长期 API Key。这个静态字符串把四个维度压扁成一个值。
所有下游控制 —— 授权、审计、撤销 —— 都建立在这个字符串上,因此全部失去分辨率。目标 API 的日志只能说「某个 token 调了我」,永远回答不了「是谁的哪个 agent、为了什么任务」。
证据
以上为第三方调查数据,非我们自采;引用前请自行复核来源。
Self-diagnosis
这是一套用客户语言写的问题分类。先看看你有几条 —— 然后再看我们的答案,以及我们覆盖到哪一步。
失控的 OAuth 授权
我们的答案RFC 9396 RAR 的 authorization_details 表达细粒度授权;MCP 增量 scope 同意(在 WWW-Authenticate 里中途索取),不再一次性给出最大授权。
agent 拿到与人等同的权限
我们的答案agent 拿到的是那个人的严格子集:granted_capabilities ⊆ blueprint 能力天花板,act 链单调收窄。agent 绝不等同于它背后的人。
agent 的动作与决策不透明
我们的答案审计携带 task.purpose 与 sensitivity —— 我们主动采集已声明的意图,而不是被动录制流量。每次调用都绑定到那个声明。
常驻令牌与密钥
我们的答案Tier 0 凭据代持 + 四步 TTL 阶梯(Tup 60–300s)。没有常驻 token,因为 agent 从来就没拿到过。
缺乏可审计性与可追溯性
我们的答案厂商中立的事件 schema(人 / agent / 蓝图 / 任务 / 工具 / 资源 / 决策 / 义务 / 委派链)+ W3C Trace Context 关联 + 哈希链防篡改。
各工具护栏不一致
我们的答案跨 IdP、跨云的单一策略平面。 Entra 管 Entra 里的 agent,AgentCore 管 AWS 里的 —— 没有人管全部。
用户自行连接 agent
我们的答案EMA / ID-JAG 把同意与策略决策从终端用户移到企业 IdP —— 无 OAuth 同意屏、无影子连接、单一撤销点。
AI 工作流中的权限蠕变
我们的答案单调收窄(scope 只能变窄)+ lifecycle_binding(任务终止即失效,不等 TTL 走完)+ 禁止 scope 沿链扩张。
Why classic PAM does not carry over
PAM 已经做了二十年的会话录制和限时借出。它对 AI agent 不成立,不是因为做得不够好,而是因为威胁模型里少了三条。
CI job 和微服务的行为可以预先枚举并白名单化。AI agent 的下一个动作由 LLM 在运行时决定。策略不能只写「允许调用 X」,必须能对运行时的意图做判断。
agent 读到的任何内容 —— 网页、issue、日志、上一个工具的返回值 —— 都可能是攻击者写的指令。因此 agent 的授权不能等同于它所持凭据的授权。传统 PAM 的威胁模型里没有这一条。
agent 代表某人行动,但不完全是那个人。传统 PAM 只有「用户」和「服务账号」两种主体,缺少「降权的、有范围的、有时限的人格」。
人 → 委派 → agent 实例 → 代持 → 工作负载凭据 这条链的每一跳都可验证、可裁剪、可撤销、可审计。
Identity model
「短时效 token」和「持久 agent 身份」不是二选一 —— 它们在不同层。实例长期存在以承载策略、担保人和审计历史;会话每任务签发以承载 on-behalf-of 与任务范围。
这一类 agent 是什么、最多能请求什么。凭据挂在蓝图上,不挂在实例上。
稳定、可寻址的注册实例。担保人强制且必须是人,因此构造上不存在孤儿 agent。
永不作为身份对象持久化。 人的绑定是会话上的一个 claim,不是身份的属性 —— 同一个实例可能自主运行,也可能在不同时刻代表不同的人。
人(sub) → agent 实例(act) → 上游凭据 —— 强制 sponsor、严格子集、从不落到 agent。「non-human」这个词不能把「人还在链条里」挤掉 —— SOC 2 CC6.1 / CC6.6 的归属性论证,全部力量来自「追得回到人」。
idtyp。
Where we sit
MCP 授权规范已经完成了 Resource Server 与 Authorization Server 的拆分。我们天然就是那个 AS —— 这不是硬插进去,这是规范原生的集成点。
Human ---- SSO / OIDC ----> Your IdP (Okta / Entra / Google)
| |
| launches | Tu id_token, TTL ~1h (your policy, not ours)
v |
+-----------------------------+ |
| Agent host process | |
| Claude Code / Cursor / | |
| Codex / in-house framework | |
+--------------+--------------+ |
| MCP (stdio | HTTP)
v |
+-----------------------------+ |
| AgentPAM Local Attestor |<-+ V2 . user-space only . heuristic
| process + device signals |
| Secure Enclave device key |
| DPoP per-request signature |
| strips creds from the env |
+--------------+--------------+
v
+-----------------------------+
| YOUR MCP Gateway | Resource Server -- yours. We do not build one.
+--------------+--------------+
| RFC 9728 AS delegation | RFC 8693 token exchange | ext_authz
v
+=========================================================+
| AgentPAM control plane (your Linux, air-gap capable) |
| Identity registry Blueprint / Identity / Session |
| PDP AuthZEN + COAZ, per-tool/param |
| Credential broker RFC 8693 exchange, DPoP-bound |
| Audit spine OCSF + W3C Trace Context |
| CAEP consumer revoke inside one token TTL |
+=============================+===========================+
| Tup 60-300s, header-injected
v *** THE AGENT NEVER SEES THIS ***
+-----------------------------+
| Sensitive API |
| GitHub / Postgres / AWS / |
| Snowflake / internal SaaS |
+-----------------------------+==== 框起来的那一层控制平面。IdP 是你的,网关是你的,上游 API 是你的。Local Attestor 是纯用户态的可选组件,其证明信号是启发式的。 见安全模型给既有产品套一个 MCP server 的外壳。安全价值:零。售前必须主动澄清我们不在这一层,否则会被归入噪音。
把 IGA 指向一份 agent 清单。这一层真实有用,也是我们的 V1 楔子 —— 但它只盘点,不拦截。
在请求路径上,逐调用校验身份、判策略、注入凭据、写审计,并且能说不。这是唯一能逐工具调用执法的位置。
Integration
RFC 9728 要求网关公布 authorization_servers,而规范允许那个 AS 指向外部 —— 于是接入我们在支持该配置的网关上就是改配置。但要说清楚:规范并不强制那个 AS 是外部的,网关完全可以自任 AS,因此这条路径不是通吃的。实测 12 家网关中 4 家干净支持。
/.well-known/oauth-protected-resource,其中 authorization_servers 指向你的 AgentPAM 实例。RFC 9728 强制WWW-Authenticate。⚠️ 自 2025-11-25 规范(SEP-985)起这一步已变为可选 —— 客户端可回退到 .well-known 发现。backendAuth.oauthTokenExchange.path 指向我们的 token 端点。这一步是唯一真正新增的配置。(本地 YAML 键是 path;tokenEndpointPath 是 xDS/proto 字段名,写进配置文件会加载失败。)我们实现 AuthZEN / COAZ-MCP 的 PDP 接口,注册为外部授权器(gRPC guardrails 或 Envoy ext_authz),凭据注入靠 allow 时的 header mutation。代价:我们看得到请求,但不拥有 token 签发。
我们作为上游 MCP server 被你的网关代理,变成真实工具前面的策略执行代理。代价:多一跳,且只看得到被路由过来的流量。好处:对你的网关零要求。
兼容性矩阵与逐网关的实测状态见架构页 —— 其中大部分条目仍标注为「待实测」,我们不会把未实测的写成已验证。 看兼容性矩阵 →
Enforcement tiers
我们不一次性铺满所有执法层。原因很实际:OS 级执行需要内核扩展、MDM 推送和安全团队审批,开发者不会自装 —— 而第一批用户正是开发者。更重要的是,Tier 0 在原理上已经吃掉了大部分绕过场景。
决定性的控制点。 agent 手上没有凭据,那么它绕过我们直接 curl 也没有用。这一条在原理上就吃掉了 Tier 3 的大部分价值。
主控制面。默认拒绝:未被策略显式允许的工具调用一律拒绝,禁止 fail-open。粒度到 server 级、tool 级、以及参数级。
拦截残留凭据与工程师既有凭据 —— ~/.aws/credentials、kubeconfig 这些本来就在机器上、不经过 MCP 的东西。
回答「非 MCP 动作掉在策略外」这个竞标攻击。这是企业版阶段的问题,不是 V1 的问题。
Deployment posture
这不是一个部署选项,是一条硬约束。凭据代持意味着我们持有通往你所有敏感 API 的钥匙 —— 那把钥匙不应该离开你的网络边界。
控制平面在你自有的 Linux 环境中运行,不要求任何出站云端访问。任何依赖我方 SaaS 才能工作的功能都不会被做出来。
OCI 镜像 + Compose / Helm。最小基础镜像、非 root 运行、只读根文件系统、明确的能力集与网络策略 —— 因为你的安全团队会做镜像审计。
没有遥测、没有在线许可证校验、没有自动更新回连。 许可证是离线签名文件;更新是你主动拉取的镜像。任何「回家」的网络行为,在气隙客户处就是一次事故。
还有一条结构性推论,值得直说:任何以公有云捆绑为前提的方案,在气隙环境中根本不作为选项存在。 这不是我们比谁强,这是部署形态决定的。
What ships
客户侧端点开源,控制平面闭源变现。先做发现与归属,再做执法 —— 因为没人会为一个数不清的群体买执法。
只读 CLI / 轻量守护进程。一条 docker run,不连任何东西,产出:有多少个 agent、各自持有什么凭据、上周碰过什么、哪些在 SOC 2 CC6 下不可归属。零爆炸半径。
OCI 容器组,部署在你自有的 Linux 上 —— 不是 SaaS。 身份注册表、策略编辑、审计视图、审计师就绪报告,以及批准疲劳度量 —— 审批通过率接近 100% 就是橡皮图章信号。
同一容器组内的服务。逐调用策略决策与 RFC 8693 令牌交换,凭据在这里代持并按请求注入。目标 P99 延迟 < 200ms。
代码签名守护进程。不能是 SDK —— SDK 跑在被证明者进程内,自己证明自己,逻辑上无效;而且要在 agent 进程之外持有凭据。
Boundaries
这一节在这里,是因为它对你比对我们更有用。下面每一条如果我们含糊其辞,你的团队在第二次会议上就会戳穿。