智能体替你登录,但不碰密码:委托授权要拆开的三层权限

一、它真正拆开的是”往表单里填值”这个动作
据公开报道,1Password 面向 AI 智能体的登录方案(1Password for Agents)机制是这样一条链:智能体遇到需要身份验证的登录页时,先以自己持有的一把数字密钥向托管端证明”我是哪个智能体”;托管端向用户的设备发出授权请求,请求里带上准备使用哪一条凭据、以及智能体自述的任务用途;用户批准后,由托管端把用户名、密码或一次性验证码填进登录表单,智能体接着往下跑,密码始终留在保险库里。智能体不会拿到整个密码库,未被明确授权的条目仍受端到端加密保护。
从工程视角读,这套东西的实质不是委托授权,而是代填:凭据值一步都没跨出托管端,但登录的产物——会话——留在了智能体那一侧的浏览器或运行时里。这个区分决定了它能被借鉴到哪里。我们更熟悉的委托授权是另一条路:OAuth 2.0 的授权码交换加刷新令牌托管,用户在同意页上勾选的是作用域,服务端换出来的是一张只能干某几件事、可独立吊销、到期自动失效的短期令牌,PKCE 负责把这次交换绑到当前那个客户端实例上。两条路的差别可以压成一句话:
- 代填保的是”秘密不泄露”,代价是动作层的约束全部留在目标应用自己家里;登录成功之后,应用在权限上看到的仍然是”这个用户来了”,而不是”这个用户被允许做这三件事”。
- 作用域令牌保的是”能力不外溢”,代价是目标系统必须支持它,而绝大多数存量网站和政企内部系统不支持。
所以它的真实定位是存量系统的适配层,不是一种新的授权模型。这一点在方案里必须写明白。洹拓科技的评审表上有一项固定动作:凡是把代填方案描述成”实现了 OAuth 级委托授权”的,直接打回重写。
二、身份、会话、动作:三层各自塌在哪里
把”智能体代持一个人的身份”拆成三层来管理,是这件事唯一有意义的产出。
- 第一层,身份:谁在发起。 这一层管的是智能体自己的可验证标识——密钥归谁生成、存放在哪、轮换周期怎么定、被吊销后正在跑的任务怎么办。它的要害是身份归属容易搞混:请求里同时存在两个人称,”用户张三批准了”和”Claude 那个智能体请求的”。日志里如果只保留了前者,那么同一批凭据被多个不同智能体用过,事后根本区分不出来。
- 第二层,会话:这次登录的产物归谁持有。 托管端注入完成后,Cookie 和本地存储落在智能体控制的那个浏览器上下文里。看不到密码确实降低了长期损失,但会话令牌对自动化程序的价值并不低于密码:改绑手机、改邮箱、导出账单,这些用密码能做的事,用一个已登录会话同样能做,而且不需要再过一次密码强度校验。
- 第三层,动作:登录之后允许做哪几件事。 这一层在绝大多数方案里是空的。目标系统只有”会话是否有效”这一个判断,它不知道会话背后是人还是自动化程序,也不知道这一次点击属于哪个任务。
三层的归属方还不同:身份层在托管端与智能体框架,会话层在浏览器/运行时,动作层在目标系统。三方各管一段,中间没有共同的判定语言,这是它最容易塌的结构性原因。第二层还有一件必须做实的事:人不在场时怎么降级。会话的存活上限、敏感动作强制二次挑战、闲置即撤销——这三件事要落在会话层,而不是落在应用页面上那句”请重新登录”的提示里。
三、人在环上的代价:合并授权要按可逆性划界
每一次登录都向用户设备推一条请求,看起来安全,成本全部落在人的注意力上。当一天出现十几条请求,用户批准的对象就从”这次登录”漂移成”这个智能体总体上可以信任”,等于用逐次授权的界面实现了常驻授权的效果——恰恰是这套机制想避免的那件事。
判断哪些动作可以并进一次授权、哪些必须逐次确认,我们的判据只有三条,按顺序问:
- 可逆吗。 提交之后能不能自己撤回、能不能由系统回滚。只读抓取和草稿填写属于可逆;对外发消息属于难逆;支付、注销、批量删除属于不可逆。难逆与不可逆一律逐次,任何”记住我的选择”都不该覆盖它们。
- 有没有金额或数据量的刻度。 有刻度就让它先小后大:首次只允许一个下界内的动作量,超出即重新确认。没有刻度的动作(改安全设置)按最难逆的那一档处理。
- 是不是第一次接触这个目标。 首次接触必须逐次确认,且这次确认不能沉淀成长期例外。理由很直接:智能体自述的用途是文本,人无法核验,而域名是可以在请求里核对的硬信息。
第三判据里藏着这套方案最实际的一个问题:授权请求展示给用户的信息质量,决定了人工确认到底值多少安全分。”用途”那一段是智能体自己写的,写”帮你整理账单”和实际去导出全部交易明细,在界面上看起来一样。我们的要求是把可核对的硬字段放在最显眼处——目标域名全称、被使用的凭据条目名称、这次会话的有效期、本次授权放开的动作集合——自述文本只作辅助说明,绝不作为批准的唯一依据。合并不在这份清单上的动作,一次授权都不能带过去。
四、审计点搬到了代理身上,日志就得换一套字段
托管方拿到的是”能替你登录任意被授权的站点”这一项能力。这在架构上等于把审计点从分散的各应用搬到了一个代理上:代理看不到业务语义,但它看得见每一次凭据使用。搬动之后,日志字段必须重排。我们认为合格的记录至少包含这六段:
- 发起方标识:智能体身份密钥的指纹、宿主框架与版本、任务实例 ID。不能只记”某用户批准了”,必须记”谁请求的”。
- 被授权的对象:凭据条目 ID 与目标域名全称。绝不记录凭据值,也不记录可还原的密文——日志里一旦出现明文口令,这套方案的意义当场清零。
- 批准的现场:批准设备、批准时间、当时展示给用户的文本原文及其摘要值。留摘要的原因是提示文案会被改,改过之后仍能证明当时用户看到的是什么。
- 注入动作:由哪个组件执行、注入到哪个 URL 的哪个表单、返回的结果是什么。
- 会话生命周期:会话标识的不可逆摘要、签发时间、撤销时间与撤销原因。会话标识本身不落盘。
- 任务终态:任务是否完成、用户在任务结束后有没有收回授权。
回溯时的提问方式也要跟着换。要能回答”这段时间里,哪一次授权放开了这个动作”,而不是只能回答”这个会话属于谁”。这要求智能体、授权记录、会话、动作四段在字段上串得起来,缺任何一段,责任就断在中间——托管端说”我是按用户批准执行的”,应用侧说”我这边只是一个合法会话”,两边都对,事情就查不下去。代理化架构的代价就在这里:它把复杂度从每个应用收走,堆到了一个必须在事故里扛住追问的组件上。
五、动作类型、合并方式与会话上限的对应关系
| 动作类型 | 可否合并授权 | 会话上限 | 我们要求留的证据 |
|---|---|---|---|
| 只读浏览与资料抓取 | 可,按”同一目标 + 同一凭据”合并为一次 | 单任务生命周期,任务结束即撤销 | 目标域名、请求次数上下界、任务实例 ID |
| 代填表单但不提交(草稿类) | 可合并 | 同上 | 表单标识、明确未提交的结果 |
| 对外可见的提交(发消息、开工单) | 首次逐次,重复同类可合并且必须能一键收回 | 会话可复用,但每次提交单独记账 | 每一条动作记录与内容摘要 |
| 改安全设置、改绑手机或邮箱 | 不可合并,逐次 | 不复用长会话,敏感动作强制二次挑战 | 二次挑战结果、目标系统自身审计流水号 |
| 支付与额度变更 | 不可合并 | 不允许智能体走完最后一步 | 金额字段、收款方、用户当场确认文本的摘要 |
| 批量导出或删除 | 不可合并,默认拒绝 | 一次性会话,用完立即撤销 | 影响范围的量级描述、目标位置、撤销时间 |
这张表背后是三条设计约束。合并的单位是”目标 + 凭据 + 动作集合”这个三元组,不是”财经类网站””办公类网站”这种分类;按分类合并等于一次授权放开一整类域名。会话上限的定义权必须在托管端而不是在智能体手里,否则”我的任务还没跑完”就是无限延长会话的理由。不可逆动作不要指望靠更谨慎的提示词避免,正确做法是把动作拆开:智能体准备好一切,最后那一下由人来点,这比任何判定规则都可靠。
六、这类委托在我们这类交付里成不成立
成立,但只在一种条件下成立:目标系统既没有开放 API,也不支持可吊销的作用域令牌,而业务确实要求智能体跨系统办事。这时候代填是净收益——它至少把”密码进了模型上下文”这条最糟的路堵住了,而这条路在真实项目里相当常见,通常表现为把凭据写进环境变量再被某个调试输出打印出来。
反过来,三种情况下我们不会签这种方案。目标系统本来支持作用域令牌却仍然用代填,等于把复杂度放错了地方:代填换来的是”密码不外泄”,换不到”能力不外溢”,而事故追责时需要的是后者。智能体自己持有浏览器且无人监督长时间运行,此时会话层的降级根本没人执行,机制退化成一层装饰。最后一类是客户已经把托管端当作日志系统的替代——托管端记录的是凭据使用,不是业务动作,两者永远不能互相还原。
判断收敛到一句:把”能操作账号”和”能看见密码”分开,是这套方案真正的贡献,也是它的全部贡献。它只解决了三层里的前两层,第三层仍然是空的,需要有人补——补的人通常是把智能体接进业务流程的那一方,而不是密码管理器。所以交付文档里必须有一节明确写”本方案没有解决什么”,比写它解决了什么更重要。这是洹拓科技在 Agent 类项目验收单上固定的第一条:一个只做到”看不见密码”的系统,如果让客户以为三层权限都已经处理完,那它比直接交密码更危险。