Skip to main content
The first security gate is Tauri’s capability system: a capability file grants a window the right to invoke specific plugin commands. This page lists the exact permission identifiers and how to wire them. For the model behind it, see Security overview.

Permission sets

The plugin ships two named sets:
The default set is read-only: open/close a connection and run select. Writes (execute) and the raw-SQL umbrella are deliberately excluded, because the webview is untrusted and DuckDB SQL can reach the filesystem and network. Grant them explicitly only where needed.

Every command permission

Each command has an autogenerated allow-<command> and deny-<command> permission. Note the identifiers are hyphenated — the underscore in a command name like load_extension becomes allow-load-extension.
allow-query-arrow corresponds to the query_arrow command, which only exists with the arrow feature. Granting it without the feature compiled in is harmless — the command returns a backend error.

Writing a capability file

Capabilities live in src-tauri/capabilities/*.json and are compiled in by tauri-build. A permission entry is either a bare identifier string or an object that also attaches a scope:
This is the example app’s capability. It grants the write and introspection commands and scopes load to duckdb::memory: and import/export to the data/ directory.
The scope object ("allow" / "deny" arrays of { connection, path } entries) is the second gate. A bare identifier string grants the command with no scope narrowing, leaving the value constraints to the init-time Policy. See Scope & Policy for the entry semantics.

How the list is generated

The command list is declared once in the crate’s build.rs and handed to the Tauri plugin permission tooling, which auto-generates the allow-* / deny-* permissions and the reference:
The same build.rs registers the scope Entry schema, so capability files get autocompletion and validation for the connection / path fields.

See also