Tauri v2: no built-in integrity check for app data restored from user backups
0 reputation · 27 Nov 2023, 07:40 UTC
0 reputation · 27 Nov 2023, 07:40 UTC
I'm designing the restore flow for a Tauri v2 desktop app. Users can export their data (SQLite file plus some JSON state from the store plugin) to a backup folder, and later point the app at that folder to restore. The open question is how the app should decide whether the restored data is trustworthy and uncorrupted before replacing the current state.
The framework's existing verification mechanisms don't seem to cover this case. The updater plugin verifies update artifacts against an embedded Ed25519 public key, but as I understand it that protection applies only to update packages, not to arbitrary files the app reads at runtime. The fs plugin's scope system restricts which paths the frontend may read, but says nothing about whether the contents are valid. Persisted data surviving an update is a matter of OS path conventions, and schema validation is left to the app.
So the unresolved decision is what the canonical pattern is for verifying restored data in Tauri v2: checksums, signing the backup with an app-held key, or schema validation alone, and whether any of this belongs in Rust commands rather than the frontend, given that fs scopes do not constrain the backend.
Is there a documented or community-accepted approach for integrity verification of restored backups in Tauri v2? Should verification live in a Rust command to avoid trusting frontend-read bytes? And is there any updater-style signing primitive exposed for reuse on arbitrary data files?
No. Tauri v2 does not ship a backup/restore integrity subsystem, and there is no single documented or community-accepted canonical pattern that replaces one. The updater's signature verification applies to update artifacts, not arbitrary files your app restores. Persistence plugins such as fs, store, and sql handle storage and access, not authenticity. You must implement verification in your app.
Confirmed by design boundaries: Tauri core handles windowing, IPC, permissions, and signed updater artifacts. It does not automatically authenticate or validate restored backups. The fs plugin's scope system restricts which paths the frontend may read; it says nothing about whether file contents are valid.
Likely explanation: "no built-in integrity check" means the app owns the restore trust decision. That usually means a manifest with format version and digests, plus optional keyed authentication if tampering is in scope.
Version note: plugin names, permissions, and APIs can change across Tauri v2 minor releases and plugin versions. Confirm against the exact versions in your project.
Yes, for any threat model where the frontend or restored bytes are not fully trusted. fs scopes constrain the frontend plugin; they do not constrain Rust backend file access. If the frontend reads bytes and computes a hash, a compromised webview can lie about both. A Rust command should resolve and canonicalize the backup path, enforce its own allowlist, read the files, verify the manifest, and only then import. Do not accept a frontend-supplied "verified: true" or digest as proof.
PRAGMA integrity_check; after digest verification. It checks structural consistency, not authenticity.The updater plugin's Ed25519 verification is tied to update packages. I am not aware of a documented public API that exposes it as a general "verify arbitrary file" primitive. For backup signing, use a Rust crypto crate directly, such as an Ed25519 or HMAC implementation, and manage keys yourself. Confirm against your exact Tauri and plugin versions.
Can an attacker modify the backup folder, or is the only realistic risk accidental corruption? If accidental only, checksums plus schema validation are proportionate. If tampering is in scope, you need a keyed MAC or signature with a key outside the backup, and verification must happen in Rust.
Cargo.toml, package.json, cargo tree, and npm ls for Tauri v2 and plugin versions.Use comments to ask for clarification. Post a solution as an answer.
31,275 reputation · 27 Nov 2023, 08:53 UTC
The restore flow cannot verify integrity unless the export flow emits a manifest containing digests (or signatures) of every file in the backup bundle. A practical pattern is to write a manifest.json alongside the SQLite and JSON files at export time:
{
"formatVersion": 1,
"createdAt": "2026-10-11T05:20:36Z",
"files": [
{ "path": "app.db", "sha256": "...", "size": 123456 },
{ "path": "store.json", "sha256": "...", "size": 789 }
]
}The Rust restore command then reads this manifest, re-hashes each file, and compares before any import. For SQLite, also run PRAGMA integrity_check and PRAGMA quick_check on the restored file before attaching it. If you later add app-signed manifests, the export command signs the manifest with an embedded Ed25519 private key; the restore command verifies with the corresponding public key. Keep the signing key separate from the updater key to avoid cross-purpose exposure.
Version note: Tauri v2 plugin APIs (fs, store, sql) are stable but minor releases may adjust permission schemas. Pin plugin versions in Cargo.toml and test the restore command against a matrix of exported bundle versions.