Skip to content

MCP 只是传输协议,企业数据安全边界应该在工具设计里 ​

MCP 让 AI client 调用外部工具变得更标准。这是一个很重要的进展。

但在企业数据访问里,有一个容易被忽略的问题:

text
MCP 解决的是 tool calling 的 transport 和协议形态,不会自动解决数据治理。

一个 MCP tool 可以设计得很安全,也可以设计得非常危险。协议本身不会判断这个工具是否绕过权限、是否暴露敏感字段、是否允许任意 SQL、是否记录审计证据。

所以在业务系统、ERP、CRM、BI、财务和库存场景里,关键问题不只是:

text
我们有没有接 MCP?

更重要的问题是:

text
我们暴露给 AI 的工具边界是什么?

MCP 解决了什么 ​

MCP 的价值很清楚:它给 AI client 和外部能力之间提供了一套通用接口。

一个 AI client 可以通过 MCP 发现工具、查看工具描述、提交参数、获取结果。对开发者来说,这比每个 IDE、每个聊天客户端、每个 agent runtime 都单独定义插件协议要清晰得多。

这让很多集成变得容易:

  • 查询文档;
  • 调用内部 API;
  • 读取文件;
  • 检索知识库;
  • 触发自动化脚本;
  • 查询数据库或业务数据。

但“能调用工具”只是第一层能力。

企业系统里真正困难的不是调用动作本身,而是调用之前和调用之后的边界:

  • 谁在调用;
  • 代表哪个用户调用;
  • 能访问哪个租户、公司或项目;
  • 能读取哪些业务对象;
  • 能看到哪些字段;
  • 工具能不能写入;
  • 结果是否需要脱敏;
  • 请求和结果是否可审计;
  • 不明确或越界时如何失败。

这些不是 MCP 自动给出的答案。

危险的 MCP 工具形态 ​

讨论 MCP 安全时,不能只停留在“有没有 sandbox”或“有没有 API key”。更直接的问题是:工具到底暴露了什么能力。

下面几类工具在 demo 里很常见,但在生产数据场景里风险很高。

raw SQL tool ​

最典型的危险工具是:

text
execute_sql(sql: string)

这类工具把问题变成“模型能否写对 SQL”。但在 ERP 和业务系统里,更大的问题是 SQL 是否应该被执行。

如果一个 AI client 可以提交任意 SQL,它可能绕过:

  • 应用层权限;
  • 多租户或多公司边界;
  • 字段可见性;
  • 数据导出限制;
  • 审计和审批流程;
  • 业务对象本身的语义约束。

即使只开放 SELECT,也不等于安全。只读查询仍然可能泄露敏感数据、跨公司数据、员工数据、客户数据或财务数据。

broad API tool ​

另一种常见形态是暴露一个很宽的 API:

text
call_internal_api(path: string, method: string, body: object)

这看起来不像 SQL,但风险类似。模型可以组合 path、参数和 body,实际调用范围取决于内部 API 的复杂权限逻辑。

如果工具没有在服务器端绑定用户上下文、校验允许路径、限制方法和参数,那它只是把 raw SQL 风险换成了 broad API 风险。

schema dump tool ​

还有一种工具是把完整数据库 schema、表说明、字段说明一次性交给模型。

schema inspection 对开发调试很有用,但它不是业务授权模型。完整 schema 可能暴露内部模块、敏感字段、定制字段、历史表和不应被普通用户知道的数据结构。

更重要的是,schema 只能说明“系统里有什么”,不能说明“当前用户应该使用什么”。

file or export tool ​

很多业务数据泄露并不是发生在查询时,而是发生在导出后。

如果一个 MCP tool 允许把结果保存为文件、上传到外部、发送邮件或写入共享目录,那么导出边界也必须被治理。否则查询本身受控,结果流转却失控。

governed tool 应该承担什么 ​

企业数据 MCP tool 不应该只是一个协议 wrapper。它应该是一个受治理的执行边界。

这个边界至少应该包含下面几层。

1. 身份和租户上下文 ​

工具不能只知道“某个 AI client 在调用”。它需要知道调用代表谁。

常见上下文包括:

  • tenant;
  • workspace;
  • organization;
  • effective user;
  • service principal;
  • company scope;
  • role 或 group;
  • request source。

如果用户身份不清楚,工具应该拒绝执行,而不是让模型在 prompt 里声明“我是谁”。

权限判断必须留在服务器端 deterministic code 里,不能依赖模型自觉遵守。

2. 宿主系统权限投影 ​

业务系统通常已经有自己的权限体系。

ERP 里有模型权限、记录规则、公司边界、字段边界。CRM 里有 owner、team、pipeline、region。数据平台里有 dataset、metric、row-level policy、column masking。

MCP tool 的职责不是重新发明一套权限,而是把宿主系统已有权限投影到 AI 查询路径里。

关键点是:权限要在执行前生效。

不能先查出完整结果,再让模型“不要展示不该看的内容”。这等于把敏感数据先交给了模型和中间链路。

3. 语义模型选择 ​

直接暴露物理表会让模型面对太多内部结构。

更稳的方式是暴露受治理的 query model 或 semantic tool:

  • 销售订单分析;
  • 应收账款分析;
  • 库存流转分析;
  • 客户贡献分析;
  • 员工或部门统计;
  • 已批准的指标和维度。

这些模型应该定义:

  • 可用字段;
  • 指标口径;
  • 可过滤维度;
  • 支持的聚合;
  • 可排序字段;
  • 允许的查询粒度;
  • 字段和结果边界。

模型选择本身也应该受权限控制。用户没有权限的 query model,不应该出现在工具发现结果里。

4. 参数校验和能力限制 ​

工具参数不能只是“JSON 任意对象”。

它应该有明确 schema,并对下面内容做校验:

  • 时间范围是否存在;
  • 查询粒度是否支持;
  • 指标是否可用;
  • 过滤字段是否允许;
  • limit 是否合理;
  • sort 是否支持;
  • 是否请求了敏感字段;
  • 是否尝试访问物理表或内部字段;
  • 是否试图绕过权限。

如果请求缺少业务口径,工具应该返回 clarify。如果请求越界,工具应该 reject。

生产系统里,clarify 和 reject 是功能,不是失败。

5. 结果裁剪、脱敏和最小化 ​

工具不应该默认把所有明细返回给 AI。

很多业务问题只需要聚合结果、TopN、分组统计或有限明细。返回越多,泄露面越大,审计也越困难。

结果处理应该遵循最小化原则:

  • 只返回回答问题需要的字段;
  • 对敏感字段脱敏或不返回;
  • 限制行数;
  • 明确总数和截断状态;
  • 对导出走单独受控流程;
  • 对错误信息做脱敏。

这比事后在 prompt 里要求模型“不要泄露敏感信息”可靠得多。

6. audit 和 provenance ​

企业数据查询不能只留下一个自然语言答案。

至少应该能复查:

  • 谁发起了请求;
  • 调用了哪个 tool;
  • 使用了哪个 query model;
  • 参数是什么;
  • 应用了哪些权限边界;
  • 查询返回多少行;
  • 是否发生 clarify 或 reject;
  • 结果来自哪个业务对象或指标;
  • 是否发生导出。

这不是为了让系统显得复杂,而是为了在出问题时能够定位责任和边界。

如果一个 AI 数据工具无法解释“为什么这次查询被允许”,它就还没有达到生产级治理要求。

7. fail closed,而不是默认放行 ​

业务数据工具遇到不确定情况时,默认策略应该是 fail closed。

例如:

  • 找不到 effective user;
  • 无法确认租户;
  • query model 不存在;
  • 字段权限不明确;
  • 指标口径冲突;
  • 请求涉及写回或外部发送;
  • 请求要求访问底层表;
  • 查询范围过大。

这些情况不应该靠模型猜,也不应该自动降级成宽权限查询。

更合理的结果是:

text
需要补充范围。

或:

text
当前请求超出可执行边界。

这种拒绝比错误地返回数据要好。

Odoo 场景为什么能说明问题 ​

Odoo 是一个很具体的例子,因为它的权限边界不在 PostgreSQL 用户上,而在 Odoo 应用层。

一个 Odoo 用户能看什么,取决于:

  • ir.model.access;
  • ir.rule;
  • multi-company;
  • field visibility;
  • 模块业务规则;
  • 实施商自定义逻辑。

如果 MCP tool 只是包了一层数据库查询,那么 AI client 可能绕过 Odoo 里真正的权限配置。

更稳的做法是:

  • MCP client 通过 Odoo 侧访问机制进入;
  • 工具绑定 effective Odoo user;
  • 可见 query model 由 Odoo 权限决定;
  • record rules 在查询执行前参与;
  • 多公司边界进入查询条件;
  • 字段边界在返回前处理;
  • 查询过程保留 evidence。

这样 MCP 不是数据库旁路,而是 Odoo 权限体系之后的受控查询入口。

一个 MCP 数据工具设计 checklist ​

如果你正在给业务系统接 MCP,可以用下面的问题做一轮自检。

身份:

  • 工具是否知道 effective user?
  • 是否能区分 tenant、company、workspace?
  • service principal 是否有最小权限?

权限:

  • 是否复用宿主系统权限?
  • 权限是否在查询执行前应用?
  • 用户不可见的模型和字段是否不会暴露给工具发现?

语义:

  • AI 面对的是业务 query model,还是物理表?
  • 指标、维度、过滤和粒度是否显式定义?
  • schema 是否只暴露必要部分?

执行:

  • 是否禁止任意 SQL?
  • 是否限制查询能力和行数?
  • 是否支持 clarify / reject?
  • 是否对错误信息脱敏?

结果:

  • 是否只返回必要字段?
  • 是否处理敏感字段?
  • 导出是否有单独治理?

审计:

  • 是否记录 tool call、query model、参数和结果范围?
  • 是否能解释权限边界?
  • 是否能追踪 clarify、reject 和导出?

如果这些问题没有答案,MCP 接入只是完成了协议集成,还没有完成生产治理。

小结 ​

MCP 很有价值,但它不是企业数据安全的终点。

协议负责让 AI client 能够调用工具;工具设计负责决定 AI 能做什么、不能做什么、代表谁做、在什么边界内做、结果如何复查。

对企业业务数据来说,更可靠的默认路线不是:

text
给 AI 一个万能数据库工具。

而是:

text
给 AI 一组受治理的语义工具,并把身份、权限、语义、执行和审计放在服务器端边界里。

Foggy Data MCP / Foggy Odoo Bridge 目前采用的也是这个方向:MCP 作为接入方式,语义查询模型作为业务接口,宿主系统权限在执行前参与,查询过程保留证据。Odoo 只是第一个具体样板,核心原则适用于更多企业业务系统。

继续阅读 ​