AWS发布在Bedrock AgentCore Gateway上治理AI Agent访问的Part 2方案
AWS博客发布系列第二篇,用AgentCore Gateway统一接收请求、由Cedar策略按工具绑定Agent与Okta委托范围,并在EKS上运行第二个Agent;作者称代码为非生产示例。
AI解读:AWS博客发布Hammad Ausaf撰写的教程第二部分,在Part 1基础上,把“一个Agent调用两个MCP服务器、授权检查写在各服务器代码里”的小规模做法,改为用AgentCore Gateway作为统一入口,并在Gateway处用Cedar策略做默认拒绝的前置判定。
来源给出的动机是规模:N个Agent对M个服务器会形成连接矩阵,同一套组检查复制到大量服务器后难审计、难统一修改。Part 2让Gateway持有目标注册表,并代表每个目标兑换Okta授权。
来源列出三项关键约束:每个目标需静态工具schema(listingMode设为DEFAULT),因为测试中按工具命名的策略无法附加到动态列出的目标;客户端需跟随分页游标;每个Agent需独立Gateway和凭据提供方。
来源称其测试覆盖Alice、Bob、Carol及第二个EKS上的Agent B:同一用户通过不同Agent获得不同权限;跨Agent使用ID-JAG、用Okta访问令牌替代ID-JAG、无令牌、发给其他Agent的ID-JAG等请求在网关或模型调用前被拒绝。
来源提供Gateway各环节延迟中位数和p90数据,并说明XAA适用于接受ID-JAG的目标应用授权服务器,拥有自己授权服务器的应用(如GitHub示例)仍依赖每用户OAuth同意。
AWS在Machine Learning博客发布由Hammad Ausaf撰写的教程第二部分,演示如何把Okta Cross App Access与Amazon Bedrock AgentCore组合的Agent授权方案,从单个Agent扩展到Gateway统一入口、Cedar策略和跨运行环境的第二个Agent。
文章明确说明,文中代码片段和配置是概念性示例,不是完整可部署方案,属于非生产用途示例代码;部署前需由安全与法务团队核对组织的安全、监管和合规要求。
从单Agent拓扑改为Gateway统一入口
Part 1的拓扑是一个Agent、两个MCP服务器,授权检查分别写在每个服务器里。文章称这种检查方式可以随规模增长,但拓扑不行:N个Agent对M个服务器会变成接线矩阵,每新增一个工具都要改动所有需要它的Agent。
Part 2让Agent只访问一个Gateway端点,由Gateway持有目标注册表;Gateway通过Part 1的凭据提供方,在Okta自定义授权服务器为每个目标兑换ID-JAG。Cedar策略把每个工具绑定到Agent和Okta委托的范围。
身份权限也随之移动。Part 1中Agent的角色持有令牌交换权限并读取提供方密钥;Part 2中这些权限归Gateway的角色,Agent角色不再持有令牌交换或密钥权限。来源称这是对Agent执行角色的唯一改动。
文章还部署了第二个名为reporting agent的Agent,运行在Amazon EKS上,使用自己的Okta注册、只允许xaa:read的资源连接、自己的Gateway和凭据提供方,用以展示统一入口不依赖Agent的运行位置。
- Gateway入站授权器只接受发给该Agent的ID-JAG,配置中通过allowedClients固定到一个Agent。
- MCP服务器变为Gateway目标,出站授权使用TOKEN_EXCHANGE,目标范围必须与ID-JAG的范围一致。
- 每个目标需设置静态工具schema(listingMode为DEFAULT,内联mcpToolSchema),使Cedar策略引用的工具名固定。
- Gateway按目标分页返回tools/list,客户端不跟随游标会丢失后续目标的工具。
- 来源称一个一次性ID-JAG可供会话内多次工具调用使用,并在测试中于 5 分钟有效期内开启了第二个会话。
Cedar策略与第二个Agent的校验
文章要求在Gateway上挂载ENFORCE模式的Policy in AgentCore引擎,只写允许型策略。Cedar将JWT声明暴露为标签;读取不存在的标签会报错并跳过策略,被跳过的允许不授予任何权限,因此默认拒绝仍然成立,但被跳过的禁止不阻止任何操作,所以策略需用hasTag保护每个标签。
来源给出的策略示例检查client_id与scope,scope标签保存ID-JAG中以空格分隔的scope声明,四个条件用于确保xaa:write作为完整条目匹配,xaa:write-admin不会被匹配。文章还提醒,附加引擎前要确认每条策略状态为ACTIVE,否则Gateway会拒绝所有调用。
运行在EKS上的Agent B没有AgentCore runtime的授权器在前,因此它在模型调用前自行校验ID-JAG的签名、签发方、受众、令牌类型oauth-id-jag+jwt、有效期,以及client_id是否为自身。
文章列出两个实际配置问题:EKS Auto Mode通用节点池只运行amd64,需构建多架构镜像;AgentCore Python SDK默认绑定localhost,需设置DOCKER_CONTAINER=true。第二部分的新增步骤估计约需 90 分钟,EKS控制平面按每小时 0.10 美元计费,另加节点和Auto Mode管理费,AgentCore功能按使用量计费。
- 测试调用方与路径:Alice经Agent A和Gateway A发起create_task,被MCP服务器以需要xaa-writers为由拒绝;Bob经同一路径创建成功;Carol因无groups声明被拒绝。
- Bob经Agent B和Gateway B只列出 4 个工具,Cedar隐藏了写工具,create_task被Gateway以“无适用策略,默认拒绝”拒绝。
- 把Agent B的ID-JAG发到Gateway A,或把Agent A的ID-JAG发到Gateway B,返回HTTP 403和insufficient_scope;用Okta访问令牌替代ID-JAG返回同样的 403;无令牌返回 401。
- 发给EKS上Agent B的Agent A ID-JAG在 98 毫秒内被拒,理由为签发给不同Agent,且发生在模型调用之前。
- Gateway对错误Agent和错误令牌类型返回相同的通用错误,文章建议对照令牌的client_id和aud排查配置。
可观测性与XAA的适用范围
文章称开启CloudWatch Transaction Search和跟踪投递后,runtime、Gateway、Identity和Policy无需改代码即可为每一跳发出OpenTelemetry span;自建服务通过AWS Distro for OpenTelemetry发出span。CloudWatch Transaction Search收集这些span,Okta的System Log通过EventBridge进入CloudWatch Logs,文章给出一个查询将ID-JAG授权事件与后续authz.check决策关联。
文章报告测试中Okta事件在发布后约 1 秒到达。示例查询显示Okta为Alice授予任务Agent xaa:read xaa:write后 16.7 秒,MCP服务器拒绝了她的create_task,随后允许list_tasks;对应的跟踪因这次拒绝被标记为fault。
来源还报告Gateway A在 24 小时内的span延迟:Gateway.InboundAuth中位数 34 毫秒、p90 69毫秒;Identity.Authorize 25毫秒、60 毫秒;Identity.GetWorkloadAccessToken 48毫秒、94 毫秒;Identity.GetResourceOauth2Token 70毫秒、439 毫秒;Cedar每次调用的Policy.AuthorizeAction 47毫秒、56 毫秒;每次工具列表的Policy.PartiallyAuthorizeActions 65毫秒、75 毫秒;Gateway.TargetInvocation 5,565 毫秒、6,273 毫秒。身份与策略span在一次工具调用中按中位数合计约 0.2 秒,MCP服务器自身的authz.check少于 1 毫秒。
文章比较两条路径:XAA适用于目标应用授权服务器接受ID-JAG的场景,由Okta管理员决定哪个Agent可代表哪些用户,用户不看到同意提示,Okta在每次请求令牌时评估策略;拥有自己授权服务器的应用(如GitHub)仍依赖每用户OAuth同意。作者称这一比较基于其部署AWS示例 07-consent-portal-auth-code-flow-targets后测得的行为。
- 部署前需准备eksctl、kubectl、Docker、Okta Log Streaming,以及Gateway、策略引擎、EKS集群、CloudWatch日志组和EventBridge规则所需的IAM权限。
- 来源称ADOT通过botocore获取区域并签名导出,缺少botocore的服务不导出span;ADOT的agent模式默认关闭requests、urllib3等HTTP客户端插桩,需通过OTEL_PYTHON_DISABLED_INSTRUMENTATIONS调整。
- 示例方案基于GitHub上的AWS示例 08-okta-xaa-delegation-chain,Part 2的增补建立在其上。