Improve secret handling on Linux

Presently, key attributes relating to encryption and authentication are stored as plain text in Joplin's database. For example:

$ sqlite3 ~/.config/joplin-desktop/database.sqlite "SELECT value FROM settings WHERE key = 'encryption.masterPassword';"

Other fields relating to sync credentials are also exposed. The only pre-existing discussion I have found on this subject was issue #7578 on GitHub a year ago[0].

While it is true that there may not be a one-size-fits-all solution, the majority of the most common distributions can be covered via D-Bus messaging. I'm not advocating for performing dbus-send(1) calls (though always available), but the use of a D-Bus Secret Service client library like libsecret[1]. Both GNOME and KDE use this library to communicate with their secure keyrings over D-Bus without burdening developers with needing to create platform specific interfaces. As long as the GNOME Keyring or KWallet daemons are running and listening, they'll pick up messages sent across the D-Bus wire.

Though libsecret is a C library, as a GObject based library it is easy to generate bindings for other languages. There's a TypeScript generator project[2] that produces these, and the secret-1 module is available here[3]. Some further JavaScript quick examples can be found in the libsecret documentation[4]. The GJS docs[5] also detail the API as a source of truth.

Hopefully this can be implemented as the default process to attempt, keeping plain text storage in reserve as a code path to fall back on. Parity with the other operating system platforms would be greatly appreciated!

As I'm not allowed to make posts with links yet:
[0] https:// github .com/laurent22/joplin/issues/7578
[1] https:// gnome.pages.gitlab.gnome .org/libsecret/
[2] https:// github .com/gjsify
[3] https:// github .com/gjsify/types/tree/main/secret-1
[4] https:// gnome.pages.gitlab.gnome .org/libsecret/libsecret-js-examples.html
[5] https:// gjs-docs.gnome .org/secret1~1/

1 Like

As a minimum, shouldn't a (good) hash of the key be stored instead? Is there a reason to not store the master key in an external password manager and have only the hash stored in the DB?