详细讲解如何在 AWS Bedrock AgentCore 中配置私钥 JWT 认证,包括 KMS 密钥生成、公钥注册和凭证提供商的完整设置步骤。针对 AWS 生态的开发者有实际参考价值。
Amazon Bedrock AgentCore Identity 现已支持 Private Key JWT 客户端认证功能。使用 Private Key JWT 客户端认证,你的 AI 智能体可以使用签名的 JSON Web Token (JWT) 客户端声明向下游身份提供者的令牌端点进行认证,而不再需要共享的 OAuth 2.0 客户端密钥。你可以向身份提供者注册公钥,而相应的私钥保留在 AWS Key Management Service (AWS KMS) 中。在认证时,AgentCore Identity 使用 AWS KMS 对声明进行签名,并将已签名的声明发送给身份提供者,身份提供者使用你注册的公钥进行验证。
本文阐述了 Private Key JWT 客户端认证在 AgentCore Identity 中的工作原理,并介绍了支持的授权流。我们随后将逐步讲解如何创建 AWS KMS 签名密钥、向身份提供者注册其公钥、在 AWS Management Console 中配置凭证提供者,以及查看记录你的 AI 智能体访问的 AWS CloudTrail 事件示例。
以下示例说明了请求流。考虑一个客户支持 AI 智能体,需要从受你身份提供者保护的内部订单 API 读取客户的订单历史。
图 1 - 机器到机器令牌请求的示例请求流,从 AI 智能体的调用到下游 API
以下关系图说明了请求流:
AI 智能体调用 AgentCore Identity 上的 GetResourceOauth2Token,为订单 API 请求令牌。
AgentCore Identity 从你的凭证提供者读取客户端 ID、KMS 密钥 ARN 和签名算法。它使用所需的有效载荷声明(加上任何你配置的额外头部或有效载荷声明,如密钥标识符或证书指纹)构建短期的 JWT 客户端声明,并使用你配置的签名算法(RS256、PS256 或 ES256)对你的 KMS 非对称签名密钥调用 kms:Sign。
AWS KMS 对声明进行签名,并将签名返回给 AgentCore Identity。私钥永不离开 KMS。
AgentCore Identity 使用 grant_type=client_credentials 和 client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer 将已签名的声明发布到你身份提供者的令牌端点。
身份提供者使用你注册的公钥验证签名,并向 AgentCore Identity 返回访问令牌。
AgentCore Identity 将访问令牌返回给你的 AI 智能体。
AI 智能体使用访问令牌调用订单 API。
订单 API 返回客户的订单历史。
Private Key JWT 认证适用于三种授权流:
机器到机器 (M2M):AI 智能体充当自身。流程中没有人类用户。AI 智能体需要访问资源,例如同步数据的后台作业,或任何客户支持 AI 智能体都可以读取的服务,无论是谁触发的。令牌代表应用程序/AI 智能体身份。使用 client_credentials 授权。令牌的主体是客户端本身。
代表行为 (OBO):AI 智能体为特定用户行动,使用该用户的现有令牌。用户已在某处登录,且存在入站用户令牌。AI 智能体需要以该用户的身份调用下游 API,以便其权限和身份得以保留。AgentCore Identity 将入站用户令牌交换为代表该用户的下游令牌,同时仍使用客户端声明对自身进行认证。根据身份提供者的不同,你可以使用 RFC 8693 令牌交换或 RFC 7523 JWT 授权授权。
用户委托访问:AI 智能体为用户行动,但用户首先以交互方式授予同意。没有预先存在的令牌可以交换。相反,用户进行交互式登录/同意(授权代码 / 三腿 OAuth 流),批准 AI 智能体可以执行的操作。获得同意后,AI 智能体获得代表用户的令牌。使用授权代码授权。
本文假设你具备以下条件
一个 AWS 账户,具有对 KMS、AgentCore 和 AWS CloudTrail 的 AWS Management Console 访问权限。
你身份提供者上的租户,可在其中为应用程序注册公钥。
客户端用来发现和集成你身份提供者的发现 URL 和客户端 ID。
确认你的身份提供者为 Private Key JWT 客户端认证所需的签名算法。确认 AWS KMS 和 AgentCore Identity 都支持相同的算法和密钥规范。
流程各部分的权限:
创建和配置 KMS 密钥 – kms:CreateKey 和 kms:PutKeyPolicy。
导出公钥以向身份提供者注册 – kms:GetPublicKey。(如果你的身份提供者生成密钥对并改为提供私钥材料,你还需要 kms:GetParametersForImport 和 kms:ImportKeyMaterial 将其导入到 KMS。)
创建凭证提供者 – bedrock-agentcore-control:CreateOauth2CredentialProvider。
以下部分说明了如何使用 AWS Management Console 配置 Private Key JWT 作为客户端认证方法。
首先创建一个非对称 KMS 密钥,AgentCore Identity 将使用它来签名 JWT 客户端声明。在此示例中,我们在 KMS 中创建密钥并将相应的公钥导出到身份提供者。但是,如果你的身份提供者生成密钥对并改为提供私钥材料,你可以将其导入到 KMS。
在与你的凭证提供者相同的 AWS 区域中打开 AWS KMS 控制台。
选择"客户管理的密钥",然后选择"创建密钥"。
对于密钥类型,选择"非对称"。
对于密钥使用,选择"签名和验证"。
对于密钥规范,选择与你的签名算法兼容的规范。此示例使用 ECC_NIST_P256 和 ES256 签名算法。
选择"下一步",输入别名,并通过密钥管理员和密钥使用权限步骤。
在"编辑密钥策略"步骤中,将以下语句添加到密钥策略中以授予 AgentCore Identity 使用密钥的权限,将 111122223333 替换为你的 AWS 账户 ID,将 <region> 替换为 AgentCore 使用的区域。kms:ViaService 条件验证密钥只有在请求源自 AgentCore Identity 时才能使用:
{
"Id": "BedrockAgentCoreIdentityPrivateKeyJwtAccess",
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": [
"kms:Sign",
"kms:DescribeKey"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceAccount": "${aws:PrincipalAccount}"
},
"StringLike": {
"kms:ViaService": "bedrock-agentcore-identity.<region>.amazonaws.com"
}
}
}
]
}
选择"完成"。在密钥的详细信息页面上,记下密钥 ARN。在创建凭证提供者时,你将提供它。
接下来,导出公钥并将其注册到你的身份提供者:
打开 Amazon Bedrock AgentCore 控制台。
在左侧导航窗格中,在"构建"下,选择"身份"。
在"出站身份验证"部分中,选择"添加出站身份验证",然后选择"添加 OAuth 客户端"。
图 2 - 从 AgentCore Identity 控制台添加 OAuth 客户端
在"添加 OAuth 客户端"页面上,在"提供者配置"部分中:
对于配置类型,选择 Discovery URL,以便 AgentCore Identity 自动检索提供商的配置。(如果提供商未发布发现端点,请选择 Manual config。)
对于客户端身份验证方法,选择 Private key JWT。
图 3——选择 Private key JWT 作为客户端身份验证方法
对于 Discovery URL,输入提供商发布其 OpenID Connect 配置的 URL(以 .well-known/openid-configuration 结尾)。
对于 Client ID,输入在身份提供商处注册的客户端标识符。
对于 KMS key,选择非对称 KMS 签名密钥的 ARN。该密钥必须以 SIGN_VERIFY 作为用途创建,并且必须位于同一 Region,才能显示在列表中。
注意:你也可以通过输入密钥的 ARN,使用同一 Region 中其他账户的密钥。跨账户访问需要在两个账户中配置额外权限。请参阅“允许其他账户中的用户使用 KMS 密钥”。
对于 Signing algorithm,选择身份提供商对 Private Key JWT 所要求的算法。该算法必须与你的 KMS 密钥规范兼容:
图 4——提供发现 URL、客户端 ID、非对称 KMS 密钥和签名算法
如果身份提供商要求在 JWT 客户端断言中包含其他声明,请在此处添加:
在 Header claims – optional 下,选择 Add header claim,以添加提供商特定的标头声明,例如密钥标识符。不能设置保留键 alg 和 typ。
在 Payload claims – optional 下,选择 Add payload claim,以添加提供商特定的载荷声明。不能设置保留键 iss、sub、jti、exp、iat 和 nbf。
选择 Add OAuth Client。
检查凭证提供商是否出现在 Outbound Auth 列表中,以验证它是否已成功创建。
图 5——在创建客户端之前添加可选的标头声明和载荷声明
当 AI 智能体使用凭证提供商获取令牌时,相关操作会记录在 AWS CloudTrail 中,以便你审计每次访问。你将看到如下事件名称:
GetWorkloadAccessToken(事件源为 bedrock-agentcore.amazonaws.com)——AI 智能体获取其工作负载身份令牌。requestParameters 记录 workloadName,resources 块标识工作负载身份,返回的令牌会被隐去:{ "eventSource":"bedrock-agentcore.amazonaws.com", "eventName":"GetWorkloadAccessToken", "requestParameters":{ "workloadName":"my-agent-workload" }, "responseElements":{ "workloadAccessToken":"HIDDEN_DUE_TO_SECURITY_REASONS" }, "resources":[ { "accountId":"111122223333", "type":"AWS::BedrockAgentCore::WorkloadIdentity", "ARN":"arn:aws:bedrock-agentcore:us-east-1:111122223333:workload-identity-directory/default/workload-identity/my-agent-workload" } ] }
{
"eventSource":"bedrock-agentcore.amazonaws.com",
"eventName":"GetWorkloadAccessToken",
"requestParameters":{
"workloadName":"my-agent-workload"
},
"responseElements":{
"workloadAccessToken":"HIDDEN_DUE_TO_SECURITY_REASONS"
},
"resources":[
{
"accountId":"111122223333",
"type":"AWS::BedrockAgentCore::WorkloadIdentity",
"ARN":"arn:aws:bedrock-agentcore:us-east-1:111122223333:workload-identity-directory/default/workload-identity/my-agent-workload"
}
]
}
GetResourceOauth2Token(事件源为 bedrock-agentcore.amazonaws.com)——AI 智能体请求下游资源的访问令牌。requestParameters 显示所使用的凭证提供商、作用域和授权流程,传入令牌会被隐去。{ "eventSource":"bedrock-agentcore.amazonaws.com", "eventName":"GetResourceOauth2Token", "requestParameters":{ "workloadIdentityToken":"HIDDEN_DUE_TO_SECURITY_REASONS", "resourceCredentialProviderName":"my-private-key-jwt-provider", "scopes":[ "https://graph.microsoft.com/.default" ], "oauth2Flow":"M2M" }, "resources":[ { "accountId":"111122223333", "type":"AWS::BedrockAgentCore::OAuth2CredentialProvider", "ARN":"arn:aws:bedrock-agentcore:us-east-1:111122223333:token-vault/default/oauth2credentialprovider/my-private-key-jwt-provider" } ] }
{
"eventSource":"bedrock-agentcore.amazonaws.com",
"eventName":"GetResourceOauth2Token",
"requestParameters":{
"workloadIdentityToken":"HIDDEN_DUE_TO_SECURITY_REASONS",
"resourceCredentialProviderName":"my-private-key-jwt-provider",
"scopes":[
"https://graph.microsoft.com/.default"
],
"oauth2Flow":"M2M"
},
"resources":[
{
"accountId":"111122223333",
"type":"AWS::BedrockAgentCore::OAuth2CredentialProvider",
"ARN":"arn:aws:bedrock-agentcore:us-east-1:111122223333:token-vault/default/oauth2credentialprovider/my-private-key-jwt-provider"
}
]
}
Sign(事件源为 kms.amazonaws.com)——AgentCore Identity 使用你的 KMS 密钥对 JWT 客户端断言进行签名。此事件表明 Private Key JWT 正在正常工作:userIdentity.invokedBy、sourceIPAddress 和 userAgent 均为 bedrock-agentcore.amazonaws.com,确认 AgentCore Identity 代表你调用了 kms:Sign。请注意,Sign 事件记录的是 KMS 签名算法名称,而不是你配置的 JWT 算法名称。{ "eventSource":"kms.amazonaws.com", "eventName":"Sign", "userIdentity":{ "invokedBy":"bedrock-agentcore.amazonaws.com" }, "sourceIPAddress":"bedrock-agentcore.amazonaws.com", "userAgent":"bedrock-agentcore.amazonaws.com", "requestParameters":{ "signingAlgorithm":"RSASSA_PKCS1_V1_5_SHA_256", "keyId":"arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", "messageType":"DIGEST" }, "responseElements":null, "readOnly":true, "managementEvent":true, "resources":[ { "accountId":"111122223333", "type":"AWS::KMS::Key", "ARN":"arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" } ] }
{
"eventSource":"kms.amazonaws.com",
"eventName":"Sign",
"userIdentity":{
"invokedBy":"bedrock-agentcore.amazonaws.com"
},
"sourceIPAddress":"bedrock-agentcore.amazonaws.com",
"userAgent":"bedrock-agentcore.amazonaws.com",
"requestParameters":{
"signingAlgorithm":"RSASSA_PKCS1_V1_5_SHA_256",
"keyId":"arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
"messageType":"DIGEST"
},
"responseElements":null,
"readOnly":true,
"managementEvent":true,
"resources":[
{
"accountId":"111122223333",
"type":"AWS::KMS::Key",
"ARN":"arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
}
]
}
为避免持续产生费用,并移除不再需要的资源,请清理本演练中创建的凭证提供商和 KMS 签名密钥。
打开 Amazon Bedrock AgentCore 控制台。
在左侧导航窗格的 Build 下,选择 Identity。
在 Outbound Auth 部分中,找到你创建的凭证提供商。
选择该提供商,选择 Delete,然后确认删除。
删除 KMS 密钥是不可逆且永久性的操作。密钥一旦被删除,便无法再生成任何依赖该密钥的数据或签名,因此 KMS 要求你设置一段等待期来计划删除,而不是立即删除。在计划删除之前,请确认任何凭证提供商或身份提供商注册均不再引用该密钥。如果你不确定该密钥是否仍在使用,请考虑改为禁用密钥;这样既可以阻止它继续被使用,又能保留恢复的可能性。
在创建密钥的 Region 中打开 AWS KMS 控制台。
选择 Customer managed keys,然后选择你创建的非对称签名密钥。
选择 Key actions,然后选择 Schedule key deletion。
输入 7 到 30 天的等待期。在此期间,密钥会被禁用,但仍可通过取消计划删除来恢复。
确认要计划删除该密钥。
等待期结束后,KMS 将永久删除该密钥。请记得同时移除或轮换在身份提供商处注册的对应公钥,使其不再信任已停用的密钥。
通过在 AgentCore Identity 中使用 Private Key JWT 客户端身份验证,你可以让 AI 智能体以无密钥且可审计的方式向身份提供商进行身份验证。签名密钥始终保留在 AWS KMS 上,每次签名操作都会记录在 AWS CloudTrail 中,并且同一个凭证提供商可以扩展用于 M2M、代表用户(on-behalf-of)和用户委托流程。有关端到端示例,包括 Entra 和 Okta 身份提供商注册,以及 M2M 和 OBO 流程,请参阅 GitHub 上的 Amazon Bedrock AgentCore 示例。