使用 Microsoft Entra 智能体 ID 保护 Amazon Bedrock 代理

本指南介绍如何使用 Microsoft Entra ID 身份验证 SDK(sidecar)向下游 API 进行身份验证来保护 Amazon Bedrock 代理。 边车作为独立容器运行,处理所有凭据管理和与 Microsoft Entra ID 的令牌交换。 代理从 sidecar 请求授权标头,sidecar 处理与 Microsoft Entra ID 的 OAuth 2.0 交换。

先决条件

在开始之前,请确保具备:

  • Microsoft Entra 的租户。
  • 一份 Azure 订阅。
  • Docker Desktop(macOS/Windows)或包含 Compose v2(Linux)的 Docker 引擎。
  • PowerShell 7+
  • Azure CLI
  • AWS CLI v2
  • 已启用 Anthropic Claude 3 Haiku(或你首选的模型)Bedrock 模型访问权限的 AWS 帐户。 在“模型访问>”下的 AWS Bedrock 控制台中启用访问权限。
  • 首次 Microsoft Entra 设置的全局管理员角色。 使用 Privileged Identity Management (PIM)实时激活此角色。

克隆示例存储库

  1. 克隆存储库并转到 AWS 示例目录:

    git clone https://github.com/microsoft/entra-agentid-samples.git
    cd entra-agentid-samples/sidecar/aws
    

Architecture

Microsoft Entra ID身份验证 SDK(sidecar)位于代理和Microsoft Entra ID之间。 代理从不直接与Microsoft Entra ID对话,也从不管理凭据。 它请求 sidecar 提供 Authorization 标头,以调用下游 API。 Amazon Bedrock 单独处理 LLM 推理,无需担心标识。

显示贝德洛克代理、sidecar、Microsoft Entra ID和天气 API 之间的令牌流的关系图。

此示例在 Docker 网桥网络上运行三个容器:

  • llm-agent-aws 具有聊天 UI 和 LangGraph ReAct 代理的 Flask 应用,该代理调用 Amazon Bedrock (Claude) 进行推理。 在端口 3001 上开放。
  • agent-id-sidecar-awsMicrosoft Entra ID 官方身份验证 SDK(sidecar)容器。 获取和缓存令牌。 没有主机端口,只能从 Docker 网络内部访问。
  • weather-api-aws 一个下游 API,用于验证代理的每个请求的 JWT(签名、颁发者、到期、访问群体),并返回天气数据。

请求将流经以下步骤:

  1. 在聊天 UI http://localhost:3001中键入查询。
  2. Flask 应用通过 LangGraph ReAct 代理将查询发送到 AWS Bedrock (Claude)。
  3. 当 Claude 确定它需要天气数据时,它会调用该工具 get_weather
  4. 该工具通过调用 GET /AuthorizationHeader?AgentIdentity={agentId}向 sidecar 请求授权标头。
  5. sidecar 使用 OAuth 2.0(客户端凭据或 OBO(代表用户)交换)向 Microsoft Entra ID 进行身份验证。
  6. Microsoft Entra ID 将请求的令牌 (TR) 返回至 sidecar。
  7. 智能体使用 Authorization: Bearer TR 调用天气 API。
  8. 天气 API 验证 TR 并返回天气 JSON 响应。

了解令牌流动

标识交换涉及三个令牌:

令牌 颁发给 何时 方式
Tc 已登录用户 仅限 OBO 流 浏览器中的 MSAL.js
T1 蓝图应用 这两个流 Sidecar (客户端凭据)
TR 代理(下游 API) 这两个流 边车仅应用(自治)或 OBO 交换

在自治流中,边车使用客户端凭据获取 T1,然后将其交换为范围为下游 API 的 TR。 在 OBO 流中,sidecar 还会接收 Tc(用户的令牌),并执行 OBO 交换来获取代表已登录用户的 TR。

在此设置中,仅向主机公开聊天 UI(端口 3001)。 Sidecar 和天气 API 只能在 Docker 网络中访问,该网络可建立明确的安全边界。

选择执行模式和标识流

此示例支持两种执行模式和两个可以组合的标识流:

自治 (仅限应用) OBO (代表用户)
直接 (无 LLM) 快速演示路径。 获取令牌并调用天气 API。 同样,但使用经过身份验证的 sidecar 终结点和用户令牌。
Bedrock + LangChain LangGraph ReAct 代理决定何时调用 get_weather 同样,但代理在工具运行时传递用户令牌。

使用直接模式来进行令牌流的端到端验证,无需访问 AWS Bedrock。 切换到 Bedrock 模式以获取完整的代理体验。

选择 AWS 身份验证层

此示例支持通过三种方法向 Amazon Bedrock 进行身份验证。 选择与您的系统环境匹配的级别:

  • 临时 STS 凭据: 最适合使用 AWS SSO 进行本地开发。 在您的AWS_ACCESS_KEY_ID文件中设置AWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN.env。 这些凭据在大约一小时后过期。
  • 基岩 API 密钥: 最适合演示和研讨会。 在AWS_BEARER_TOKEN_BEDROCK文件中设置.env。 仅适用于贝德洛克,并具有可配置的生命周期。
  • OIDC 联合身份验证:最适合Azure 应用服务的生产部署。 使用平台设置的 AWS_ROLE_ARNAWS_WEB_IDENTITY_TOKEN_FILE。 没有机密存储在任何地方。

选择基岩模型

该示例默认为 us.anthropic.claude-3-haiku-20240307-v1:0,因为它是 Bedrock 上最便宜的Anthropic模型,并支持工具调用。 前缀 us. 指示跨区域推理配置文件,该配置文件在美国区域之间路由以实现更高的可用性。

其他受支持的模型:

模型标识符 每 1K 个输入令牌的成本 备注
us.anthropic.claude-3-haiku-20240307-v1:0 $0.00025 违约。 快速、最便宜,并支持工具调用。
us.anthropic.claude-3-5-haiku-20241022-v1:0 $0.0008 更新,更智能,仍然负担得起。
us.anthropic.claude-3-5-sonnet-20241022-v2:0 $0.003 最佳质量/成本比率。

通过在BEDROCK_MODEL_ID文件中设置.env来覆盖默认设置。 必须先在 AWS Bedrock 控制台>模型访问 中启用每个模型,然后才能调用该模型。

创建Microsoft Entra对象(首次设置)

如果你已有上一次运行中 .env 已填充的 BLUEPRINT_APP_ID 文件,请跳转到配置环境变量

为每个租户运行以下命令一次,以创建用于 OBO 登录的蓝图应用、代理 ID 和 SPA 应用。

  1. 按照 创建代理身份蓝图创建代理身份 中的 PowerShell 工作流,为自动化流程创建蓝图应用和代理 ID。 最后,你有:

    • TENANT_IDMicrosoft Entra 租户。
    • BLUEPRINT_APP_ID 蓝图应用注册。
    • BLUEPRINT_CLIENT_SECRET 蓝图的客户端密钥。
    • AGENT_CLIENT_ID 从蓝图创建的代理 ID。
  2. (可选)创建 SPA 应用并配置 OBO。 仅当想要使用 OBO 标识流时,才需要执行此步骤:

    运行以下脚本以创建 SPA 应用注册并在蓝图上配置 OBO 权限。 脚本注册 SPA 重定向 URI 并授予所需的委派权限。

    Bash:

    bash ../../scripts/setup-obo-client-app.sh
    bash ../../scripts/setup-obo-blueprint.sh
    

    PowerShell

    pwsh ../../scripts/setup-obo-client-app.ps1
    pwsh ../../scripts/setup-obo-blueprint.ps1 `
        -TenantId        '<TENANT_ID>' `
        -BlueprintAppId  '<BLUEPRINT_APP_ID>' `
        -AgentAppId      '<AGENT_CLIENT_ID>' `
        -ClientSpaAppId  '<CLIENT_SPA_APP_ID>'
    

此示例的 SPA 重定向 URI 为 http://localhost:3001 (端口 3001,而不是 3003)。 请确保已注册此 URI。

配置环境变量

通过 AzureAd__ClientCredentials__0__SourceType 中的 docker-compose.yml 设置,Sidecar 支持多种凭据类型:

  • ClientSecret 仅限本地开发。 此示例包含此类型。
  • SignedAssertionFromManagedIdentity部署在Azure上。 建议采用零秘密原则进行生产。
  • KeyVault来自Azure 密钥保管库的证书。
  • StoreWithThumbprint 来自本地计算机存储的证书。
  1. 从包含的模板创建本地 .env 配置文件。 此文件存储租户、应用和 AWS 凭据:

Bash:

cp .env.example .env

PowerShell

Copy-Item .env.example .env
  1. .env 文件中设置以下变量:

    • TENANT_ID 你的 Microsoft Entra 租户 ID。
    • BLUEPRINT_APP_ID 蓝图应用注册。 sidecar 作为此应用进行身份验证。
    • BLUEPRINT_CLIENT_SECRET 蓝图客户端密码(仅限本地开发)。
    • AGENT_CLIENT_ID 代理 ID。 显示为 AgentIdentity 查询参数。
    • CLIENT_SPA_APP_IDMSAL.js 用于浏览器登录的 SPA 应用 ID(仅限 OBO)。
    • AWS_REGION Bedrock 的 AWS 区域,例如 us-east-2
    • BEDROCK_MODEL_ID 模型 ID。 默认值:us.anthropic.claude-3-haiku-20240307-v1:0
    • VALIDATE_TOKEN_SIGNATURE 默认值 true。 将false设置为跳过天气 API 中的 JWKS 签名验证(仅限调试)。
  2. 根据您选择的等级输入 AWS 凭据:

    • 层 A(STS):设置AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN
    • 第 B 层(API 密钥): 设置 AWS_BEARER_TOKEN_BEDROCK
    • 第 C 层(OIDC):通过平台应用设置进行配置,而不是在.env

Tip

如果你在上一个会话中已有 .env,则只需更新 AWS 凭证,因为 STS 令牌约一小时后会过期。 直接跳到 “启动堆栈”。

启动堆栈

  1. 验证 Docker Desktop(或 Docker 引擎)是否在计算机上运行。

  2. 生成容器映像,并在分离模式下启动所有三个服务(代理、sidecar 和天气 API):

    docker compose up --build -d
    
  3. 通过查询状态终结点检查所有容器是否已成功启动。 该响应会指示代理是否能够连接到 AWS Bedrock:

    Bash:

    curl http://localhost:3001/api/status
    

    PowerShell

    Invoke-RestMethod http://localhost:3001/api/status
    

    你会看到一个响应指示 bedrock_available: true(如果你使用不带 AWS 凭据的 Direct 模式则为 false)。

Important

更新 .env 时(例如刷新过期的 STS 凭据), docker compose restart 不会重新加载环境变量。 改用 docker compose up -d --force-recreate llm-agent-aws

通过聊天 UI 发送查询

  1. 在浏览器中打开 http://localhost:3001

  2. 使用标题栏配置演示:

    • 执行模式:Direct (跳过 LLM)或 Bedrock (Claude 上的 LangChain ReAct 代理)。
    • 标识流:Autonomous(仅应用令牌)或 OBO(代表已登录用户操作)。
  3. 如果选择 OBO,请选择 “登录 ”以通过 MSAL.js 弹出窗口进行身份验证。

  4. 键入 “达拉斯天气” 之类的查询,然后选择“ 发送”。

  5. 观看右侧的 “标识跟踪 ”面板,了解每个令牌交换和 API 调用的分步细分。 面板显示每个令牌(Tc、T1、TR)的彩色编码 JWT 卡片,包含解码后的声明。

排查常见问题

如果某些内容未按预期工作,请检查下表中是否存在常见问题和修补程序:

症状 可能的原因 修复
/api/status 显示 bedrock_available: false AWS 凭据缺失或过期,或者未授予模型访问权限。 请检查 docker logs llm-agent-aws。 使用 aws sso login 刷新 STS 凭据。 在 Bedrock 控制台中启用模型。
ExpiredTokenException 从贝德洛克 STS 会话令牌(A级)已过期。 将新凭据粘贴到 .env其中,然后运行 docker compose up -d --force-recreate llm-agent-aws
AccessDeniedExceptionInvokeModel IAM 主体缺少 bedrock:InvokeModel 权限,或未启用模型访问。 授予 bedrock:InvokeModel 对模型和推理配置文件 ARN 的权限。
ValidationException: invalid model identifier 区域未托管模型,或者使用了裸模型 ID 而不是 us. 推理配置文件。 使用us.前缀的推理配置文件 ID(例如us.anthropic.claude-3-haiku-20240307-v1:0)。
天气 API 返回 401 Unauthorized 令牌租户不匹配、过期的密钥或签名检查失败。 验证 TENANT_ID 是否与蓝图的租户匹配。 检查 sidecar 日志。
大语言模型响应但未调用工具 查询看起来不像工具,或者模型不支持工具调用。 使用 Claude 3 Haiku 或更高版本。 将请求短语为“城市<中的>天气是什么?”
OBO 登录弹出窗口被阻止 浏览器弹出窗口阻止程序。 允许弹出窗口。localhost:3001
OBO 期间来自边车的 4xx CLIENT_SPA_APP_ID 缺少,或 SPA 重定向 URI 不匹配。 重新运行 setup-obo-client-app。 确保 http://localhost:3001 位于 SPA 的重定向 URI 上。

如果在执行故障排除步骤后仍存在问题,请直接检查容器日志。 每个服务都将日志记录到各自的容器中:

docker logs llm-agent-aws          # Agent app: Bedrock calls, tool invocations
docker logs agent-id-sidecar-aws   # Sidecar: token acquisition, credential errors
docker logs weather-api-aws        # Weather API: JWT validation, request handling

清理资源

完成测试后,停止本地容器以释放系统资源。 根据您是否希望保留映像以加快重启速度,选择以下清理选项之一。

Important

docker compose down 仅删除本地 Docker 容器。 Microsoft Entra 对象(智能体蓝图、智能体 ID、SPA 应用注册)属于租户侧状态,并会持续存在。 如果不再需要它们,请在Microsoft Entra 管理中心中手动删除它们。

# Stop containers but keep volumes and images for faster restarts
docker compose down

# Remove everything including volumes and images
docker compose down -v --rmi all