AWS 与 Keyfactor 展示如何用 X.509 PKI 保护 AI 智能体身份
Securing AI agent identity with X.509 PKI on AWS
AWS 与 Keyfactor 展示了一套基于 X.509 PKI 的 AI 智能体身份认证参考架构,使用 Keyfactor EJBCA 和 AWS 服务保护智能体间通信及 MCP 工具调用。
文章把 X.509 身份认证拆为用户、智能体间和 MCP 工具服务器三层,并说明签名信封、委托断言、受众限定令牌与 OCSP 如何衔接。
当 AI 代理访问数据库、API 和敏感业务操作时,通过 X.509 公钥基础设施(PKI)建立加密身份便成为一项关键要求。核心挑战在于证明哪个代理发出了请求、防止代理之间相互伪造身份,并确认每个代理只代表经过授权的用户行事。诸如在组件之间共享 API 密钥或在代理链中传递 OAuth 令牌等传统方法,无法满足企业部署所要求的零信任标准。
多代理 AI 框架越来越多地使用模型上下文协议(MCP)将代理连接到外部工具和数据源。MCP 定义了由大型语言模型(LLM)驱动的代理如何调用数据库查询或电子邮件操作等工具。然而,MCP 没有内置的身份验证标准,其设计本身与传输方式无关。这造成了一个关键缺口:如果没有恰当的身份机制,任何组件都可能冒充代理、重放截获的凭证,或在未经授权的情况下调用工具。
在本文中,我们将介绍如何结合使用 Keyfactor EJBCA 与 AWS 服务来弥补这一缺口。EJBCA 是一个 PKI 平台,支持高可用部署、REST API 自动化以及在线证书状态协议(OCSP)验证。该参考架构采用四种互补的安全机制。第一,签名请求信封为每次代理调用提供加密持有证明。第二,由用户签名的委派断言可在不共享凭证的情况下授权代理。第三,符合 RFC 8693 的受众范围令牌可限制任何单个令牌泄露所造成的影响范围。第四,实时 OCSP 撤销检查可立即将凭证变更同步到所有代理。
该解决方案通过 Amazon Bedrock,使用 AWS Strands Agents SDK 进行 LLM 推理。虽然此参考架构使用数据库作为受保护资源,但相同的身份验证模式适用于任何兼容 MCP 的工具服务器。所有示例的完整源代码均可在随附的 GitHub 存储库中获取。
关于 Keyfactor EJBCA
据 Keyfactor 称,Keyfactor 提供广泛采用的机器身份管理平台,全球有超过 1,500 家企业客户在使用。客户涵盖金融服务、医疗保健、制造业和政府部门。Keyfactor 通过证书生命周期管理、PKI 运营和机器身份治理,帮助组织建立并维护加密信任。
EJBCA Enterprise 是 Keyfactor 的证书颁发机构(CA)和 PKI 平台,专为高可用部署和 REST API 自动化而设计。EJBCA 作为企业级产品提供 X.509 证书颁发、OCSP 验证、证书吊销列表(CRL)分发,以及通过 Web 控制台和 REST API 实现的完整证书生命周期管理。EJBCA 支持在本地、容器中或 Amazon Elastic Compute Cloud(Amazon EC2)上部署。
AWS 与 Keyfactor 的合作将 AWS 托管服务(Amazon Bedrock、AWS Secrets Manager、Amazon Relational Database Service (Amazon RDS))与 PKI 基础设施结合起来,支持证书生命周期管理、自动注册和实时吊销。这种组合弥补了 AI 代理生态系统中的一个缺口。AWS 提供计算、存储和 AI 推理层,而 Keyfactor 提供加密身份层,将代理绑定到可验证、可撤销且有效期短的凭证。AWS 和 Keyfactor 工程团队共同开发的这一联合参考架构,展示了如何集成这些技术。你可以将这里展示的模式应用于自己的多代理部署。
解决方案概览
该架构实现了三个身份验证层,分别用于处理代理通信链中的不同信任边界。这三个层使用了前文介绍的四种安全机制:用于持有证明的签名信封、用于无凭证授权的委派断言、用于限制暴露范围的受众范围令牌,以及用于实时吊销的 OCSP。这些机制在各层中的组合方式如下表所示。
| 层 | 信任边界 | 机制 | 验证内容 |
| 1. 用户身份验证 | 用户到系统 | OAuth + X.509 证书 + 委派签发 | 用户身份、凭证绑定 |
| 2. 代理到代理 | 代理到代理 | 签名信封(PoP + nonce + timestamp) | 调用方身份、请求时效性、防止重放 |
| 3. MCP 身份验证 | 代理到工具服务器 | 范围受限令牌 + 信封 + 委派 | 所有身份、授权链、OCSP |
图 1 展示了三个身份验证层,以及凭证如何在用户、代理和 MCP 工具服务器之间流转。该图说明了用户凭证(保留在登录流程中)、代理凭证(按代理限定范围)以及将它们连接起来的委派链之间的区别。
图 1:AWS 上 AI 代理系统的三层 PKI 身份验证架构
图 2 展示了典型用户会话期间的详细流量流程。该图显示了从登录、证书签发、代理委派、工具调用到会话清理的身份验证步骤顺序。
图 2:从用户登录到代理委派、工具调用和会话清理的身份验证流量
使用的 AWS 服务
以下 AWS 服务构成了该参考架构的基础。
| 服务 | 用途 |
| Amazon Bedrock | 通过 Strands Agents SDK 执行 LLM 推理 |
| Amazon RDS for MySQL | 通过 MCP 工具访问的应用程序数据库 |
| Amazon Simple Email Service (Amazon SES) | 为 Email Agent 提供电子邮件投递服务 |
| AWS Secrets Manager | 安全存储 PKCS12 捆绑包、令牌和元数据 |
| Amazon EC2 | 托管 Keycloak IDP 和 EJBCA PKI 服务器 |
解决方案演练
以下步骤将逐一介绍架构的各个组件,从用户初始登录到会话清理。每个步骤都建立在前一步的基础上,构建一条信任链,将人类用户与最终工具执行连接起来。
先决条件
- 一个可访问 Amazon Bedrock、Amazon RDS for MySQL、Amazon SES 和 AWS Secrets Manager 的有效 AWS 账户。
- Keycloak 26.2 或更高版本(RFC 8693 标准令牌交换所必需。旧版本使用不兼容的旧式交换机制)。
- 配置了 REST API V1 和 OCSP 响应程序的 Keyfactor EJBCA Enterprise。
- 用于 REST API 身份验证的 EJBCA API 管理员证书 (
api-admin.p12)。 - Python 3.9+ 开发环境。
- 熟悉 X.509 证书、OCSP、OAuth 2.0、RSA 数字签名和 PKCS#12 密钥库。
步骤 1:用户登录、证书签发和委托生成
登录流程通过三种机制验证用户身份,然后将权限委托给 AI 代理,而不共享用户凭据。这种分离至关重要:代理会收到授权证明,但绝不会持有用户的私钥或完整会话 OAuth 令牌。
首先,应用使用 OAuth 2.0 密码授权向 Keycloak 验证用户身份,并获取完整会话访问令牌和刷新令牌。随后,应用立即执行 RFC 8693 令牌交换,以获取权限范围缩减的令牌。此令牌的受众仅限于 MCP 服务器。只有这个受限令牌会交给代理。如果它意外泄露,也无法访问组织中的任何其他服务。
其次,应用在本地生成 RSA 2048+ 密钥对,并通过 pkcs10enroll REST API 端点向 EJBCA 提交证书签名请求 (CSR)。EJBCA 对 CSR 签名并返回证书。应用将证书和私钥打包到 PKCS12 容器中,并将其存储在 AWS Secrets Manager 中。私钥绝不会离开应用边界。它不会发送给 EJBCA,不会与代理共享,也不会存储在文件系统中。使用相同的基于 CSR 的流程为三个代理签发证书,每个代理角色对应一张证书。
第三,用户的私钥会对委托声明进行签名。这是一份 JSON 文档,其中列出了三个代理证书的 SHA-256 指纹,以及用户的主题名称、签发时间和到期时间。此委托证明用户授权这些特定代理代表自己行事。代理携带此委托,而非用户的证书。
# RFC 8693 Token Exchange - downscope to MCP audience
downscoped_token = keycloak.token_exchange(
original_token, audience="mysql-mcp-server", scope="database:write"
)
# Client-side key generation (user key never leaves this flow)
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
csr = build_csr(private_key, f"CN={username},E={username}@org.com")
user_cert = ejbca.pkcs10enroll(csr, ca_name="UserCA")
# User signs delegation over agent cert fingerprints
delegation = mint_delegation(
username=username,
user_cert_pem=user_cert,
user_key_pem=private_key_pem,
agent_cert_pems=[orch_cert, mysql_cert, email_cert]
)
# Result: {sub, agent_fingerprints[], iat, exp, user_cert_pem, signature_b64}步骤 2:代理间签名信封
当编排代理将请求路由到子代理(例如 MySQL 代理或 Email 代理)时,它不会仅仅传递自己的证书以供识别。相反,它会使用私钥和 RSA-PSS-SHA256 对整个请求负载进行签名,其中包括工具名称、参数、时间戳和密码学随机数。生成的签名信封可提供持有证明。接收代理可以验证调用方是否确实持有与所提供证书相对应的私钥。
接收代理在处理请求前会对信封执行六项验证检查:
- 签名验证:证明发送方持有私钥(持有证明)。
- 时间戳时效性:信封的时间戳必须在当前时间的
ENVELOPE_MAX_AGE_SECONDS(默认 60 秒)范围内。 - 随机数唯一性:
ReplayCache会拒绝任何此前见过的随机数,从而防止请求重放。 - CA 链验证:发送方的证书必须链接到受信任的 CA(
UserCA.pem)。 - 角色授权:证书 CN 中的角色后缀必须包含在此代理的
ALLOWED_CALLER_ROLES中。 - OCSP 吊销检查:通过向 EJBCA 发起实时检查,确认该证书尚未被吊销。
如果编排代理需要重新发送同一个提示(例如,在发生暂时性故障后),则必须使用新的随机数创建一个新信封。旧信封无法重放,即使是合法发送方也不行。
# Orchestrator signs request to sub-agent
envelope = sign_envelope(
payload={"tool": "query_database", "args": {"sql": "SELECT ..."}},
cert_pem=orchestrator_cert_pem,
private_key_pem=orchestrator_key_pem
)
# envelope: {payload_b64, cert_pem, timestamp, nonce, signature_b64, alg}
# Sub-agent verifies (six checks)
verified_payload = verify_envelope(
envelope,
allowed_role="orchestrator-agent",
ca_cert_pem=ca_pem,
replay_cache=cache
)步骤 3:MCP 服务器身份验证
MCP 服务器(FastMCP)是数据库操作运行前的最后一道信任边界。它会对每次工具调用执行四项验证检查,贯彻纵深防御原则。即使某个凭据遭到未授权访问,其余检查也能阻止未授权操作。
身份验证流程:
- 令牌内省:向 Keycloak
/token/introspect端点发送 POST 请求,以验证令牌是否处于活动状态,且其受众包含“mcp-server”。不含正确受众的完整会话令牌将被拒绝。 - 信封验证:验证代理的签名信封,包括签名正确性、时间戳时效性、随机数唯一性、CA 链信任、角色匹配(
mysql-agent)以及 OCSP 未撤销状态。 - 委托验证:验证用户的委托声明。签名证明用户密钥持有者授权了此委托,调用代理的证书指纹出现在授权列表中,并通过 OCSP 检查用户证书。
- 身份交叉核验:令牌用户名、委托主体和代理证书 CN 前缀必须全部匹配。这确保了从用户到工具执行的身份链条一致。
# MCP Server - Four validation checks
# 1. Token: must be active with correct audience
info = introspect(token)
assert info["active"] and "mcp-server" in info["aud"]
# 2. Envelope: proof-of-possession + freshness + replay + CA + role + OCSP
payload = verify_envelope(envelope, "mysql-agent", ca_pem, replay_cache)
# 3. Delegation: user authorized this agent + user cert not revoked
claims = verify_delegation(delegation, agent_cert_pem, ca_pem)
# 4. Cross-check: consistent identity chain
assert token_username == claims["sub"] == agent_cn.rsplit("_", 1)[0]
# All checks passed - execute tool
result = execute_sql(payload["args"]["sql"])步骤 4:防止重放
每个签名信封都带有唯一随机数,这是一个由 Python 的 secrets 模块生成的 128 位加密安全随机十六进制字符串。ReplayCache 是一个线程安全的内存存储区,会记住每个随机数,直至其时效窗口过期(2x ENVELOPE_MAX_AGE_SECONDS)。如果同一个随机数出现在第二个请求中,即使其签名有效且时间戳仍在时效范围内,也会立即拒绝该信封。
时间戳验证与随机数检查相辅相成。信封的时间戳与服务器当前时间的差值必须在 ENVELOPE_MAX_AGE_SECONDS 以内(默认 60 秒)。这些机制共同应对四种未授权访问情形:
- 已记录请求的重放:未授权用户捕获有效信封并在稍后重新提交。该随机数已被记录。
- 延迟传递:传输过程中被拦截的信封在时效窗口过后才到达。时间戳检查失败。
- 重用过期请求:代理缓存的旧信封被重新提交。随机数和时间戳检查均失败。
- 预先伪造:未授权用户无法预测未来的随机数来预先签署信封。
步骤 5:客户端密钥生成
此架构的一项关键安全特性是,私钥在本地生成,绝不传输到任何外部系统。应用程序使用 Python cryptography 库生成 RSA 2048+ 密钥对。它构造一个仅包含公钥和主题信息的 CSR,并仅通过 pkcs10enroll 端点将 CSR 发送给 EJBCA。
EJBCA 验证 CSR,应用证书配置文件(有效期 7 天、密钥用途限制),使用 CA 密钥对其签名,并返回签发的证书。随后,应用程序将本地持有的私钥与返回的证书打包到 PKCS12 容器中,并将其存储在 AWS Secrets Manager 中。
此设计提供了多项安全特性:
- 用户的私钥仅在登录时用于签署委托声明,绝不与代理共享。
- 每个代理的私钥仅由该代理用于签署信封,绝不在代理之间共享。
- EJBCA 从不接触或存储私钥。它仅作为证书颁发机构运行。
- 如果 Secrets Manager 遭到未授权访问,单独存储的 PKCS12 密码会增加一道额外防护。
- 下次登录时重新注册新的 CSR,即可独立轮换密钥材料。
第 6 步:完成注销并撤销凭证
注销会触发撤销级联,立即使所有尚未失效的凭证失效。该流程完成后,不会留下任何仍有效的凭证:
- 在 EJBCA 中撤销用户证书:这会立即使所有尚未失效的委派失效,因为委派验证会通过 OCSP 实时检查用户证书。
- 撤销全部三个代理证书:这会使所有尚未失效的签名信封失效,因为信封验证包含 OCSP 检查。
- 从 AWS Secrets Manager 删除所有密钥:使用
ForceDeleteWithoutRecovery立即删除,且不设恢复期限。 - 终止 Keycloak 会话:通过会话终止端点使缩减权限的令牌失效。
撤销级联是关键的安全属性。在 PKI 层撤销单个用户证书,即可迅速撤销所有下游代理权限,无需逐一撤销令牌、删除会话或联系每个代理。OCSP 提供了传播机制,并且由于每个请求都会检查 OCSP,因此效果会立即生效。
安全注意事项
此架构中的设计选择解决了若干对生产环境中的多代理部署至关重要的安全属性。
私钥隔离。用户的私钥仅在登录流程期间存在,且仅用于签署委派。代理密钥按代理划分,绝不共享。任何密钥材料都不会跨越信任边界。
委派与凭证共享的比较。代理通过加密链(从委派到代理指纹,再到信封签名)证明其权限,而不会持有用户凭证。如果代理密钥泄露,泄露的也仅是该代理的密钥,而非用户的密钥。
受众范围限定的令牌。RFC 8693 令牌交换生成的令牌仅能被 MCP 服务器接受。意外泄露的缩减权限令牌无法用于向 Keycloak 管理 API、其他服务,甚至不同的 MCP 服务器实例进行身份验证。
防止重放。每个请求使用唯一随机数并设有 60 秒有效期,两者结合可确保每个请求只能使用一次且受时间限制。ReplayCache 具备线程安全性,并会自动清理。
失败时关闭设计。每次验证失败都会立即拒绝请求。OCSP 无法访问:拒绝。签名无效:拒绝。时间戳已过期:拒绝。随机数已重放:拒绝。受众错误:拒绝。安全检查不会以降低安全性的方式继续运行。
撤销级联。撤销一个用户证书即可迅速使所有委派、所有代理权限以及所有尚未失效的信封失效。此操作通过实时 OCSP 传播,无需逐一清理凭证。
单向信任链。ALLOWED_CALLER_ROLES映射强制规定只有 orchestrator-agent 才能调用 mysql-agent 和 email-agent。子代理不能互相调用,不能向上调用编排器,也不能冒充用户。
AI 治理注意事项
该系统中的 PKI 架构为 AI 代理内置了行为边界。生产部署应使用 Amazon Bedrock Guardrails 对代理响应实施内容过滤、主题规避和依据核查,并配合本文所述的基于 PKI 的访问控制。
- 工具边界:AI 代理在严格的工具约束下运行。它只能调用预定义的 MCP 工具(
execute_sql、describe_table、list_tables)。代理无法执行任意代码,也无法访问其证书范围之外的资源。 - 人工监督:所有代理操作都会被记录并可审计。AWS CloudTrail 会捕获 AWS API 调用,MCP 服务器会记录每次经过验证的工具调用,以及完整的身份链(用户、代理、时间戳和操作)。
- 数据处理:用户查询和结果均保留在经过身份验证的会话边界内。受众限定令牌将数据访问限制在特定的 MCP 服务器实例上。
- 基于证书的行为边界:代理只能调用其持有有效证书的工具。没有
mysql-agent证书的代理无法访问数据库,无论 LLM 可能生成什么指令。
扩展架构
你可以扩展此架构,以支持其他代理类型、横向扩展和多租户隔离。以下段落介绍了最常见的扩展点。
- 要添加新的代理类型,只需在
ALLOWED_CALLER_ROLES中添加一个条目即可。证书会在登录时自动签发,委派断言会动态包含新代理的指纹。无需更改基础设施。 - 对于横向扩展,你可以在负载均衡器后以高可用模式部署 EJBCA 的 OCSP 响应程序。AWS Secrets Manager 支持适用于此工作负载的高请求速率。
ReplayCache可以由 Amazon ElastiCache 提供支持,以用于分布式部署。 - 要强化生产环境中的架构,你可以通过 AWS CloudHSM 或本地 HSM 使用由硬件安全模块(HSM)支持的 EJBCA 签名密钥。OCSP 响应装订可降低验证延迟,证书透明度日志则能提供完整的已签发证书审计跟踪。
- 对于多租户部署,你可以为每个租户创建独立的证书颁发机构,或创建独立的委派机构,以实现基于加密的租户隔离。结合按租户划分的 AWS 账户,可以在租户之间实现强隔离。
- 你还可以使用 AWS Identity and Access Management(IAM)角色来补充基于 PKI 的代理身份。使用 PKI 进行代理到代理的身份验证,使用 IAM 进行 AWS 服务授权。这两个系统彼此独立,可提供纵深防御。
清理
为避免持续产生费用,请删除本演练期间创建的资源:
- 删除 Amazon RDS for MySQL 实例(如果使用脚本化设置,则删除 AWS CloudFormation 堆栈)。
- 删除 AWS Secrets Manager 中的所有密钥,包括
mcp/前缀下的用户证书和代理证书。 - 从 Amazon SES 中移除已验证的发件人电子邮件地址。
- 终止运行 Keycloak 和 EJBCA 的 Amazon EC2 实例(如果为本演示部署了这些实例)。
- 通过 EJBCA 管理控制台或 REST API 撤销并删除 EJBCA 中的所有测试证书。
- 移除 Keycloak realm(
mcp-realm)及其关联的客户端。 - 如果使用了脚本化设置,请运行
./scripts/cleanup.sh(Linux)或./scripts/cleanup.bat(Windows)来自动执行这些步骤。
结论
在本文中,我们演示了一个使用 Keyfactor EJBCA 和 AWS 服务,通过 X.509 PKI 保护 AI 代理通信的参考架构。该架构通过四种互补机制,解决了多代理 AI 系统中的根本性身份缺口:
- 签名请求信封为每次代理间调用提供加密持有证明,使未经授权的一方更难伪造代理身份或重放其请求。
- 由用户签名的委派断言将授权与凭证共享解耦。代理无需持有用户的私钥或完整会话令牌,即可证明自己获准代表用户执行操作。
- RFC 8693 受众范围限定令牌将任何令牌泄露所造成的暴露范围限制在单个服务边界内。
- 实时 OCSP 撤销检查可确认凭证撤销立即在整个系统中生效。撤销一个用户证书即可迅速终止所有下游代理权限。
该架构与框架无关。虽然我们使用 AWS Strands Agents SDK 和 FastMCP 对其进行了演示,但相同的 PKI 模式也适用于 LangChain、CrewAI、AutoGen 或任何其他使用工具协议的多代理框架。随着 AI 代理不断普及并获得对日益敏感操作的访问权限,代理身份基础设施正从可选项变为必需项。
如需开始使用此参考架构,请参阅配套的 GitHub 存储库。有关所用服务的更多信息,请参阅以下资源:
- Amazon Bedrock
- Amazon Bedrock 用户指南
- Keyfactor EJBCA Enterprise
- MCP 规范
- AWS Strands Agents SDK
- 介绍 Strands Agents:开源 AI 代理 SDK(AWS 开源博客文章)
关于作者
Deepakkumar Sharma
Deepakkumar 是 Amazon Web Services 的解决方案架构师,专注于生成式 AI、安全架构和云原生应用设计。他与企业客户合作,在 AWS 上构建安全的 AI 系统,并热衷于将加密身份引入 AI 代理生态系统。
JD Kilgallin
JD 负责 Keyfactor 的 Analytics and AI 团队,专注于 Agentic AI 的身份与信任管理解决方案。他致力于将企业 PKI 能力引入新兴 AI 框架和多代理架构。
Alex Ament
Alex 是 Keyfactor Analytics and AI 团队的软件工程师助理,负责支持 PKI 软件与 Agentic AI 的集成。他为该参考架构贡献了签名信封、委派断言和重放防护实现。
来源:AWS Machine Learning Blog · aws.amazon.com

