Problem
When LIBSQL_ENCRYPTION_KEY is set, the local-only database (todos.enc.db) is correctly encrypted, but the Turso embedded replica (todos-turso.enc.db) is not encrypted — it's readable by plain sqlite3.
Debug logging confirms the encryption_config reaches open_replica() with encryption=true, cipher and key intact. The config is passed to Builder<RemoteReplica>.encryption_config(...). Yet the resulting file is unencrypted.
Root cause (upstream libsql bug)
Due to upstream libsql bugs
In libsql 0.9.29, Builder<RemoteReplica>::build() has a #[cfg(feature = "sync")] block that probes the server for V2 sync protocol support. Turso always responds successfully, so the builder internally switches to Builder<SyncedDatabase>. During this switch, encryption_config (local file encryption) is silently dropped — only remote_encryption (remote server communication) is forwarded.
The SyncedDatabase / DbType::Offline path has no support for local encryption at all:
- No
encryption_config field on the struct or enum variant
connect() never calls set_encryption_cipher / set_encryption_key
bootstrap_db() downloads the raw db file without applying encryption
The V1 replication path (DbType::Sync) handles encryption correctly, but Turso only supports V2, making V1 unusable.
Upstream issue
To be filed at tursodatabase/libsql — draft prepared.
Current state
examples/todo-list/src-tauri/Cargo.toml was updated to include features = ["replication", "encryption"] (previously missing encryption, which meant the encryption code in open_replica was compiled out — a separate bug now fixed)
- Even with that fix, encryption still doesn't work due to the upstream bug described above
Workarounds (for users)
- Pure remote mode — connect to Turso without a local replica file (no local data stored)
- Local-only databases — encryption works correctly for non-Turso databases
- Accept unencrypted replica — if the data on Turso is already access-controlled
Resolution
Blocked on upstream fix in tursodatabase/libsql. Once fixed, no plugin changes should be needed — the existing open_replica code already passes encryption_config to the builder correctly.
Problem
When
LIBSQL_ENCRYPTION_KEYis set, the local-only database (todos.enc.db) is correctly encrypted, but the Turso embedded replica (todos-turso.enc.db) is not encrypted — it's readable by plainsqlite3.Debug logging confirms the
encryption_configreachesopen_replica()withencryption=true, cipher and key intact. The config is passed toBuilder<RemoteReplica>.encryption_config(...). Yet the resulting file is unencrypted.Root cause (upstream libsql bug)
Due to upstream libsql bugs
In libsql 0.9.29,
Builder<RemoteReplica>::build()has a#[cfg(feature = "sync")]block that probes the server for V2 sync protocol support. Turso always responds successfully, so the builder internally switches toBuilder<SyncedDatabase>. During this switch,encryption_config(local file encryption) is silently dropped — onlyremote_encryption(remote server communication) is forwarded.The
SyncedDatabase/DbType::Offlinepath has no support for local encryption at all:encryption_configfield on the struct or enum variantconnect()never callsset_encryption_cipher/set_encryption_keybootstrap_db()downloads the raw db file without applying encryptionThe V1 replication path (
DbType::Sync) handles encryption correctly, but Turso only supports V2, making V1 unusable.Upstream issue
To be filed at tursodatabase/libsql — draft prepared.
Current state
examples/todo-list/src-tauri/Cargo.tomlwas updated to includefeatures = ["replication", "encryption"](previously missingencryption, which meant the encryption code inopen_replicawas compiled out — a separate bug now fixed)Workarounds (for users)
Resolution
Blocked on upstream fix in tursodatabase/libsql. Once fixed, no plugin changes should be needed — the existing
open_replicacode already passesencryption_configto the builder correctly.