Why isEncryptionAvailable() Wasn't Enough to Ship Our Password Vault on Linux
Our browser had a password vault that only worked on Windows. The check was blunt and honest: available (): boolean { return process . platform === ' win32 ' && safeStorage . isEncryptionAvailable (); } When we decided to enable it on Linux and macOS, the obvious change looked like a one-liner: drop the platform check and trust Electron's safeStorage.isEncryptionAvailable() . That one-liner would…
The original password vault application only functioned on Windows. The code used a simple check to determine if encryption was available on the system using the `process.platform` method and the `safeStorage.isEncryptionAvailable()` function. When expanding support to Linux and macOS, the team assumed a simple one-liner would suffice by dropping the platform check and relying on `safeStorage.isEncryptionAvailable()`.
However, this approach overlooked two crucial issues. First, on Linux, the `encryptionAvailable()` function indicates whether the application is ready for encryption, but it does not reveal the type of encryption backend in use. On minimal or headless Linux systems without a keyring, the `encryptString()` function still returns encrypted data, but the encryption key is not secret.
This creates a false sense of security, as the encrypted data on disk can be accessed by anyone who gains unauthorized access. Second, calling `getSelectedStorageBackend()` before the Electron `ready` event is triggered could lead to inconsistent results. If the vault availability check occurs during startup, such as when prompting the user to show the password import button, the function may return "unknown," which is treated as "not allowed."
This could result in the vault being unavailable during startup, even if encryption is technically possible. The team implemented a solution consisting of three main components. First, they created a function to determine if the OS encryption backend is acceptable. This function denies access by default and only allows Linux systems using GNOME Keyring (libsecret) or KDE's KWallet, rejecting other backends like `basic_text` or "unknown."
The rationale is that accepting unknown or insecure backends would compromise the security of the password vault. The team also chose to throw exceptions when encountering issues like a locked keyring or D-Bus errors, ensuring that the application does not proceed with potentially insecure encryption. Second, the vault's own availability check was modified to incorporate the earlier gate, verify that the application is ready, and confirm that the selected backend is acceptable using the `osEncryptionBackendAllowed()` function.
If any part of this process fails, the function returns false. Finally, the error message displayed to users was updated from "Windows password encryption is unavailable" to "Operating system password encryption is unavailable." This change ensures consistency across platforms and prevents confusion for users on non-Windows systems.
To validate the changes, the team created a test suite that simulated various scenarios on Windows, macOS, and Linux. The tests confirmed that the new implementation correctly identifies unavailable vaults on Linux, handles exceptions gracefully, and displays appropriate error messages to users.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.