mcpField
C
configuring-tauri-scopes

configuring-tauri-scopes

github.com/dchuk安全36154 次安装40 周前更新
代码仓库

关于 configuring-tauri-scopes

面向 Tauri v2 开发者的范围配置技能,介绍如何通过能力文件为文件系统、HTTP 和命令设置细粒度访问边界,并管理运行时范围。

主要功能

  1. 01配置文件路径允许与拒绝规则
  2. 02使用 Glob 模式匹配路径
  3. 03按 URL 限制 HTTP 访问
  4. 04通过 Rust 在运行时调整范围

适用场景

  1. 01仅允许应用访问指定目录
  2. 02阻止访问敏感文件夹
  3. 03限制应用可请求的 API 地址
  4. 04根据验证后的路径扩展访问范围

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dchuk/claude-code-tauri-skills --skill configuring-tauri-scopes

安装后在 Claude Code 中输入/configuring-tauri-scopes确认已加载。

详细介绍

Tauri 命令作用域

本技能介绍如何在 Tauri v2 应用中配置作用域,以精细控制对命令和资源的访问。

什么是作用域?

作用域是 Tauri 中的一种细粒度授权机制,用于控制命令可以执行哪些特定操作。相比基本的命令访问权限,作用域提供了更精细的权限边界。

主要特征
  • 允许作用域:明确允许某些操作
  • 拒绝作用域:明确限制某些操作
  • 拒绝优先:两者同时存在时,拒绝规则始终优先
  • 命令职责:命令实现必须验证并强制执行作用域限制
作用域的工作方式

执行期间,作用域会传递给命令。命令实现负责根据作用域进行验证并强制执行限制。这意味着开发者必须谨慎实现作用域验证,以防止绕过限制。

作用域配置位置

作用域配置在以下能力文件中:

  • src-tauri/capabilities/default.json(主要文件)
  • src-tauri/capabilities/*.json(其他能力文件)

文件系统作用域

文件系统插件使用兼容 glob 的路径模式来定义可访问的路径。

基本文件系统作用域配置
{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "description": "Default capability for the application",
  "windows": ["main"],
  "permissions": [
    {
      "identifier": "fs:scope",
      "allow": [{ "path": "$APPDATA" }, { "path": "$APPDATA/**" }]
    }
  ]
}
特定命令的作用域

限制单个文件系统操作,而非全局访问:

{
  "permissions": [
    {
      "identifier": "fs:allow-read-text-file",
      "allow": [{ "path": "$DOCUMENT/**" }]
    },
    {
      "identifier": "fs:allow-write-text-file",
      "allow": [{ "path": "$HOME/notes.txt" }]
    }
  ]
}
组合使用允许和拒绝作用域
{
  "permissions": [
    {
      "identifier": "fs:allow-rename",
      "allow": [{ "path": "$HOME/**" }],
      "deny": [{ "path": "$HOME/.config/**" }]
    }
  ]
}
可用路径变量

Tauri 提供了运行时注入的变量,用于表示常见系统目录:

变量描述
$APPCONFIG应用配置目录
$APPDATA应用数据目录
$APPLOCALDATA应用本地数据目录
$APPCACHE应用缓存目录
$APPLOG应用日志目录
$AUDIO用户音频目录
$CACHE系统缓存目录
$CONFIG系统配置目录
$DATA系统数据目录
$DESKTOP用户桌面目录
$DOCUMENT用户文档目录
$DOWNLOAD用户下载目录
$EXE应用可执行文件目录
$HOME用户主目录
$PICTURE用户图片目录
$PUBLIC公共目录
$RESOURCE应用资源目录
$TEMP临时目录
$VIDEO用户视频目录

作用域模式

作用域支持 glob 模式,可灵活匹配路径。

模式示例
{
  "permissions": [
    {
      "identifier": "fs:scope",
      "allow": [
        { "path": "$APPDATA/databases/*" },
        { "path": "$DOCUMENT/**/*.txt" },
        { "path": "$HOME/project/src/**" }
      ],
      "deny": [
        { "path": "$HOME/.ssh/**" },
        { "path": "$HOME/.gnupg/**" }
      ]
    }
  ]
}
模式语法
模式含义
*匹配除路径分隔符以外的任意字符
**匹配包括路径分隔符在内的任意字符(递归)
?匹配单个字符
[abc]匹配方括号中的任意字符
路径遍历防护

Tauri 会阻止路径遍历攻击。以下路径不允许使用:

  • /usr/path/to/../file
  • ../path/to/file

HTTP 插件作用域

HTTP 插件使用 URL 模式来控制网络访问。

URL 作用域配置
{
  "permissions": [
    {
      "identifier": "http:default",
      "allow": [{ "url": "https://*.tauri.app" }],
      "deny": [{ "url": "https://private.tauri.app" }]
    }
  ]
}
URL 模式示例
{
  "permissions": [
    {
      "identifier": "http:default",
      "allow": [
        { "url": "https://api.example.com/*" },
        { "url": "https://*.cdn.example.com/**" }
      ]
    }
  ]
}

使用作用域定义自定义权限(TOML)

对于插件或自定义命令,可在 TOML 文件中定义权限。

带作用域的基本权限
# permissions/my-permission.toml
[[permission]]
identifier = "scope-appdata-recursive"
description = "Recursive access to APPDATA folder"

[[permission.scope.allow]]
path = "$APPDATA/**"
带拒绝作用域的权限
[[permission]]
identifier = "deny-sensitive-data"
description = "Denies access to sensitive directories"
platforms = ["linux", "macos"]

[[permission.scope.deny]]
path = "$HOME/.ssh/**"

[[permission.scope.deny]]
path = "$HOME/.gnupg/**"
权限集

将权限组合成可复用的集合:

[[set]]
identifier = "safe-appdata-access"
description = "Allows APPDATA access while denying sensitive folders"
permissions = ["scope-appdata-recursive", "deny-sensitive-data"]

动态作用域(运行时管理)

Tauri 支持使用 Rust 的 FsExt 特征在运行时修改作用域。

基本的运行时作用域扩展
use tauri_plugin_fs::FsExt;

pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_fs::init())
        .setup(|app| {
            let scope = app.fs_scope();
            // Allow a specific directory (non-recursive)
            scope.allow_directory("/path/to/directory", false)?;
            // Check what's currently allowed
            dbg!(scope.allowed());
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
用于扩展作用域的 Tauri 命令
use tauri_plugin_fs::FsExt;

#[tauri::command]
fn expand_scope(
    app_handle: tauri::AppHandle,
    folder_path: std::path::PathBuf
) -> Result<(), String> {
    // Verify path before expanding scope
    if !folder_path.exists() {
        return Err("Path does not exist".to_string());
    }

    // true = allow inner directories recursively
    app_handle
        .fs_scope()
        .allow_directory(&folder_path, true)
        .map_err(|err| err.to_string())
}
允许访问特定文件
#[tauri::command]
fn allow_file(
    app_handle: tauri::AppHandle,
    file_path: std::path::PathBuf
) -> Result<(), String> {
    app_handle
        .fs_scope()
        .allow_file(&file_path)
        .map_err(|err| err.to_string())
}
安全警告

应谨慎使用动态作用域扩展:

  • 扩展作用域前验证路径
  • 尽可能优先使用静态配置
  • 绝不要根据未经验证的用户输入扩展作用域

远程 URL 作用域(能力)

控制哪些远程 URL 可以访问应用的命令。

{
  "identifier": "remote-api-access",
  "description": "Allow remote access from specific domains",
  "windows": ["main"],
  "remote": {
    "urls": ["https://*.mydomain.dev", "https://app.example.com"]
  },
  "permissions": ["core:default"]
}

完整能力文件示例

{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "description": "Default capability for desktop application",
  "windows": ["main", "settings"],
  "platforms": ["linux", "macos", "windows"],
  "permissions": [
    "core:default",
    "core:window:allow-set-title",
    {
      "identifier": "fs:default"
    },
    {
      "identifier": "fs:allow-read-text-file",
      "allow": [
        { "path": "$DOCUMENT/**/*.md" },
        { "path": "$DOCUMENT/**/*.txt" }
      ]
    },
    {
      "identifier": "fs:allow-write-text-file",
      "allow": [{ "path": "$APPDATA/notes/**" }],
      "deny": [{ "path": "$APPDATA/notes/.secret/**" }]
    },
    {
      "identifier": "http:default",
      "allow": [{ "url": "https://api.example.com/*" }]
    }
  ]
}

安全最佳实践

  1. 尽量缩小范围:只允许绝对必要的路径和 URL
  2. 使用拒绝规则:即使在允许的路径中,也要明确屏蔽敏感目录
  3. 优先使用命令专属范围:使用 fs:allow-read-text-file,而非全局 fs:scope
  4. 验证动态范围:运行时扩展范围前,务必验证路径
  5. 审计范围强制执行:命令开发者必须实现适当的范围验证
  6. 使用路径变量:为提高可移植性,优先使用 $APPDATA,而非硬编码路径

常见范围模式

只读应用数据
{
  "permissions": [
    {
      "identifier": "fs:allow-read-text-file",
      "allow": [{ "path": "$APPDATA/**" }]
    },
    {
      "identifier": "fs:allow-exists",
      "allow": [{ "path": "$APPDATA/**" }]
    }
  ]
}
用户文档访问
{
  "permissions": [
    {
      "identifier": "fs:scope",
      "allow": [{ "path": "$DOCUMENT/**" }],
      "deny": [
        { "path": "$DOCUMENT/.hidden/**" },
        { "path": "$DOCUMENT/**/*.key" }
      ]
    }
  ]
}
仅限 API 的 HTTP 访问
{
  "permissions": [
    {
      "identifier": "http:default",
      "allow": [
        { "url": "https://api.myapp.com/v1/*" },
        { "url": "https://cdn.myapp.com/**" }
      ],
      "deny": [
        { "url": "https://api.myapp.com/v1/admin/*" }
      ]
    }
  ]
}

故障排除

“路径不在配置的范围内”

此错误表示请求的路径超出了配置范围。解决方法:

  1. 将路径添加到 capability 的允许列表中
  2. 检查路径变量是否有拼写错误
  3. 确认 glob 模式与预期路径匹配
  4. 检查是否有拒绝规则屏蔽了该路径
测试范围配置

在开发模式下运行以测试权限:

pnpm tauri dev
# or
cargo tauri dev

控制台中会显示权限错误,指出需要配置哪些权限。

参考资料

评论

支持 Markdown