OpenAPI 架构目标
OpenAPI(以前称为 Swagger)是描述 RESTful API 的广泛使用的标准。Gateway 支持用于定义 API 目标的 OpenAPI 3.0 规范。
OpenAPI 目标将你的网关连接到使用 OpenAPI 规范定义的 REST API。网关将传入的 MCP 请求转换为对这些 API 的 HTTP 请求并处理响应格式。
查看关键注意事项和限制,包括功能支持,以帮助您决定 OpenAPI 目标是否适用于您的用例。如果是,则可以创建符合规范的架构,然后为网关设置访问目标的权限。选择一个主题以了解更多信息:
主要考虑因素和局限性
重要
OpenAPI 规范必须包含要作为工具公开的所有操作的operationId字段。OperationID 在 MCP 接口中用作工具名称。
使用 OpenAPI 目标时,请记住以下要求和限制:
-
支持 OpenAPI 版本 3.0 和 3.1(不支持 Swagger 2.0)
-
OpenAPI 文件必须没有语义错误
-
服务器属性需要具有实际端点的有效 URL
-
完全支持仅 application/json 内容类型
-
不支持 oneOf、anyOF 和 allOF 等复杂架构功能
-
不支持用于查询、标头和 cookie 参数的路径参数序列化器和参数序列化器
-
每个 LLM 都有约 ToolSpec 束条件。如果 OpenAPI ToolSpec 的 APIs/properties/object 名称不符合相应的下游 LLM,则数据平面将失败。常见的错误是属性名称超过允许的长度或名称包含不支持的字符。
要在使用 OpenAPI 目标时获得最佳效果,请执行以下操作:
-
务必在所有操作中包含操作 ID
-
使用简单的参数结构代替复杂的序列化
-
在规范之外实现身份验证和授权
-
为了最大限度地提高兼容性,请仅使用支持的媒体类型
URL 参数的安全最佳实践
警告
在 OpenAPI 规范中定义服务器 URL 时,请避免使用过于宽松的 URL 参数模式,因为这可能会使您的网关面临安全风险。
OpenAPI 服务器定义中的 URL 参数允许动态端点配置。但是,如果限制不当,某些模式可能会引入安全漏洞。具体而言,请避免使用完全动态的域模式,例如:
-
https://{yourDomain}/-允许任意域替换 -
https://{subdomain}.{env}.{domain}.com-多个不受约束的占位符 -
https://{host}/api/-不受限制的主机参数
这些模式有可能被利用来:
-
将请求重定向到非预期或恶意终端节点
-
访问内部网络资源(Server-Side 请求伪造)
-
泄露凭据或敏感数据
推荐的做法:
-
尽可能使用完全限定的静态 URL:
https://api.example.com/v1 -
将参数限制在受控域内的子域上,并在应用程序中实现验证
-
避免使用允许任意域或主机替换的参数
-
在您的 API 中实现额外的验证,以验证运行时参数值是否与预期模式匹配
AgentCore Gateway 会自动验证区域参数并阻止对私有 IP 范围的请求。
安全服务器 URL 配置示例:
{ "servers": [ { "url": "https://api.example.com/v1" } ] }
如果需要动态参数,请使用占位符和枚举限制最少的完全限定域:
{ "servers": [ { "url": "https://{tenant}.api.example.com/v1", "variables": { "tenant": { "default": "default-tenant", "description": "Customer tenant identifier", "enum": ["tenant1", "tenant2", "tenant3"] } } } ] }
这种方法将 URL 参数限制为受控域内的特定子域,同时保持多租户部署的灵活性。使用枚举限制可以防止任意值,并通过将参数限制为预定义的安全值来帮助防御 SSRF 攻击。此外,请务必在应用程序逻辑中验证租户值。
在考虑将 OpenAPI 架构目标与 AgentCore Gateway 配合使用时,请查看以下功能支持表。
OpenAPI 功能支持
下表概述了 Gateway 支持和不支持的 OpenAPI 功能:
| 支持的功能 | 不支持的特征 |
|---|---|
|
架构定义基本数据类型(字符串、数字、整数、布尔值、数组、对象)必填字段验证嵌套对象结构带有项目规格的数组定义 |
架构组合 oneOf 规范 anyOF 规范 allOF 规范 |
|
HTTP 方法标准 HTTP 方法(GET、POST、PUT、DELETE、PATCH、HEAD、选项) |
安全方案 OpenAPI 规范级别的安全方案(必须使用网关的出站授权配置来配置身份验证) |
|
媒体类型 application/json application/xml multipart/form-数据-www-form-urlencoded application/x |
媒体类型支持列表之外的自定义媒体类型二进制媒体类型 |
|
路径参数简单路径参数定义(示例:/users/ {userID}) |
参数序列化复杂路径参数序列化器(示例: |
|
查询参数基本查询参数定义简单的字符串、数字和布尔类型 |
回调和 Webhook 回调操作 Webhook 定义 |
|
Request/Response 正文 JSON 请求和响应正文 XML 请求和响应正文标准 HTTP 状态代码(200、201、400、404、500 等) |
链接操作间的链接 |
授权策略
OpenAPI 目标支持以下类型的出站授权:
-
无授权 — 网关无需预先配置的授权即可调用 OpenAPI 目标。不建议使用这种方法。
-
OAuth — 网关同时支持双方 OAuth(客户端凭证授予类型)和三方 OAuth(授权码授予类型)。您可以在 Amazon Bedrock Ident AgentCore ity 中将授权提供者配置为与网关相同的账户和区域。
-
API 密钥 — 网关使用 API 密钥凭据提供者向 OpenAPI 目标进行身份验证。您可以在 Amazon Bedrock Ident AgentCore ity 中将 API 密钥提供程序配置为与网关相同的账户和区域。
-
IAM(AWS 签名版本 4(Sig V4))— 网关使用带有网关服务角色证书的 Sigv4 来签署向 OpenAPI 目标发出的请求。您可以
IamCredentialProvider使用 Sigv4 签名所需的服务名称和可选区域(默认为网关区域)来配置。
重要
IAM (Sigv4) 出站授权要求 OpenAPI 目标托管在原生支持 IAM 身份验证的 AWS 服务后面。网关使用 Sigv4 对出站请求进行签名,但不修改目标上的身份验证配置。目标服务必须能够验证 Sigv4 签名。
以下 AWS 服务原生支持 IAM 身份验证,并且与 OpenAPI 目标的 IAM 出站授权兼容:
-
Amazon API Gateway
-
Lambda 函数网址
-
Amazon 基岩网关 AgentCore
不进行本机验证 Sigv4 签名的服务(例如 Application Load Balancer 或直接 Amazon EC2 终端节点)与 IAM 出站授权不兼容。如果您的 OpenAPI 目标托管在其中一个服务后面,请改用 OAuth 或 API 密钥授权。
有关设置出站授权的更多信息,请参阅为网关设置出站授权。
OpenAPI 架构规范
OpenAPI 规范定义了您的网关将公开的 REST API。设置 OpenAPI 规范时,请参阅以下资源:
-
有关将 OpenAPI 规范 AgentCore 与网关一起使用时支持和不支持的功能的信息,请参阅 Op enAPI 功能支持中的表格。遵守这些要求以防止在目标创建和调用过程中出现错误。
定义 OpenAPI 架构后,您可以执行以下操作之一:
-
将其上传到 Amazon S3 存储桶,并在将目标添加到网关时参考 S3 位置。
-
将目标添加到网关时,内联粘贴定义。
展开一节,查看支持和不支持的 OpenAPI 规范的示例:
下面显示了受支持的 OpenAPI 规范的示例
支持的 OpenAPI 规范示例:
{ "openapi": "3.0.0", "info": { "title": "Weather API", "version": "1.0.0", "description": "API for retrieving weather information" }, "servers": [ { "url": "https://api.example.com/v1" } ], "paths": { "/weather": { "get": { "summary": "Get current weather", "description": "Returns current weather information for a location", "operationId": "getCurrentWeather", "parameters": [ { "name": "location", "in": "query", "description": "City name or coordinates", "required": true, "schema": { "type": "string" } }, { "name": "units", "in": "query", "description": "Units of measurement (metric or imperial)", "required": false, "schema": { "type": "string", "enum": ["metric", "imperial"], "default": "metric" } } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "location": { "type": "string" }, "temperature": { "type": "number" }, "conditions": { "type": "string" }, "humidity": { "type": "number" } } } } } }, "400": { "description": "Invalid request" }, "404": { "description": "Location not found" } } } } } }
下面显示了另一个受支持的 OpenAPI 规范的示例。
{ "openapi": "3.0.0", "info": { "title": "Search API", "version": "1.0.0", "description": "API for searching content" }, "servers": [ { "url": "https://api.example.com/v1" } ], "paths": { "/search": { "get": { "summary": "Search for content", "operationId": "searchContent", "parameters": [ { "name": "query", "in": "query", "description": "Search query", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results", "required": false, "schema": { "type": "integer", "default": 10 } } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "results": { "type": "array", "items": { "type": "object", "properties": { "title": { "type": "string" }, "url": { "type": "string" }, "snippet": { "type": "string" } } } }, "total": { "type": "integer" } } } } } }, "400": { "description": "Bad request" } } } } } }
以下显示了使用 oneOF 的不支持的架构的示例:
{ "oneOf": [ {"$ref": "#/components/schemas/Pencil"}, {"$ref": "#/components/schemas/Pen"} ] }