让业务AI的操作权限受用户身份约束
案例将所有写入工具设计为提案接口,只生成待审批请求,暂不修改业务记录。审批后再由服务端根据组织、目标记录、操作类型与成员身份校验权限。
AI 深度解读
让 AI 替人审批采购单、标记发票已付款,接上 API 就能做;难的是,它凭谁的权限做?如果助手拿着高权限服务账号,普通员工就可能借它完成自己无权执行的操作。
Inaya Business Workspace 给出的方案是「受控执行」(guarded execution):AI 只提交变更建议,由人审批,服务端再核验审批人的真实权限。这篇文章的价值,在于讲清了权限边界,以及守住它需要付出的交互和维护成本。
AI 可以提议,但不能直接改业务记录
作者把所有会改变数据的工具都设计成 propose_*。助手认为某张发票应该标记为已付款时,只会创建一条操作申请,记录目标、拟执行的变更和理由,状态设为 PENDING。
此时,真实发票没有发生变化。
模型决定建议做什么,服务端决定这件事能否落地。
这比在提示词里要求「不要越权」更具体:写操作先进入待审批流程,执行权限不交给模型。审批人可以批准,也可以拒绝。
代价同样直接。财务、人事操作多一次确认,作者认为合理;琐碎任务也走这套流程,就容易让人烦躁。文章没有提供操作耗时或用户接受度数据,这部分是他们团队的取舍。
审批按钮背后,必须检查原有业务权限
有人点击同意,还不足以执行操作。服务端必须确认:这个审批人原本就有权对这条记录执行这项变更。
下面是作者给出的简化入口,用来集中判断审批资格:
// ai-action-approval-gate.js (simplified)
export async function resolveCanApprove({ orgId, targetRecordType, targetRecordId, proposedAction, membership }) {
if (targetRecordType === "TASK") { /* same check the real task transition uses */ }
if (targetRecordType === "INVOICE") { /* same check the real invoice transition uses */ }
// one case per record type
}
要看的是 TASK 和 INVOICE 两个分支:它们应当执行真实业务状态转换所需的同一套权限检查,不能仅凭「能看到审批页面」就放行。代码省略了具体实现,因此无法据此核实检查是否完整。
作者强调,审批人的权限应与手动调用对应 transitionX() 时一致。他们没有单独维护一套「AI 权限」模型;每增加一种记录类型,就给入口补一个分支,审批状态机继续复用。没有对应分支的操作不能获批。
权限入口还被放进不依赖 Web 框架的普通模块,可以用 node --test 做单元测试,不必每次通过 HTTP 请求验证。提议、批准和拒绝都会写入活动日志,让执行结果能追溯到具体建议和审批人。
我的判断
我认可这套方案把权限检查放在服务端,并且对未覆盖的操作拒绝放行。对于多用户业务系统,这比让助手持有宽泛权限、再靠提示词约束行为更容易审查。
不过,人工审批是否可靠,仍取决于它是否真正复用了业务权限规则。
作者称这提供了单一事实来源,但原文用的是「重新推导」真实转换函数的检查。如果两个入口各写一份相似逻辑,仍可能逐渐分叉。文章没有展示它们如何共享实现,也没有说明审批前记录状态变化时如何处理,更没展开审批与执行之间的一致性问题。
它解决的范围也要划清:阻止用户通过助手越权,不代表助手建议正确。一个有权限的人,依然可能批准错误操作。人工复核是否有效,文章没有给出对照数据。
作者还披露,文档上传前使用客户端 AES-256-GCM 加密,安全聊天使用 MLS(RFC 9420),但产品尚未经过独立安全审计。这些信息应保留;加密机制也不能作为审批权限实现正确的证明。
如果既有业务 API 已能严格按照当前用户身份检查权限,也可以考虑让 AI 操作经过这些接口。原文没有比较这类方案,不能据此断言所有操作都必须增加人工审批。
能拿来做什么
- 给业务系统接入 AI 写操作时,可以先让工具生成包含目标、变更和理由的
PENDING申请,在审批页面让用户看清具体会改什么。 - 在 Node 服务端集中组织审批权限判断,优先复用已有业务检查,并用
node --test验证无权限、记录类型未覆盖等拒绝路径。 - 根据操作后果决定人工确认范围。财务、人事可以采用更严格的流程,琐碎任务则需要评估确认成本;不要把作者的取舍当成已经验证的通用结论。
- 把提议、批准和拒绝写入活动日志,保留审批人和变更内容,让排查问题时能还原完整过程。