一、为什么需要命令作用域?
试想这样一个场景:你的 Tauri 应用需要读取用户 $APPLOCALDATA 目录下的某些配置文件,于是你开放了文件读取命令。但问题来了------这个目录下同时存放着 WebView 的运行时数据(如 Cookies、IndexedDB、Session 信息),一旦被恶意前端代码读取,将造成严重的隐私泄露。
如果权限粒度只能精确到"命令级别",你只能在"全部放开"和"全部禁止"之间二选一。命令作用域(Command Scopes) 正是为解决这一问题而生------它允许你在开放某个命令的同时,精确约束这个命令能操作的资源边界。
二、作用域的核心概念
2.1 allow 与 deny
作用域分为两类,规则简洁而明确:
| 类型 | 含义 |
|---|---|
allow |
显式允许命令操作的资源范围 |
deny |
显式拒绝命令操作的资源范围 |
核心规则:deny 的优先级永远高于 allow。 无论 allow 范围有多宽泛,只要资源命中了 deny 规则,访问就会被拒绝,没有任何例外。
2.2 作用域的类型系统
作用域的值类型必须是可被 serde 序列化的 Rust 类型,具体类型由各插件或应用自行定义。不同插件使用不同类型来描述"资源"的概念:
fs插件 :使用glob路径字符串(如$HOME/**)描述文件系统路径http插件:使用 URL 字符串描述允许访问的网络地址
作用域由命令实现层接收并强制执行。这意味着命令开发者必须自行实现作用域校验逻辑,框架本身不会自动过滤。
⚠️ 安全警告:命令开发者有责任确保作用域校验逻辑不存在绕过漏洞(例如路径穿越攻击)。所有校验代码都应经过安全审计。
三、实战:fs 插件的作用域配置
下面以 Tauri 官方 fs 插件为例,完整演示作用域的配置方式。在这个插件中,作用域类型统一为 glob 路径字符串。
3.1 定义允许范围:递归访问 APPLOCALDATA
toml
# plugins/fs/permissions/autogenerated/base-directories/applocaldata.toml
[[permission]]
identifier = "scope-applocaldata-recursive"
description = '''
This scope recursive access to the complete $APPLOCALDATA folder,
including sub directories and files.
'''
[[permission.scope.allow]]
path = "$APPLOCALDATA/**"
这里有两个细节值得注意:
$APPLOCALDATA是 Tauri 内置的路径变量,会在运行时被解析为平台对应的目录(Windows 下为%LOCALAPPDATA%,Linux 下为~/.local/share)/**是 glob 通配符,表示递归匹配该目录下所有子目录和文件。若只写/*,则只匹配一层,不会深入子目录
3.2 定义拒绝范围:保护 WebView 敏感数据
WebView 引擎会在 $APPLOCALDATA 下存储用户会话、缓存等敏感数据,不同平台的存储路径有所差异,因此需要分平台配置拒绝规则:
toml
# plugins/fs/permissions/deny-webview-data.toml
# ---- Linux 平台 ----
[[permission]]
identifier = "deny-webview-data-linux"
description = '''
This denies read access to the $APPLOCALDATA folder on linux as the webview
data and configuration values are stored here.
Allowing access can lead to sensitive information disclosure.
'''
platforms = ["linux"]
[[scope.deny]]
path = "$APPLOCALDATA/**"
# ---- Windows 平台 ----
[[permission]]
identifier = "deny-webview-data-windows"
description = '''
This denies read access to the $APPLOCALDATA/EBWebView folder on windows
as the webview data and configuration values are stored here.
'''
platforms = ["windows"]
[[scope.deny]]
path = "$APPLOCALDATA/EBWebView/**"
platforms 字段 是这里的关键------同一个 .toml 文件中可以定义多条权限,每条权限可以通过 platforms 声明其生效的操作系统,做到跨平台差异化配置,无需为每个平台单独维护文件。
两条规则的差异体现了 Linux 和 Windows WebView 实现的不同:
- Linux :整个
$APPLOCALDATA都用于存储 WebView 数据,因此整体拒绝 - Windows :只有
EBWebView子目录存储 Edge WebView2 的数据,精准拒绝即可
四、分层组合:用权限集构建作用域体系
单个作用域权限如同零件,真正的工程实践是将它们有机组合。Tauri 推荐通过权限集(Permission Set) 进行分层组合,每一层都应有清晰的语义。
第一层:合并拒绝规则,建立安全基线
toml
# plugins/fs/permissions/deny-default.toml
[[set]]
identifier = "deny-default"
description = '''
This denies access to dangerous Tauri relevant files and
folders by default.
'''
permissions = [
"deny-webview-data-linux",
"deny-webview-data-windows"
]
deny-default 将两个平台的拒绝规则合并,形成一个平台无关的安全基线。无论应用运行在哪个系统,引用这一个标识符就能自动应用正确的拒绝规则。
第二层:allow + deny 合并,形成合理的访问策略
toml
[[set]]
identifier = "scope-applocaldata-reasonable"
description = '''
This scope set allows access to the APPLOCALDATA folder and subfolders
except for linux, while it denies access to dangerous Tauri relevant
files and folders by default on windows.
'''
permissions = [
"scope-applocaldata-recursive", # 允许递归访问
"deny-default" # 但屏蔽危险路径
]
scope-applocaldata-reasonable 的命名本身就是一种设计表达------"合理的(reasonable)APPLOCALDATA 访问策略",在放开访问的同时内置了安全保障,引用者无需关心底层细节。
第三层:作用域 + 命令权限合并,形成完整功能单元
toml
[[set]]
identifier = "read-files-applocaldata"
description = '''
This set allows file read access to the APPLOCALDATA folder and
subfolders except for linux, while it denies access to dangerous
Tauri relevant files and folders by default on windows.
'''
permissions = [
"scope-applocaldata-reasonable", # 作用域策略
"allow-read-file" # 开放读取命令
]
read-files-applocaldata 是最终对外暴露的功能级权限集,语义完整、开箱即用:调用者只需引用这一个标识符,就能获得"在 APPLOCALDATA 下安全读取文件"的完整能力。
五、整体设计思路图解

这种分层设计的好处在于:
- 关注点分离:allow 规则和 deny 规则各自独立维护
- 复用性强 :
deny-default可被所有涉及 APPLOCALDATA 的权限集复用 - 语义清晰:每一层的命名都能准确表达其意图
- 易于审计:安全相关的拒绝规则集中管理,不会散落在各处
六、作用域的两种应用场景
配置好的作用域权限集,可以用于两种不同的作用范围:
场景一:全局作用域
将作用域权限集应用于插件的全局 scope,该插件的所有命令都会受到约束。适用于对整个插件统一设定资源访问边界的场景。
场景二:命令级作用域
将作用域权限与特定命令权限组合(如上文 read-files-applocaldata 的做法),仅对该命令生效。适用于不同命令需要不同资源访问策略的场景。
七、实践建议
设计作用域时:
- glob 路径要严谨 :
/*只匹配当前层,/**才会递归,根据实际需要选择,避免无意间开放过宽的权限 - 始终配套 deny :任何开放系统目录访问的
allow规则,都应搭配针对敏感子路径的deny规则 - 平台差异显式化 :用
platforms字段将平台逻辑内聚在权限文件中,不要依赖外部条件判断
实现命令时:
- 作用域校验不能省:框架传入 scope 数据,但校验必须由命令实现层主动执行
- 防止路径穿越 :对用户传入的路径参数进行规范化(
canonicalize)后再与 scope 比对 - 安全审计要落实:校验逻辑上线前应经过独立的代码审查,尤其是涉及文件系统和网络的命令
总结
Tauri 的命令作用域机制提供了远超传统"开/关"粒度的访问控制能力。其核心设计哲学可以归纳为三点:
- 精确授权 :
allow明确放行,deny兜底屏蔽,两者组合实现精准的资源边界 - 分层复用:从原子作用域到安全基线,再到功能权限集,每一层都可独立复用
- 平台感知 :
platforms字段让同一套配置体系优雅地处理跨平台差异
对于构建安全 Tauri 应用的开发者来说,命令作用域是不可忽视的核心机制。合理设计作用域体系,不仅能提升应用安全性,也能让权限配置本身成为一份清晰的"资源访问说明书"。