跳到正文
AWS Machine Learning Blog· Deepakkumar Sharma·· 3 小时前AI 评分38

在 AWS 上用 X.509 PKI 保障 AI 智能体身份安全

Securing AI agent identity with X.509 PKI on AWS

AI 导读

AWS 与 Keyfactor 联合发布参考架构,用 Keyfactor EJBCA 的 X.509 PKI 为 AI 智能体建立可验证、可撤销的加密身份,填补 MCP 无内置认证标准的缺口。

正文 · AI 翻译

当 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 通过 Web 控制台和 REST API 提供 X.509 证书颁发、OCSP 验证、证书吊销列表(CRL)分发以及完整的证书生命周期管理。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 + 时间戳) 调用方身份、请求新鲜度、无重放
3. MCP 认证 智能体到工具服务器 限定令牌 + 信封 + 委托 所有身份、授权链、OCSP

图 1 展示了三个身份验证层以及凭证在用户、智能体和 MCP 工具服务器之间的流转方式。该图说明了用户凭证(保留在登录流程中)、智能体凭证(按智能体限定范围)以及连接二者的委托链之间的分离。

Three-layer PKI authentication architecture showing credential flow between the user, agents, and the MCP tool server

图 1:AWS 上 AI 智能体系统的三层 PKI 身份验证架构

图 2 展示了典型用户会话期间的详细流量。它显示了从登录到证书签发、智能体委托、工具调用和会话清理的身份验证步骤序列。

Authentication traffic flow from login through certificate issuance, agent delegation, tool invocation, and session cleanup

图 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 服务器

解决方案演练

以下步骤逐一介绍架构的每个组件,从初始用户登录一直到会话清理。每一步都建立在前一步之上,形成一条将人类用户连接到最终工具执行的信任链。

先决条件

  • 一个活跃的 AWS 账户,可访问 Amazon Bedrock、Amazon RDS for MySQL、Amazon SES 和 AWS Secrets Manager。
  • Keycloak 26.2 或更高版本(RFC 8693 标准令牌交换所需。早期版本使用不兼容的旧版交换)。
  • Keyfactor EJBCA Enterprise,具有 REST API V1 并配置了 OCSP 响应器。
  • 用于 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 对整个请求负载进行签名,包括工具名称、参数、时间戳和加密随机 nonce。生成的签名信封提供了持有证明。接收代理可以验证调用方确实持有与所出示证书对应的私钥。

接收代理在处理请求之前对信封执行六项验证检查:

  1. 签名验证:证明发送方拥有私钥(持有证明)。
  2. 时间戳新鲜度:信封必须在当前时间的 ENVELOPE_MAX_AGE_SECONDS 范围内(默认 60 秒)。
  3. Nonce 唯一性:ReplayCache 拒绝任何先前见过的 nonce,防止请求重放。
  4. CA 链验证:发送方的证书必须链接到受信任的 CA(UserCA.pem)。
  5. 角色授权:证书 CN 的角色后缀必须在此代理的 ALLOWED_CALLER_ROLES 中。
  6. OCSP 吊销检查:针对 EJBCA 的实时检查确认证书未被吊销。

如果编排器需要重新发送相同的提示(例如,在瞬时故障之后),它必须使用新的 nonce 创建新信封。旧信封无法被重放,即使是合法发送方也不行。

# 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)是任何数据库操作运行前的最终信任边界。它对每次工具调用执行四项验证检查,实现纵深防御。即使某个凭据遭到未经授权的访问,其余检查也能阻止未经授权的操作。

认证流程如下:

  1. 令牌内省:向 Keycloak /token/introspect 端点发送 POST 请求,验证令牌处于活动状态且其受众包含“mcp-server”。没有正确受众的完整会话令牌会被拒绝。
  2. 信封验证:验证代理的签名信封的签名正确性、时间戳新鲜度、nonce 唯一性、CA 链信任、角色匹配(mysql-agent)以及 OCSP 未吊销状态。
  3. 委托验证:验证用户的委托断言。签名证明用户密钥持有者授权了此委托,调用代理的证书指纹出现在授权列表中,并且用户的证书通过 OCSP 进行检查。
  4. 身份交叉核对:令牌用户名、委托主体和代理证书 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 步:防重放

每个签名信封都携带一个唯一的 nonce,即使用 Python 的 secrets 模块生成的 128 位加密随机十六进制字符串。ReplayCache 是一个线程安全的内存存储,会记住每个 nonce 直到其新鲜度窗口过期(2 倍 ENVELOPE_MAX_AGE_SECONDS)。如果同一个 nonce 出现在第二个请求中,信封会立即被拒绝,即使其签名有效且时间戳新鲜。

时间戳验证与 nonce 检查相辅相成。信封的时间戳必须在服务器当前时间的 ENVELOPE_MAX_AGE_SECONDS(默认 60 秒)以内。这些机制共同应对四种未经授权的访问场景:

  • 录制重放:未经授权的用户捕获有效信封并稍后重新提交。该 nonce 已被见过。
  • 延迟投递:在传输中被拦截的信封在新鲜度窗口之后到达。时间戳检查失败。
  • 过期请求重用:代理缓存的旧信封被重新提交。nonce 和时间戳检查均失败。
  • 预计算伪造:未经授权的用户无法预测未来的 nonce 来预先签名信封。

第 5 步:客户端密钥生成

此架构的一个关键安全特性是私钥在本地生成,且从不传输到任何外部系统。应用程序使用 Python cryptography 库生成 RSA 2048+ 密钥对。它构造一个仅包含公钥和主体信息的 CSR,并仅通过 pkcs10enroll 端点将 CSR 发送到 EJBCA。

EJBCA 验证 CSR,应用证书配置文件(7 天有效期、密钥用途约束),用 CA 密钥签名,并返回签发的证书。然后,应用程序将本地持有的私钥与返回的证书打包到 PKCS12 容器中,并存储在 AWS Secrets Manager 中。

此设计提供了若干安全特性:

  • 用户的私钥仅在登录时用于签署委托断言。它从不与代理共享。
  • 每个代理的私钥仅由该代理用于签署信封。它从不在代理之间共享。
  • EJBCA 从不查看或存储私钥。它纯粹作为证书颁发机构运行。
  • 如果 Secrets Manager 遭到未经授权的访问,PKCS12 密码(单独存储)会提供额外的保护层。
  • 密钥材料可以通过在下次登录时使用新的 CSR 重新注册来独立轮换。

步骤 6:完成注销和凭证吊销

注销会触发吊销级联,立即作废所有未到期的凭证。该序列完成后不会留下任何有效凭证:

  1. 在 EJBCA 中吊销用户证书:这会立即作废所有未到期的委托,因为委托验证会通过 OCSP 实时检查用户证书。
  2. 吊销全部三个代理证书:这会作废所有未到期的已签名信封,因为信封验证包含 OCSP 检查。
  3. 从 AWS Secrets Manager 中删除所有密钥:使用 ForceDeleteWithoutRecovery 立即删除,无恢复窗口。
  4. 终止 Keycloak 会话:通过会话终止端点使降权令牌失效。

吊销级联是关键的安全属性。在 PKI 层吊销单个用户证书即可迅速吊销所有下游代理权限,无需逐个吊销令牌、删除会话或联系每个代理。OCSP 提供传播机制,并且由于每个请求都会检查 OCSP,效果是即时的。

安全考量

此架构中的设计选择满足了若干对生产环境多代理部署至关重要的安全属性。

私钥隔离。用户的私钥仅在登录流程期间存在,且仅用于签署委托。代理密钥按代理划分作用域,绝不共享。任何密钥材料都不会跨越信任边界。

委托与凭证共享的对比。代理通过密码学链(委托到代理指纹再到信封签名)证明其权限,而无需持有用户凭证。如果某个代理密钥泄露,只会暴露该代理的密钥,而非用户的密钥。

受众限定令牌。RFC 8693 令牌交换生成的令牌仅被 MCP 服务器接受。意外泄露的降权令牌无法通过 Keycloak 管理 API、其他服务甚至其他 MCP 服务器实例的身份验证。

防重放。每请求 nonce 与 60 秒新鲜度窗口的组合确保每个请求都是单次使用且有时间限制的。ReplayCache 是线程安全且自清理的。

故障关闭设计。任何验证失败都会导致立即拒绝。OCSP 不可达:拒绝。签名无效:拒绝。时间戳过期:拒绝。nonce 重放:拒绝。受众错误:拒绝。安全检查不存在优雅降级。

吊销级联。吊销一个用户证书即可迅速作废所有委托、所有代理权限以及所有未到期的信封。这通过实时 OCSP 传播,无需逐个清理凭证。

仅向前的信任链。ALLOWED_CALLER_ROLES 映射强制只有 orchestrator-agent 可以调用 mysql-agent 和 email-agent。子代理不能相互调用,不能向上调用编排器,也不能冒充用户。

AI 治理考量

PKI 架构为此系统中的 AI 代理提供了内置的行为边界。生产部署应使用 Amazon Bedrock Guardrails 对代理响应实施内容过滤、话题规避和接地检查,并与本文所述的基于 PKI 的访问控制配合使用。

  • 工具边界:AI agent 在严格的工具约束下运行。它只能调用预定义的 MCP 工具(execute_sql、describe_table、list_tables)。该 agent 无法执行任意代码,也无法访问其证书范围之外的资源。
  • 人工监督:所有 agent 操作都会被记录并可审计。AWS CloudTrail 捕获 AWS API 调用,MCP 服务器记录每一次经过验证的工具调用,并包含完整的身份链(用户、agent、时间戳和操作)。
  • 数据处理:用户查询和结果保留在已认证的会话边界内。受众范围令牌将数据访问限制在特定的 MCP 服务器实例内。
  • 基于证书的行为边界:agent 只能调用其持有有效证书的工具。没有 mysql-agent 证书的 agent 无法访问数据库,无论 LLM 可能生成什么指令。

扩展架构

你可以扩展此架构以支持更多 agent 类型、水平扩展和多租户隔离。以下段落描述了最常见的扩展点。

  • 要添加新的 agent 类型,只需在 ALLOWED_CALLER_ROLES 中添加一个条目。证书会在登录时自动签发,委托断言会动态包含新 agent 的指纹。无需更改基础设施。
  • 对于水平扩展,你可以在负载均衡器后面以高可用模式部署 EJBCA 的 OCSP 响应器。AWS Secrets Manager 支持适合此工作负载的高请求速率。ReplayCache 可以由 Amazon ElastiCache 支持,用于分布式部署。
  • 要为生产环境加固此架构,你可以通过 AWS CloudHSM 或本地 HSM 使用由硬件安全模块(HSM)支持的 EJBCA 签名密钥。OCSP 响应装订可降低验证延迟,证书透明度日志可提供已签发证书的完整审计轨迹。
  • 对于多租户部署,你可以创建按租户划分的证书颁发机构或按租户划分的委托机构,以实现加密层面的租户隔离。结合按租户划分的 AWS 账户,这可以在租户之间实现强隔离。
  • 你还可以用 AWS Identity and Access Management(IAM)角色来补充基于 PKI 的 agent 身份。使用 PKI 进行 agent 到 agent 的认证,使用 IAM 进行 AWS 服务授权。这两个系统独立工作,提供纵深防御。

清理

为避免持续产生费用,请删除本演练期间创建的资源:

  • 删除 Amazon RDS for MySQL 实例(如果你使用了脚本化设置,则删除 AWS CloudFormation 堆栈)。
  • 从 AWS Secrets Manager 中删除所有密钥,包括 mcp/ 前缀下的用户证书和 agent 证书。
  • 从 Amazon SES 中移除已验证的发件人电子邮件地址。
  • 终止运行 Keycloak 和 EJBCA 的 Amazon EC2 实例(如果为本演示部署了它们)。
  • 使用 EJBCA 管理控制台或 REST API 撤销并删除 EJBCA 中的所有测试证书。
  • 移除 Keycloak 领域(mcp-realm)及关联客户端。
  • 如果你使用了脚本化设置,请运行 ./scripts/cleanup.sh(Linux)或 ./scripts/cleanup.bat(Windows)来自动执行这些步骤。

结论

在本文中,我们展示了一个参考架构,使用 X.509 PKI 结合 Keyfactor EJBCA 和 AWS 服务来保护 AI agent 通信。该架构通过四种互补机制解决了多 agent AI 系统中的根本性身份缺口:

  • 签名请求信封在每次代理间调用时提供加密的所有权证明,使未经授权的第三方伪造代理身份或重放其请求变得显著更加困难。
  • 用户签名的委托断言将授权与凭证共享解耦。代理无需持有用户的私钥或完整会话令牌,即可证明其被授权代表用户行事。
  • RFC 8693 受众范围令牌将任何令牌泄露的暴露范围限制在单一服务边界内。
  • 实时 OCSP 吊销检查确认凭证吊销在整个系统中立即生效。吊销一个用户证书即可迅速终止所有下游代理权限。

此架构与框架无关。虽然我们使用 AWS Strands Agents SDK 和 FastMCP 进行了演示,但相同的 PKI 模式适用于 LangChain、CrewAI、AutoGen 或任何其他使用工具协议的多代理框架。随着 AI 代理的激增并获得对日益敏感操作的访问权限,代理身份基础设施从可选变为必需。

要开始使用此参考架构,请参阅随附的 GitHub 仓库。有关所用服务的更多信息,请参阅以下资源:


关于作者

Deepakkumar Sharma

Deepakkumar Sharma

Deepakkumar 是 Amazon Web Services 的解决方案架构师,专长于生成式 AI、安全架构和云原生应用设计。他与企业客户合作在 AWS 上构建安全的 AI 系统,并热衷于将加密身份引入 AI 代理生态系统。

JD Kilgallin

JD Kilgallin

JD 领导 Keyfactor 分析与 AI 团队,专注于 Agentic AI 的身份和信任管理解决方案。他致力于将企业 PKI 能力引入新兴的 AI 框架和多代理架构。

Alex Ament

Alex Ament

Alex 是 Keyfactor 分析与 AI 团队的副软件工程师,支持 PKI 软件与 Agentic AI 的集成。他贡献了此参考架构中的签名信封、委托断言和重放防护实现。

来源:AWS Machine Learning Blog · aws.amazon.com