Process And Trust Boundaries
Tauri splits the app into a native core process and one or more webview processes. The important design question is not “Can the frontend call Rust?” It is “Which native authority is the webview allowed to ask for?”
Boundary Model
User action
-> Webview UI
-> typed frontend IPC wrapper
-> Tauri IPC
-> Rust command or plugin
-> OS, filesystem, network, sidecar, window, or app state
The webview is web code. Treat its inputs like browser inputs. The Rust core and plugins are trusted native code with OS access.
Authority Placement
| Concern | Put it in | Why |
|---|---|---|
| Secrets | Rust core, OS keychain, Stronghold, or approved secure storage | Renderer code is easier to inspect and manipulate |
| File writes | Rust commands or scoped filesystem plugin calls | Backend can validate paths and business rules |
| Shell/process execution | Rust command or narrowly scoped shell plugin | Free-form process args are high risk |
| App state | Rust State<T> or an explicit data layer | Keeps trusted state away from webview globals |
| UI state | Frontend framework state | Fast, local, and not authoritative |
| Native APIs | Official plugin or custom plugin | Permissions and platform implementations stay packaged together |
Capability Attachment
Capabilities attach permissions to windows and webviews. A main window, logs window, and system monitor window should not automatically share the same native permissions.
Review every capability with this question:
If this window were compromised, what native authority would it gain?
If the answer is too broad, split the capability or move the operation behind a stricter command.
Remote Content Rule
Do not grant Tauri API access to remote content unless you have a written threat model. The official docs warn that remote API access has platform caveats, and Linux/Android cannot distinguish iframe requests from top-level window requests for that feature.
Case Study: Jan
Jan’s local repo shows a production-style AI app with multiple capabilities, CSP entries for loopback and asset protocols, broad HTTP allowances, updater configuration, desktop sidecars, and mobile-specific override configs. Use it to understand what a complex app may need. Do not copy its broad scopes into a starter.