人工智能
用 Okta Cross App Access 与 Amazon Bedrock AgentCore 治理 AI 智能体访问 – 第 2 部分在 第 1 部分中,你在 Amazon Bedrock AgentCore上构建了一个任务智能体,该平台可用任意框架或模型大规模构建、连接和优化智能体。该智能体运行在 Amazon Bedrock AgentCore runtime(Amazon Bedrock AgentCore 的一项能力)上,并通过 Okta Cross App Access(XAA)代表已登录用户执行操作。Okta 决定哪个智能体可以代表哪个用户执行操作,而 Amazon Bedrock AgentCore Identity(Amazon Bedrock AgentCore 的一项能力)则在智能体内部兑换了 Okta 的授权。这证明了治理机制可行,但它运行在一个刻意精简的拓扑上:一个智能体、两个 Model Context Protocol(MCP)服务器,以及写入每个服务器的授权检查。
该机制可以扩展,但拓扑不行。对于一个智能体和两个工具来说没问题的三件事,在企业拥有数百个智能体和数千个工具时就成了工作负担:
| 第 1 部分做了什么 | 为什么它无法扩展 | 第 2 部分改用什么方案 |
| 智能体持有每个 MCP 服务器的运行时 ARN,并直接调用它 | N 个智能体对 M 个服务器构成一张接线矩阵,每新增一个工具都要改动所有需要它的智能体 | 智能体只访问一个 Gateway 端点,由 Gateway 持有目标注册表 |
| 智能体的角色持有令牌交换权限,并读取提供方的密钥 | 每个代表用户执行操作的智能体,都会获得一条通往其可能访问的每个资源的凭证路径 | Gateway 兑换授权,而智能体角色不持有任何令牌交换或密钥权限 |
每个 MCP 服务器都在自己的代码中执行相同的 groups 检查 |
同一条规则被复制到数千个服务器后会产生漂移,无法审计,也无法在一处修改 | 在工具运行之前,由 Gateway 评估一套默认拒绝的 Cedar 策略 |
在本文中,你将在第 1 部分的解决方案上做出这一改动。Amazon Bedrock AgentCore Gateway 是 Amazon Bedrock AgentCore 的一项能力,它成为唯一的统一入口,并为每个目标兑换 Okta 的授权。Amazon Bedrock AgentCore 中的 Policy 会评估 Cedar 策略,这些策略将每个工具绑定到智能体以及 Okta 委托的 scope。Amazon Elastic Kubernetes Service(Amazon EKS)上的第二个智能体以自己的 Okta 身份加入,以表明这个统一入口并不关心智能体运行在哪里。而 Amazon Bedrock AgentCore Observability 是 Amazon Bedrock AgentCore 的一项能力,它与 Amazon CloudWatch 结合,为你提供一个统一的位置来读取每一个决策,包括 Okta 的决策。我们还会针对无法接受 Okta 授权的应用,将 XAA 与按用户 OAuth 同意进行比较。
与第 1 部分相比有哪些变化
Okta 配置、AgentCore Identity 凭证提供方以及第 1 部分中的 MCP 服务器均保持不变。图 1 展示了新增部分后的架构。
图 1:采用 AgentCore Gateway、Policy 和 Observability 的第 1 部分解决方案,Amazon EKS 上的第二个智能体,以及审计路径,图中编号与后续步骤相对应
- 用户登录后,前端后端(BFF)将 ID 令牌兑换为签发给任务智能体(智能体 A)的 Identity Assertion JWT Authorization Grant(ID-JAG),与第 1 部分相同。
- BFF 使用该 ID-JAG 在 AgentCore 运行时上调用智能体 A。
- 智能体 A 将该 ID-JAG 转发给其 Gateway,作为其 MCP 会话的持有者令牌。Gateway 的入站授权器只接受智能体 A 的 ID-JAG。
- AgentCore 中的 Policy 会在 Gateway 调用目标之前,针对每次工具列表和每次工具调用评估 Cedar 策略。
- 对于 Cedar 允许的调用,Gateway 会让 AgentCore Identity 通过第 1 部分的凭证提供方,在 Okta 的自定义授权服务器上为每个目标兑换该 ID-JAG。Cedar 拒绝的调用不会兑换该 ID-JAG。
- MCP 服务器会像第 1 部分那样检查用户的组和 scope,并将每个决策记录为一个
authz.checkspan。 - 每一跳都会向 AgentCore Observability 发送 OpenTelemetry span,由 CloudWatch Transaction Search 收集,而 Okta 则通过 Amazon EventBridge 将其 System Log 流式传输到 CloudWatch。
报告智能体,即智能体 B,运行在 Amazon EKS 上,并通过其自己的 Gateway 遵循相同的路径。
先决条件
除第 1 部分的解决方案外,你还需要以下内容:
| 先决条件 | 用于 |
| eksctl、kubectl 和 Docker | Amazon EKS 上的第二个智能体 |
| Okta 日志流式传输 | CloudWatch 中的 Okta 系统日志 |
| AWS Identity and Access Management (IAM) 权限 | AgentCore Gateways 和策略引擎、Amazon EKS 集群、CloudWatch 日志组以及 Amazon EventBridge 规则 |
新增部分大约需要 90 分钟。EKS 控制平面每小时收费 $0.10,外加节点和 Amazon EKS Auto Mode 管理费,AgentCore 功能按使用量收费。参见 Amazon EKS 定价 和 Amazon Bedrock AgentCore 定价.
与第 1 部分一样,本解决方案的基础是 GitHub 上的 AWS 示例 08-okta-xaa-delegation-chain ,你可以在其之上构建第 2 部分的附加内容。除该示例之外,本文中的代码片段和配置仅从概念上展示该模式。它们并不是一个完整、可部署的解决方案。该代码是供非生产使用的示例代码,因此在部署之前,请与你的安全和法务团队合作,以满足你组织的安全、监管和合规要求。
创建一个接受 ID-JAG 的 Gateway
Gateway 的入站授权器的工作方式与第 1 部分中的运行时授权器相同。其签发者是 Okta 的组织授权服务器,其受众是自定义授权服务器,并且 allowedClients 将其固定到一个智能体:
authorizer = {"customJWTAuthorizer": {
"discoveryUrl": f"{OKTA_ORG}/.well-known/openid-configuration", # the ID-JAG's issuer
"allowedAudience": [f"{OKTA_ORG}/oauth2/{CUSTOM_AS_ID}"], # the resource's authorization server
"allowedClients": [AGENT_CLIENT_ID], # only this agent's ID-JAGs
"allowedScopes": ["xaa:read", "xaa:write"],
}}
图 2 展示了生成的入站授权器。
图 2:Gateway 仅接受 Okta 为该资源的授权服务器签发给该智能体的 ID-JAG
每个 MCP 服务器都会成为一个 Gateway 目标,其出站授权使用 TOKEN_EXCHANGE 通过第 1 部分的凭证提供程序,因此 Gateway 会执行第二次交换:
"credentialProviderConfigurations": [{
"credentialProviderType": "OAUTH",
"credentialProvider": {"oauthCredentialProvider": {
"providerArn": provider_arn, # the JWT_AUTHORIZATION_GRANT provider from Part 1
"scopes": ["xaa:read", "xaa:write"], # must equal the ID-JAG's scopes
"grantType": "TOKEN_EXCHANGE",
}},
}]
图 3 展示了按此方式配置的目标。
图 3:任务管理器目标通过第 1 部分的凭证提供程序兑换 ID-JAG
这里有三个细节很重要。第一,与第 1 部分一样,目标的 scopes 必须与 ID-JAG 的 scopes 相等。第二,为每个目标提供一个静态工具 schema(listingMode 设置为 DEFAULT 并内联 mcpToolSchema),这样你在编写 Cedar 策略时引用的工具名称就是固定的。在我们的测试中,指定工具名称的策略也无法附加到动态列出的目标上。第三,Gateway 会分页 tools/list 按目标分页,因此你的客户端必须跟随分页游标,否则后续目标中的工具就会消失。AgentCore Identity 会保留 Gateway 交换所得的令牌,因此一个一次性 ID-JAG 即可服务于会话中的每一次工具调用。在我们的测试中,它还在其 5 分钟有效期内开启了第二个会话。
由于一个凭证提供程序只能以一个 Okta 智能体身份进行认证,请为每个智能体分配各自的 Gateway 和提供程序。示例 08-okta-xaa-delegation-chain 采用了不同的路径,其中由 Gateway 拦截器自行完成两次交换。
用 Cedar 将工具绑定到智能体
在 AgentCore 引擎中将 Policy 以 ENFORCE 模式附加到 Gateway,并编写仅允许(permit-only)的策略。Cedar 会将 JWT 声明暴露为标签。读取缺失标签的策略会报错并被跳过。被跳过的 permit 不会授予任何权限,因此默认拒绝依然生效,但被跳过的 forbid 块。用 保护每个标签, hasTag:
permit(
principal is AgentCore::OAuthUser,
action in [AgentCore::Action::"taskmanager___create_task",
AgentCore::Action::"taskmanager___update_task_status"],
resource == AgentCore::Gateway::"<gateway-arn>"
) when {
principal.hasTag("client_id") && principal.getTag("client_id") == "<agent-client-id>" &&
principal.hasTag("scope") &&
(principal.getTag("scope") == "xaa:write" ||
principal.getTag("scope") like "xaa:write *" ||
principal.getTag("scope") like "* xaa:write" ||
principal.getTag("scope") like "* xaa:write *")
};
作用域标签保存 ID-JAG 以空格分隔的 scope 声明,因此四个条件仅作为整体条目匹配 xaa:write 。像 xaa:write-admin 这样的作用域不会匹配。以相同方式编写的匹配策略允许读取工具使用 xaa:read。在附加引擎之前,请检查每个策略是否 ACTIVE :如果引擎的策略创建失败,Gateway 会拒绝所有调用。Cedar 将工具绑定到智能体及其委托作用域,而 MCP 服务器仍会根据 groups 声明决定每个用户的权限,与第 1 部分相同。
将智能体指向 Gateway
现在,智能体 A 不再自行调用 AgentCore Identity,而是将其入站 ID-JAG 转发给 Gateway:
id_jag = context.request_headers["Authorization"].removeprefix("Bearer ") # allowlisted header
tools = make_client(GATEWAY_URL, id_jag) # the Gateway redeems the ID-JAG for each target
从智能体的执行角色中移除第 1 部分的 AgentCore Identity 语句。这是对该角色的唯一改动,该角色现在不再持有令牌交换或密钥权限,因为 Gateway 的角色持有交换令牌的权限。保留 allowedClients 在运行时的授权器上。
在 Amazon EKS 上运行第二个智能体
我们的第二个智能体是一个报告智能体,它在 Amazon EKS 上运行相同的代码,并拥有自己的 Okta 注册。其资源连接仅允许 xaa:read,并且它有自己的 Gateway 和凭证提供程序。EKS Pod Identity 为该 Pod 提供一个 IAM 角色,该角色只能调用模型并写入自己的日志和跟踪,除此之外别无其他。AWS Distro for OpenTelemetry (ADOT) SDK 导出其跟踪。 agents-on-eks 示例 展示了 Pod Identity 的配置。
在 AgentCore 运行时之外,Pod 前面没有授权器,因此智能体在调用模型之前会验证 ID-JAG。它会检查签名、签发者、受众、令牌类型、 oauth-id-jag+jwt、过期时间,以及 client_id 是否为其自身。如果你保留了第 1 部分中 MCP 服务器里的智能体检查,请将智能体 B 的客户端 ID 添加到 REGISTERED_AGENTS。有两个设置让我们踩了坑。EKS Auto Mode 的通用节点池仅运行 amd64,因此需要构建多架构镜像。而 AgentCore Python SDK(Amazon Bedrock AgentCore 的一项能力)会绑定到 localhost ,除非你设置 DOCKER_CONTAINER=true.
用 AgentCore Observability 追踪每一个决策
本节的 span 是 AgentCore Observability,即图 1 中位于智能体与 CloudWatch 之间的组件。在你开启 Transaction Search 和跟踪投递后,Runtime、Gateway、Identity 和 Policy 无需更改代码,就会为每一跳发出 OpenTelemetry span。你自己的服务则通过 AWS Distro for OpenTelemetry (ADOT) 添加各自的 span。CloudWatch Transaction Search 收集这些 span,AgentCore 控制台将它们作为智能体跟踪读取,而 Amazon CloudWatch Omni 将相同的 span 读取为 traces.default,正因如此,一次查询就能将它们与 Okta 的事件并列呈现。
因此,一次工具调用会产生如下 span 链,每个 span 都标明做出决策的控制组件:
| Span | 发出方 | 记录内容 |
AgentCore.Gateway.InboundAuth |
Gateway | 入站 ID-JAG 是否签发给了此智能体 |
AgentCore.Policy.AuthorizeAction |
策略 | 此工具的 Cedar 决策 |
AgentCore.Identity.GetWorkloadAccessToken |
身份 | 将智能体的工作负载身份绑定到用户 |
AgentCore.Identity.GetResourceOauth2Token |
身份 | 在 Okta 兑换 ID-JAG 以获取限定范围的访问令牌 |
AgentCore.Gateway.InvokeTool |
网关 | 工具调用及其结果 |
authz.check |
MCP 服务器(ADOT) | 用户的组、智能体、决策和原因 |
Okta 的 System Log 是 AWS 无法发出的那一条记录,因此你需要将它引入。图 4 显示两条路径在 Omni 中汇合。
图 4:审计路径,其中 span 和 Okta 的 System Log 到达 CloudWatch,并由一次 Omni 查询将它们关联起来
要进行设置:
- 为每个 Gateway 开启 CloudWatch Transaction Search、开启跟踪投递(参见此 示例脚本),并将 ADOT 添加到 BFF 和 MCP 服务器。任务管理器将每个决策、用户和智能体写入一个
authz.checkspan。 - 在 Okta 中,为 Amazon EventBridge 添加一个 Log Stream。Okta 将每个事件投递到您账户中的合作伙伴事件总线,并由一条规则将其写入 CloudWatch Logs 日志组。在我们的测试中,事件在 Okta 发布后约 1 秒到达。每个 ID-JAG 授权事件都将智能体记为执行者、用户记为目标,并记录授予的范围和资源连接。
- 在该账户和 AWS 区域中设置一个 Omni 空间,将 Okta 日志组添加到 CloudWatch Dataset 集成,并保存一个视图,
view.xaa_authz_decisions, 覆盖这些authz.checkspan。
然后,一次查询将每个 ID-JAG 授权与其导致的决策关联起来:
SELECT o.okta_time, o.agent, o.user_email, o.granted, a.decision_time, a.decision, a.reason
FROM (SELECT `@timestamp` AS okta_time, detail['actor']['id'] AS agent_id,
detail['actor']['displayName'] AS agent,
array_element(regexp_match(`@message`, '"type"\s*:\s*"User"\s*,\s*"alternateId"\s*:\s*"([^"]+)"'), 1) AS user_email,
detail['debugContext']['debugData']['grantedScopes'] AS granted
FROM "logs.default"
WHERE `@timestamp` BETWEEN NOW() - INTERVAL '1' HOUR AND NOW()
AND detail['eventType'] = 'app.oauth2.token.grant.id_jag') o
JOIN (SELECT `@timestamp` AS decision_time, user_id, agent_client_id, decision, reason
FROM "view.xaa_authz_decisions"
WHERE `@timestamp` BETWEEN NOW() - INTERVAL '1' HOUR AND NOW()) a
ON a.user_id = o.user_email AND a.agent_client_id = o.agent_id
AND a.decision_time BETWEEN o.okta_time AND o.okta_time + INTERVAL '5' MINUTE
对于 Alice,结果显示 Okta 向任务智能体授予了 xaa:read xaa:write ,随后 MCP 服务器拒绝了她 create_task 16.7 秒后,并允许 list_tasks 随后,如图 5 所示。
图 5:Omni 查询将 Okta System Log 中 Alice 的 ID-JAG 授权与其导致的两次决策关联起来
每个请求也是一条 trace,从 BFF 经过智能体、Gateway 的身份与策略检查,再到 MCP 服务器的决策,如图 6 所示。Omni 将该 trace 标记为故障,因为智能体的 create_task 调用返回了拒绝结果。
图 6:Alice 请求的一条 trace,从智能体的工具调用,经过 Gateway 的身份与 Cedar 检查,直到 MCP 服务器的拒绝
有两个插桩细节很重要。ADOT 会查找 Region 并通过它签署其导出内容, botocore,因此添加 botocore 对于缺少该能力的服务也是如此。在此之前,我们的 MCP 服务器没有导出任何 span。而 ADOT 的 agent 模式会关闭对 HTTP 客户端库的插桩,例如 requests , urllib3 默认情况下,因此在你的 BFF 中设置 OTEL_PYTHON_DISABLED_INSTRUMENTATIONS ,以覆盖该默认值,改用一份不包含 BFF 的 HTTP 客户端的列表(requests(在我们的配置中),否则其 trace 上下文将无法到达智能体。
验证结果
我们用第 1 部分中的用户,通过两个 Gateway 分别运行了每一项检查。每个会话先列出工具,然后调用 list_tasks, create_task,以及一个员工查询:
| 调用方与路径 | 列出的工具 | create_task |
读取 |
| Alice,智能体 A,Gateway A | 6 | 被 MCP 服务器拒绝:需要 xaa-writers |
允许 |
| Bob,智能体 A,Gateway A | 6 | 已创建 | 允许 |
| Carol,智能体 A,Gateway A | 6 | 被 MCP 服务器拒绝:需要 groups 允许 |
允许 |
| Bob,智能体 B,Gateway B | 4:Cedar 隐藏了写入工具 | 被 Gateway 拒绝:“没有策略适用于该请求(默认拒绝)” | 允许 |
通过部署的智能体,结果一致:智能体 A 拒绝了 Alice 和 Carol,并为 Bob 创建了任务;智能体 B 则告诉 Bob 它没有创建任务的工具。同一个用户通过不同的智能体获得了不同的权限,而这一切由 Okta 决定。
这些请求在门口就被拦下了:
| 请求 | 响应 |
| 智能体 B 的 ID-JAG 发往 Gateway A,或智能体 A 的 ID-JAG 发往 Gateway B | HTTP 403,MCP 错误 -32002 insufficient_scope |
| 改用 Okta 访问令牌,而非 ID-JAG | HTTP 403,同样的错误 |
| 无令牌 | HTTP 401,“缺少 Bearer 令牌” |
| 智能体 A 的 ID-JAG 在 EKS 上发送给智能体 B | 在 98 毫秒内被拒绝,发生在模型调用之前:“签发给了另一个智能体” |
Gateway 对错误的智能体和错误的令牌类型返回相同的通用错误,因此请对照令牌的 client_id 以及 aud 看到它时。
与工具本身相比,Gateway 的身份与策略工作规模很小。以下是 Omni 中 Gateway A 在 24 小时内的 span 的中位数与第 90 百分位数:
| p50p9034 毫秒69 毫秒25 毫秒60 毫秒48 毫秒94 毫秒70 毫秒439 毫秒(Cedar,每次调用)47 毫秒56 毫秒(Cedar,每次工具列表)65 毫秒75 毫秒(AgentCore 运行时上的 MCP 服务器)5,565 毫秒6,273 毫秒一次工具调用的身份与策略 span 按中位数合计约 0.2 秒,而 MCP 服务器自身的 span 耗时不到 1 毫秒。Gateway B 表现出相同的模式,其中 在中位数为 408 毫秒。Cross App Access 或按用户同意XAA 适用于目标应用的授权服务器接受 I | p50 | p90 |
Gateway.InboundAuth |
34 毫秒 | 69 毫秒 |
Identity.Authorize |
25 毫秒 | 60 毫秒 |
Identity.GetWorkloadAccessToken |
48 毫秒 | 94 毫秒 |
Identity.GetResourceOauth2Token |
70 毫秒 | 439 毫秒 |
Policy.AuthorizeAction (Cedar,每次调用) |
47 毫秒 | 56 毫秒 |
Policy.PartiallyAuthorizeActions (Cedar,按工具列表) |
65 毫秒 | 75 毫秒 |
Gateway.TargetInvocation (AgentCore 运行时上的 MCP 服务器) |
5,565 毫秒 | 6,273 毫秒 |
一次工具调用的身份与策略 span 按中位数合计约 0.2 秒,而 MCP 服务器自身的 authz.check span 耗时不到 1 毫秒。Gateway B 表现出相同的模式,其中 GetResourceOauth2Token 中位数为 408 毫秒。
Cross App Access 或按用户同意
XAA 适用于目标应用的授权服务器接受 ID-JAG 的场景。在那里,您的 Okta 管理员决定哪个智能体可以代表哪些用户行事,用户不会看到同意提示,并且 Okta 在每次请求令牌时都会评估策略。拥有自己授权服务器的应用(例如 GitHub)则依赖每个用户自己的 OAuth 同意。图 7 比较了两者,正如我们所测量的那样。
图 7:Cross App Access 与按用户 OAuth 同意的对比,以及我们测得的撤销行为
我们部署了 AWS 示例 在我们技术栈旁部署了 AWS 示例,由 Okta 让用户登录 AgentCore Identity 同意门户,并在其自己的 Gateway 上设置了一个 GitHub 目标。Alice 通过该门户连接了一个 GitHub 测试账户,而 Bob 从未连接过。文章《Manage end-user OAuth consent for AI agents with Amazon Bedrock AgentCore》完整介绍了这条路径。以下是我们观察到的情况:操作下一次 GitHub 工具调用Alice 在门户中表示同意返回了她的 GitHub 身份从未表示同意的 BobMCP 错误 -32042,并带有 AgentCore 授权 在我们技术栈旁部署了 AWS 示例,由 Okta 让用户登录 AgentCore Identity 同意门户,并在其自己的 Gateway 上设置了一个 GitHub 目标。Alice 通过该门户连接了一个 GitHub 测试账户,而 Bob 从未连接过。文章《 使用 Amazon Bedrock AgentCore 管理 AI 智能体的最终用户 OAuth 同意 完整介绍了这条路径。以下是我们观察到的情况:
| 操作 | 下一次 GitHub 工具调用 |
| Alice 在门户中表示同意 | 返回了她的 GitHub 身份 |
| 从未表示同意的 Bob | MCP 错误 -32042,并带有 AgentCore 授权 URL |
| Alice 在 Okta 中被暂停,先前签发的令牌仍被复用 | 仍然有效:Gateway 会检查入站令牌的签名和过期时间,而该令牌的有效期为 1 小时 |
| Alice 在 Okta 中被暂停,重新登录 | 被拒绝 |
| Alice 在 Okta 中被暂停,重新登录被拒绝 | 在未获得新同意的情况下仍然有效 |
| Alice 的授权通过同意门户的 API 断开连接 | 未连接,则再次返回 -32042 |
这两条路径的撤销机制不同。在 XAA 中,Okta 的控制会阻止下一次 ID-JAG 签发,已签发的令牌约在 5 分钟内过期。在同意路径中,Okta 只控制登录:已存储的授权在暂停后仍然存在,直到我们将其断开连接。请按目标应用分别选择,而不是对整个企业统一选择一次。
此模式适用的场景
在媒体与娱乐行业,智能体队伍会迅速到位。一家制片厂、流媒体或游戏机构会为制作跟踪、标题与资产元数据、版权与本地化,以及观众或玩家支持分别配备智能体,每个智能体都位于不同的系统之前,各自拥有自己的授权模型和自己的审计人员。问题不在于能否治理好一个智能体,而在于第一百个智能体是否也以同样的方式受到治理,以及管理员是否仍然能够回答:哪些智能体为哪些用户访问哪些系统。
这里没有任何内容是该行业特有的。智能体是您 IdP 中的一个身份,目标是 OAuth 2.0 授权服务器,而 Gateway 是做出授权决策的地方。金融服务、医疗保健和公共部门的团队将不同的资源放在同一个前门之后,并获得相同的审计跟踪。
接下来:可观测性与评估
本文使用 AgentCore Observability 只为一个目的:证明每一次允许和拒绝都能追溯到某项控制。它的内容不止于此,本身也是一项独立的工作。这些 span 已经承载了每个治理决策背后的模型和工具延迟,Transaction Search 可以对拒绝次数的激增发出告警,而 AgentCore 评估可以按照你自己的标准为智能体的行为打分,既可在线针对实时流量进行,也可按需针对选定的一组 span 进行。后续文章会接着讨论:在受治理的智能体上应衡量哪些指标,哪些评估器能发现某个智能体在被拒绝的工具调用之后仍报告成功,以及如何同时运行这两者,而不至于让 trace 变成你最大的一笔账单。
清理
为避免持续产生费用,请删除第 2 部分的资源,然后按照以下清理步骤操作: 第 1 部分:
- 删除 Amazon EKS 集群(
eksctl delete cluster)及其 Amazon Elastic Container Registry(Amazon ECR)存储库。 - 删除 Gateway 及其目标,然后删除 AgentCore 引擎中的 Policy,最后删除智能体 B 的凭证提供程序。
- 删除 CloudWatch Omni 空间和域、Dataset 集成、Amazon EventBridge 规则和合作伙伴事件总线,以及 CloudWatch 日志组。
- 如果您部署了示例 07,请按照其清理步骤操作。
- 删除您创建的 IAM 角色和策略。
- 在 Okta 中,删除日志流,并停用和删除智能体 B 及其关联的应用。
结论
在本文中,你将 第 1 部分 从适合少量智能体和工具的拓扑,转变为能在众多智能体和工具下依然成立的拓扑。Gateway 成为唯一的统一入口,并兑换 Okta 的授权,因此智能体不持有任何工具凭证。由 Policy in AgentCore 评估的 Cedar 策略取代了原先复制到每个服务器中的检查。Amazon EKS 上的第二个智能体以自己的 Okta 身份加入。AgentCore Observability 与 Okta 的 System Log 一同位于 CloudWatch Omni 中,将每一次允许和拒绝都追溯到智能体、用户以及做出该决定的控制。治理机制本身没有改变,而这正是关键所在:改变的只是它周围的拓扑。
要开始使用,请浏览 AgentCore 示例 以及 Okta 的 Cross App Access 文档。若要通过 Gateway 进行纯令牌交换,请阅读 为多租户智能体在 Amazon Bedrock AgentCore Gateway 上实现代表用户(on-behalf-of)的令牌交换.