AgentCore Gateway
生成一个 Amazon Bedrock AgentCore Gateway 项目。AgentCore Gateway 是一个托管的入口点,它将一个或多个 MCP 服务器目标聚合在单个 MCP 端点后面,针对 Cedar 策略引擎评估每个工具调用,并使用 IAM SigV4 对发往 MCP 服务器的出站流量进行签名。
生成 AgentCore Gateway
Section titled “生成 AgentCore Gateway”- 安装 Nx Console VSCode Plugin 如果您尚未安装
- 在VSCode中打开Nx控制台
- 点击
Generate (UI)在"Common Nx Commands"部分 - 搜索
@aws/nx-plugin - agentcore-gateway - 填写必需参数
- 点击
Generate
pnpm nx g @aws/nx-plugin:agentcore-gatewayyarn nx g @aws/nx-plugin:agentcore-gatewaynpx nx g @aws/nx-plugin:agentcore-gatewaybunx nx g @aws/nx-plugin:agentcore-gateway您还可以执行试运行以查看哪些文件会被更改
pnpm nx g @aws/nx-plugin:agentcore-gateway --dry-runyarn nx g @aws/nx-plugin:agentcore-gateway --dry-runnpx nx g @aws/nx-plugin:agentcore-gateway --dry-runbunx nx g @aws/nx-plugin:agentcore-gateway --dry-run| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| name 必需 | string | - | 您的 AgentCore Gateway 项目的名称 |
| directory | string | packages | 放置网关项目的父目录。 |
| subDirectory | string | - | 项目放置的子目录。默认情况下,这是项目名称。 |
| protocol | mcp | mcp | 您的网关公开的入站协议。目前仅支持 mcp;未来可能会添加其他协议。 |
| auth | iam | iam | 用于验证网关入站请求的方法。目前仅支持 iam;未来可能会添加 cognito 和 custom-jwt。 |
| cedarPolicy | boolean | true | 是否包含 Cedar 策略引擎以在网关上强制执行细粒度授权。 |
| infra | agentcore | none | agentcore | 托管网关的基础设施类型。选择 none 表示不托管。 |
| iac | inherit | cdk | terraform | inherit | 首选的 IaC 提供商。默认情况下,这继承自您的初始选择。 |
| preferInstallDependencies | boolean | true | 是否在生成器运行后优先安装依赖项。设置为 false 可在批量运行多个生成器时延迟安装(如果后续生成器需要计算 Nx 项目图,仍会运行安装);在最后统一安装一次。 |
生成器在 packages/<name>/ 创建一个新项目,以及用于基础设施的 CDK 构造或 Terraform 模块:
文件夹packages/<name>/
文件夹policies/ Cedar 策略源文件(当
cedarPolicy: false时省略)- permit-all.cedar 默认的 Cedar 策略,允许来自同一 AWS 账户内的已认证调用者
- README.md 编写 Cedar 策略的参考文档
- local-dev.ts 用于本地开发的本地网关,聚合附加的 MCP 服务器
- project.json 添加
serve和dev目标
当 infra 为 agentcore(默认值)时生成基础设施。使用 infra: none 时不生成基础设施——稍后使用 infra: agentcore 重新运行生成器以添加它。
由于该生成器会根据您选择的 iacProvider 以基础设施即代码的形式输出,它将在 packages/common 目录下创建一个包含相关 CDK 构造体或 Terraform 模块的项目。
通用的基础设施即代码项目结构如下:
文件夹packages/common/constructs
文件夹src
文件夹app/ 针对特定项目/生成器的基础设施构造体
- …
文件夹core/ 被
app目录构造体重用的通用构造体- …
- index.ts 导出
app目录构造体的入口文件
- project.json 项目构建目标与配置
文件夹packages/common/terraform
文件夹src
文件夹app/ 针对特定项目/生成器的 Terraform 模块
- …
文件夹core/ 被
app目录模块重用的通用模块- …
- project.json 项目构建目标与配置
文件夹packages/common/constructs/src
文件夹core
文件夹agentcore-gateway/ 共享网关构造(就绪探针、Cedar 策略加载)
- …
文件夹app
文件夹gateways
文件夹<name>/
- <name>.ts 用于部署 Gateway 的 CDK 构造
文件夹packages/common/terraform/src
文件夹app
文件夹gateways
文件夹<name>/
- <name>.tf 用于部署 Gateway 的 Terraform 模块
生成的构造创建以下 AWS 资源:
- 一个为 MCP 协议配置的
AgentCore::Gateway,使用GatewayAuthorizer.usingAwsIam()(入站 IAM 身份验证) - 一个以
ENFORCE模式运行的AgentCore::PolicyEngine,附加到 Gateway(当cedarPolicy: false时省略) policies/中每个.cedar文件对应一个AgentCore::Policy
Gateway URL 会自动注册到 运行时配置的 agentcore.gateways.<ClassName> 命名空间中,以便代理可以在运行时发现它。
Cedar 是 AgentCore Gateway 用于授权工具调用的策略语言。流经 Gateway 的每个 tools/list 和 tools/call 请求都会针对附加的策略集进行评估,调用者必须至少有一个匹配的 permit 语句(且没有匹配的 forbid)才能使请求成功。
有关完整参考,请参阅 AWS 关于 AgentCore Gateway 策略的文档,包括常见策略模式。
要添加策略,请在 permit-all.cedar 旁边创建一个新的 .cedar 文件。policies/ 中的每个 .cedar 文件必须恰好包含一个 permit 或 forbid 语句,并作为单个 AWS::BedrockAgentCore::Policy 资源部署。策略资源的名称派生自文件名:permit-all.cedar 变成 PermitAll(kebab/snake-case 转换为 PascalCase)。包含多个语句的文件会在部署时产生 unexpected token 'forbid' 错误——将它们拆分为单独的文件。
例如,要仅允许特定的代理角色调用特定工具,请创建:
permit ( principal is AgentCore::IamEntity, action == AgentCore::Action::"ts-mcp___divide", resource == AgentCore::Gateway::"<%= gatewayArn %>") when { principal.id like "<%= tsAgentRoleArn %>/*"};将角色 ARN 作为模板变量传入(参见下面的模板变量),而不是硬编码或模式匹配它。重新合成或重新计划以部署新策略。
策略是在合成/计划时渲染的 EJS 模板,以便它们在不同账户和 Gateway 重新部署之间保持可移植性:
| 变量 | 替换为 |
|---|---|
<%= gatewayArn %> | 已部署 Gateway 的 ARN |
<%= accountId %> | 部署此 Gateway 的 AWS 账户 |
始终引用这些变量,而不是硬编码值。
添加您自己的变量
Section titled “添加您自己的变量”添加新变量到策略渲染的位置,例如将代理的执行角色 ARN 传递给上面的 ts-agent-divide.cedar 示例:
在 packages/common/constructs/src/app/gateways/<name>/<name>.ts 中,添加到传递给 ejs.render 的对象:
ejs.render(raw, { gatewayArn: cdk.Token.asString(this.gateway.gatewayArn), tsAgentRoleArn: cdk.Token.asString(tsAgent.agentCoreRuntime.role.roleArn), // ...}),在 packages/common/terraform/src/app/gateways/<name>/<name>.tf 中,添加到 rendered_policies 数据源的 query:
query = { template = "${local.policies_dir}/${each.value}" gatewayArn = aws_bedrockagentcore_gateway.this.gateway_arn tsAgentRoleName = var.ts_agent_role_name # ...}ENFORCE 模式和默认拒绝
Section titled “ENFORCE 模式和默认拒绝”PolicyEngine 以 ENFORCE 模式运行,这意味着应用默认拒绝语义:如果没有 permit 语句匹配(principal、action、resource)元组,请求将被拒绝。被拒绝的工具调用返回:
Tool Execution Denied: Tool call not allowed due to policy enforcement[No policy applies to the request (denied by default).]此外,Gateway 会过滤 tools/list 的响应,以便调用者只能看到他们至少有一个匹配 permit 的工具:如果代理缺少对给定工具的权限,该工具将完全隐藏,而不是显示并在调用时失败。
默认 permit-all.cedar
Section titled “默认 permit-all.cedar”生成器提供了一个默认策略,允许来自部署 Gateway 的 AWS 账户的任何 IAM 调用者:
permit ( principal is AgentCore::IamEntity, action, resource == AgentCore::Gateway::"<%= gatewayArn %>") when { principal.id like "arn:aws:*::<%= accountId %>:*"};要进一步锁定,请在其旁边添加更窄的策略。始终在策略集中保留至少一个匹配的 permit,否则默认拒绝将阻止每个调用。
策略范围参考
Section titled “策略范围参考”对于此插件生成的 Gateway,所有调用者都是 IAM 主体(Gateway 配置为 GatewayAuthorizer.usingAwsIam()):
principal is AgentCore::IamEntity主体的 id 属性保存调用者的 IAM ARN。调用者通常以带有生成的会话后缀的 STS assumed-role ARN 到达,因此将确切的角色 ARN 作为模板变量传入,并使用 like 匹配会话后缀:
principal.id like "<%= myAgentRoleArn %>/*"工具调用以以下形式的操作到达策略引擎:
AgentCore::Action::"<target-name>___<tool-name>"其中 <target-name> 是 Gateway 目标名称(使用 gateway.addMcpServer(...) 时默认为 MCP 服务器的 mcpServerName,派生自 MCP 项目的类名的 kebab-case 格式——例如 TsMcp → ts-mcp),<tool-name> 是 MCP 工具的名称,分隔符是 ___(三个下划线)。Cedar 不支持操作上的通配符——匹配确切的操作,或省略 action == 以匹配所有操作。
资源始终是 Gateway 本身:
resource == AgentCore::Gateway::"<%= gatewayArn %>"验证注意事项
Section titled “验证注意事项”生成的基础设施使用 IGNORE_ALL_FINDINGS 创建策略:AgentCore 的 Cedar 分析器(FAIL_ON_ANY_FINDINGS,服务默认值)会拒绝许多合法的策略——例如,禁用所有调用者的单个工具的 forbid 会被拒绝为”过于限制”,即使使用 when 子句限定范围也是如此。执行不受影响;它由策略引擎的 ENFORCE 模式配置。
仍然适用一个排序约束:引用 AgentCore::Action::"<target>___<tool>" 的策略仅在目标向 Gateway 注册该工具后才能验证,这就是为什么生成的基础设施在 Gateway 目标之后创建策略。
如果策略部署失败,CloudFormation 会将拒绝显示为不透明的 Resource stabilization failed 错误——运行 aws bedrock-agentcore-control list-policies --policy-engine-id <id> 以检索验证器的 statusReasons,其中包含实际原因。
示例:禁止一个工具同时保留更广泛的 permit
Section titled “示例:禁止一个工具同时保留更广泛的 permit”将窄的 forbid 与更广泛的 permit 配对(Cedar 评估 forbid 优先于 permit):
forbid ( principal is AgentCore::IamEntity, action == AgentCore::Action::"ts-mcp___divide", resource == AgentCore::Gateway::"<%= gatewayArn %>") when { principal.id like "<%= pyAgentRoleArn %>/*"};这会拒绝 Python 代理角色调用 ts-mcp___divide,同时为所有其他调用者保留更广泛的 permit-all.cedar。
生成器向 Gateway 项目添加一个 dev 目标,该目标运行 local-dev.ts:一个本地网关,公开单个 MCP 端点,聚合每个附加的 MCP 服务器(通过 agentcore-gateway#mcp-connection 生成器连接),工具前缀为 <target>___<tool> 以匹配已部署的 Gateway。运行它会一起启动本地网关和所有附加的 MCP 服务器:
pnpm nx dev <name>yarn nx dev <name>npx nx dev <name>bunx nx dev <name>有关完整的本地开发故事,请参阅连接指南。
使用 connection 生成器将此项目与工作区中的其他项目集成。以下连接涉及此项目: