ANN: rook, a kdbx secret service

I wrote another thing.

Rook #

You might be interested in Rook if you run headless systems, are trying to keep memory use down, prefer to not have a lot of background GUI apps running, or are interested in using a Keepass kdbx as a secret-service backend.


Rook is a secret service tool; these are password managers for your operating system, and they allow programs to request credentials to do things for you. On my desktop, I have programs running that periodically sync my email from my email server, sync my calendar and contacts with another server, and every time I send an email, the SMTP connection is authenticated so that program needs a password, too. In days of yore, we might have put the passwords directly in the config files for these programs; now, we use secret services for this.

Gnome and KDE come with their own secret services for their frameworks. There are others like pass/gopass that do clever things like store encrypted secrets in a github repo, mainly for sharing secrets within organizations. Some applications, like Firefox and Chrome, build their own secret-services right into the app. There are dozens of these things floating around, so why do we need another one? While I’m tempted to reference xkcd #927 A comic about standards in this case, I’m going the other direction: I’m trying to avoid having multiple places where my passwords are scattered about, and to do this, I want a tool that uses Keepass v2 kdbxes as the database.

Most secret services have their own bespoke password database. This means that if you use one of these things, but also keep your passwords somewhere else (like KeepassXC) so that you can access them from handy places like your mobile phone, then you have to manually keep the passwords in sync. It’s a sort of vendor lock-in, and I dislike vendor lock-in.

Keepass is also bespoke, but Keepass is everywhere. There are not only clients for different devices, there are often several different clients for any given device. The database format is well-documented, and so many people have written tools that work with Keepass DBs. This is freedom, in that a dozen different clients could go obsolete – including the original company that invented the format – and people would still be able to find and use clients with their databases. A Keepass DB has a lot of nice features, including entry attributes, OTP, file attachments, multiple password and per-entry locking, trash cans and modification metadata, and different entry types… and it’s a single file, making it easy to keep copies of, and back up. It has more features than I can easily list, and it’s a really nice way to store secrets.

So, back to secret services. KeepassXC, an absolutely fantastic Qt client, even provides a secret-service function over DBus (a common communication bus for secret services and a mostly de-facto standard shared between Gnome and KDE); KeepassXC can also be an ssh-agent and gpg-agent, meeting any and all of your credentialing needs… except that it’s a GUI program. There’s no headless version of it, and while the package does come with a keepassxc-cli, it’s not a service – it requires the user to enter a password every time it is called. There are a couple of tools that are pretty close: passhole and kpmenu, but both have a relatively large amount of code that needs to be audited, due to dependencies: passhole is Python and I don’t even want to take on auditing the list of packages that get imported, much less the code (and, I’m sorry, but the project name does not inspire confidence); and kpmenu recently went through some refactoring that changed – and exploded – the dependency list to a challenging audit task. kpmenu also has a more paranoid (in a good way!) security model that makes it unsuitable for use as a background secret service for scripting; it’s ironic that the security model is stronger than rook, while the large number of dependencies makes it weaker.

And so: Rook. Rook doesn’t do too much; it has a handful of things it can do – run as a service, search for entries, match autotype entries, generate OTP, show data from entries – but what it tries hardest to do is stay small and to minimize dependencies. If you know Go, and you trust the core Go team to not be trying to steal your secrets, you should be able to easily audit every line of code Rook uses. The project itself has ca. 1,100 LOC, and it pulls in three external, non-Google, dependencies: one, Claptrap – a flags library I wrote, and which itself has no depndencies – and two related to parsing the Keepass DBs and both written by @tobischo on Github. The kdbx library is around 2k LOC, and it uses a small crypto library @tobischo also wrote that’s under 300 LOC. Claptrap is ~1,300 LOC, is a single file, and imports no network code. All of this is imminently auditable, and is even not an insurmountable task even if you don’t know Go. This can not be said of many of the other options.

Read more about Rook here. I talk about the security model, provide examples and pre-built binaries, and repeat much of what I’ve said here. Rook is fit-for-purpose; while I’m still tuning some of the helper scripts, the binary client/server is stable. It’s providing secrets to my half-dozen credentialed cron jobs, and is providing autotype service via scripts provided in the repo. As always, let me know what you think!