MCP 访问控制:为 AI 智能体落实最小权限

更新时间 8/14/2026

核心要点

  • MCP 访问控制必须同时治理工具发现与工具调用。对 tools/list 隐藏工具很重要,但每次 tools/call 仍需独立执行授权检查。
  • AISIX AI Gateway 使用调用方 API key 对 MCP 客户端进行认证,并根据 github__create_issue 这类带命名空间的工具标识评估权限。
  • 精确名称提供最小授权范围。按 Server 和全局通配符可以简化管理,但也会自动涵盖未来新增的匹配工具。
  • AISIX Cloud 可以把数百个 key 上的共享权限迁移到环境和团队策略,同时允许每个 key 继承、收窄或拒绝这些权限。
  • key 可以收窄继承的授权,却不能将其扩大;所有适用的 deny 规则始终优先。
  • Server 审核决定哪些工具来源可以进入网关,访问策略再决定哪些调用方能够发现和调用已发布的工具。

当 AI 智能体获得 MCP Server 访问权时,它得到的并不只是另一个只读数据源。它可能能够创建工单、变更基础设施、查询客户记录,或者触发业务工作流。在生产环境中,把这种连接视为“已连接”或“未连接”两种状态,粒度远远不够。

更安全的方式是落实最小权限:只公开智能体完成其角色任务所需的工具,阻止它发现无权使用的工具,在每次调用时重新检查权限,并确保添加新 Server 不会静默扩大现有访问范围。

AISIX AI Gateway 将调用方 API key 作为这条授权边界。同一身份可以统一治理模型访问、MCP 工具和 A2A 智能体,而 MCP 链路会在向上游路由调用前应用工具级权限。小规模发布可以直接在每个 key 上配置权限;规模扩大后,AISIX Cloud 还提供环境默认策略、团队权限、按 key 限制、迁移预览和有效权限检查。

为什么 MCP 授权必须覆盖发现与调用

MCP 将工具发现与工具执行分开。根据官方 MCP 工具契约,客户端通常先调用 tools/list 了解可用工具,再发送包含所选工具名称与参数的 tools/call。这两个操作都涉及安全。

即使后续调用会被拒绝,未受限制的工具列表仍可能泄露内部系统名称、运维工作流和高风险操作。过滤后的列表可以减少这类暴露,也能改善智能体行为:模型只需从一组较小且相关的工具中选择,而不用分析它永远无法使用的能力。

但仅靠过滤并不等于授权。调用方可以直接构造 JSON-RPC 请求,而不必从返回列表中选择工具。因此,AISIX 会在 tools/call 时再次检查有效授权。如果调用方无权使用该工具,网关会返回中性的 MCP 错误,而且绝不会联系上游 Server。错误不会透露指定工具或 Server 是否存在。

AISIX 还会为聚合工具提供稳定标识。每个注册的 Server 都有名称,其工具会通过 /mcp<server>__<tool> 的形式公开。例如:

  • github__create_issue 调用 create_issue,该工具来自已注册的 github Server;
  • runbooks__search 调用 search,该工具来自 runbooks
  • erp__get_invoice 调用 get_invoice,该工具来自 erp

命名空间可以防止一个 Server 上的 search 工具与另一个 Server 上的 search 工具混淆。授权和 deny 模式使用完整的命名空间形式,而 mcp_rate_limits 使用其中的已注册 Server 部分。即使客户端通过 /mcp/github 这类单 Server 端点连接,工具通常以原始上游名称呈现,同一策略含义依然成立。

1sequenceDiagram
2    participant Agent as AI 智能体
3    participant AISIX as AISIX AI Gateway
4    participant Authz as 有效工具授权
5    participant MCP as 上游 MCP Server
6
7    Agent->>AISIX: tools/list + 调用方 API key
8    AISIX->>Authz: 过滤带命名空间的工具
9    Authz-->>AISIX: 仅返回允许的工具
10    AISIX-->>Agent: 过滤后的工具列表
11    Agent->>AISIX: tools/call github__create_issue
12    AISIX->>Authz: 重新检查精确工具
13    alt 允许
14        AISIX->>MCP: 调用 create_issue
15        MCP-->>AISIX: 结果
16        AISIX-->>Agent: MCP 结果
17    else 拒绝
18        AISIX-->>Agent: 中性 MCP 错误
19    end

策略变更后,这项请求时检查尤为重要。撤销工具权限不依赖客户端刷新缓存的工具列表,下一次调用会按照当前有效访问权限重新评估。

从按 key 的最小权限开始

AISIX 的直接访问模型在调用方 API key 的 allowed_tools 中保存工具模式。如果该字段被省略、设为 null 或为空,key 就没有任何 MCP 工具访问权。这个默认拒绝行为可以防止仅用于模型流量的 key 意外获得工具权限。

三种模式可以覆盖大多数设计:

模式含义推荐用途
github__create_issue一个精确工具面向特定任务的智能体和写操作的默认选择
github__*一个 Server 当前及未来的所有工具可信且只服务于特定系统的智能体
*当前及未来所有 Server 的所有工具仅限例外的管理用途

模式采用单星号通配规则,因此 *__search 可以授权不同 Server 中名为 search 的工具。这对严格标准化的目录可能有用,但精确名称和按 Server 模式更容易审计。

假设三个智能体使用同一个聚合 MCP 端点:

智能体角色所需工具建议授权
客服只读智能体搜索操作手册和读取客户状态runbooks__searchcrm__get_customer_status
运维智能体读取操作手册和管理已批准的事件runbooks__*tickets__create_incidenttickets__update_incident
财务智能体读取发票,但绝不修改支付状态erp__get_invoiceerp__list_overdue_invoices

表中的角色授权有意保持不对称。运维智能体可以使用经过筛选的 runbooks Server 上全部工具,但在工单 Server 上只获得精确授权。财务智能体不使用通配符,因为未来的 ERP 操作可能包含退款、账户变更或其他高影响动作。

开源 AISIX 的资源文件可以直接表达这些授权:

1_format_version: "1"
2
3api_keys:
4  - display_name: support-reader
5    key_env: SUPPORT_READER_KEY
6    allowed_models: []
7    allowed_tools:
8      - runbooks__search
9      - crm__get_customer_status
10
11  - display_name: operations-agent
12    key_env: OPERATIONS_AGENT_KEY
13    allowed_models: []
14    allowed_tools:
15      - runbooks__*
16      - tickets__create_incident
17      - tickets__update_incident
18
19  - display_name: finance-agent
20    key_env: FINANCE_AGENT_KEY
21    allowed_models: []
22    allowed_tools:
23      - erp__get_invoice
24      - erp__list_overdue_invoices

应通过环境变量插值传入明文 key,验证完整资源文件后再重载网关。在 AISIX Cloud 中,Admin API 和控制台提供同样的按 key 授权模型,而且明文 key 只会在创建时返回。

通过环境、团队和 key 策略扩展访问治理

按 key 的 allowlist 很精确,但当组织拥有数百个调用方时,维护会变得困难。如果每个 key 都需要相同基线,而且平台团队注册了新的已批准工具,逐个更新 key 会造成延迟和权限不一致。

AISIX Cloud 通过三层策略解决这一问题:

  1. 环境默认策略 为一个环境内的 key 提供基础授权。
  2. 如果存在 团队权限,它会取代环境默认授权,供整个组织中分配给该团队的 key 使用。
  3. key 的 mcp_access 模式 决定它是继承基础授权、与更窄的限制取交集,还是完全拒绝 MCP 访问。

有效 allow 侧可以概括为:

1base grant = team entitlement, when present; otherwise environment default
2effective  = (base grant intersect key restriction) minus applicable denies

下面的 AISIX Cloud 示例为环境建立基线和不可绕过的 deny,随后读取一个 mcp_access.modeinherit 的现有 key 所对应的策略解析结果:

1curl -fsS -X PUT "$AISIX_CP/environments/$ENV_ID/mcp_policy" \
2  -H "Authorization: Bearer $AISIX_TOKEN" \
3  -H "Content-Type: application/json" \
4  -d '{
5    "mode": "selected",
6    "allow": ["github__*"],
7    "deny": ["github__delete_repository"]
8  }'
9
10curl -fsS \
11  "$AISIX_CP/environments/$ENV_ID/api_keys/$API_KEY_ID/effective_permissions" \
12  -H "Authorization: Bearer $AISIX_TOKEN" \
13  | jq '.effective_permissions.mcp'

使用 inherit 的 key 原样获得基础授权。使用 restrict 的 key 将自身 allow 模式与基础授权取交集,无法添加基础授权中不存在的工具。使用 deny 的 key 不获得任何 MCP 访问权。环境、团队和 key 的 deny 模式会在 allow 计算后统一扣除,因此 deny 始终优先。

有一点尤其重要:团队权限会取代环境的 allow 授权,但环境级 deny 仍然生效。它也适用于继续使用显式 allowed_tools 的旧 key。这让安全团队拥有紧急或全组织范围的否决能力,又不会静默扩大任何 key 的 allow 侧。

1flowchart TD
2    Key["调用方 API key"] --> Team{"团队是否有 MCP 权限?"}
3    Team -->|是| TeamBase["使用团队 allow 授权"]
4    Team -->|否| EnvBase["使用环境 allow 授权"]
5    TeamBase --> Mode{"key 的 mcp_access 模式"}
6    EnvBase --> Mode
7    Mode -->|inherit| Base["保留基础授权"]
8    Mode -->|restrict| Intersect["基础授权与 key allow 取交集"]
9    Mode -->|deny| None["无 MCP 访问权"]
10    Base --> Denies["扣除环境、团队和 key 的 deny"]
11    Intersect --> Denies
12    Denies --> Effective["有效工具授权"]

例如,没有团队权限的 key 会继承环境的 github__* 授权。平台团队权限可以用 github__create_issuerunbooks__* 取代这一 allow 侧,而不是与更宽的环境 allow 合并。环境的 github__delete_repository deny 仍然生效;CI key 可以再次收窄其基础授权,但无法绕过 deny,也无法添加新工具。

管理员可以查看 API key 的有效权限,了解解析后的 allow 与 deny 模式,以及每项权限的来源。某项规则的行为与团队预期不一致时,来源信息至关重要。它把授权排查从猜测变成可追溯的策略计算。

共享访问策略、团队权限和有效权限检查属于 AISIX Cloud 功能。开源部署则在每个调用方 key 上使用显式 allowed_tools 配置。

治理哪些 MCP Server 可以发布

调用方授权回答的是“谁可以使用这个工具?”,还需要另一项控制来回答“这个工具来源是否应该出现在网关上?”

MCP Server 注册项可以通过调用方提供的参数执行远程操作。因此,AISIX Cloud 提供审核工作流,把“提出 Server”与“发布 Server”分离。自定义角色可以拥有 mcp_server_submissions 写权限但不拥有 mcp_servers 写权限,从而提交新 Server 或提出变更,再由审批人决定其能否进入网关数据面。

新提交的状态为 pending_review,不会投射到任何网关。它不会出现在 tools/list 中;即使某个 API key 拥有匹配的工具模式,也无法调用。批准后,它会发布到选定环境;拒绝则继续保持不可用,并可向提交者附加说明。

对已上线 Server 的变更会单独暂存。当新 URL、凭证、环境分配或 OpenAPI 文档等待审核时,网关继续使用最后一次批准的配置。批准操作会在一次控制面动作中应用并发布暂存变更,随后异步投射到已连接的网关。拒绝则丢弃提案,不会中断线上 Server。

审核人应检查:

  • Server 名称是否会与其他命名空间产生易混淆的近似名称;
  • 上游 URL 和允许的环境是否正确;
  • 认证模式和凭证来源是否可信;
  • 基于 OpenAPI 的 Server 是否生成预期的工具范围;
  • 高风险工具是否会采用足够严格的调用方策略。

提交、创建、批准、拒绝、更新和删除 MCP Server 都会生成组织审计事件。策略写入、团队权限变更和 key 迁移也会被审计。审核工作流与访问策略共同构成两道关卡:先批准能力,再授权调用方。

迁移现有 key 时避免意外扩大权限

AISIX Cloud 不会自动把使用显式 allowed_tools 列表的现有 key 迁移到策略继承模式。这项兼容规则是有意设计的:创建宽泛的环境策略不应静默向旧调用方授予新工具。

应使用受控迁移流程:

  • 定义拟采用的环境策略及其 deny 规则。
  • 保存或应用前预览影响。
  • 检查有多少旧 key 将获得、失去或保留原有模式。
  • 检查发生变化的 key 样本,优先关注高权限和生产调用方。
  • 先将迁移应用到一小组 key_ids
  • 读取每个测试 key 的有效权限,并验证策略来源。
  • 测试 tools/list、一次允许调用和一次拒绝调用。
  • 仅在日志和用量事件符合预期后扩大迁移范围。
  • 保留之前的 allowed_tools 值,以便按 key 回滚。

预览比较的是模式,而不是把模式展开成每个具体工具。这一区别对通配符尤其重要:github__* 可能包括以后注册的工具。审核人必须同时评估当前工具目录和每个模式隐含的未来范围。

MCP 访问控制常见问题

tools/list 会暴露调用方无权使用的工具吗?

不会。AISIX 会根据调用方的有效授权过滤发现结果。它还会在 tools/call 时重新检查授权,因此手动构造的请求无法绕过过滤后的列表。

allow 和 deny 模式同时匹配时会发生什么?

deny 优先。适用的环境、团队和 key deny 模式会在 allow 计算后扣除,其中也包括继续使用 allowed_tools 的旧 key。

开源 AISIX 支持共享 MCP 访问策略吗?

共享环境与团队策略、迁移预览和有效权限检查属于 AISIX Cloud 功能。开源 AISIX 在每个调用方 API key 上使用显式 allowed_tools 模式。

让最小权限成为默认的 MCP 使用方式

当 MCP 访问控制属于平台能力,而不是藏在提示词或智能体代码中时,它最为可靠。应过滤工具发现,让智能体只看到相关工具;授权每次调用;对敏感操作使用精确名称;并保留任何继承授权都无法绕过的 deny 机制。

小规模部署可以从按 key 的 allowed_tools 开始。随着团队和调用方数量增长,AISIX Cloud 策略可以把通用授权上移到环境和团队层级,同时阻止单个 key 扩大自身权限。Server 审核工作流则确保新能力先经过检查,访问规则才能将其公开。

下一步,可以通过防护规则和按 Server 限流增加运行时保护。有关配置详情,请参阅控制工具访问使用策略管理 MCP 访问审核并批准 MCP Server

获取方案