new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Tauri · Plugins and security · all subjects

permissions & security model

56 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Permissions vs Capabilities terminology in Japanese documentation

In Tauri's Japanese documentation, 'Permissions' is translated as 'アクセス権' (access rights/permissions), and 'Capabilities' is translated as 'セキュリティ・レベル' (security level, indicating the degree of security authority).

Finding appropriate permissions for plugin commands

To enable a specific command with minimal system access, find the permission in the plugin's autogenerated permissions that allows the desired action (e.g., 'allow-write-text-file' for writing text files), then add the permission and corresponding scope to either 'src-tauri/tauri.conf.json' in the capabilities section or to a file in 'src-tauri/capabilities/' folder. By default, 'src-tauri/capabilities/default.json' contains an editable default capability.

Capability file schema location

Capability files reference a schema at '../gen/schemas/desktop-schema.json' via the $schema field. Each capability has an identifier, description, windows array listing which windows can use it, and a permissions array.

Capability permission array structure

The permissions array in a capability file can contain both string permissions (e.g., 'fs:default') and permission objects with identifier and allow/deny properties. A permission object specifies scopes with path arrays to restrict access to specific file system paths.

Default permission set contains permissions and scopes for plugin

Each plugin has a default permission set which contains all permissions and scopes to use the plugin out of the box with a reasonable minimal feature set. For official maintained plugins, the default permission is rendered in the documentation. For community plugins, it is defined in your-plugin/permissions/default.toml.

Find plugin permissions in documentation or source code

Plugin permissions can be found in the documentation for official plugins, or in the source code of community plugins. For the fs plugin, autogenerated permissions are located in the documentation or in fs/permissions/autogenerated. Permissions can enable or disable individual commands and allow or disable global scopes.

Configure permissions in capabilities file or tauri.conf.json

Permissions must be added to the capabilities section in either src-tauri/tauri.conf.json or in a file in the src-tauri/capabilities/ folder. By default, src-tauri/capabilities/default.json can be modified to add permissions.

Create custom scope for file access with permission identifier

Custom scopes can be configured by adding a permission object with an identifier and allow array. The allow array contains an object with a path property specifying the file path. For example, a custom scope for fs:allow-write-text-file can be restricted to a specific file like $HOME/test.txt using {"identifier": "fs:allow-write-text-file", "allow": [{"path": "$HOME/test.txt"}]}.

Permission denied error for fs.write_text_file

If the error 'fs.write_text_file not allowed' occurs, check that the correct permission (fs:allow-write-text-file) has been properly added to the capabilities and that the custom scope is correctly configured. The error message lists all permissions associated with the command.

Autogenerated command permissions in Tauri plugins

Tauri's build system automatically generates allow and deny permissions for plugin commands. For a command named write_custom_file, the system generates allow-write-custom-file and deny-write-custom-file permissions. These are created in the permissions/autogenerated/commands folder.

Default permissions in default.toml

Define default permissions for a plugin in permissions/default.toml. Example: [default] description = "Default permissions for the plugin" permissions = ["allow-ping", "allow-write-custom-file"]

File System permissions are blocked by default

By default, all potentially dangerous File System plugin commands and their scopes are blocked. To enable them, modify access permissions in the capabilities configuration.

File System capability permission example with fs:allow-exists

Example capability configuration in src-tauri/capabilities/default.json: {"$schema": "../gen/schemas/desktop-schema.json", "identifier": "main-capability", "description": "Capability for the main window", "windows": ["main"], "permissions": ["fs:default", {"identifier": "fs:allow-exists", "allow": [{"path": "$APPDATA/*"}]}]}

What is a scope and how scopes protect API access in File System

Scopes in File System plugin define which paths are allowed or denied for operations. Scopes are arrays containing path entries in {path: string} format. The deny scope takes priority over allow scope - if a path is denied by one scope, it will be blocked at runtime even if allowed by another scope. Scopes can reference common system paths using variables like $APPDATA, $HOME, $TEMP, etc.

File System global scope example with fs:scope

To apply scope to all fs commands, use "fs:scope" permission: {"identifier": "fs:scope", "allow": [{"path": "$APPDATA"}, {"path": "$APPDATA/**/*"}]}

File System command-specific scope example

To apply scope only to specific fs commands, use individual permission identifiers like fs:allow-rename and fs:allow-exists. Example: {"identifier": "fs:allow-rename", "allow": [{"path": "$HOME/**/*"}]}, {"identifier": "fs:allow-rename", "deny": [{"path": "$HOME/.config/**/*"}]}, {"identifier": "fs:allow-exists", "allow": [{"path": "$APPDATA/*"}]}

Tauri config structure changes in v2

In tauri.conf.json, package.productName and package.version moved to top level. Binary is no longer auto-renamed to productName; add mainBinaryName at top level matching productName. The package object is removed. The tauri key is renamed to app. Removed: tauri.allowlist (migrate to permissions). tauri.cli moved to plugins.cli. tauri.updater moved to plugins.updater. tauri.systemTray renamed to app.trayIcon. tauri.pattern moved to app.security.pattern. tauri.bundle moved to top level bundle object.

Scope module restructuring

scope::IpcScope was removed, use scope::ipc::Scope instead. scope::FsScope, scope::GlobPattern, and scope::FsScopeEvent were removed, use scope::fs::Scope, scope::fs::Pattern, and scope::fs::Event respectively.

Event system redesign in v2

The event system was redesigned: emit() now emits to all listeners. New emit_to() function triggers events to specific targets. emit_filter() filters by EventTarget instead of event source. listen_global() renamed to listen_any() and listens to all events regardless of filters and targets.

Permissions migration from v1 to v2

The v1 allowlist was rewritten to a new ACL-based permission system for individual plugins. Create capability files in src-tauri/capabilities/ folder. The CLI migrate command automatically analyzes v1 allowlist and generates associated capability files. New system allows per-plugin permissions, window-specific permissions, domain-specific permissions, and access scopes.

HTTP plugin URL permissions configuration

Configure allowed URLs in the capability file (e.g., `src-tauri/capabilities/default.json`) using the `http:default` permission identifier with allow and deny URL patterns. Example: ```json { "permissions": [ { "identifier": "http:default", "allow": [{ "url": "https://*.tauri.app" }], "deny": [{ "url": "https://private.tauri.app" }] } ] } ```

Allowlist removed in Tauri 2.0

The 'tauri > allowlist' configuration option has been removed entirely in Tauri 2.0. Functionality has been moved to plugins and the security > assetProtocol configuration.

Store plugin default capability permission

To enable Store plugin access, add 'store:default' to the permissions array in src-tauri/capabilities/default.json.

Store plugin permissions default blocking

By default, all potentially dangerous plugin commands and their scopes are blocked and inaccessible. To enable them, permissions must be changed in the capabilities configuration.

Scopes are fine-grained definitions of allowed or denied command actions

Scopes define which operations are permitted or denied for Tauri commands at a granular level. They are classified into allow scopes and deny scopes, with deny scopes always taking priority over allow scopes.

Scope types must be serde-serializable types

Scope types must be any type that can be serialized using serde. These types are typically plugin-specific. For scoped commands implemented in Tauri applications, the scope type must be defined in the application and applied in the command implementation.

Deny scopes always take priority over allow scopes

When both allow and deny scopes are defined for a command, deny scopes are always evaluated first and take precedence over allow scopes.

Scopes are passed to commands for handling and enforcement

Scopes are passed to commands, and the commands themselves are responsible for their handling and proper enforcement.

Command developers must ensure scope bypass is impossible

Command developers are responsible for ensuring that scope bypass cannot occur. Scope validation implementations must be audited to ensure their correctness and accuracy.

Deny scopes prevent access to sensitive WebView data folders

The Fs plugin includes deny scopes that prevent read access to $APPLOCALDATA folder on Linux and $APPLOCALDATA/EBWebView on Windows, as WebView data and configuration values are stored there. Allowing access to these folders can lead to sensitive information disclosure.

Multiple scopes can be combined into permission sets

Deny scopes and allow scopes can be merged together into sets identified by a unique identifier. For example, deny scopes can be grouped into a 'deny-default' set, which can then be combined with allow scopes into a larger scope set like 'scope-applocaldata-reasonable'.

Scopes can apply globally or to individual commands within permissions

Scopes can be used for all commands by extending a plugin's global scope, or they can be used only for selected commands when combined within an access permission.

Creating multiple windows in Tauri config file

Multiple windows can be created in the Tauri configuration file (typically tauri.conf.json) by defining them in the 'app.windows' array. Each window object must have a 'label' field for identification, and can include 'title', 'width', and 'height' fields. Example: two windows labeled 'first' and 'second', each with title 'First'/'Second', width 800, and height 600.

Creating multiple windows programmatically in Rust

Multiple windows can be created in Rust code using tauri::Builder with a setup closure. Use tauri::WebviewWindowBuilder::new() to create each window, passing the app context, a unique label string, and the WebviewUrl. Clone the webview_url if reusing it for multiple windows. Call .build()? on each builder to create the window.

Window-specific security levels using capability files

Different security levels can be applied to different windows by using the 'windows' field in capability files located in src-tauri/capabilities/. The 'windows' field accepts an array of window labels to which the capabilities apply. Example: a capability with 'windows': ['first'] applies only to the window labeled 'first'.

Capability file structure with windows targeting

A capability file JSON object contains: 'identifier' (string, unique ID), 'description' (string, explaining the capability), 'local' (boolean, typically true), 'windows' (array of strings, window labels), 'permissions' (array of strings, permission names like 'fs:allow-home-read'), and optionally 'platforms' (array of supported platforms).

Platform-specific capabilities using platforms field

Security capabilities can be made platform-specific by including a 'platforms' field in the capability file with an array of target platforms. Available platforms are: 'linux', 'windows', 'macos', 'android', and 'ios'. When the platforms field is specified, the capability only applies to those platforms.

Organizing capabilities into separate files by category

It is recommended to organize capability files by category of enabled actions. For example, create separate JSON files in src-tauri/capabilities/ for different capability types: filesystem.json for file system capabilities, dialog.json for dialog capabilities, etc. This improves maintainability and allows independent security level management per category.

Example: filesystem capability for home directory read access

A capability file filesystem.json can grant read access to the home directory for specific windows. Example structure: identifier 'fs-read-home', description 'Allow access file access to home directory', local true, windows array with target window labels, permissions array containing 'fs:allow-home-read'.

Example: dialog capability for multiple windows

A capability file dialog.json can grant dialog permissions to multiple windows. Example structure: identifier 'dialog', description 'Allow to open a dialog', local true, windows array containing ['first', 'second'], permissions array containing 'dialog:allow-ask' to allow Yes/No dialogs.

Capabilities definition and purpose

Capabilities (セキュリティ・レベル) are sets of permissions assigned to application windows and Webviews according to assigned labels. They are used to restrict fine-grained access to the core implementation exposed to the application frontend running in the system WebView.

Capability files location and formats

Capability files are defined as JSON or TOML files within the src-tauri/capabilities directory. Each file can be referenced by its identifier in tauri.conf.json, or capabilities can be defined directly in the capabilities field of tauri.conf.json.

Default capability behavior

All capabilities defined in the capabilities directory are automatically enabled by default. Once capabilities are explicitly enabled in tauri.conf.json, only those specified capabilities are used during application build.

Multiple windows and Webview security boundaries

Windows and Webviews that are targets of multiple security capabilities effectively combine all associated permissions and security boundaries from all related capabilities.

Default capability example with core plugins

A typical default capability configuration enables core plugins and APIs like window.setTitle. Example permissions include: core:path:default, core:event:default, core:window:default, core:app:default, core:resources:default, core:menu:default, core:tray:default, and core:window:allow-set-title.

Platform-specific capability configuration

Capabilities can be targeted to specific platforms using the platforms array. By default, capabilities apply to all targets, but can be limited to subsets of: linux, macOS, windows, iOS, and android. Desktop capabilities can enable desktop-only plugin permissions, and mobile capabilities can enable mobile-only plugin permissions.

Remote API access configuration

By default, APIs are accessible only to code bundled with the Tauri app. To allow remote sources to access specific Tauri commands, capabilities must be defined with a remote field containing urls array. Remote capabilities require a schema property set to gen/schemas/remote-schema.json.

Remote API access platform limitations

On Linux and Android, Tauri cannot distinguish between requests from embedded iframe tags and requests from the window itself. Changes to remote API access functionality should be made with caution, and the security implications for target operating systems should be thoroughly understood.

Security boundaries provided by capabilities

Capabilities and permissions minimize frontend security breach impacts, prevent or mitigate accidental leakage of local system interfaces and data, and prevent or mitigate privilege escalation from frontend to backend/system.

Security boundaries not provided by capabilities

Capabilities do not protect against: malicious or unsafe Rust code, overly permissive scopes and configurations, inaccurate scope checking in command implementations, intentional bypassing from Rust code, anything written in the app's Rust Core, zero-day or unpatched one-day attacks in the system WebView, supply chain attacks, or compromised developer systems.

Security boundaries depend on window label

Security boundaries depend on window labels (not titles). Window creation functionality should be restricted to apply only to windows with higher privileges.

JSON schema generation and autocomplete

Tauri generates JSON schemas containing all available permissions for the application, enabling IDE autocomplete. Schema usage requires setting the $schema property in configuration to a platform-specific schema in the gen/schemas directory, typically ../gen/schemas/desktop-schema.json or ../gen/schemas/mobile-schema.json, or a schema for a specific target platform.

Capability file inline vs. referenced configuration

Capabilities can be referenced by identifier string in tauri.conf.json (pointing to files in src-tauri/capabilities), or can be defined inline as objects within the capabilities array in tauri.conf.json. Both approaches can be mixed in the same capabilities array.

Desktop capability example with global-shortcut

A desktop capability configuration example that targets linux, macOS, and windows platforms, with identifier 'desktop-capability', windows target 'main', and permission 'global-shortcut:allow-register'. Uses schema ../gen/schemas/desktop-schema.json.

Mobile capability example with NFC and biometric

A mobile capability configuration example that targets iOS and android platforms, with identifier 'mobile-capability', windows target 'main', and permissions including: nfc:allow-scan, biometric:allow-authenticate, barcode-scanner:allow-scan. Uses schema ../gen/schemas/mobile-schema.json.

Remote capability example with NFC and barcode scanner

A remote capability example with identifier 'remote-tag-capability', targeting iOS and android platforms, windows 'main', remote urls ['https://*.tauri.app'], and permissions nfc:allow-scan and barcode-scanner:allow-scan. Uses schema ../gen/schemas/remote-schema.json.

Give your agent this brain