关于 understanding-tauri-runtime-authority
介绍 Tauri 运行时权限执行机制的技术参考技能,说明其如何控制 WebView 到命令的请求。适用于配置或排查权限、能力和作用域的开发者。
主要功能
- 01验证 IPC 请求来源
- 02解析窗口能力
- 03检查命令权限
- 04注入并执行作用域
- 05拒绝规则优先于允许规则
- 06阻止路径遍历
适用场景
- 01排查命令调用的权限拒绝
- 02按路径限制文件系统访问
- 03为不同窗口划分权限
- 04审查运行时访问配置
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dchuk/ claude-code-tauri-skills --skill understanding-tauri-runtime-authority安装后在 Claude Code 中输入/understanding-tauri-runtime-authority确认已加载。
详细介绍
Tauri 运行时权限控制
运行时权限控制是 Tauri 的核心组件,负责在应用执行期间实施安全策略。它会验证权限、解析能力,并在命令执行前注入作用域。
什么是运行时权限控制?
运行时权限控制是位于 WebView 前端和 Tauri 命令之间的执行层。它充当所有 IPC(进程间通信)请求的守门人。
核心功能
当 WebView 调用 Tauri 命令时,运行时权限控制会:
- 接收来自 WebView 的调用请求
- 验证请求来源是否获准调用所请求的命令
- 确认请求来源属于适用的能力
- 将已定义的作用域注入请求
- 将经过验证的请求传递给 Tauri 命令
如果请求来源未获授权,请求将被拒绝,命令不会执行。
信任边界模型
Tauri 通过信任边界将 Rust 核心代码与 WebView 前端代码隔离:
| 区域 | 信任级别 | 访问权限 |
|---|---|---|
| Rust 核心 | 完全信任 | 不受限制的系统访问权限 |
| WebView 前端 | 有限信任 | 只能通过 IPC 访问已公开的资源 |
运行时权限控制会在执行时强制实施此边界。
安全架构
运行时权限控制的作用
Frontend (WebView)
|
v
[IPC Invoke Request]
|
v
+------------------+
| Runtime Authority| <-- Validates permissions, capabilities, scopes
+------------------+
|
v (if allowed)
[Tauri Command Execution]
|
v
[System Resources]
核心组件
| 组件 | 在运行时的作用 |
|---|---|
| 权限 | 定义有哪些命令及其访问规则 |
| 能力 | 将权限映射到特定窗口/WebView |
| 作用域 | 通过路径/资源限制来约束命令行为 |
| 运行时权限控制 | 在执行时强制实施上述所有规则 |
运行时的能力解析
调用命令时,运行时权限控制会解析适用的能力。
解析流程
- 识别来源:确定发出请求的窗口/WebView
- 匹配能力:查找包含此窗口的所有能力
- 收集权限:汇总所有匹配能力中的权限
- 检查命令访问权限:验证是否允许调用该命令
- 合并作用域:组合所有适用的作用域限制
- 验证或拒绝:注入作用域后继续执行,或拒绝请求
窗口能力合并
当一个窗口属于多个能力时,安全边界会合并:
// capability-1.json
{
"identifier": "basic-access",
"windows": ["main"],
"permissions": ["fs:allow-read-file"]
}
// capability-2.json
{
"identifier": "write-access",
"windows": ["main"],
"permissions": ["fs:allow-write-file"]
}
结果:“main”窗口同时获得读权限和写权限。
特定平台的解析
能力可以针对特定平台。在运行时,只会考虑与当前平台匹配的能力:
{
"identifier": "desktop-features",
"platforms": ["linux", "macOS", "windows"],
"windows": ["main"],
"permissions": ["shell:allow-execute"]
}
在 iOS/Android 上,运行时会忽略此能力。
访问控制实施
拒绝优先规则
评估访问权限时,拒绝规则始终优先:
{
"permissions": [
{
"identifier": "fs:allow-read-file",
"allow": [{ "path": "$HOME/**" }],
"deny": [{ "path": "$HOME/.ssh/**" }]
}
]
}
在运行时:
- 读取
$HOME/documents/file.txt的请求——允许 - 读取
$HOME/.ssh/id_rsa的请求——拒绝(匹配拒绝规则)
命令级验证
执行任何命令之前:
- 运行时权限控制会检查是否存在该命令的权限
- 验证调用窗口是否通过其能力获得该权限
- 验证是否满足所有作用域限制
Window "editor" calls fs.readFile("/home/user/doc.txt")
|
v
Runtime Authority checks:
- Does "editor" have fs:allow-read-file? Yes
- Is "/home/user/doc.txt" in allowed scope? Yes
- Is it in any deny scope? No
|
v
Command executes with scopes injected
作用域注入
作用域在运行时的工作方式
作用域不只是验证规则,还会被注入命令执行上下文。命令可以访问适用的作用域,以强制实施限制。
作用域变量
在运行时,作用域变量会解析为实际路径:
| 变量 | 运行时解析结果 |
|---|---|
$APP | 应用安装目录 |
$APPDATA | 应用数据目录 |
$APPCONFIG | 应用配置目录 |
$HOME | 用户主目录 |
$TEMP | 临时目录 |
$DOCUMENT | 文档目录 |
$DOWNLOAD | 下载目录 |
$DESKTOP | 桌面目录 |
作用域组合示例
{
"identifier": "main-capability",
"windows": ["main"],
"permissions": [
{
"identifier": "fs:allow-read-file",
"allow": [{ "path": "$APPDATA/*" }]
},
{
"identifier": "fs:allow-write-file",
"allow": [{ "path": "$APPDATA/config.json" }]
}
]
}
对于运行时的“main”窗口:
- 允许在
$APPDATA/*中进行读取操作 - 只允许对
$APPDATA/config.json进行写入操作
路径遍历防护
运行时权限内置路径遍历防护:
Request: /usr/path/to/../../../etc/passwd
Result: DENIED (path traversal detected)
路径中的父目录访问器(..)会被屏蔽,确保无法绕过范围限制。
配置示例
基本运行时安全设置
src-tauri/capabilities/default.json:
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default-capability",
"description": "Default runtime permissions",
"windows": ["main"],
"permissions": [
"core:default",
"core:event:default",
"core:window:default"
]
}
文件系统访问范围
src-tauri/capabilities/files.json:
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "file-access",
"description": "Controlled filesystem access",
"windows": ["main"],
"permissions": [
"fs:default",
{
"identifier": "fs:allow-read-file",
"allow": [
{ "path": "$APPDATA/**" },
{ "path": "$DOCUMENT/**" }
],
"deny": [
{ "path": "$DOCUMENT/private/**" }
]
},
{
"identifier": "fs:allow-write-file",
"allow": [
{ "path": "$APPDATA/**" }
]
}
]
}
多窗口安全边界
src-tauri/capabilities/editor.json:
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "editor-capability",
"description": "Full editor permissions",
"windows": ["editor"],
"permissions": [
"core:default",
"fs:default",
"fs:allow-read-file",
"fs:allow-write-file",
"dialog:default"
]
}
src-tauri/capabilities/preview.json:
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "preview-capability",
"description": "Read-only preview permissions",
"windows": ["preview"],
"permissions": [
"core:window:default",
"core:event:default",
{
"identifier": "fs:allow-read-file",
"allow": [{ "path": "$TEMP/preview/**" }]
}
]
}
运行时:
- “editor” 窗口可以读取和写入文件,并打开对话框
- “preview” 窗口只能从临时预览目录读取
HTTP 请求范围
{
"identifier": "api-access",
"windows": ["main"],
"permissions": [
{
"identifier": "http:default",
"allow": [
{ "url": "https://api.myapp.com/*" },
{ "url": "https://cdn.myapp.com/*" }
],
"deny": [
{ "url": "https://api.myapp.com/admin/*" }
]
}
]
}
运行时安全保障
运行时权限防护的内容
| 威胁 | 防护措施 |
|---|---|
| 前端遭到入侵 | 将损害限制在已授予的权限范围内 |
| 未经授权的命令访问 | 未显式授予能力时拒绝命令 |
| 路径遍历攻击 | 在运行时内置防护 |
| 试图绕过范围限制 | 在命令执行前强制执行所有范围限制 |
| 跨窗口访问 | 每个窗口都限制在自身的能力范围内 |
运行时权限无法防护的内容
| 威胁 | 无法防护的原因 |
|---|---|
| 恶意 Rust 代码 | Rust 核心拥有完全信任 |
| 权限过于宽松的配置 | 由开发者负责 |
| WebView 漏洞 | 由操作系统的 WebView 安全边界负责 |
| 供应链攻击 | 由依赖项安全负责 |
调试运行时权限
权限被拒绝错误
命令因权限被拒绝而失败时:
- 检查窗口标签:确认发出请求的窗口
- 检查能力:确保某项能力的目标窗口是该窗口
- 检查权限:确认能力中包含该权限
- 检查范围:确认资源位于允许的范围内,且未被拒绝
常见运行时问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 不允许执行命令 | 能力中缺少权限 | 将权限添加到能力中 |
| 未应用范围限制 | 未为权限定义范围 | 添加允许范围 |
| 尽管允许仍被拒绝访问 | 拒绝规则优先级更高 | 移除冲突的拒绝规则 |
| 窗口没有权限 | 能力未指定该窗口为目标 | 检查能力中的窗口标签 |
验证运行时配置
检查生成的架构,查看有哪些权限可用:
src-tauri/gen/schemas/desktop-schema.json
src-tauri/gen/schemas/mobile-schema.json
最佳实践
最小权限原则
仅授予每个窗口实际需要的权限:
// Good: Specific permissions
{
"windows": ["settings"],
"permissions": [
"core:window:allow-close",
"fs:allow-read-file"
]
}
// Avoid: Overly broad permissions
{
"windows": ["settings"],
"permissions": ["fs:default", "shell:default"]
}
始终定义范围
切勿让文件系统或网络权限没有范围限制:
// Good: Scoped access
{
"identifier": "fs:allow-read-file",
"allow": [{ "path": "$APPDATA/**" }]
}
// Avoid: Unscoped access
{
"permissions": ["fs:allow-read-file"]
}
拒绝访问敏感路径
明确拒绝对敏感位置的访问:
{
"identifier": "fs:allow-read-file",
"allow": [{ "path": "$HOME/**" }],
"deny": [
{ "path": "$HOME/.ssh/**" },
{ "path": "$HOME/.gnupg/**" },
{ "path": "$HOME/.aws/**" }
]
}
按信任级别划分能力
为不同的安全上下文创建独立的能力:
capabilities/
main-trusted.json # Full access for main window
plugin-limited.json # Restricted for plugin windows
preview-readonly.json # Read-only for preview
特定平台的安全设置
使用平台目标设置操作系统专属权限:
{
"identifier": "desktop-shell",
"platforms": ["linux", "macOS", "windows"],
"windows": ["main"],
"permissions": ["shell:allow-execute"]
}
这可以防止仅限桌面端的权限在移动端被评估。
总结
运行时权限是 Tauri 针对基于 ACL 的安全模型的强制执行机制:
- 每个 IPC 请求都会经过运行时权限验证
- 能力解析在运行时根据发起请求的窗口进行
- 范围注入到命令执行上下文中
- 拒绝规则始终优先于允许规则
- 路径遍历会被自动屏蔽
- 安全边界合并适用于拥有多项能力的窗口
正确配置能力和权限后,运行时权限会确保它们在应用程序执行过程中始终得到一致的强制执行。