How it is built
Data and encryption
What Nuvo stores, where, how it is encrypted, how keys are derived, and how migrations are backed up.
What is stored
The library lives in one SQLCipher database, library.db. It holds:
- tracks and the snapshots of their metadata,
- liked tracks, saved albums and artists,
- playlists and their items, and playlist covers,
- play events and now-playing state,
- the lyrics cache and your own lyrics,
- recommendation data: taste model, suppressions, candidate graph, starters,
- imports and their rows,
- local music folders and files, and the save-as-files queue,
- settings and appearance,
- recognition history and the Last.fm queue.
Keys
A keyring item (service nuvo-core, item master-key) holds the master key, which is 32 random bytes. The master key and the 24-word recovery phrase (BIP39) convert in both directions: the phrase is the master key written as words. Two sub-keys derive from the master key with HKDF-SHA256: the database key (info string nuvo/db/v1) and the audio key (info string nuvo/audio/v1).
- On first run the daemon creates a 32-byte master key and stores it in the Secret Service keyring.
- Sub-keys come from the master key with HKDF-SHA256. The
infostrings carry a version, so a new scheme can sit beside old data. - The database key opens SQLCipher in raw key mode. The audio key seals cached audio.
- The recovery phrase is the master key written as 24 BIP39 words. Nuvo shows it once, until you confirm you wrote it down. After that the route returns
404.
Locked state
If library.db exists and the keyring has no key, or a key that does not open it, the daemon starts locked. It never replaces an existing database. Enter your 24 words and it unlocks. A phrase that does not open the library is refused.
Migrations and backups
The database has a schema version. Before a migration on an existing library, the daemon copies library.db to backups/library-<time>-v<version>.db and keeps the three newest. A database written by a newer Nuvo is refused instead of changed.
Search
Filters fold text to lowercase in every script, using a function inside the database. Sort and search keys for local files are stored, so listing 20,000 files does not recompute them.
What is not encrypted
The window’s own browser storage (Electron profile) holds interface state. The database holds your library and settings. Local music files stay as they are.
Backup
See the backup guide.