官方更新 AWS ML Blog Tue, 20 Oct 2026 正文 ok 3324 words

在 AWS 上使用 X.509 PKI 保障 AI Agent 身份安全

英文标题:Securing AI agent identity with X.509 PKI on AWS

随着多 Agent 框架广泛采用模型上下文协议(MCP),缺少内置身份验证标准的问题日益凸显,传统共享 API Key 或传递 OAuth Token 的方式难以满足企业级零信任需求。AWS 联合 Keyfactor 推出参考架构,结合 Keyfactor EJBCA 与 AWS 服务,引入签名请求信封、用户签名委托断言、RFC 8693 受众作用域令牌以及实时 OCSP 吊销四大密码学安全机制。该方案在保护底层凭据不泄露的前提下,实现了从人类用户到最终工具执行的端到端可信链条与即时权限撤销,为企业部署安全、可审计的多 Agent 生产系统提供了标准实践范式。
打开原文相关 5.4 · 机会 4
media1.3 MB media1.3 MB media2.4 KB media345.0 KB media141.2 KB media346.5 KB media130.6 KB media134.8 KB media21.8 KB media22.6 KB media20.2 KB media51.1 KB

中文

当 AI Agent 访问数据库、API 以及敏感业务操作时,通过 X.509 公钥基础设施(PKI)建立密码学身份已成为一项关键要求。其核心挑战在于证明请求具体由哪个 Agent 发起、防止 Agent 之间的伪造行为,并确保每个 Agent 仅代表经授权的用户行事。在组件之间共享 API Key 或在 Agent 链中传递 OAuth Token 等传统方法,无法满足企业级部署所要求的零信任标准。

多 Agent AI 框架越来越多地使用模型上下文协议(Model Context Protocol,简称 MCP)将 Agent 连接到外部工具和数据源。MCP 定义了由大语言模型(LLM)驱动的 Agent 如何调用工具(例如数据库查询或邮件发送)。然而,MCP 本身没有内置的身份验证标准,其设计初衷是与传输层无关的(transport-agnostic)。这导致了一个关键安全隐患:如果没有适当的身份机制,任何组件都可能伪造 Agent 身份、重放截获的凭据,或未经授权调用底层工具。

在本文中,我们将展示如何结合 Keyfactor EJBCA 与 AWS 服务来解决这一隐患。EJBCA 是一个支持高可用部署、REST API 自动化以及在线证书状态协议(OCSP)验证的 PKI 平台。该参考架构采用了四种互补的安全机制:首先,**签名请求信封(Signed request envelopes)**在每次 Agent 调用时提供密码学的所有权证明(proof-of-possession);其次,**用户签名的委托断言(User-signed delegation assertions)**在不共享私有凭据的情况下对 Agent 进行授权;第三,**RFC 8693 受众作用域令牌(Audience-scoped tokens)**限制了单点令牌泄露带来的影响范围;第四,**实时 OCSP 吊销检查(Real-time OCSP revocation checking)**可将凭据变更即时同步到所有 Agent。

该方案通过 AWS Strands Agents SDK 使用 Amazon Bedrock 进行 LLM 推理。虽然此参考架构以数据库作为受保护资源,但相同的身份验证模式适用于任何兼容 MCP 的工具服务器。所有示例的完整源代码均可在随附的 GitHub 代码库中获取。

关于 Keyfactor EJBCA

Keyfactor 表示,其机器身份管理平台已被全球 1500 多家企业客户广泛采用。这些机构涵盖金融服务、医疗保健、制造业和政府部门。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 Agent 生态系统中的一项空白。AWS 提供计算、存储和 AI 推理层,而 Keyfactor 则提供密码学身份层,将 Agent 绑定到可验证、可撤销的短期凭证上。这一由 AWS 和 Keyfactor 工程团队联合开发的参考架构展示了如何集成这些技术。您可以将此处展示的模式应用于自己的多 Agent 生产部署中。

方案概述

该架构实现了三个身份验证层,每一层都解决了 Agent 通信链中不同的信任边界问题。这三个层采用了前面介绍的四种安全机制:用于所有权证明的签名信封、用于免凭据授权的委托断言、用于限制暴露范围的受众作用域令牌,以及用于实时吊销的 OCSP。这些机制在各层中的组合如下表所示:

层级 信任边界 机制 验证内容
  1. 用户认证 (User Auth) | 用户到系统 (User to System) | OAuth + X.509 证书 + 委托生成 | 用户身份、凭据绑定
  2. Agent 间认证 (Agent-to-Agent) | Agent 到 Agent | 签名信封(PoP 所有权证明 + 随机数 nonce + 时间戳) | 调用者身份、请求时效性、防重放
  3. MCP 认证 (MCP Auth) | Agent 到工具服务器 | 受限作用域令牌 + 信封 + 委托 | 所有身份、授权链、OCSP

图 1 展示了三个身份验证层,以及凭据如何在用户、Agent 和 MCP 工具服务器之间流动。该图说明了用户凭据(仅保留在登录流程中)、Agent 凭据(按 Agent 划分作用域)以及连接它们的委托链之间的分离设计。

展示用户、Agent 和 MCP 工具服务器之间凭据流的三层 PKI 身份验证架构

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

图 2 说明了典型用户会话期间的详细通信流量。它展示了从登录到证书签发、Agent 委托、工具调用和会话清理的一系列身份验证步骤。

从登录到证书签发、Agent 委托、工具调用和会话清理的身份验证通信流程

图 2:从用户登录到 Agent 委托、工具调用和会话清理的身份验证通信流程

使用的 AWS 服务

以下 AWS 服务构成了该参考架构的基础。

服务 用途
Amazon Bedrock 通过 Strands Agents SDK 进行 LLM 推理
Amazon RDS for MySQL 通过 MCP 工具访问的应用程序数据库
Amazon Simple Email Service (Amazon SES) 为邮件 Agent(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 Agent。这种分离至关重要:Agent 获得授权证明,但绝不会持有用户的私钥或完整会话 OAuth 令牌。

首先,应用程序使用 OAuth 2.0 密码授权模式针对 Keycloak 对用户进行身份验证,接收完整会话的访问令牌(access token)和刷新令牌(refresh token)。紧接着,应用程序执行 RFC 8693 令牌交换以获取降权令牌(downscoped token)。该令牌的受众被严格限制为 MCP 服务器。只有这个受限令牌会被移交给 Agent。即便该令牌不慎暴露,也无法用于访问组织内的任何其他服务。

其次,应用程序在本地生成 RSA 2048+ 密钥对,并通过 pkcs10enroll REST API 端点向 EJBCA 提交证书签名请求(CSR)。EJBCA 对 CSR 进行签名并返回证书。应用程序将证书和私钥打包到 PKCS12 容器中,并将其存储在 AWS Secrets Manager 中。私钥绝不会离开应用程序边界——它既不会发送给 EJBCA,也不会与 Agent 共享,更不会存储在本地文件系统上。三个 Agent 证书也是使用相同的基于 CSR 的流程签发的,每个 Agent 角色分配一个证书。

第三,用户的私钥对委托断言(delegation assertion)进行签名。这是一个 JSON 文档,其中列出了所有三个 Agent 证书的 SHA-256 指纹,以及用户的主题名称(subject name)、签发时间和过期时间。此委托证明了用户已授权这些特定的 Agent 代表其行事。Agent 携带此委托凭证,而无需持有用户的证书。

python

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:Agent 间签名信封

当协调器 Agent(orchestrator agent)将请求路由到子 Agent(例如 MySQL Agent 或 Email Agent)时,它不会简单地传递其证书进行身份验证。相反,它使用自己的私钥并通过 RSA-PSS-SHA256 对整个请求负载进行签名,包括工具名称、参数、时间戳和密码学随机数(nonce)。由此生成的签名信封(signed envelope)提供了所有权证明(proof-of-possession)。接收方 Agent 可以验证调用方确实持有与所出示证书相对应的私钥。

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

  1. 签名验证(Signature verification): 证明发送方拥有对应的私钥(所有权证明)。
  2. 时间戳时效性(Timestamp freshness): 信封的时间必须在当前时间的 ENVELOPE_MAX_AGE_SECONDS(默认 60 秒)以内。
  3. 随机数唯一性(Nonce uniqueness): ReplayCache 会拒绝任何之前见过的随机数,从而防止请求重放攻击。
  4. CA 链验证(CA chain validation): 发送方的证书必须能够链接到受信任的根 CA(UserCA.pem)。
  5. 角色授权(Role authorization): 证书 CN 的角色后缀必须在当前 Agent 允许的 ALLOWED_CALLER_ROLES 列表中。
  6. OCSP 吊销检查(OCSP revocation check): 针对 EJBCA 进行实时检查,确认证书未被吊销。

如果协调器需要重新发送相同的 Prompt(例如遭遇网络瞬态故障后),它必须使用全新的随机数创建一个新信封。即使是合法的发送方,旧信封也无法被二次重放。

python

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. 令牌内省(Token introspection): 向 Keycloak 的 /token/introspect 端点发送 POST 请求,验证令牌处于活跃状态且其受众包含“mcp-server”。没有包含正确受众的完整会话令牌将被直接拒绝。
  2. 信封验证(Envelope verification): 校验 Agent 的签名信封,检查签名正确性、时间戳时效性、随机数唯一性、CA 链信任、角色匹配(mysql-agent)以及 OCSP 未吊销状态。
  3. 委托验证(Delegation verification): 校验用户的委托断言。签名证明了用户密钥持有者授权了此委托,调用方 Agent 的证书指纹包含在授权列表中,并通过 OCSP 验证了用户证书的有效性。
  4. 身份交叉检查(Identity cross-check): 令牌中的用户名、委托断言中的主题以及 Agent 证书 CN 前缀必须完全匹配。这确保了从用户到最终工具执行构成了单一且一致的信任链。

python

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"]

English / 原文

When AI agents access databases, APIs, and sensitive business operations, establishing cryptographic identity through X.509 public key infrastructure (PKI) becomes a critical requirement. The core challenge is proving which agent made a request, preventing forgery between agents, and confirming that each agent acts only on behalf of an authorized user. Traditional approaches such as sharing API keys between components or passing OAuth tokens through agent chains fall short of the zero-trust requirements that enterprise deployments demand.

Multi-agent AI frameworks increasingly use the Model Context Protocol (MCP) to connect agents to external tools and data sources. MCP defines how a large language model (LLM)-powered agent invokes tools such as database queries or email operations. However, MCP has no built-in authentication standard. It is transport-agnostic by design. This creates a critical gap: Without proper identity mechanisms, any component could impersonate an agent, replay intercepted credentials, or invoke tools without authorization.

In this post, we show you how to address this gap using Keyfactor EJBCA combined with AWS services. EJBCA is a PKI platform that supports high-availability deployment, REST API automation, and Online Certificate Status Protocol (OCSP) validation. The reference architecture uses four complementary security mechanisms. First, signed request envelopes provide cryptographic proof-of-possession on every agent call. Second, user-signed delegation assertions authorize agents without sharing credentials. Third, RFC 8693 audience-scoped tokens limit the scope of exposure from any single token disclosure. Fourth, real-time OCSP revocation checking propagates credential changes immediately across all agents.

The solution uses Amazon Bedrock for LLM inference through the AWS Strands Agents SDK. While this reference architecture uses a database as the protected resource, the same authentication pattern applies to any MCP-compatible tool server. Complete source code for all examples is available in the accompanying GitHub repository.

About Keyfactor EJBCA

Keyfactor provides a widely adopted machine identity management platform used by more than 1,500 enterprise customers worldwide, according to Keyfactor. These organizations span financial services, healthcare, manufacturing, and government. Keyfactor helps organizations establish and maintain cryptographic trust through certificate lifecycle management, PKI operations, and machine identity governance.

EJBCA Enterprise is Keyfactor’s Certificate Authority (CA) and PKI platform, designed for high-availability deployment and REST API automation. Available as an enterprise product, EJBCA provides X.509 certificate issuance, OCSP validation, certificate revocation list (CRL) distribution, and full certificate lifecycle management through both a web console and REST API. EJBCA supports deployment on-premises, in containers, or on Amazon Elastic Compute Cloud (Amazon EC2).

The partnership between AWS and Keyfactor brings together AWS managed services (Amazon Bedrock, AWS Secrets Manager, Amazon Relational Database Service (Amazon RDS)) with PKI infrastructure that supports certificate lifecycle management, automated enrollment, and real-time revocation. This combination addresses a gap in the AI agent ecosystem. While AWS provides the compute, storage, and AI inference layers, Keyfactor provides the cryptographic identity layer that binds agents to verifiable, revocable, short-lived credentials. This joint reference architecture, developed collaboratively by the AWS and Keyfactor engineering teams, demonstrates how to integrate these technologies. You can adapt the patterns shown here to your own multi-agent deployments.

Solution overview

The architecture implements three authentication layers, each addressing a different trust boundary in the agent communication chain. These three layers use the four security mechanisms introduced earlier: signed envelopes for proof-of-possession, delegation assertions for credential-free authorization, audience-scoped tokens for exposure limitation, and OCSP for real-time revocation. The mechanisms combine across layers as shown in the following table.

Layer Trust boundary Mechanism Validates
1. User Auth User to System OAuth + X.509 cert + delegation minting User identity, credential binding
2. Agent-to-Agent Agent to Agent Signed envelopes (PoP + nonce + timestamp) Caller identity, request freshness, no replay
3. MCP Auth Agent to Tool Server Scoped token + envelope + delegation All identities, authorization chain, OCSP

Figure 1 shows the three authentication layers and how credentials flow between the user, agents, and the MCP tool server. The diagram illustrates the separation between user credentials (which stay in the login flow), agent credentials (scoped per agent), and the delegation chain that connects them.

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

Figure 1: Three-layer PKI authentication architecture for AI agent systems on AWS

Figure 2 illustrates the detailed traffic flow during a typical user session. It shows the sequence of authentication steps from login through certificate issuance, agent delegation, tool invocation, and session cleanup.

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

Figure 2: Authentication traffic flow from user login through agent delegation, tool invocation, and session cleanup

AWS services used

The following AWS services form the foundation of the reference architecture.

Service Purpose
Amazon Bedrock LLM inference through Strands Agents SDK
Amazon RDS for MySQL Application database accessed through MCP tools
Amazon Simple Email Service (Amazon SES) Email delivery for the Email Agent
AWS Secrets Manager Secure storage for PKCS12 bundles, tokens, and metadata
Amazon EC2 Hosts Keycloak IDP and EJBCA PKI server

Solution walkthrough

The following steps walk through each component of the architecture, from initial user login through to session cleanup. Each step builds on the previous one, establishing a chain of trust that connects the human user to the final tool execution.

Prerequisites

  • An active AWS account with access to Amazon Bedrock, Amazon RDS for MySQL, Amazon SES, and AWS Secrets Manager.
  • Keycloak 26.2 or later (required for RFC 8693 standard token exchange. Previous versions use a legacy exchange that is incompatible).
  • Keyfactor EJBCA Enterprise with REST API V1 and an OCSP responder configured.
  • EJBCA API administrator certificate (api-admin.p12) for REST API authentication.
  • Python 3.9+ development environment.
  • Familiarity with X.509 certificates, OCSP, OAuth 2.0, RSA digital signatures, and PKCS#12 key stores.

Step 1: User login, certificate issuance, and delegation minting

The login flow establishes the user’s identity through three mechanisms and then delegates authority to the AI agents without sharing the user’s credentials. This separation is critical: Agents receive proof of authorization without ever holding the user’s private key or full-session OAuth token.

First, the application authenticates the user against Keycloak using an OAuth 2.0 password grant, receiving a full-session access token and refresh token. Immediately after, the application performs an RFC 8693 token exchange to obtain a downscoped token. This token’s audience is restricted to the MCP server. Only this limited token is handed to agents. If it’s inadvertently exposed, it can’t access any other service in the organization.

Second, the application generates an RSA 2048+ key pair locally and submits a Certificate Signing Request (CSR) to EJBCA through the pkcs10enroll REST API endpoint. EJBCA signs the CSR and returns the certificate. The application bundles the certificate and private key into a PKCS12 container and stores it in AWS Secrets Manager. The private key never leaves the application boundary. It is not sent to EJBCA, not shared with agents, and not stored on the filesystem. Three agent certificates are issued using the same CSR-based flow, one per agent role.

Third, the user’s private key signs a delegation assertion. This is a JSON document listing the SHA-256 fingerprints of all three agent certificates, along with the user’s subject name, issuance time, and expiry. This delegation proves that the user authorized these specific agents to act on their behalf. Agents carry this delegation instead of the user’s certificate.

# 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}

Step 2: Agent-to-agent signed envelopes

When the orchestrator agent routes a request to a sub-agent (such as the MySQL agent or Email agent), it does not simply pass its certificate for identification. Instead, it signs the entire request payload, including the tool name, arguments, a timestamp, and a cryptographically random nonce, using its private key with RSA-PSS-SHA256. The resulting signed envelope provides proof-of-possession. The receiving agent can verify that the caller actually holds the private key corresponding to the presented certificate.

The receiving agent performs six validation checks on the envelope before processing the request:

  1. Signature verification: Proves the sender possesses the private key (proof-of-possession).
  2. Timestamp freshness: The envelope must be within ENVELOPE_MAX_AGE_SECONDS (default 60 seconds) of the current time.
  3. Nonce uniqueness: The ReplayCache rejects any previously seen nonce, preventing request replay.
  4. CA chain validation: The sender’s certificate must chain to the trusted CA (UserCA.pem).
  5. Role authorization: The certificate CN’s role suffix must be in ALLOWED_CALLER_ROLES for this agent.
  6. OCSP revocation check: A real-time check against EJBCA confirms the certificate has not been revoked.

If the orchestrator needs to re-send the same prompt (for example, after a transient failure), it must create a new envelope with a fresh nonce. Old envelopes can’t be replayed, even by the legitimate sender.

# 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
)

Step 3: MCP server authentication

The MCP server (FastMCP) is the final trust boundary before any database operation runs. It performs four validation checks on every tool invocation, implementing defense-in-depth. Even if one credential is subject to unauthorized access, the remaining checks prevent unauthorized operations.

The authentication sequence:

  1. Token introspection: A POST to the Keycloak /token/introspect endpoint verifies the token is active and its audience contains “mcp-server”. A full-session token without the correct audience is rejected.
  2. Envelope verification: The agent’s signed envelope is validated for signature correctness, timestamp freshness, nonce uniqueness, CA chain trust, role match (mysql-agent), and OCSP non-revocation.
  3. Delegation verification: The user’s delegation assertion is validated. The signature proves the user’s key holder authorized this delegation, the calling agent’s certificate fingerprint appears in the authorized list, and the user’s certificate is checked through OCSP.
  4. Identity cross-check: The token username, the delegation subject, and the agent certificate CN prefix must all match. This confirms a single consistent identity chain from user through to tool execution.
# 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"])

Step 4: Replay prevention

Every signed envelope carries a unique nonce, a 128-bit cryptographically random hex string generated with Python’s secrets module. The ReplayCache is a thread-safe in-memory store that remembers every nonce until its freshness window expires (2x ENVELOPE_MAX_AGE_SECONDS). If the same nonce appears in a second request, the envelope is immediately rejected, even if its signature is valid and the timestamp is fresh.

The timestamp validation complements the nonce check. An envelope’s timestamp must be within ENVELOPE_MAX_AGE_SECONDS (default 60 seconds) of the server’s current time. Together, these mechanisms address four unauthorized access scenarios:

  • Recorded replay: An unauthorized user captures a valid envelope and resubmits it later. The nonce was already seen.
  • Delayed delivery: An envelope intercepted in transit arrives after the freshness window. The timestamp check fails.
  • Stale request reuse: An old envelope cached by a proxy is resubmitted. Both nonce and timestamp checks fail.
  • Precomputed forgery: An unauthorized user cannot predict future nonces to pre-sign envelopes.

Step 5: Client-side key generation

A critical security property of this architecture is that private keys are generated locally and never transmitted to any external system. The application generates RSA 2048+ key pairs using the Python cryptography library. It constructs a CSR containing only the public key and subject information, and sends only the CSR to EJBCA through the pkcs10enroll endpoint.

EJBCA validates the CSR, applies the certificate profile (7-day validity, key usage constraints), signs it with the CA key, and returns the issued certificate. The application then bundles the locally held private key with the returned certificate into a PKCS12 container and stores it in AWS Secrets Manager.

This design provides several security properties:

  • The user’s private key is used only at login to sign the delegation assertion. It’s never shared with agents.
  • Each agent’s private key is used only by that agent to sign envelopes. It’s never shared between agents.
  • EJBCA never sees or stores private keys. It operates purely as a certificate authority.
  • If Secrets Manager is subject to unauthorized access, the PKCS12 password (stored separately) adds an additional layer.
  • Key material can be rotated independently by re-enrolling with a new CSR at next login.

Step 6: Complete logout and credential revocation

Logout triggers a revocation cascade that immediately invalidates all outstanding credentials. The sequence results in no remaining valid credentials after completion:

  1. Revoke user certificate in EJBCA: This immediately invalidates all outstanding delegations, because delegation verification checks the user’s certificate through OCSP in real time.
  2. Revoke all three agent certificates: This invalidates all outstanding signed envelopes, since envelope verification includes OCSP.
  3. Delete all secrets from AWS Secrets Manager: Using ForceDeleteWithoutRecovery for immediate removal with no recovery window.
  4. Terminate Keycloak session: Invalidates the downscoped token through the session termination endpoint.

The revocation cascade is the key security property. Revoking a single user certificate at the PKI layer promptly revokes all downstream agent authority without needing to individually revoke tokens, delete sessions, or contact each agent. OCSP provides the propagation mechanism, and because every request checks OCSP, the effect is immediate.

Security considerations

The design choices in this architecture address several security properties that are important for production multi-agent deployments.

Private key isolation. The user’s private key exists only during the login flow and is used solely to sign the delegation. Agent keys are scoped per-agent and never shared. No key material crosses trust boundaries.

Delegation compared to credential sharing. Agents prove their authority through a cryptographic chain (delegation to agent fingerprint to envelope signature) without ever holding user credentials. If an agent key is exposed, only that agent’s key is revealed, not the user’s.

Audience-scoped tokens. RFC 8693 token exchange produces a token accepted only by the MCP server. An inadvertently disclosed downscoped token cannot authenticate against Keycloak admin APIs, other services, or even a different MCP server instance.

Replay prevention. The combination of per-request nonces and a 60-second freshness window confirms that every request is single-use and time-bound. The ReplayCache is thread-safe and self-cleaning.

Fail-closed design. Every validation failure results in immediate denial. OCSP unreachable: deny. Invalid signature: deny. Expired timestamp: deny. Replayed nonce: deny. Wrong audience: deny. There’s no graceful degradation for security checks.

Revocation cascade. Revoking one user certificate promptly invalidates all delegations, all agent authority, and all outstanding envelopes. This is propagated through real-time OCSP without requiring individual credential cleanup.

Forward-only trust chain. The ALLOWED_CALLER_ROLES map enforces that only orchestrator-agent can call mysql-agent and email-agent. Sub-agents cannot call each other, can’t call upward to the orchestrator, and cannot impersonate the user.

AI governance considerations

The PKI architecture provides built-in behavior boundaries for the AI agents in this system. Production deployments should use Amazon Bedrock Guardrails to enforce content filtering, topic avoidance, and grounding checks on agent responses, alongside the PKI-based access controls described in this post.

  • Tool boundaries : The AI agent operates under strict tool constraints. It can only invoke pre-defined MCP tools (execute_sql, describe_table, list_tables). The agent can’t execute arbitrary code or access resources outside its certificate scope.
  • Human oversight : All agent actions are logged and auditable. AWS CloudTrail captures AWS API calls, and the MCP server logs every validated tool invocation with the full identity chain (user, agent, timestamp, and operation).
  • Data handling : User queries and results stay within the authenticated session boundary. The audience-scoped token confines data access to the specific MCP server instance.
  • Certificate-based behavior boundaries : Agents can only invoke tools they hold valid certificates for. An agent without a mysql-agent certificate cannot access the database, regardless of what the LLM might generate as instructions.

Extending the architecture

You can extend this architecture to support additional agent types, horizontal scaling, and multi-tenant isolation. The following paragraphs describe the most common extension points.

  • To add new agent types, you only need to add an entry in ALLOWED_CALLER_ROLES. Certificates are automatically issued at login, and the delegation assertion dynamically includes the new agent’s fingerprint. No infrastructure changes are required.
  • For horizontal scaling, you can deploy EJBCA’s OCSP responder in high-availability mode behind a load balancer. AWS Secrets Manager supports high request rates suitable for this workload. The ReplayCache can be backed by Amazon ElastiCache for distributed deployments.
  • To harden the architecture for production, you can use hardware security module (HSM)-backed EJBCA signing keys through AWS CloudHSM or an on-premises HSM. OCSP response stapling reduces validation latency, and Certificate Transparency logs provide a full audit trail of issued certificates.
  • For multi-tenant deployments, you can create per-tenant Certificate Authorities or per-tenant delegation authorities for cryptographic tenant isolation. Combined with per-tenant AWS accounts, this delivers strong isolation between tenants.
  • You can also complement PKI-based agent identity with AWS Identity and Access Management (IAM) roles. Use PKI for agent-to-agent authentication and IAM for AWS service authorization. The two systems work independently, providing defense in depth.

Clean up

To avoid ongoing charges, remove the resources created during this walkthrough:

  • Delete the Amazon RDS for MySQL instance (or the AWS CloudFormation stack if you used the scripted setup).
  • Delete all secrets from AWS Secrets Manager, including user certificates and agent certificates under the mcp/ prefix.
  • Remove the verified sender email address from Amazon SES.
  • Terminate the Amazon EC2 instances running Keycloak and EJBCA (if deployed for this demonstration).
  • Revoke and delete all test certificates in EJBCA by using the EJBCA admin console or REST API.
  • Remove the Keycloak realm (mcp-realm) and associated clients.
  • If you used the scripted setup, run ./scripts/cleanup.sh (Linux) or ./scripts/cleanup.bat (Windows) to automate these steps.

Conclusion

In this post, we demonstrated a reference architecture for securing AI agent communications using X.509 PKI with Keyfactor EJBCA and AWS services. The architecture addresses the fundamental identity gap in multi-agent AI systems through four complementary mechanisms:

  • Signed request envelopes provide cryptographic proof-of-possession on every inter-agent call, making it significantly harder for an unauthorized party to forge an agent’s identity or replay its requests.
  • User-signed delegation assertions decouple authorization from credential sharing. Agents prove they are authorized to act on the user’s behalf without holding the user’s private key or full-session token.
  • RFC 8693 audience-scoped tokens limit the scope of exposure from any token disclosure to a single service boundary.
  • Real-time OCSP revocation checking confirms that credential revocation takes immediate effect across the entire system. Revoking one user certificate promptly ends all downstream agent authority.

This architecture is framework-agnostic. While we demonstrated it with the AWS Strands Agents SDK and FastMCP, the same PKI patterns apply to LangChain, CrewAI, AutoGen, or any other multi-agent framework that uses tool protocols. As AI agents proliferate and gain access to increasingly sensitive operations, agent identity infrastructure moves from optional to essential.

To get started with this reference architecture, see the accompanying GitHub repository. For more information about the services used, see the following resources:


About the authors

Deepakkumar Sharma

Deepakkumar is a Solutions Architect at Amazon Web Services specializing in generative AI, security architecture, and cloud-native application design. He works with enterprise customers to build secure AI systems on AWS and is passionate about bringing cryptographic identity to the AI agent ecosystem.

JD Kilgallin

JD leads the Keyfactor Analytics and AI team specializing in identity and trust management solutions for Agentic AI. He focuses on bringing enterprise PKI capabilities to emerging AI frameworks and multi-agent architectures.

Alex Ament

Alex is an associate Software Engineer on the Keyfactor Analytics and AI team supporting integrations of PKI software with Agentic AI. He contributed the signed envelope, delegation assertion, and replay prevention implementations in this reference architecture.