Tauri 的安全模型有一个核心原则:前端代码不可信。WebView 中运行的 JavaScript 天生暴露在 XSS、依赖库投毒等风险下,如果让它直接调用系统 API,后果不堪设想。因此,Tauri 设计了一套严格的白名单机制,将“前端能调用什么后端能力”这件事,锁定在开发者预先声明的极小范围里。
什么是 Allowlist?
Allowlist 是 tauri.conf.json 中的一个配置块(tauri > allowlist),它逐项声明了哪些 Tauri 核心 API 可以被前端使用。每一项 API 都默认禁用,只有你在配置中显式开启后,对应的 Rust 命令才会暴露给 WebView 中的 JavaScript。
这相当于为你的应用划出一条清晰的边界:前端只能调用你明确允许的 API,其他任何系统调用都无法触及。即使前端被完全控制,攻击者也无法越权读写文件、启动进程或访问网络。
API 粒度的精细控制
Tauri 的权限控制不是简单的“开/关”开关,而是细化到具体操作和参数级别。以 fs(文件系统)模块为例,你可以:
- 允许
readTextFile,但禁止writeFile; - 允许
readDir,但限定作用域为特定的应用数据目录; - 设定
scope白名单,仅允许访问/user/docs或$HOME/.config/myapp等安全路径。
类似地,shell 模块可以控制是否允许执行命令,dialog 模块可以控制是否允许打开文件选择框,clipboard 模块控制读写剪贴板——每个模块都提供了详细的配置项。
一个实际例子
假设你需要开发一个 Markdown 编辑器,允许用户打开和保存文件,但不允许应用执行任何外部命令。tauri.conf.json 中的 allowlist 可以这样配置:
{
"tauri": {
"allowlist": {
"fs": {
"all": false, // 默认关闭所有文件系统API
"readFile": true,
"writeFile": true,
"scope": ["**"] // 可以限制为某些扩展名或路径, 这里仅示意
},
"shell": {
"all": false // 完全禁止执行shell命令
}
}
}
}
此时,前端可以调用 @tauri-apps/api/fs 的 readTextFile 和 writeTextFile,但如果你尝试调用 Command.create('rm')(假设 Tauri 提供了 shell API),则会直接报错——因为 shell 完全关闭。
为什么这很重要?
传统的 Electron 应用中,主进程和渲染进程之间的通信通过 contextBridge 暴露的函数控制,但权限粒度较粗,通常需要开发者手动封装检查。Tauri 把这种检查提前到了配置层,并强制对每个 API 调用进行签名校验。这意味着:
- 降低安全成本:开发者不用在每个命令里写权限判断,Tauri 核心已经在 IPC 层拦截;
- 防止遗漏:所有敏感 API 默认关闭,忘记配置就是安全,而非忘记关闭就是漏洞;
- 可审计性:所有权限声明集中在配置文件中,一目了然,方便安全审计时证明应用只有最小权限。
从 Allowlist 到 Permissions(Tauri v2)
Tauri v2 进一步增强了权限系统,将 allowlist 替换为基于 permissions 的声明式模型。权限文件(capabilities)可以按窗口、按功能模块灵活组合,并支持通过 ACL 风格分配能力。其核心理念不变:默认拒绝,显式授权,最小权限。不过本书大部分示例基于 Tauri v1 的 allowlist,因为其概念更直观,且与 v2 的权限文件一一对应,迁移成本很低。
一句话总结:Allowlist 就像你的应用的安全水闸,每个 API 都有一个专属闸口,默认全部关闭。你只打开那些真正需要的,并且还可以控制它们能做什么、能访问哪些范围。这样做,即使风雨再大,底层系统也稳如泰山。