大厂 MCP 面试实录:Tool 调用身份认证、授权与最小权限落地实践
本文采用模拟面试复盘形式,围绕「为 MCP Tool 调用增加身份认证、授权与最小权限管控」的业务场景,由浅入深考察候选人对 MCP 安全边界、传输机制、权限设计及工程落地的掌握程度。
面试场景
面试官:候选人你好,今天我们聊一个实际业务问题:公司正在落地内部 AI 助手,集成了多个第三方 MCP Server,其中部分 Tool 涉及薪资查询、数据库配置修改、云资源操作等敏感能力。现在要求给所有 Tool 调用增加身份认证、授权与最小权限管控,你会怎么设计整体方案?
候选人:我会采用三层分治的设计思路,结合 MCP 的传输特性、Resources 能力与运行隔离机制落地: 1. 第一层是传输层认证,保证只有合法的 MCP Client 能发起调用:本地 stdio 传输场景通过进程级权限管控限制调用方,远程 Streamable HTTP 场景用 OAuth2.0 或 JWT 做传输层认证; 2. 第二层是身份传递与细粒度授权,把用户身份从 Host 层传递到 Server 层,结合 Resources 做权限校验; 3. 第三层是高风险操作的隔离与审计,用容器化隔离高风险 Server,同时补全审计与异常处理逻辑。 具体来说,授权层面把用户的角色、可访问的资源范围封装成 MCP Resource,Server 启动时加载这些权限配置,每次 Tool 调用前先校验用户是否有对应权限;同时 Tool 的业务逻辑里还要做参数级校验,不能只靠参数 schema 的结构约束。高风险 Tool 用容器运行,限制文件系统、网络访问权限,只给最小必要权限。
递进追问与解答
追问1:身份传递的安全风险
面试官:你提到要把用户身份从 Host 层传到 MCP Server 层,MCP 协议本身有没有标准的身份传递机制?如果直接把用户在 Host 层拿到的登录 Token 透传给 Server,会有什么问题?
候选人:MCP 协议原生没有定义标准的用户身份传递字段,所以通常我们会通过 JSON-RPC 请求的扩展元数据传递用户身份标识(比如用户ID、角色),绝对不能透传用户的原始登录 Token。 如果 Server 需要调用上游 API,必须自己用客户端凭证向上游授权服务器申请 Token,还要按照 MCP 安全规范,用 RFC 8707 定义的resource参数绑定要访问的上游资源,避免 Token 被跨服务滥用[资料2]。另外直接透传 Token 还会引发 Mix-Up 攻击:攻击者如果控制了某个授权服务器,可能会把其他 honest 授权服务器颁发的 Token 发给我们的 Server,导致权限混乱,所以 Server 在认证的时候还要校验 Token 的 audience 是否指向自己,防止这种攻击[资料3]。 如果是本地 stdio 传输场景,Host 和 Server 在同一个主机上,还可以通过 Unix Socket 的 UID/GID 校验调用方身份,进一步降低风险。
追问2:细粒度授权与 Resources 的协作
面试官:现在业务要求权限粒度到「研发岗可以查询自己的薪资,不能修改配置;运维岗可以修改数据库配置,不能查询他人薪资」,你怎么实现 Tool 级的细粒度授权?Resources 在这里具体承担什么角色?
候选人:我会做两阶段授权,Resources 作为权限的事实来源,实现配置与逻辑解耦: 1. 功能级授权:先判断用户有没有权限调用这个 Tool,把「角色-Tool 权限」的映射关系配置成 MCP Resource,存在配置中心或者随 Server 启动时加载,每次调用 Tool 前先查这个映射,没有权限直接拒绝; 2. 参数级细粒度授权:就算用户有 Tool 的调用权限,也要校验传入的参数是否在用户的权限范围内,比如查询薪资时,用户只能传入自己的员工 ID 或者下属的 ID,不能传其他部门的 ID。这里可以把用户的「可访问资源范围」(比如可见的员工列表、可操作的数据库实例)也封装成 Resource,Tool 执行前先从 Resource 里拉取用户的权限范围,和传入的参数做比对,不满足直接拒绝。 Resources 在这里相当于权限的“统一数据源”,Server 不需要硬编码权限逻辑,只需要按需读取对应的 Resource 做校验,后续加新 Tool 或者调整权限的时候,只需要修改 Resource 的配置,不用改 Server 的代码,扩展性更好。 对应到代码层面,MCP Java SDK 提供了可插拔的授权钩子,我们可以基于传输层扩展实现统一的身份解析与授权校验,伪代码如下:
// 授权拦截器伪代码(基于 MCP Java SDK 传输层扩展能力) public class ToolAuthInterceptor implements ToolInvocationHook { @Override public boolean beforeInvoke(ToolRequest request, UserInfo user) { // 从 Resource 加载 Tool 权限映射 Map<String, List<String>> toolPermission = permissionResource.getToolPermission(); // 判断用户是否有权限调用该 Tool if (!toolPermission.get(request.getToolName()).contains(user.getRole())) { throw new AccessDeniedException("无权限调用该 Tool"); } // 参数级细粒度校验 return paramAuthCheck(request, user); } }追问3:高风险操作的确认、审计与异常处理
面试官:现在有些 Tool 是高风险不可逆操作,比如删除生产数据、修改云资源配置,你刚才的方案里怎么处理用户确认和审计?如果 Tool 调用时上游服务超时,怎么处理异常?
候选人:高风险操作需要从流程、审计、异常三个维度补全能力: 1. 前置确认:高风险 Tool 必须加二次确认流程,Server 在真正执行操作前,先把操作的具体影响(比如「即将删除生产环境核心表,涉及大量生产数据,操作不可恢复」)返回给 Host,由 Host 弹窗让用户明确确认后再执行; 2. 审计日志:每次 Tool 调用都要记录全链路信息:调用时间、用户 ID、Tool 名称、关键参数(敏感字段脱敏)、操作的目标资源、执行结果状态、错误码,日志不能存在本地,要同步到统一的审计平台,满足合规要求[资料1]; 3. 异常处理:首先根据业务 SLA 给每个 Tool 调用设置合理的超时阈值,高风险操作超时阈值设得更短,超时直接中断执行,返回明确的错误码;如果上游服务超时,要区分是网络问题还是上游故障,返回对应的用户友好提示,不能把原始的错误堆栈暴露给用户,防止信息泄露。可观测性方面,给每个 Tool 调用生成唯一的 Trace ID,串联整个调用链路,统计每个 Tool 的调用成功率、耗时、错误率,方便后续排错。
追问4:容器隔离的具体设计与踩坑点
面试官:你之前提到用容器隔离高风险 MCP Server,具体怎么设计?有没有什么容易踩坑的细节?
候选人:高风险 MCP Server 我们会用容器运行,严格遵循最小权限原则,配置示例如下:
# 高风险 MCP Server 的容器配置示例 services: mcp-db-server: image: company/mcp-db-tool:1.0 user: "1000:1000" # 非 root 用户运行 read_only: true # 只读文件系统 tmpfs: - /tmp # 临时目录可写 volumes: - ./config/db.yaml:/app/config/db.yaml:ro # 只挂载必要配置 networks: - mcp-internal # 仅允许访问内部 API 网关 security_opt: - no-new-privileges # 禁止提权如果是 stdio 传输场景,Host 启动 Server 时直接拉起对应容器,把容器的标准输入输出和 Host 的进程管道对接,既符合 stdio 的传输要求,又能实现隔离[资料3]。 容易踩坑的点有两个:一是 MCP Server 的日志必须写到标准错误,不能写到标准输出,否则会破坏 JSON-RPC 的通信格式;二是如果 Server 需要访问宿主机的资源,绝对不能挂载根目录,只能挂载最小必要的目录,并且是只读的,避免容器逃逸风险。
追问5:扩展性与取舍
面试官:如果后续业务要新增几十个 Tool,你的方案怎么保证扩展性?有没有什么取舍?
候选人:扩展性上我们做了三点设计: 1. 认证、授权、审计逻辑和 Tool 业务逻辑解耦,用拦截器或者 AOP 实现,新增 Tool 只需要实现业务逻辑,不需要重复写安全代码; 2. 权限配置全部外部化,存在配置中心或者 IAM 系统,调整权限不需要改 Server 代码; 3. Resources 的读取做了本地缓存,避免每次调用都查远程配置中心,提升性能。 取舍方面,细粒度的参数级授权会增加每次调用的耗时,所以对于性能要求极高的 Tool,可以把权限缓存到本地,设置合理的过期时间,平衡权限实时性和性能;另外容器隔离会带来一定的资源开销,对于只读无副作用的轻量 Tool,不需要用容器隔离,用进程级权限管控即可,平衡安全和资源消耗。
面试官点评
考察点
- 对 MCP 安全边界的理解:是否清楚 Tool 参数 schema 仅为结构约束,不能代替服务端授权校验;
- 对 MCP 传输与身份机制掌握:是否了解不同传输方式的适配方案,是否清楚 Token 透传的风险与 Mix-Up 攻击防护;
- 细粒度权限设计能力:能否结合 MCP Resources 能力实现可扩展的权限管控,是否符合最小权限原则;
- 工程化落地能力:是否考虑异常处理、审计、可观测性、容器隔离等生产环境需要的细节。
合格回答
能给出分层权限设计的思路,清楚服务端必须做参数校验,知道高风险操作需要用户确认,了解审计日志需要脱敏,知道用容器隔离高风险服务。
加分项
能准确说出 MCP Server 禁止透传从 Client 收到的 Token 给上游 API,需要用 resource 参数绑定目标资源;能结合 Resources 实现权限配置的外部化与可扩展;能说出 stdio 传输的日志输出规范、容器隔离的具体安全配置,以及权限缓存的一致性取舍。
总结
为 MCP Tool 调用增加身份认证、授权与最小权限,核心是遵循 MCP 的安全边界规范,不做“信任来自 AI 应用的请求就默认可信”的假设。整体方案要分层设计:传输层负责身份认证,身份传递层避免 Token 泄露与混入攻击,授权层结合 Resources 实现细粒度权限管控,运行层用容器隔离高风险服务,同时补全审计、异常处理与可观测性能力。在实际落地时,需要根据 Tool 的风险等级选择合适的隔离方案,平衡安全性与性能,避免过度设计或者防护不足。
参考资料
- MCP 基础知识
- Authorization Security Considerations | https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization/security-considerations
- Security Best Practices | https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices
- MCP Java SDK | https://github.com/modelcontextprotocol/java-sdk