1- # kpcache
1+ # kpxc
22
3- Tiny shell wrapper that caches your ** KeePassXC master password in tmpfs **
4- so that ` keepassxc-cli ` lookups don't prompt for it on every call .
3+ Cached wrapper around ` keepassxc-cli ` : unlock once per session, then run any
4+ KeePassXC subcommand without reprompting for the master password .
55
66For headless / WSL / server setups where you want to use KeePassXC entries
7- from CLI tools (himalaya, mbsync, mutt, isync, restic, …) without typing
8- the master password each time and without running a long-lived daemon.
7+ from CLI tools (himalaya, mbsync, mutt, isync, restic) without typing the
8+ master password each time and without running a long-lived daemon.
9+
10+ > Unofficial third-party wrapper. Not affiliated with the KeePassXC project.
911
1012## Quickstart
1113
1214``` sh
13- git clone https://github.com/magnattic/kpcache ~ /.local/share/kpcache
14- ln -s ~ /.local/share/kpcache /bin/kp{unlock,get,lock} ~ /.local/bin/
15+ git clone https://github.com/magnattic/kpxc ~ /.local/share/kpxc
16+ ln -s ~ /.local/share/kpxc /bin/kp{unlock,get,lock,xc } ~ /.local/bin/
1517
1618export KP_DB=~ /Passwords.kdbx
1719kpunlock # type master password once
18- kpget " Email/personal" # → password, no prompt
20+ kpget " Email/personal" # password, no prompt
1921kpget " Email/personal" -a User # any keepassxc-cli show option
22+ kpxc ls /Email # any keepassxc-cli subcommand
2023kplock # clear the cache
2124```
2225
2326## Why
2427
25- ` keepassxc-cli ` is fast - it's the official C++ binary that uses native
26- Argon2/AES ( via Botan) - but it prompts for the master password on every
28+ ` keepassxc-cli ` is fast ( it's the official C++ binary using native
29+ Argon2/AES via Botan), but it prompts for the master password on every
2730invocation. That's unworkable when an MTA polls IMAP every 60 seconds or
2831when scripts make many lookups.
2932
@@ -36,12 +39,12 @@ Existing solutions don't fit headless setups well:
3639 unlocked, with the browser-extension protocol. Doesn't work headless.
3740- ** keepasxcli-wrapper** - unmaintained since 2021.
3841
39- ` kpcache ` is ~ 80 lines of bash that:
42+ ` kpxc ` is ~ 120 lines of bash that:
4043
41- 1 . Prompts for the master password once.
42- 2 . Stores it in ` /dev/shm/<uid>-kpcache ` with mode ` 0600 ` .
43- 3 . Each subsequent ` kpget ` reads from the cache and shells out to
44- ` keepassxc-cli show ` - fast because it's the official binary.
44+ 1 . Prompts for the master password once ( ` kpunlock ` ) .
45+ 2 . Stores it in ` /dev/shm/<uid>-kpxc ` with mode ` 0600 ` .
46+ 3 . Each subsequent ` kpget ` / ` kpxc ` reads from the cache and shells out
47+ to ` keepassxc-cli ` . Fast because it's the official binary.
4548
4649The master password lives in RAM only (tmpfs is in-memory). It's gone
4750after reboot or ` kplock ` .
@@ -53,7 +56,7 @@ after reboot or `kplock`.
5356You need ` keepassxc-cli ` in ` $PATH ` .
5457
5558``` sh
56- # Debian/Ubuntu (newer releases also have keepassxc-minimal - no GUI deps)
59+ # Debian/Ubuntu (newer releases also have keepassxc-minimal, no GUI deps)
5760sudo apt install keepassxc
5861
5962# Arch
@@ -62,52 +65,67 @@ sudo pacman -S keepassxc
6265# Fedora
6366sudo dnf install keepassxc
6467
65- # macOS - brew installs CLI inside the .app bundle, symlink it into PATH:
68+ # macOS: brew installs the CLI inside the .app bundle, symlink it into PATH:
6669brew install --cask keepassxc
6770sudo ln -s /Applications/KeePassXC.app/Contents/MacOS/keepassxc-cli \
6871 /usr/local/bin/keepassxc-cli
6972```
7073
71- ### kpcache itself
74+ ### kpxc itself
7275
7376``` sh
74- git clone https://github.com/magnattic/kpcache ~ /.local/share/kpcache
75- ln -s ~ /.local/share/kpcache /bin/kp{unlock,get,lock} ~ /.local/bin/
77+ git clone https://github.com/magnattic/kpxc ~ /.local/share/kpxc
78+ ln -s ~ /.local/share/kpxc /bin/kp{unlock,get,lock,xc } ~ /.local/bin/
7679```
7780
7881Make sure ` ~/.local/bin ` is in your ` $PATH ` .
7982
8083## Configure
8184
8285Set the database path either as an env var or in
83- ` ~/.config/kpcache /config ` :
86+ ` ~/.config/kpxc /config ` :
8487
8588``` sh
86- mkdir -p ~ /.config/kpcache
87- cat > ~ /.config/kpcache /config << 'EOF '
88- KPCACHE_DB ="/path/to/your.kdbx"
89- # KPCACHE_KEYFILE ="/path/to/keyfile" # if your DB uses one
90- # KPCACHE_TTL =28800 # optional: expire cache after 8h
89+ mkdir -p ~ /.config/kpxc
90+ cat > ~ /.config/kpxc /config << 'EOF '
91+ KPXC_DB ="/path/to/your.kdbx"
92+ # KPXC_KEYFILE ="/path/to/keyfile" # if your DB uses one
93+ # KPXC_TTL =28800 # optional: expire cache after 8h
9194EOF
9295```
9396
9497## Use
9598
99+ Two commands cover almost everything:
100+
96101``` sh
97102kpunlock # prompts for master password, caches it
98- kpget " Email/personal" # prints the password
103+ kpget " Email/personal" # prints the password (hot path for scripts)
99104kpget " Email/personal" -a Username # prints the username
100105kpget " Servers/prod" -a URL # any keepassxc-cli show -a value
101106kpget " Email/personal" -s # show all attributes
102107kplock # clears the cache (manual lock)
103108```
104109
110+ For everything beyond ` show ` , use the generic wrapper:
111+
112+ ``` sh
113+ kpxc ls /Email # list entries in a group
114+ kpxc search github # full-text search
115+ kpxc db-info # database metadata
116+ kpxc show -a Password Servers/prod # equivalent to kpget Servers/prod
117+ ```
118+
119+ ` kpxc ` forwards any ` keepassxc-cli ` subcommand and injects the cached
120+ password automatically. ` kpget ` is just a shortcut for the most common
121+ case (printing one attribute) and stays terse in config files.
122+
105123## Integrate with other tools
106124
107125### himalaya (CLI mail client)
108126
109127``` toml
110- # ~/.config/himalaya/config.toml - tested with himalaya v1.2+
128+ # ~/.config/himalaya/config.toml, tested with himalaya v1.2+
111129backend.auth.cmd = " kpget Email/personal"
112130```
113131
@@ -137,28 +155,28 @@ See [`examples/`](examples/) for full configs.
137155
138156## Security model
139157
140- ** What kpcache protects against:**
158+ ** What kpxc protects against:**
141159
142160- The master password is never passed as a command-line argument, so it
143161 doesn't appear in ` ps aux ` or shell history.
144162- The cache file is created atomically with ` install -m 600 /dev/null ` ,
145163 so there's no readable window even before ` chmod ` .
146164- ` set -euo pipefail ` plus an ` ERR/INT/TERM ` trap ensure the cache is
147165 removed if ` kpunlock ` is interrupted mid-write.
148- - Entry paths are passed to ` keepassxc-cli ` after ` -- ` , so an entry name
149- starting with ` - ` cannot be misinterpreted as an option.
166+ - Entry paths are passed to ` keepassxc-cli show ` after ` -- ` , so an entry
167+ name starting with ` - ` cannot be misinterpreted as an option.
150168
151- ** What kpcache does * not* protect against:**
169+ ** What kpxc does * not* protect against:**
152170
153171- ** Root.** A root user can read any process memory or any file on the
154172 system. Not a goal here.
155173- ** Memory forensics.** The decrypted master password sits in tmpfs RAM.
156174 An attacker with kernel access (or a coredump) can read it.
157175- ** A compromised user account.** Any other process running as your user
158- can read ` /dev/shm/<uid>-kpcache ` . The model assumes your local user
159- is trusted.
176+ can read ` /dev/shm/<uid>-kpxc ` . The model assumes your local user is
177+ trusted.
160178- ** Hardware tokens (YubiKey challenge-response).** Not currently
161- supported. Patches welcome.
179+ supported. PRs welcome.
162180
163181If your threat model requires per-process secret isolation, hardware
164182tokens, or memory hardening, use a kernel-keyring solution or the
@@ -175,14 +193,14 @@ still get fast lookups.
175193
176194## Alternatives
177195
178- - [ kpsh] ( https://git.goral.net.pl/keepass-shell.git ) - daemon, pure-Python
196+ - [ kpsh] ( https://git.goral.net.pl/keepass-shell.git ) : daemon, pure-Python
179197 pykeepass. Good if your DB uses moderate KDF rounds.
180- - [ git-credential-keepassxc] ( https://github.com/Frederick888/git-credential-keepassxc )
181- - talks to a running KeePassXC GUI via the browser-extension protocol.
198+ - [ git-credential-keepassxc] ( https://github.com/Frederick888/git-credential-keepassxc ) :
199+ talks to a running KeePassXC GUI via the browser-extension protocol.
182200 Best if you have a GUI session anyway.
183- - [ pass] ( https://www.passwordstore.org/ ) - drop KeePass, use GPG-encrypted
201+ - [ pass] ( https://www.passwordstore.org/ ) : drop KeePass, use GPG-encrypted
184202 files with ` gpg-agent ` for caching. Larger migration.
185203
186204## License
187205
188- MIT - see [ LICENSE] ( LICENSE ) .
206+ MIT, see [ LICENSE] ( LICENSE ) .
0 commit comments