跳到主要内容

安全护栏

AISIX AI 网关可以在调用上游工具之前,以及工具结果返回客户端之前,对 MCP 工具调用执行安全护栏。被阻断的调用会以失败的工具结果返回,并且不会发送到上游 MCP 服务器。

MCP 工具调用使用与模型流量相同的安全护栏链。请在共享的流量控制部分创建安全护栏,然后将其挂载到可以作用于 MCP 流量的作用域。与模型路径共用的作用域和执行模式语义请参见安全护栏行为

安全护栏如何作用于 MCP

网关只会对 tools/call 请求执行安全护栏。MCP 握手和 tools/list 不包含工具内容,因此不会被扫描。

对于每个工具调用,AISIX 会解析一次安全护栏链,并在输入和输出两个方向运行:

  • 输入:AISIX 会在调用工具之前扫描工具调用参数。如果安全护栏阻断,请求会被拒绝,AISIX 不会联系上游 MCP 服务器。
  • 输出:AISIX 会在工具结果返回客户端之前扫描结果。如果安全护栏阻断,AISIX 会拦截结果并改为返回失败的工具结果。

MCP 工具调用没有模型,因此模型作用域的安全护栏不会作用于 MCP。环境、MCP 服务器、调用方 API Key 和团队作用域都可以匹配 MCP 调用。在 AISIX Cloud 和开源 AISIX 网关中,安全护栏的作用域都由挂载关系决定。未挂载的安全护栏不会检查任何流量,包括 MCP 调用。

当没有匹配的安全护栏时,工具调用不会增加安全护栏带来的额外延迟。

会扫描哪些内容

  • 输入:tools/call 请求中的参数对象。AISIX 会把参数交给与模型路径相同的输入检查流程。
  • 输出:工具结果中的文本内容。AISIX 会解析结果的 text 内容块并扫描其中的文本,而不是扫描序列化后的 JSON 外层结构。外层字段名不会造成误报,被转义的字符也无法绕过拦截。
  • 输出:结果中 structuredContent 里的取值。返回结构化输出的工具会把该字段与 content 一起发送给客户端,而且它不一定会被同时写入文本块,因此 AISIX 会遍历该字段并扫描其中的字符串值。字段名不会被扫描——它们属于工具的输出结构定义,而不是数据本身。

没有 result 数据内容的协议级错误结果没有可扫描的工具输出,会被直接放行。

网关只在传输过程中检查 MCP 工具参数或结果,不会存储它们。内容捕获与安全护栏检查是不同的能力边界。

阻断响应

当安全护栏阻断某个工具调用或工具结果时,AISIX 返回的是 HTTP 200 加标记了 isError 的工具结果,而不是模型路径中的 HTTP 422

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [{ "type": "text", "text": "tool call blocked by content policy (guardrail 'block-secrets')" }],
"isError": true
}
}

MCP 区分两类失败:请求本身不合法属于 JSON-RPC 协议错误,而调用没有成功则通过结果中的 isError 表达。策略拒绝属于后者——请求格式是合法的,因此拒绝会作为工具输出返回给调用方 Agent,让它能够读取并据此调整,而不是被当作传输层故障。

错误信息会标明触发的安全护栏,以及被阻断的是输入参数还是输出结果,并且不会回显命中的内容。网关会把被阻断的调用记录为用量事件,并设置安全护栏阻断标记。

信息

如果工具结果无法按预期 JSON 响应解析,AISIX 会阻断该结果,而不是返回未经过扫描的内容。只要调用挂载了安全护栏,就不会返回安全护栏无法检查的工具输出。

完整 MCP 错误格式和其他 MCP 状态行为请参见响应头与错误码

将安全护栏限定到单个 MCP 服务器

使用 mcp_server 作用域挂载安全护栏,即可只检查路由到某个已注册服务器的工具调用。在 AISIX Cloud 中,将 scope_id 设为服务器 ID;在 resources.yaml 中,则使用服务器名称。AISIX 会同时扫描发送到该服务器的参数及其返回的结果。

mcp_server 是唯一按目标服务器筛选流量的作用域。若要按调用方缩小覆盖范围,可以为单个调用方使用 api_key 挂载,或为同一团队的调用方使用 team 挂载。这些基于调用方的作用域也会作用于同一 API Key 或团队发起的模型流量。模型作用域永远不会作用于 MCP,因为工具调用不会解析出模型。

该服务器必须可供安全护栏所作用的环境使用。AISIX Cloud 会拒绝挂载到未在该环境中开放的服务器;如果资源文件中的挂载指向未定义的服务器,该文件将加载失败。要保护多个服务器,需要为每个服务器分别添加挂载;安全护栏在每次请求中仍只运行一次。

验证安全护栏阻断

创建一个关键词安全护栏,并设置一个容易触发的词,例如 secret。将其挂载到测试时使用的调用方 API Key。在 AISIX Cloud 中,以调用方 API Key ID 作为挂载的 scope_id;在 resources.yaml 中,则使用该 Key 的 display_name

配置流程请参见内置关键词安全护栏

然后使用允许访问某个工具的调用方 API Key 连接 MCP 客户端,在工具参数中包含被阻断词并调用该工具。

工具调用应返回 HTTP 200,且结果中的 isErrortrue,上游 MCP 服务器不会收到请求。参数和结果都干净的调用会正常返回。把安全护栏切换为监控模式后,同样的调用会被放行,但仍会记录命中信息;详见使用监控模式

AISIX Cloud 控制面

在 AISIX Cloud 中,请通过控制面创建和挂载安全护栏,而不是在资源文件中声明。要检查 MCP 工具调用,请使用可以作用于非模型流量的作用域:整个环境、指定 MCP 服务器、调用方 API Key 或团队。

当安全护栏需要检查 MCP 流量时,不要使用模型专属作用域。MCP 工具调用没有模型,因此模型作用域安全护栏不会运行。

早于 MCP 服务器作用域支持的网关无法识别该作用域,并会丢弃这条挂载,因此保存的作用域不会在该网关上运行。此时的行为取决于网关版本:早于“仅通过挂载确定作用域”机制的版本会让安全护栏作用于整个环境,使规则覆盖的流量多于预期;当前机制下则会让安全护栏不检查任何流量。如果环境中有任一数据面运行此类版本,AISIX 会在保存时发出警告;在依赖更窄的作用域前,请先升级这些网关。

下一步

你现在已经了解安全护栏如何检查 MCP 工具参数和工具结果。使用下面的指南创建安全护栏,或观察被阻断的调用: