The Gatekeeper: Permissions and Capabilities
The Gatekeeper: Permissions and Capabilities
Section titled “The Gatekeeper: Permissions and Capabilities”In modern application development, security is paramount. Since the frontend of a Tauri app is essentially a web page, it faces the same threats as the web, such as XSS (Cross-Site Scripting). If a malicious script runs on your frontend, you don’t want it to have unchecked access to your user’s operating system.
Tauri v2 introduces a robust new security system based on Access Control Lists (ACLs), which we call Capabilities. This replaces the simpler ‘allowlist’ found in v1.
Understanding Capabilities
Section titled “Understanding Capabilities”Think of the Tauri Core (Rust) as a highly secure bank vault, and the Frontend as a customer. The customer cannot simply walk into the vault and take whatever they want. They need specific keys to open specific deposit boxes. These keys are Permissions, and the set of keys a customer holds is their Capability.
Capabilities are defined in JSON or TOML files located in src-tauri/capabilities/. When you create a new app, you likely have a default.json file.
Anatomy of a Capability File
Section titled “Anatomy of a Capability File”A capability file maps a set of permissions to specific windows or webviews. Here is an example structure:
{ "identifier": "default-capability", "description": "Capability for the main window", "windows": ["main"], "permissions": [ "core:default", "fs:read-text-file", "shell:open" ]}- identifier: A unique name for this capability set.
- windows: The list of window labels (defined in
tauri.conf.json) that grant these permissions. If a window isn’t listed here, it cannot use these commands. - permissions: The specific API commands allowed.
core:defaultusually covers basic app functionality.
Permissions vs. Scopes
Section titled “Permissions vs. Scopes”Granting permission is often not enough. For example, granting fs:read-text-file technically allows the frontend to read any file the user has access to. This is dangerous. To mitigate this, we use Scopes.
A Scope acts as a filter for permissions. It defines where or how a permission can be used. You can define scopes directly inside the capability file.
{ "identifier": "fs-scope-example", "windows": ["main"], "permissions": [ { "identifier": "fs:read-text-file", "allow": [{ "path": "$HOME/Documents/*.txt" }], "deny": [{ "path": "$HOME/Documents/secret.txt" }] } ]}In the example above, the frontend can read any .txt file in the user’s Documents folder, except for secret.txt. If the frontend tries to read /etc/passwd or secret.txt, the Rust backend will reject the request immediately.
Managing Plugin Permissions
Section titled “Managing Plugin Permissions”In Tauri v2, most functionality (File System, HTTP, Dialogs) has been moved to plugins. When you install a plugin, it comes with a set of default permissions. You must explicitly add these to your capability file to use them.
For example, after adding the HTTP plugin, you must add http:default (for broad access) or granular permissions like http:request to your capabilities permissions array. If you forget this step, your API calls in the frontend will fail silently or throw an ‘access denied’ error.