managing-tauri-plugin-permissions

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Managing Tauri Plugin Permissions

管理Tauri插件权限

Tauri's capability and permission system provides granular security control for desktop and mobile applications. This skill covers configuring capabilities for windows and platforms, using plugin permissions effectively, and writing custom plugin permissions.
Tauri的Capability与权限系统为桌面和移动应用提供精细化的安全控制。本内容涵盖为窗口和平台配置Capability、有效使用插件权限,以及编写自定义插件权限的方法。

Core Concepts

核心概念

Capabilities

Capabilities

Capabilities are JSON configuration files that assign permissions to specific windows and platforms. They follow the principle of least privilege.
Location:
src-tauri/capabilities/
Structure:
json
{
  "identifier": "capability-name",
  "description": "Human-readable purpose",
  "local": true,
  "windows": ["window-label"],
  "permissions": ["plugin:allow-action"],
  "platforms": ["linux", "windows", "macos", "android", "ios"]
}
Capabilities是JSON配置文件,用于为特定窗口和平台分配权限,遵循最小权限原则。
存放位置
src-tauri/capabilities/
结构
json
{
  "identifier": "capability-name",
  "description": "Human-readable purpose",
  "local": true,
  "windows": ["window-label"],
  "permissions": ["plugin:allow-action"],
  "platforms": ["linux", "windows", "macos", "android", "ios"]
}

Permission Levels

权限级别

Permissions operate at two levels:
  • Commands: Individual operations (e.g.,
    allow-write-text-file
    )
  • Scopes: Path-based restrictions defining accessible files/directories
权限分为两个级别:
  • 命令:单个操作(例如:
    allow-write-text-file
  • 作用域:基于路径的限制,定义可访问的文件/目录

Platform-Specific Capabilities

平台专属Capability

Targeting Platforms

定向平台

Restrict capabilities to specific operating systems using the
platforms
field:
json
{
  "identifier": "desktop-fs-access",
  "description": "Filesystem access for desktop platforms",
  "windows": ["main"],
  "permissions": ["fs:allow-home-read"],
  "platforms": ["linux", "windows", "macos"]
}
Available platforms:
linux
,
windows
,
macos
,
android
,
ios
使用
platforms
字段将Capability限制在特定操作系统:
json
{
  "identifier": "desktop-fs-access",
  "description": "Filesystem access for desktop platforms",
  "windows": ["main"],
  "permissions": ["fs:allow-home-read"],
  "platforms": ["linux", "windows", "macos"]
}
支持的平台:
linux
,
windows
,
macos
,
android
,
ios

Mobile-Only Capabilities

移动端专属Capability

json
{
  "identifier": "mobile-camera",
  "description": "Camera access for mobile devices",
  "windows": ["main"],
  "permissions": ["camera:allow-capture"],
  "platforms": ["android", "ios"]
}
json
{
  "identifier": "mobile-camera",
  "description": "Camera access for mobile devices",
  "windows": ["main"],
  "permissions": ["camera:allow-capture"],
  "platforms": ["android", "ios"]
}

Window-Specific Capabilities

窗口专属Capability

Configuring Multiple Windows

配置多窗口

Define windows in
tauri.conf.json
:
json
{
  "windows": [
    {
      "label": "main",
      "title": "Main Window",
      "width": 800,
      "height": 600
    },
    {
      "label": "settings",
      "title": "Settings",
      "width": 400,
      "height": 300
    }
  ]
}
tauri.conf.json
中定义窗口:
json
{
  "windows": [
    {
      "label": "main",
      "title": "Main Window",
      "width": 800,
      "height": 600
    },
    {
      "label": "settings",
      "title": "Settings",
      "width": 400,
      "height": 300
    }
  ]
}

Assigning Capabilities to Windows

为窗口分配Capability

Create separate capability files for each window's needs:
src-tauri/capabilities/main-window.json
:
json
{
  "identifier": "main-window-capabilities",
  "description": "Full access for main window",
  "local": true,
  "windows": ["main"],
  "permissions": [
    "fs:allow-home-read",
    "fs:allow-home-write",
    "dialog:allow-open",
    "dialog:allow-save"
  ]
}
src-tauri/capabilities/settings-window.json
:
json
{
  "identifier": "settings-window-capabilities",
  "description": "Limited access for settings window",
  "local": true,
  "windows": ["settings"],
  "permissions": [
    "fs:allow-app-read",
    "fs:allow-app-write"
  ]
}
为每个窗口的需求创建独立的Capability文件:
src-tauri/capabilities/main-window.json
json
{
  "identifier": "main-window-capabilities",
  "description": "Full access for main window",
  "local": true,
  "windows": ["main"],
  "permissions": [
    "fs:allow-home-read",
    "fs:allow-home-write",
    "dialog:allow-open",
    "dialog:allow-save"
  ]
}
src-tauri/capabilities/settings-window.json
json
{
  "identifier": "settings-window-capabilities",
  "description": "Limited access for settings window",
  "local": true,
  "windows": ["settings"],
  "permissions": [
    "fs:allow-app-read",
    "fs:allow-app-write"
  ]
}

Shared Capabilities Across Windows

多窗口共享Capability

json
{
  "identifier": "shared-dialog",
  "description": "Dialog access for multiple windows",
  "local": true,
  "windows": ["main", "settings"],
  "permissions": ["dialog:allow-ask", "dialog:allow-message"]
}
json
{
  "identifier": "shared-dialog",
  "description": "Dialog access for multiple windows",
  "local": true,
  "windows": ["main", "settings"],
  "permissions": ["dialog:allow-ask", "dialog:allow-message"]
}

Using Plugin Permissions

使用插件权限

Default Permission Sets

默认权限集

Every plugin provides a
default
permission set with baseline access. Enable it with:
json
{
  "permissions": ["plugin-name:default"]
}
每个插件都提供一个
default
权限集,包含基础访问权限。通过以下方式启用:
json
{
  "permissions": ["plugin-name:default"]
}

Finding Available Permissions

查找可用权限

  1. Official plugins: Check Tauri documentation's permission tables
  2. Plugin source: Look in
    permissions/autogenerated
    directories
  3. Community plugins: Check repository or crates.io page
  1. 官方插件:查看Tauri文档中的权限表格
  2. 插件源码:查看
    permissions/autogenerated
    目录
  3. 社区插件:查看仓库或crates.io页面

Permission Identifier Format

权限标识符格式

plugin-name:permission-name
Examples:
  • fs:allow-read
  • fs:allow-write-text-file
  • dialog:allow-open
  • shell:allow-spawn
plugin-name:permission-name
示例:
  • fs:allow-read
  • fs:allow-write-text-file
  • dialog:allow-open
  • shell:allow-spawn

Configuring with Scopes

结合作用域配置

Restrict permissions to specific paths:
json
{
  "identifier": "default",
  "description": "Main window capabilities",
  "windows": ["main"],
  "permissions": [
    "fs:allow-write-text-file",
    {
      "identifier": "fs:allow-read",
      "allow": [{ "path": "$HOME/Documents/**" }]
    },
    {
      "identifier": "fs:allow-write",
      "allow": [{ "path": "$APP/**" }]
    }
  ]
}
将权限限制在特定路径:
json
{
  "identifier": "default",
  "description": "Main window capabilities",
  "windows": ["main"],
  "permissions": [
    "fs:allow-write-text-file",
    {
      "identifier": "fs:allow-read",
      "allow": [{ "path": "$HOME/Documents/**" }]
    },
    {
      "identifier": "fs:allow-write",
      "allow": [{ "path": "$APP/**" }]
    }
  ]
}

Common Scope Variables

常用作用域变量

VariableDescription
$APP
Application data directory
$HOME
User home directory
$RESOURCE
Application resources
$TEMP
Temporary directory
$DESKTOP
User desktop
$DOCUMENT
User documents
$DOWNLOAD
User downloads
变量描述
$APP
应用数据目录
$HOME
用户主目录
$RESOURCE
应用资源目录
$TEMP
临时目录
$DESKTOP
用户桌面目录
$DOCUMENT
用户文档目录
$DOWNLOAD
用户下载目录

Deny Permissions

拒绝权限

Explicitly deny specific operations:
json
{
  "permissions": [
    "fs:default",
    "fs:deny-write-text-file"
  ]
}
显式拒绝特定操作:
json
{
  "permissions": [
    "fs:default",
    "fs:deny-write-text-file"
  ]
}

Writing Custom Plugin Permissions

编写自定义插件权限

Plugin Structure

插件结构

Create a plugin with the Tauri CLI:
bash
cargo tauri plugin new my-plugin
cd tauri-plugin-my-plugin
使用Tauri CLI创建插件:
bash
cargo tauri plugin new my-plugin
cd tauri-plugin-my-plugin

Implementing Commands

实现命令

src/commands.rs
:
rust
use tauri::{command, AppHandle, Runtime};

#[command]
pub(crate) async fn read_data<R: Runtime>(
    key: String,
    app: AppHandle<R>,
) -> Result<String, String> {
    // Implementation
    Ok(format!("Data for key: {}", key))
}

#[command]
pub(crate) async fn write_data<R: Runtime>(
    key: String,
    value: String,
    app: AppHandle<R>,
) -> Result<(), String> {
    // Implementation
    Ok(())
}

#[command]
pub(crate) async fn delete_data<R: Runtime>(
    key: String,
    app: AppHandle<R>,
) -> Result<(), String> {
    // Implementation
    Ok(())
}
src/commands.rs
rust
use tauri::{command, AppHandle, Runtime};

#[command]
pub(crate) async fn read_data<R: Runtime>(
    key: String,
    app: AppHandle<R>,
) -> Result<String, String> {
    // Implementation
    Ok(format!("Data for key: {}", key))
}

#[command]
pub(crate) async fn write_data<R: Runtime>(
    key: String,
    value: String,
    app: AppHandle<R>,
) -> Result<(), String> {
    // Implementation
    Ok(())
}

#[command]
pub(crate) async fn delete_data<R: Runtime>(
    key: String,
    app: AppHandle<R>,
) -> Result<(), String> {
    // Implementation
    Ok(())
}

Auto-Generating Permissions

自动生成权限

src/build.rs
:
rust
const COMMANDS: &[&str] = &["read_data", "write_data", "delete_data"];

fn main() {
    tauri_plugin::Builder::new(COMMANDS)
        .global_api_script_path("./api-iife.js")
        .build();
}
This generates:
  • allow-read-data
    /
    deny-read-data
  • allow-write-data
    /
    deny-write-data
  • allow-delete-data
    /
    deny-delete-data
src/build.rs
rust
const COMMANDS: &[&str] = &["read_data", "write_data", "delete_data"];

fn main() {
    tauri_plugin::Builder::new(COMMANDS)
        .global_api_script_path("./api-iife.js")
        .build();
}
这将生成:
  • allow-read-data
    /
    deny-read-data
  • allow-write-data
    /
    deny-write-data
  • allow-delete-data
    /
    deny-delete-data

Defining Default Permissions

定义默认权限

permissions/default.toml
:
toml
"$schema" = "schemas/schema.json"

[default]
description = "Default permissions for my-plugin. Allows read operations only."
permissions = ["allow-read-data"]
permissions/default.toml
toml
"$schema" = "schemas/schema.json"

[default]
description = "Default permissions for my-plugin. Allows read operations only."
permissions = ["allow-read-data"]

Creating Permission Sets

创建权限集

permissions/read-write.toml
:
toml
"$schema" = "schemas/schema.json"

[[set]]
identifier = "read-write"
description = "Allows both read and write operations"
permissions = ["allow-read-data", "allow-write-data"]
permissions/full-access.toml
:
toml
"$schema" = "schemas/schema.json"

[[set]]
identifier = "full-access"
description = "Allows all operations including delete"
permissions = ["allow-read-data", "allow-write-data", "allow-delete-data"]
permissions/read-write.toml
toml
"$schema" = "schemas/schema.json"

[[set]]
identifier = "read-write"
description = "Allows both read and write operations"
permissions = ["allow-read-data", "allow-write-data"]
permissions/full-access.toml
toml
"$schema" = "schemas/schema.json"

[[set]]
identifier = "full-access"
description = "Allows all operations including delete"
permissions = ["allow-read-data", "allow-write-data", "allow-delete-data"]

Registering Commands

注册命令

src/lib.rs
:
rust
use tauri::{
    plugin::{Builder, TauriPlugin},
    Manager, Runtime,
};

mod commands;

pub fn init<R: Runtime>() -> TauriPlugin<R> {
    Builder::new("my-plugin")
        .invoke_handler(tauri::generate_handler![
            commands::read_data,
            commands::write_data,
            commands::delete_data,
        ])
        .build()
}
src/lib.rs
rust
use tauri::{
    plugin::{Builder, TauriPlugin},
    Manager, Runtime,
};

mod commands;

pub fn init<R: Runtime>() -> TauriPlugin<R> {
    Builder::new("my-plugin")
        .invoke_handler(tauri::generate_handler![
            commands::read_data,
            commands::write_data,
            commands::delete_data,
        ])
        .build()
}

Frontend JavaScript Bindings

前端JavaScript绑定

guest-js/index.ts
:
typescript
import { invoke } from '@tauri-apps/api/core';

export async function readData(key: string): Promise<string> {
  return await invoke('plugin:my-plugin|read_data', { key });
}

export async function writeData(key: string, value: string): Promise<void> {
  return await invoke('plugin:my-plugin|write_data', { key, value });
}

export async function deleteData(key: string): Promise<void> {
  return await invoke('plugin:my-plugin|delete_data', { key });
}
guest-js/index.ts
typescript
import { invoke } from '@tauri-apps/api/core';

export async function readData(key: string): Promise<string> {
  return await invoke('plugin:my-plugin|read_data', { key });
}

export async function writeData(key: string, value: string): Promise<void> {
  return await invoke('plugin:my-plugin|write_data', { key, value });
}

export async function deleteData(key: string): Promise<void> {
  return await invoke('plugin:my-plugin|delete_data', { key });
}

Using Custom Plugin Permissions

使用自定义插件权限

In your application's capability file:
json
{
  "identifier": "default",
  "windows": ["main"],
  "permissions": [
    "my-plugin:default",
    "my-plugin:read-write",
    "my-plugin:allow-delete-data"
  ]
}
在应用的Capability文件中:
json
{
  "identifier": "default",
  "windows": ["main"],
  "permissions": [
    "my-plugin:default",
    "my-plugin:read-write",
    "my-plugin:allow-delete-data"
  ]
}

Complete Example: Cross-Platform App

完整示例:跨平台应用

src-tauri/capabilities/desktop.json
:
json
{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "desktop",
  "windows": ["main"],
  "platforms": ["linux", "windows", "macos"],
  "permissions": [
    "core:default",
    "fs:default",
    { "identifier": "fs:allow-read", "allow": [{ "path": "$HOME/Documents/**" }] },
    { "identifier": "fs:allow-write", "allow": [{ "path": "$APP/**" }] },
    "dialog:allow-open",
    "dialog:allow-save",
    "shell:allow-open"
  ]
}
src-tauri/capabilities/mobile.json
:
json
{
  "identifier": "mobile",
  "windows": ["main"],
  "platforms": ["android", "ios"],
  "permissions": [
    "fs:allow-app-read",
    "fs:allow-app-write",
    "notification:default"
  ]
}
src-tauri/capabilities/desktop.json
json
{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "desktop",
  "windows": ["main"],
  "platforms": ["linux", "windows", "macos"],
  "permissions": [
    "core:default",
    "fs:default",
    { "identifier": "fs:allow-read", "allow": [{ "path": "$HOME/Documents/**" }] },
    { "identifier": "fs:allow-write", "allow": [{ "path": "$APP/**" }] },
    "dialog:allow-open",
    "dialog:allow-save",
    "shell:allow-open"
  ]
}
src-tauri/capabilities/mobile.json
json
{
  "identifier": "mobile",
  "windows": ["main"],
  "platforms": ["android", "ios"],
  "permissions": [
    "fs:allow-app-read",
    "fs:allow-app-write",
    "notification:default"
  ]
}

Best Practices

最佳实践

Security

安全

  1. Principle of least privilege: Grant only required permissions
  2. Use scopes: Restrict file access to specific paths rather than broad permissions
  3. Separate by window: Each window should have only the permissions it needs
  4. Platform targeting: Avoid granting mobile permissions on desktop and vice versa
  1. 最小权限原则:仅授予所需的权限
  2. 使用作用域:将文件访问限制在特定路径,而非宽泛权限
  3. 按窗口分离:每个窗口应仅拥有其所需的权限
  4. 平台定向:避免在桌面平台授予移动权限,反之亦然

Organization

组织

  1. Organize by function: Group capabilities by feature area
  2. Use descriptive identifiers: Make capability purposes clear
  3. Document permissions: Include descriptions explaining why each permission is needed
  1. 按功能组织:按功能领域分组Capability
  2. 使用描述性标识符:明确Capability的用途
  3. 文档化权限:包含说明,解释每个权限的必要性

Plugin Development

插件开发

  1. Minimal defaults: Default permission sets should be restrictive
  2. Create permission sets: Offer tiered access levels (read-only, read-write, full)
  3. Use auto-generation: Let Tauri generate allow/deny permissions for commands
  4. Test permissions: Verify permission behavior with example applications
  1. 最小化默认权限:默认权限集应具有限制性
  2. 创建权限集:提供分层访问级别(只读、读写、完全访问)
  3. 使用自动生成:让Tauri为命令生成允许/拒绝权限
  4. 测试权限:通过示例应用验证权限行为

Troubleshooting

故障排除

Permission Denied Errors

权限拒绝错误

If you encounter permission errors:
  1. Check capability file syntax (valid JSON)
  2. Verify the window label matches your configuration
  3. Confirm the permission identifier is correct
  4. Check if a scope is required for path-based operations
如果遇到权限错误:
  1. 检查Capability文件语法(有效的JSON)
  2. 验证窗口标签与配置匹配
  3. 确认权限标识符正确
  4. 检查基于路径的操作是否需要作用域

Capability Not Applied

Capability未生效

  1. Ensure capability files are in
    src-tauri/capabilities/
  2. Verify the
    windows
    array contains the correct window labels
  3. Check
    platforms
    includes your target OS
  4. Rebuild the application after capability changes
  1. 确保Capability文件位于
    src-tauri/capabilities/
    目录
  2. 验证
    windows
    数组包含正确的窗口标签
  3. 检查
    platforms
    是否包含目标操作系统
  4. 修改Capability后重新构建应用

References

参考资料