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

如何在 AWS 上用 X.509 PKI 保护 AI 智能体身份

Securing AI agent identity with X.509 PKI on AWS

AI 导读

AWS 博文给出与 Keyfactor 合作的参考架构,用 Keyfactor EJBCA 签发 X.509 证书,并结合 Amazon Bedrock 与 Strands Agents SDK,为通过 MCP 访问数据库等工具的 AI 智能体补上加密身份。

正文 · AI 翻译

当 AI 智能体访问数据库、API 和敏感业务操作时,通过 X.509 公钥基础设施(PKI)建立加密身份成为一项关键要求。核心挑战在于证明是哪个智能体发出了请求、防止智能体之间的伪造,并确认每个智能体仅代表已授权用户行事。在组件之间共享 API 密钥或通过智能体链传递 OAuth 令牌等传统方法,无法满足企业部署所要求的零信任要求。

多智能体 AI 框架越来越多地使用模型上下文协议(MCP)将智能体连接到外部工具和数据源。MCP 定义了由大语言模型(LLM)驱动的智能体如何调用数据库查询或电子邮件操作等工具。然而,MCP 没有内置的身份验证标准。它在设计上与传输无关。这造成了一个关键缺口:如果没有适当的身份机制,任何组件都可能冒充智能体、重放截获的凭证,或在未经授权的情况下调用工具。

在本文中,我们将向你展示如何结合 AWS 服务使用 Keyfactor EJBCA 来弥补这一缺口。EJBCA 是一个支持高可用部署、REST API 自动化以及在线证书状态协议(OCSP)验证的 PKI 平台。该参考架构使用四种互补的安全机制。第一,签名请求信封为每次智能体调用提供加密的持有证明。第二,用户签名的委托断言在不共享凭证的情况下授权智能体。第三,符合 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 服务器

解决方案演练

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

前提条件

  • 一个可访问 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 对整个请求载荷进行签名,其中包括工具名称、参数、时间戳以及加密随机 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,直到其新鲜度窗口过期(2x 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 代理在严格的工具约束下运行。它只能调用预定义的 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 响应装订可降低验证延迟,Certificate Transparency 日志则为已颁发证书提供完整的审计跟踪。
  • 对于多租户部署,你可以创建按租户划分的证书颁发机构或按租户划分的委托机构,以实现加密层面的租户隔离。再结合按租户划分的 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 领域(mcp-realm)及相关客户端。
  • 如果你使用了脚本化设置,请运行 ./scripts/cleanup.sh(Linux)或 ./scripts/cleanup.bat(Windows)以自动执行这些步骤。

结论

在本文中,我们演示了一种参考架构,使用 X.509 PKI 以及 Keyfactor EJBCA 和 AWS 服务来保护 AI 代理通信。该架构通过四种互补机制,解决多智能体 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 Analytics and AI 团队,专注于面向智能体 AI 的身份与信任管理解决方案。他致力于将企业级 PKI 能力引入新兴 AI 框架和多智能体架构。

Alex Ament

Alex Ament

Alex 是 Keyfactor Analytics and AI 团队的助理软件工程师,负责支持 PKI 软件与智能体 AI 的集成。他在此参考架构中贡献了签名信封、委托断言和重放防护的实现。

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