Kpmenu is a tool written in Go used to view a KeePass database via a dmenu, or rofi, menu.
At some point, I realized my needs conflicted with a core principle of kpmenu. I wanted a secret service agent backed by a KeePass database. kpmenu is a security-first tool for allowing users to manually request access to secrets. In the interest of safety, kpmenu is designed to require the user to confirm access to secrets; indeed, this is about as good as secure as you can get. However, it prevents the tool for being used in any way for automation -- such as accessing secrets for background processes such as vdirsyncer
, restic
backups, and any other number of automated tools.
Since these objectives are not compatible, I wrote rook. rook's design is less secure than kpmenu's: it doesn't require the user to confirm every access. There are instructions in rook's README for maximizing security, such as disallowing access to secrets from other user sessions, or even by root, but fundamentally, it can't be as secure as kpmenu without the user confirmation for every access. On the other hand, rook can be used as a secret service, backed by a KeePass DB.
Rook addresses my needs; consequently, I'm archiving this. fork. Note that this last commit includes work that relaxes kpmenu's strict security model; it was a work in progress, and HEAD may not work. If you're looking for a secret service, backed by a KeePass DB rather than some besoke DB, then rook is probably a better solution for you. I would not use this fork.
This is a hard fork of AlessioDP's, with some significant changes. There are threat model differences, so please read at least the Why? section; you may prefer the original.
- Supports KDBX v3.1 and v4.0 (based on gokeepasslib)
- Pretty fast database decode thanks to Go
- Interfaced with dmenu, rofi, wofi and any custom executable
- Customize dmenu/rofi with additional command arguments
- Kpmenu can be started as a daemon, so you don't need to re-insert credentials
- By default the first instance of kpmenu will enter in daemon mode (cache option) for 60 seconds
- You can start a permanent daemon with
--daemon
option (it won't ask open the database) - Even if the cache times out, the daemon won't be killed
- Automatically put selected value into the clipboard (for a custom time)
- xsel and wl-clipboard supported
- A custom executable can be defined for every action (copy/paste/clean clipboard)
- By default it will use xsel, you can override it via config or
--clipboardTool
option - Hidden password typing
- OTP support
- If a field have an otp key, you can generate the number
- New OTP and old TOTP methods are supported
The most impactful difference with upstream is the threat model. AlessioDP's project has a distinct threat model and protections; this fork deviates from some of those core principles.
The first difference is a result of some reluctance of upstream to include PRs necessary to enable autotype, via quasiauto. I've been having to maintain a separate fork for those changes anyway; this fork includes them.
The second change replaces viper with claptrap. Viper is a large library with many dependencies, which increases the surface area for security issues. By using Claptrap, not only are there fewer dependencies (and far less code) to audit, but the resulting binary is much smaller as well:
Number of external library dependencies | Executable size | |
---|---|---|
kpmenu + viper | 22 | 7,581k |
kpmenu + claptrap | 9 | 5,393k |
That's fewer than half the libraries pulled in, and a 30% reduction in binary size.
The third change is the most significant vis-a-vis threat model, and ultimately why this must be a hard fork: I plan to add support that will let kpmenu be used as a replacement for secret-tool / pass. This requires a substantial change to the client/server model, and justifies a hard fork. See the Security section for more details.
go
(compile only)
dmenu
,rofi
andwofi
(you can define a custom executable)xsel
andwl-clipboard
(you can define a custom executable)
I created kpmenu to make an easy and fast way to access into my KeePass database. These are some commands that you can do:
# Open a database
kpmenu -d path/to/database.kdbx
# Open a database with a key
kpmenu -d path/to/database.kdbx -k path/to/database.key
# Open a database (credentials taken from config) with a password and rofi
kpmenu -p "mypassword" -m rofi
You can directly install the package kpmenu.
If you do not set $GOPATH
, go sources will be downloaded into $HOME/go
.
# Clone repository
git clone https://git.sr.ht/~ser/kpmenu
cd kpmenu
# Build
make build
# Install
sudo make install
You can set options via config
or cli arguments.
Kpmenu will check for $HOME/.config/kpmenu/config
, you can copy the default one with cp ./resources/config.default $HOME/.config/kpmenu/config
.
The original kpmenu has a server process that opens a socket and listens for commands. There is no security on the socket; any user on the machine can send the server messages. kpmenu avoids being attacked on this channel by never passing secrets back from the server: a client can request a server to do something, but it's sending messages to a black hole. The attacker can only get information out of the kpmenu server if they can also talk to the X server, which means kpmenu's threat model only covers attackers not on the system, or not able to access the X session. If the attacker can access the X session, they can access the clipboard and therefore the secrets.
This fork is based on the recognition that if the attacker has access to the machine as the user, they have full control of the process space; they can access any processes' memory, trace processes, and introspect secrets in any number of ways, including inspecting the X clipboard, through which upstream kpmenu transmits secrets.
Therefore, this fork eliminates the false security of the server never sharing passing secrets over the (insecure) socket, and implements pipes secured with Unix permissions. A kpmenu client, running as the user, can request a specific credential from the server. For the paranoid, the server process can be configured to always require confirmation from the desktop.
This change allows using kpmenu as a replacement for secret-tool
/ pass
/ gopass
, which means it can be used to credential synchronization tools such as mbsync
, offlineimap
,
vdirsyncer
and other jobs.
Options taken with kpmenu --help
Usage of kpmenu:
--argsEntry string Additional arguments for dmenu at entry selection, separated by a space
--argsField string Additional arguments for dmenu at field selection, separated by a space
--argsMenu string Additional arguments for dmenu at menu selection, separated by a space
--argsPassword string Additional arguments for dmenu at password selection, separated by a space
--cacheOneTime Cache the database only the first time
--cacheTimeout int Timeout of cache in seconds (default 60)
-c, --clipboardTime int Timeout of clipboard in seconds (0 = no timeout) (default 15)
--clipboardTool string Choose which clipboard tool to use (default "xsel")
--customClipboardCopy string Custom executable for clipboard copy
--customClipboardPaste string Custom executable for clipboard paste
--customPromptEntries string Custom executable for prompt entries
--customPromptFields string Custom executable for prompt fields
--customPromptMenu string Custom executable for prompt menu
--customPromptPassword string Custom executable for prompt password
--daemon Start kpmenu directly as daemon
-d, --database string Path to the KeePass database
--fieldOrder string String order of fields to show on field selection (default "Password UserName URL")
--fillBlacklist string String of blacklisted fields that won't be shown
--fillOtherFields Enable fill of remaining fields (default true)
-k, --keyfile string Path to the database keyfile
-m, --menu string Choose which menu to use (default "dmenu")
-n, --nocache Disable caching of database
--nootp Disable OTP handling
-p, --password string Password of the database
--passwordBackground string Color of dmenu background and text for password selection, used to hide password typing (default "black")
--textEntry string Label for entry selection (default "Entry")
--textField string Label for field selection (default "Field")
--textMenu string Label for menu selection (default "Select")
--textPassword string Label for password selection (default "Password")
-v, --version Show kpmenu version
See the LICENSE file.