AI Agent 需要边界,而非万能钥匙
通过 MCP 让 AI Agent 访问你的应用是具有风险的。你就像是交出了一个钥匙串,并寄希望于它们只打开特定的门。这种信任本身就是一种安全风险。
在为多租户 Laravel 应用构建 MCP 工具时,你必须解决一个问题:如何在让 Agent 操作应用的同时,防止其访问他人的数据。
每个 MCP 工具都充当一个端点(endpoint)。Agent 调用工具,你的服务器运行代码。在多租户设置中,每个工具都必须回答两个问题:
- 你被允许执行此操作吗?
- 你被允许在此处执行吗?
如果你忽略了这两点,你就会制造安全漏洞。
Web 请求使用 Session 来处理多租户逻辑,而 MCP 工具使用的是 Token。这里没有 Session,也没有用于设置当前租户上下文(tenant context)的中间件。如果你依赖于在 Session 中查找“当前组织(current org)”的全局作用域(global scopes),它们将一无所获。一个本应受到限制的查询可能会返回数据库中的每一行数据。
我使用以下四条规则来确保安全:
- 显式过滤:在 Token 认证下,绝不要依赖环境作用域(ambient scope)。每次都使用单一的 Trait 根据组织进行过滤。
- 使用 UUID:绝不要使用自增 ID。使用不可预测的标识符,这样 Agent 就无法猜到其他记录。
- 复用权限:不要为 Agent 创建新的权限集。使用与你的 Web 应用相同的权限字符串(ability strings)。
- 标记副作用:使用注解(annotations)将工具标记为“只读”或“可写”。
通过使用单一的 Trait 进行组织查询,你创建了一个统一的审计点。如果查询返回 null,工具会告知 Agent 未找到该记录。Agent 不会获得关于其他租户的任何信息。
这不是一个 AI 问题,而是一个多租户和授权问题。MCP 让暴露应用变得轻而易举,因此你必须严格遵守边界。
Agent 应该在所属租户范围内,且仅能执行人类用户所能执行的操作,不多也不少。
Optional learning community: https://t.me/GyaanSetuAi
