DEV Community

Cover image for Tauri Sandbox Permissions — Why Your Command Silently Does Nothing
hiyoyo
hiyoyo

Posted on

Tauri Sandbox Permissions — Why Your Command Silently Does Nothing

All tests run on an 8-year-old MacBook Air. All results from shipping 7 Mac apps as a solo developer. No sponsored opinion.

The most common Tauri v2 frustration: you write a command, invoke it from the frontend, and nothing happens. No error. No crash. Just silence. It's almost always permissions.


How Tauri v2 permissions work

Tauri v2 introduced a capability system. Every plugin action — reading files, executing shell commands, sending notifications — requires an explicit permission declaration in your config. Without the permission, the plugin call fails silently on the frontend. The Rust code never runs.

// src-tauri/capabilities/main.json
{
  "identifier": "main-capability",
  "description": "Permissions for main window",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "fs:read-all",
    "fs:write-all",
    "shell:allow-execute",
    "opener:allow-open",
    "global-shortcut:allow-register",
    "global-shortcut:allow-unregister"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Note: As of Tauri v2.1, shell:allow-open is deprecated. Use tauri-plugin-opener and opener:allow-open instead.


The debugging flow

When a command does nothing:

  1. Open DevTools (Cmd+Option+I in dev mode) — check the console for a rejected Promise or permission error
  2. Check your terminal output — the Rust side logs errors directly in the tauri dev terminal; look for lines like [tauri] permission denied or not allowed
  3. Enable verbose logging — set RUST_LOG=tauri=debug before running tauri dev for more detailed backend output
  4. Check your capabilities file — missing or misspelled permission identifiers are the #1 cause

Permission errors in the console typically look like a rejected Promise with a message such as plugin:shell|execute not allowed. The capabilities file is always the first thing to check.


Common permissions you'll need

"permissions": [
  "core:default",
  "fs:read-all",              // read any file
  "fs:write-all",             // write any file
  {
    "identifier": "shell:allow-execute",
    "allow": [{ "name": "my-cmd", "cmd": "adb", "args": true }]
  },
  "opener:allow-open",        // open URLs / files (replaces shell:allow-open)
  "path:allow-app-data-dir",  // access app data directory
  "notification:default",     // send notifications
  "global-shortcut:allow-register",
  "clipboard-manager:allow-read-text",
  "clipboard-manager:allow-write-text"
]
Enter fullscreen mode Exit fullscreen mode

shell:allow-execute now requires an explicit allow scope — wildcards are blocked by default for security.


The scope system

For filesystem access, Tauri supports scoped permissions — allow access only to specific directories:

{
  "identifier": "fs:allow-app-data-read",
  "allow": [{ "path": "$APPDATA/**" }]
}
Enter fullscreen mode Exit fullscreen mode

Use scoped permissions in production. fs:read-all is convenient for development, but shipping with it exposes more than needed.


The verdict

Tauri v2's permission system is correct. The sandboxing is good for security. The silent failure mode is painful until you know the pattern. When something stops working after a plugin update, always check whether the permission identifiers have changed — opener replacing shell:allow-open is a real example of this happening.

Check the capabilities file first. Always.


If this was useful, a ❤️ helps more than you'd think — thanks!

Hiyoko PDF Vault → https://hiyokomtp.lemonsqueezy.com/checkout/buy/a1b4d7d8-a4b8-433c-9d36-abdc0f3937c3

X → @hiyoyok

Top comments (1)

Collapse
 
hiyoyok profile image
hiyoyo

TL;DR: Silent failures in Tauri v2 are almost always a missing permission in your capabilities file. Check DevTools console first — the rejected Promise message tells you exactly which permission you need.