← 全部文章
应用搭建 开发者 · · · 作者 ObjectStack Team

Retool RBAC 与审计日志:Retool 能否支撑受治理的 AI 应用开发

对照 Retool 官方文档核查其 RBAC、审计日志与访问策略:它们在 AI 生成的应用中治理什么,企业应用选 Retool 还是 Lovable 有何差别,以及仍然留下的业务权限缺口。

Retool RBAC 与审计日志:Retool 能否支撑受治理的 AI 应用开发 Retool RBAC 与审计日志:Retool 能否支撑受治理的 AI 应用开发
  • Retool
  • RBAC
  • 审计日志
  • Lovable

TL;DR: 如果你正在评估 Retool 能否用于受治理的 AI 应用开发,它的访问层是过关的,你也不该假装不是这样。Retool 有基于权限组的 RBAC、按角色控制谁能使用其 AI 构建器、记录每一次查询执行的审计日志、SSO、自托管,以及(自 2026 年 10 月起,针对 Postgres 公开测试中的)任何查询都无法豁免的资源访问策略。自 2026 年 6 月起,它还把这些控制延伸到用 Lovable、Cursor 或 Claude Code 构建的应用上。它不提供的,是作为声明式事实的业务权限。“这个人能不能发起一笔 1.2 万美元的退款?”依然往往分散在各组件属性和查询逻辑里的 JavaScript 中,而 AI 写出这些表达式的速度,比任何 PR 审查得过来的速度都快。缺口不在基础安全,而在于权限是代码,不是审查者能在一处读到的规则。

设想世上最寻常的那个 Retool 应用:一个退款控制台。一位工程师花一个下午就把它建好——一张订单表、一个“退款”按钮、几条查询。客服在用。它很棒。这正是 Retool 最出彩的样子,而 Retool 在这件事上确实是品类里最好的。

如今半年过去了。当初构建它的工程师已经换了团队。安全团队正在做访问审查,向新的负责人抛出一个一句话的问题:“哪些角色能发起超过 1 万美元的退款,以及它究竟在哪里被强制执行?”

看看新负责人为了回答得做些什么。没有一个单一的地方可供查看。他打开应用,开始读 JavaScript。

grep 测试

“它在哪里被强制执行”,在一个真实的 Retool 应用里实际长这样。发起一笔大额退款的权限,至少散落在三处彼此独立的表达式中,每一处都是手写的,每一处形状都不同:

// 1. refundButton → “Hidden” 属性
{{ current_user.groups.map(g => g.name).includes('admin') ||
   (current_user.groups.map(g => g.name).includes('support_lead') && refundAmount.value <= 10000) }}

// 2. refundAmount input → “disabled” 属性
{{ !current_user.groups.map(g => g.name).includes('support_lead') }}

// 3. issueRefund query → transformer(这才是真正写入的那部分)
if (refundAmount.value > 10000 && !current_user.groups.map(g => g.name).includes('finance')) {
  throw new Error('Refunds over $10k require finance');
}

三个地方。三个微妙不同的条件。按钮对某些用户隐藏自己;输入框对另一些用户禁用自己;查询则对第三组人抛出错误。它们本应加总成一条自洽的规则——“二级客服可退到 1 万美元,更高的归财务”——但没有任何东西保证它们会如此。把一个按钮隐藏掉,只要有人换条路触发,底下那条查询照样会跑。下个季度添加第二条写入路径却忘了那道 finance 检查,你就有了一个任何屏幕都不会暴露的漏洞。

把这叫作 grep 测试:要回答“谁能做 X”,你是读一条声明过的规则,还是得对整个应用 grep?如果是 grep,那么这个应用在权限层就没有被治理——它仅仅是被编码出来的,而访问治理(Retool 做得无可挑剔)所在的那一层,恰好高过真正能伤到你的那个东西一层。

作为对照,这里是同一份权限作为一项声明过的事实——一条规则,无论你是从哪个按钮或哪条查询进来的,运行时都会在每一条路径上强制执行:

action: issue_refund
  who_can_run:
    - role: SupportLead   when: amount <= 10000
    - role: Finance       when: amount  > 10000
  requires_approval:      when: amount > 10000      # 一道预防性的闸门,而非一个被抛出的错误
  audit: always

只有一处可读。只有一处可改。只有一件事要让审查者——或一个 AI——去推敲。三处手工维护的表达式与一条声明过的规则之间的差别,正是“应用是被编码出来的”与“应用的权限是被治理的”之间的全部差别。

Retool RBAC 与审计日志:每项控制实际覆盖什么

只有把 Retool 确实具备的控制准确列出来,grep 测试才算公平。以下内容于 2026 年 11 月对照 Retool 自己的文档核实:

控制治理什么止于何处
权限组(RBAC)权限组“授予角色,并控制对应用、资源、工作流和智能体的访问”(Retool 权限指南)管的是谁能打开、编辑或查询,而不是某人进来之后某个动作可以做什么
Assist RBAC(2026 年 2 月,Business 与 Enterprise)按角色设定:Ask 与 Build 模式、仅 Ask 模式,或无权使用 AI 构建器(更新日志)管的是谁能生成改动,而不是生成的改动授予了什么
审计日志用户操作,“例如查询执行和密码重置”,记录确切的查询、参数、IP 地址和响应时间;Cloud 版保留一年,Business 与 Enterprise 支持 CSV 导出,Enterprise 支持流式推送到 Datadog 或 Splunk(审计日志)检测式:记录已经运行了什么,且是在运行之后
current_user 行过滤这些值“在服务端根据已认证的会话计算”,并注入每条查询(行级安全)逐条查询、手工添加:“遗漏该过滤条件的查询会返回未经过滤的数据。”
资源访问策略对某个资源的表、列和行访问,在来自应用、查询库、原始 SQL 和智能体的每一条查询上强制执行(访问策略)仅限 PostgreSQL,自 2026 年 10 月起公开测试;行过滤器“不校验用户创建的行,也不校验用户写入的值”
AI 编码应用的治理(2026 年 6 月)在 Lovable、Replit、Cursor 或 Claude Code 中构建的应用“继承现有的权限和审计轨迹”;“权限附着在数据源上”(Retool 新闻室)同一层:数据源权限,而不是动作级的业务规则

其中两行比其余更重要,因为它们正是 Retool 在朝本文所主张的方向前进。

访问策略是一条声明过的规则,而不是三处表达式。 资源上的策略适用于每一条查询,“因此没有任何查询能够选择退出”,这与逐条查询添加的 current_user 过滤正好相反。对于数据权限——二级客服可以读取或删除哪些行——这在 Postgres 上基本通过了 grep 测试。相对于本文 6 月的版本,诚实的更新是:Retool 现在对这一层有了真正的答案。

策略表达不了的,是那条退款规则。 访问策略文档描述的是对表、列和行的读取、写入和删除权限。它没有描述金额阈值、审批闸门,或针对写入值的条件;而行过滤器明确不检查用户写入的内容。“二级客服可退到 1 万美元,更高的归财务,超过界线需要审批”是一条关于动作及其参数的规则,所以它依然活在上面的按钮、输入框和 transformer 里。策略把数据权限收拢到了一处,业务权限仍留在 JavaScript 里。

把这张表当作记分卡来读,Retool 能通过安全审查会问到的每一个访问治理问题。它无法在一处回答的,是本文开头那个问题:哪些角色能发起超过 1 万美元的退款,它又在哪里被强制执行?

为什么源代码管理填不上这道缺口

精明的 Retool 工程师的反驳很在理,你得精确地回应它:“我们有 Git 支撑的源代码管理、审计日志和 RBAC。改动会在 PR 里审查。访问是被治理的。还缺什么?”

具体缺三样东西。

第一,对一个 Retool 应用的 PR,审查的是散落在各组件间的 JavaScript 与绑定——你在做代码审查,这意味着 (a) 它需要一位工程师,且 (b) 不存在一个结构化的表征来说明*“这次改动改变了谁能发起一笔大额退款。”* 审查者必须自己察觉到:三个组件之外的某个 Hidden 表达式的一点小改,挪动了一道权限边界。散落逻辑的 diff,恰恰把你最需要看见的那个东西藏了起来。

第二,源代码管理审查的是代码,而非作为事实的权限。“这个 PR 改变了谁能退款超过 1 万美元吗?”不是一个 Git diff 能直接回答的问题;这是一个你得在脑子里追着代码去回答的问题。而上面那条声明过的规则让这份 diff 变得微不足道:who_can_run 改了,或者没改。

第三——也是对行业走向最要紧的一点——低代码的整个前提,就是非工程师和 AI会去改这个应用,常常是在可视化编辑器里,常常不经过传统 PR。你所倚仗的那种治理(代码审查),未必覆盖低代码本来要服务的那些改动。审计日志会在事后告诉你某个 Hidden 属性变了——是检测式的,不是预防式的——但在它上线之前,业务负责人未必看见过它改变了什么权限。

AI 不会打破这一点。它会成倍放大它。

多年来 grep 测试还能活下去,是因为有一个人写下 JavaScript,另一个人承载着每条规则存活在何处的知识。散落的逻辑,只要是人构建并记得的,就还摸索得通。

把一个 AI 对准同一个应用,经济账便在两个方向上同时反转。AI 能在一分钟内生成五十个绑定和十几个 transformer——它产出权限决策的速度比任何审查者能追踪的速度都快。而要审查它产出的东西,你又回到了一屏接一屏地读 JavaScript,因为依然没有一份单一的、结构化的权限表征可供 diff。“Retool AI”和智能体(2025)真实存在且有用,但它们是在同一套手工搭建的底座之上做自动化:智能体是被治理的(Retool 能限定它可以调用什么),但智能体所编辑的那个应用却不是——它在任何一种 AI——或人类——能当作事实而非代码来审查的形式上,都没有被权限治理。

AI 最擅长快速产出的东西,恰恰也是这种模式下最需要结构化审查的东西。

Retool vs. Lovable:企业应用对比

人们常做的另一种比较是 Retool 对 Lovable,通常被框定为“内部工具构建器 vs. AI 应用生成器”。对企业应用而言,更有用的框定是:每一项控制治理的是谁的用户?

RetoolLovable
AI 产出什么运行在 Retool 组件运行时上的应用,接入你现有的资源全栈项目代码;默认“存放在 Lovable 的托管基础设施中”,可与 GitHub、GitLab 或 Bitbucket 同步(Lovable for Enterprise)
角色权限组控制对应用及其背后的资源、工作流和智能体的访问所有者、管理员、编辑者、查看者和外部协作者治理的是构建应用的工作区(同一页面)
最终用户数据访问数据源权限、current_user 过滤、访问策略内置后端中“用于按用户划分数据”的行级安全,属于生成项目的一部分;Quick scan“在每次发布时运行,检查数据库访问规则”
审计查询级审计日志,Cloud 版保留一年工作区审计日志“保留 13 周”,可定时导出到 SIEM 或存储桶
自托管由 Retool 托管或自行管理的自托管实例(自托管 Retool)后端和数据库可迁移到你自己运营的基础设施上,“包括自托管的 Supabase”;构建器本身仍是 SaaS

第二行和第三行的区别,才是决定企业适配度的那一个。Lovable 的角色和审计日志治理的是构建应用的人;使用应用的人,则由生成项目自身后端里的访问规则来保护,并由每次发布时运行的扫描来检查。Retool 治理的是使用应用的人,因为应用运行在 Retool 内部。这就是为什么 Retool 2026 年 6 月的动作,是在自己的数据源权限之下托管用 Lovable 及类似工具构建的应用,而不是在生成能力上与它们竞争。

所以现实的企业模式不是“Retool 还是 Lovable”,而是“在哪里生成都行,在受治理的地方运行”。两者都改变不了 grep 测试:Lovable 应用的退款阈值活在它生成的代码里,Retool 应用的则活在它的绑定和 transformer 里;两种情况下,审查者都得靠读代码来重建业务权限。

Retool 才是正确选择的场合——以及元数据模型让你付出代价的场合

两个方向上都要诚实,因为一篇一边倒的文章,对一个真要做决定的人毫无价值。

Retool 的访问治理确实是同类最佳,而且对一大批应用来说,grep 测试很可能咬不到你:一个由可信员工操作、藏在 SSO 之后、由当初编写它的同一批工程师维护的内部工具,其中“二级客服可退到 1 万美元”被强制执行在三处恰好彼此一致、又极少改动的地方。对这样的场合——以及对那种需求一旦古怪就能随时落到 SQL 和任意 JavaScript 的自由——Retool 都很出色,而“快速接好一个工具”这件事我们是赢不了的。

而声明式元数据模型在另一个方向上有实打实的代价:你拿原始的灵活性,换来了可读性。当模型里没有容纳它的地方时,你没法只是往一个属性里粘一段任意的 JavaScript;把真正不寻常的逻辑表达成声明过的规则,比随处可用的 {{ }} 更受约束。对一个用完即弃的工具来说,这份约束是纯粹的额外开销。只有当“谁能做什么”是某种你会被要求去证明的东西时——被审计人员、被监管方,或被下一任负责人——并且当做改动的是一个 AI、而非原作者时,这个模型才值回它的代价。

那就是那条线。线之下,Retool 凭实力取胜。线之上,grep 测试正是半年之后、在某个拿着写字板的人面前,你会栽的那一项。

ObjectStack 的立场

ObjectStack 保留了 Retool 做对的东西——强大的访问控制、自托管、你自己的基础设施——并把权限下沉到同一个被治理的层。应用的逻辑是开放、可读的元数据:一个像 issue_refund 这样的操作,携带着它自己的 who_can_run、它自己的审批闸门、它自己的审计要求,声明一次,由运行时在每一条路径上强制执行。一次 AI 改动,就是针对那份声明过的权限的一份 diff——“这次改动让 SupportLead 能退到 2.5 万美元”是一句非工程师能在上线前读懂并批准的话——而不是一个你日后才靠 grep 发现的 Hidden 表达式。

我们并不打算在“落到 JavaScript、午饭前就发布一个工具”这件事上胜过 Retool。这个主张更窄,且只在那条线之上才要紧:当 AI 在编写你的内部软件时,谁能做什么应当是一项你能在一个地方读到、并能当作 diff 来审查的事实——而不是三处表达式的某种涌现属性,它们必须彼此一致、通常也确实一致,直到它们不一致的那个季度。