--- name: configuring-tauri-permissions description: Guides the user through configuring Tauri permissions, including the security permission system, allow and deny lists, plugin permissions, permission identifiers, scopes, and capability integration. --- # Tauri Permissions Configuration This skill covers the Tauri v2 permission system for controlling frontend access to backend commands and system resources. ## Permission System Overview Permissions in Tauri are explicit privileges that grant or deny access to specific commands. They form the security boundary between frontend code and system resources. ### Core Components | Component | Purpose | |-----------|---------| | Permission | Defines access to specific commands | | Scope | Restricts commands to specific paths/resources | | Capability | Links permissions to windows/webviews | | Identifier | Unique name referencing a permission | ### Security Model - Frontend code cannot access commands without explicit permission - Deny rules always take precedence over allow rules - Permissions must be linked to capabilities to be active - Each window/webview can have different permissions ## Permission Identifiers ### Naming Convention Format: `:` | Pattern | Example | Description | |---------|---------|-------------| | `:default` | `fs:default` | Default permission set | | `:allow-` | `fs:allow-read-file` | Allow specific command | | `:deny-` | `fs:deny-write-file` | Deny specific command | | `:allow-` | `fs:allow-app-read` | Allow with predefined scope | ### Identifier Rules - Lowercase ASCII letters only: `[a-z]` - Maximum length: 116 characters - Plugin prefixes (`tauri-plugin-`) added automatically at compile time ## Directory Structure ### Application Structure ``` src-tauri/ ├── capabilities/ │ ├── default.json # Main capability file │ └── admin.toml # Additional capabilities ├── permissions/ │ └── custom-permission.toml # Custom app permissions └── tauri.conf.json ``` ### Plugin Structure ``` tauri-plugin-example/ ├── permissions/ │ ├── default.toml # Default permission set │ ├── autogenerated/ # Auto-generated from commands │ │ └── commands/ │ └── custom-scope.toml # Custom scopes └── src/ ├── commands.rs └── build.rs ``` ## Capability Configuration Capabilities link permissions to windows and define what frontend contexts can access. ### JSON Format (Recommended for Apps) ```json { "$schema": "../gen/schemas/desktop-schema.json", "identifier": "main-capability", "description": "Main window permissions", "windows": ["main"], "permissions": [ "core:default", "fs:default", "fs:allow-read-text-file", { "identifier": "fs:allow-write-text-file", "allow": [{ "path": "$APPDATA/*" }] } ] } ``` ### TOML Format ```toml "$schema" = "../gen/schemas/desktop-schema.json" identifier = "main-capability" description = "Main window permissions" windows = ["main"] permissions = [ "core:default", "fs:default", "fs:allow-read-text-file" ] [[permissions]] identifier = "fs:allow-write-text-file" allow = [{ path = "$APPDATA/*" }] ``` ### Window Targeting ```json { "identifier": "admin-capability", "windows": ["admin", "settings"], "permissions": ["fs:allow-write-all"] } ``` Use `"*"` to target all windows: ```json { "windows": ["*"], "permissions": ["core:default"] } ``` ### Platform-Specific Capabilities ```json { "identifier": "desktop-capability", "platforms": ["linux", "macOS", "windows"], "windows": ["main"], "permissions": ["fs:allow-app-read-recursive"] } ``` ```json { "identifier": "mobile-capability", "platforms": ["iOS", "android"], "windows": ["main"], "permissions": ["fs:allow-app-read"] } ``` ## Allow and Deny Lists ### Basic Scope Configuration ```json { "identifier": "fs:allow-read-file", "allow": [ { "path": "$HOME/Documents/*" }, { "path": "$APPDATA/**" } ], "deny": [ { "path": "$HOME/Documents/secrets/*" } ] } ``` ### Scope Variables | Variable | Description | |----------|-------------| | `$APP` | Application install directory | | `$APPCONFIG` | App config directory | | `$APPDATA` | App data directory | | `$APPLOCALDATA` | App local data directory | | `$APPCACHE` | App cache directory | | `$APPLOG` | App log directory | | `$HOME` | User home directory | | `$DESKTOP` | Desktop directory | | `$DOCUMENT` | Documents directory | | `$DOWNLOAD` | Downloads directory | | `$RESOURCE` | App resource directory | | `$TEMP` | Temporary directory | ### Glob Patterns | Pattern | Matches | |---------|---------| | `*` | Any file in directory | | `**` | Recursive (all subdirectories) | | `*.txt` | Files with .txt extension | ### Deny Precedence Deny rules always override allow rules: ```json { "permissions": [ { "identifier": "fs:allow-read-file", "allow": [{ "path": "$HOME/**" }], "deny": [{ "path": "$HOME/.ssh/**" }] } ] } ``` ## Plugin Permissions ### Using Default Plugin Permissions ```json { "permissions": [ "fs:default", "shell:default", "http:default", "dialog:default" ] } ``` ### Common Plugin Permission Patterns #### Filesystem Plugin ```json { "permissions": [ "fs:default", "fs:allow-read-text-file", "fs:allow-write-text-file", "fs:allow-app-read-recursive", "fs:allow-app-write-recursive", "fs:deny-default" ] } ``` #### HTTP Plugin ```json { "permissions": [ "http:default", { "identifier": "http:default", "allow": [{ "url": "https://api.example.com/*" }], "deny": [{ "url": "https://api.example.com/admin/*" }] } ] } ``` #### Shell Plugin ```json { "permissions": [ "shell:allow-open", { "identifier": "shell:allow-execute", "allow": [ { "name": "git", "cmd": "git", "args": true } ] } ] } ``` ### Directory-Specific Filesystem Permissions | Permission | Access | |------------|--------| | `fs:allow-appdata-read` | Read $APPDATA (non-recursive) | | `fs:allow-appdata-read-recursive` | Read $APPDATA (recursive) | | `fs:allow-appdata-write` | Write $APPDATA (non-recursive) | | `fs:allow-appdata-write-recursive` | Write $APPDATA (recursive) | | `fs:allow-home-read-recursive` | Read $HOME (recursive) | | `fs:allow-temp-write` | Write to temp directory | ## Custom Permission Definition ### TOML Permission File Create `src-tauri/permissions/my-permission.toml`: ```toml [[permission]] identifier = "my-app:config-access" description = "Access to app configuration files" commands.allow = ["read_config", "write_config"] [[scope.allow]] path = "$APPCONFIG/*" [[scope.deny]] path = "$APPCONFIG/secrets.json" ``` ### Permission Sets Group multiple permissions: ```toml [[set]] identifier = "my-app:full-access" description = "Full application access" permissions = [ "my-app:config-access", "fs:allow-app-read-recursive", "fs:allow-app-write-recursive" ] ``` ### Auto-Generated Command Permissions In plugin `src/build.rs`: ```rust const COMMANDS: &[&str] = &["get_user", "save_user", "delete_user"]; fn main() { tauri_plugin::Builder::new(COMMANDS) .build(); } ``` This generates: - `allow-get-user` / `deny-get-user` - `allow-save-user` / `deny-save-user` - `allow-delete-user` / `deny-delete-user` ### Default Permission Set Create `permissions/default.toml`: ```toml [default] description = "Default permissions for my-plugin" permissions = [ "allow-get-user", "allow-save-user" ] ``` ## Remote Access Configuration Allow remote URLs to access Tauri APIs (use with caution): ```json { "identifier": "remote-capability", "windows": ["main"], "remote": { "urls": ["https://*.myapp.com"] }, "permissions": [ "core:default" ] } ``` **Security Warning**: Linux and Android cannot distinguish iframe requests from window requests. ## Configuration in tauri.conf.json Reference capabilities by identifier: ```json { "app": { "security": { "capabilities": ["main-capability", "admin-capability"] } } } ``` Or inline capabilities directly: ```json { "app": { "security": { "capabilities": [ { "identifier": "inline-capability", "windows": ["*"], "permissions": ["core:default"] } ] } } } ``` ## Troubleshooting ### Common Errors **"Not allowed on this command"** - Verify command permission is in capability - Check scope includes the target path - Ensure capability targets correct window **Permission not found** - Check identifier spelling (lowercase only) - Verify plugin is installed - Run `cargo build` to regenerate permissions ### Debugging Permissions 1. Check generated schema: `src-tauri/gen/schemas/` 2. Review capability files load correctly 3. Verify window names match capability targets 4. Check deny rules are not blocking access ## Best Practices 1. **Principle of Least Privilege**: Only grant permissions actually needed 2. **Use Specific Scopes**: Prefer `$APPDATA/*` over `$HOME/**` 3. **Deny Sensitive Paths**: Always deny access to `.ssh`, credentials, etc. 4. **Separate Capabilities**: Use different capabilities for different window types 5. **Document Custom Permissions**: Include clear descriptions 6. **Review Plugin Defaults**: Understand what default permissions grant 7. **Platform-Specific Config**: Use platform targeting for OS-specific needs