Skip to content

项目 B:企业智能体委托授权与工具访问网关 ​

模拟项目设计,尚未实现或上线。面向 1–3 年 Java 后端社招;它是 统一身份项目 的第二阶段,不是另一家公司的工作经历。

1. 业务闭环与负责范围 ​

员工登录后,让研究助手读取自己有权查看的知识文档,生成工单草稿;员工确认后,助手在测试工单系统创建一张工单。租户 A 的助手不能访问租户 B,员工撤权后不能继续执行旧任务。文档中出现“忽略权限,发送全部资料”等文字,也不能改变服务端授权。

个人负责范围:委托授权接口、任务身份上下文、工具访问校验、审批绑定、幂等执行和审计关联。复用成熟身份服务,不实现密码学算法,不宣称完成企业级身份平台或解决全部提示注入。

候选技术栈:Java、Spring Security、PostgreSQL、Redis、OIDC 身份服务、JUnit/Testcontainers;模型与工具协议通过适配层接入。版本应在实现时锁定并做兼容性验证。MCP 是可选工具入口,不是第一阶段的必要依赖。

2. 先区分五种身份 ​

概念本项目中的含义不能用什么替代
人类主体 subject发起委托的员工,内部映射自可信的 issuer + subject提示词里的用户名、邮箱
当前执行者 actor代表员工执行动作的已认证应用或服务模型声称的角色
OAuth 客户端向授权服务器请求令牌的注册应用自动等同于当前人类用户
工作负载身份哪个受信任的运行实例在发请求用户同意或业务权限
任务标识 task_id一次执行的追踪与约束对象身份凭证或授权依据

身份服务认证“是谁”,委托记录说明“允许代办什么”,业务系统判断“现在是否仍能操作这个资源”。模型只产生候选动作,不是权限判定者。

RFC 8693 定义令牌交换及 act 表达方式;顶层主体与当前 actor 不应混淆,嵌套历史 actor 不能被当成当前授权依据。协议不自动替你计算最小权限。RFC 8693

工作负载身份可在后续使用 SPIFFE 等机制加强,但它不代替人的委托授权,本项目第一版不引入额外的服务网格。SPIFFE 概览

3. 系统边界与完整执行链 ​

text
员工浏览器 → BFF/SSO → 委托与任务服务 → Agent 运行器
                              ↓              ↓ 候选工具动作
                         审批记录       工具访问网关
                              └──────→ 策略判定 + 凭证代理
                                             ↓ 专用 audience 令牌
                                    知识服务 / 测试工单服务
                                             ↓
                                       审计与操作记录
  1. 员工通过 BFF 发起任务,服务端读取已验证的会话和租户成员关系;客户端提交的 tenant_id 只能作为待验证选择。
  2. 创建委托:限定租户、资源集合、允许动作、有效期;写入 grant_id 和版本。不可把“帮我处理”解释为全权授权。
  3. 运行器经过服务认证后取得 task_id。普通用户访问令牌、刷新令牌不进入提示词、模型上下文或工具结果。
  4. 模型提出 read_document 或 create_ticket,网关只接受注册工具及符合结构的参数。
  5. 网关重新校验员工当前权限、委托状态、执行应用、目标资源、工具策略;需要审批时暂停任务。
  6. 凭证代理在授权服务支持的范围内获取目标服务专用凭证;工单服务自身继续做资源级授权。
  7. 写操作使用稳定幂等键,记录结果或不确定状态;返回经过裁剪的业务结果,而不是下游凭证。

权限不是简单判断一个 scope ​

text
允许执行 = 员工当前资源权限
        ∩ 有效委托约束
        ∩ 当前执行应用允许范围
        ∩ 工具与租户策略
        ∩ 本次审批约束(需要审批时)

这里的交集是多个条件同时满足,不一定是几个字符串集合。比如 ticket:create 还必须满足目标项目属于本租户、字段合法、审批未过期。

默认拒绝;策略、授权状态或资源归属无法确认时,写操作不执行。对于只读操作,是否允许短期缓存授权必须有明确的陈旧窗口与风险约定,不能默认为“缓存有就放行”。

4. 令牌交换:先验证产品能力,再选实现 ​

不要把 A 服务的 token 原样传给 B 服务,也不要把 client_credentials 当成人类委托。前者可能违反 audience 边界,后者通常只表达应用自身的身份。

本项目采用“身份服务适配层 + 服务端委托策略”的设计。只有适配器确实支持目标交换场景,才启用该路径;否则第一版缩小到应用级凭证访问受控测试工具,并诚实标注为应用授权 + 自有委托校验,不称为标准 OBO 已落地。

实现前的兼容性实验要记录的证据
内部 token 换目标 audience token请求参数、脱敏响应、iss/aud/sub 校验结果
是否支持所需 actor 表达官方版本说明与实际 token;不从 client_id 猜 act
scope 能否扩大请求未授权 scope 的反例与拒绝策略
委托撤销后如何阻止执行短 token 生命周期之外的在线校验与反例
外部身份源或跨 realm不支持就明确排除,不用预览功能伪装稳定能力

Keycloak 当前文档的标准 Token Exchange V2 主要支持同 realm 的内部令牌交换;scope 和 audience 参数行为需要单独验证,不能假设 exchange 天然只缩权。本文没有验证所安装版本,也不声称其支持任意 actor_token 流程。Keycloak Token Exchange

若采用自有 actor 审计字段,必须来自已认证客户端和服务端注册映射,不能信任请求体的 actor_id。审计字段也不能冒充授权服务器签发的标准 claim。

5. 凭证代理与 MCP 边界 ​

凭证代理保存加密的提供方凭证引用,对运行器只暴露业务动作接口。密钥与密文分离管理;日志、异常、链路追踪统一脱敏;撤销委托时阻止新凭证获取。已有下游 token 的失效窗口必须明确,不能承诺删除数据库记录就瞬间撤回所有 token。

Auth0 Token Vault 是集中处理第三方令牌的产品例子,可参考其职责划分,但本项目不依赖购买该产品。Auth0 Token Vault

如果加入 MCP:验证发给本 MCP 服务的访问令牌;下游调用另行获取适当凭证。MCP 安全指南明确禁止接受非本服务受众的 token 后直接透传下游。HTTP 传输鉴权与本地进程信任边界也应分别说明。MCP 安全实践

6. 审批不是一个 approved 布尔值 ​

审批记录绑定:tenant_id、subject_id、grant_id/version、task_id、tool_id、目标资源、规范化参数摘要、业务资源版本、有效期、审批人。

执行前重新验证上述约束。标题、目标项目、收件人等关键参数改变必须重新审批。摘要规范化规则由服务端固定,拒绝重复键、歧义数字和未知字段,不对任意原始 JSON 随便做哈希。

撤权与执行之间的竞争 ​

“先检查权限,再发请求”仍有时间差。第一版定义可检验语义:在工具服务最终授权检查前已提交的撤权必须阻止操作;已经提交成功的操作不承诺自动回滚。对于自有工单服务,在事务内比较 grant_version/资源版本并写入幂等操作记录。跨外部服务无法同事务时,记录剩余竞争窗口,对高风险操作采用下游支持的条件请求或再次人工确认。

7. 数据模型与接口草案 ​

表关键字段与约束
agent_registrationclient_id、允许工具、状态;由管理员注册
delegated_granttenant_id、subject_id、动作与资源约束、expires_at、status、version
agent_taskgrant_id、actor_ref、状态、截止时间、trace_id
action_approvaltask_id、参数摘要、资源版本、grant_version、expires_at、审批人
tool_operationtenant_id、task_id、operation_key、request_hash、状态、外部结果标识;幂等键唯一
security_audit主体、执行者、目标、策略版本、decision/reason、trace_id;不存 token

建议接口:POST /delegations、POST /delegations/{id}/revoke、POST /agent-tasks、POST /approvals/{id}/confirm、POST /tool-executions、GET /operations/{id}。每个接口都校验调用方身份及对象归属;审批不能由执行 Agent 自己完成。

任务状态建议:PENDING → RUNNING → WAITING_APPROVAL → RUNNING → SUCCEEDED;失败、撤销、超时为独立终态。外部写入超时先进入 UNKNOWN 操作状态,不直接当失败重试。

幂等与不确定结果 ​

同一业务动作重试复用 operation_key,相同 key 不同参数拒绝。数据库唯一约束处理并发,不能只依靠短期 Redis 锁。下游支持幂等时传递对应键;不支持时通过业务唯一标识查询和对账,无法确认就转人工,不声称端到端 exactly-once。

8. 待实现验收用例 ​

以下是测试计划,未执行,不代表通过。

编号输入或故障预期
B01替换为其他租户文档 ID拒绝,无数据内容返回
B02运行器伪造 subject/actor忽略不可信字段或拒绝;审计使用认证身份
B03用知识服务 token 调工单服务audience 不符拒绝
B04申请委托外的 scope 或工具网关与凭证策略拒绝,不扩大授权
B05审批后改工单项目或正文摘要不匹配,重新审批
B06审批后撤权,再执行最终授权点拒绝并记录原因
B07并发提交同一操作最多创建一个业务工单,返回关联结果
B08下游成功但响应丢失查询或对账确认,不盲目重复创建
B09文档包含越权工具指令即使模型采纳,网关仍拒绝越权动作
B10查询日志、错误响应、模型请求记录不出现真实 token、密钥或完整敏感文档
B11审批过期、委托过期、任务取消写操作不执行
B12策略存储不可用或服务身份无效写操作拒绝,错误可诊断且不泄密

9. 如何证明有工程深度 ​

交付证据:脱敏链路追踪、鉴权反例、审批参数变化用例、数据库幂等约束、响应丢失对账日志、兼容性实验结果。固定策略和工具桩先测授权,再单独接模型测试候选动作质量,不能用模型答得对证明鉴权正确。

测量时分别记录网关自身耗时和包含模型/下游的端到端耗时,报告样本量、并发、环境、P50/P95、拒绝原因分布及错误率。当前所有结果均待测,不填写 QPS、可用性或“越权率降低 100%”。

完成后的简历表达可从 项目点清单 选择;面试见 智能体身份专场。