KeePassXC credential support
July 15, 2026 · View on GitHub
This image does not include keepassxc-cli by default because the only Alpine
package available (keepassxc) pulls in the full Qt6 GUI stack — adding
~150 MB to an image that is otherwise under 200 MB. That trade-off is not
reasonable for users who never touch KeePass.
Instead, this image ships a lightweight Python shim that replicates the exact CLI interface that borgmatic calls. You opt in by mounting a single init script at container startup. No changes to borgmatic itself are needed.
How the shim works (note for borgmatic developers)
borgmatic calls keepassxc-cli like this:
keepassxc-cli show --show-protected --attributes Password \
[--no-password] [--key-file /path/to/key] \
/path/to/database.kdbx "entry-title"
The shim at /usr/local/bin/keepassxc-cli accepts the same arguments and
flags, uses pykeepass (a
pure-Python KeePass 4 reader) to open the database, and prints the requested
attribute to stdout — identical output to the real keepassxc-cli.
Because the interface is identical, borgmatic does not need to know or care
that it is talking to a Python script instead of the real binary. The
keepassxc_cli_command config option can be left at its default
(keepassxc-cli) since the shim is installed at the same path.
Supported flags: --show-protected, --attributes/-a, --no-password,
--key-file/-k. --yubikey is rejected with an error — hardware tokens
are not supported. The only supported attribute is Password, matching the
only attribute borgmatic's KeePassXC hook ever requests; any other value
errors out. Group-path style entry names (Group/Entry) are supported.
Setup
1. Mount the init script
Add a volume mount to your docker-compose.yml:
services:
borgmatic:
volumes:
# ... your existing volumes ...
- ./data/borgscripts/init-keepassxc-cli.sh:/custom-cont-init.d/init-keepassxc-cli.sh:ro
At startup the script installs pykeepass (~2 MB, no system packages) and
writes the keepassxc-cli shim to /usr/local/bin/keepassxc-cli.
2. Mount your KeePass database (and key file, if used)
volumes:
- /path/to/your/passwords.kdbx:/etc/borgmatic/passwords.kdbx:ro
- /path/to/your/passwords.keyx:/run/secrets/keepass.keyx:ro # optional
Keep the database and key file outside your backup source so they are not backed up to themselves.
3. Configure borgmatic
Add a keepassxc: block to your borgmatic config:
keepassxc:
database: /etc/borgmatic/passwords.kdbx
# Set to false to use a key file instead of typing a password at startup.
# Required for unattended/scheduled backups.
ask_for_password: false
# Optional — omit if your database is password-protected only.
key_file: /run/secrets/keepass.keyx
Then reference credentials anywhere a password is expected:
# Borg repository passphrase
encryption_passphrase: "{credential keepassxc /etc/borgmatic/passwords.kdbx MyBorgEntry}"
# Database hook credentials
postgresql_databases:
- name: mydb
username: "{credential keepassxc /etc/borgmatic/passwords.kdbx PostgresUser}"
password: "{credential keepassxc /etc/borgmatic/passwords.kdbx PostgresPassword}"
The value in quotes (MyBorgEntry, PostgresUser, etc.) is the title of
the entry inside your KeePass database.
4. Verify at startup
When the container starts you should see:
[init-keepassxc-cli] Installing pykeepass...
[init-keepassxc-cli] Writing /usr/local/bin/keepassxc-cli shim...
[init-keepassxc-cli] Done. keepassxc-cli shim is ready.
Run a manual check to confirm borgmatic can reach the database:
docker exec -it borgmatic borgmatic config validate
Unattended backups and key files
keepassxc-cli normally prompts for the database master password interactively,
which breaks scheduled (cron) backups. Use a key file instead and set
ask_for_password: false in your borgmatic config — the shim will open the
database with the key file alone, no prompt.
Store the key file outside your container (e.g. in a Docker secret or a host path not included in your backup source) and mount it read-only.
Limitations
Secret Service integration is not supported
borgmatic supports a {credential keepassxc secret-service <key>} syntax that
retrieves credentials via the D-Bus Secret Service API — the mechanism desktop
apps use to talk to a running KeePassXC or GNOME Keyring instance.
This does not work in a headless Docker container. The Secret Service API
requires a running D-Bus session bus and a Secret Service provider (KeePassXC
GUI or gnome-keyring-daemon) — neither of which exist in a container, and
providing them would pull in the full Qt6/GTK desktop stack that this shim
exists to avoid.
For unattended Docker backups, use the key file approach (ask_for_password: false + key_file). It requires no interactive prompt and no running desktop
environment.
Security notes
- The
pykeepasslibrary reads the KeePass 4 (.kdbx) format entirely in-process — the database is never sent anywhere. - The shim prints the requested attribute to stdout exactly as
keepassxc-clidoes; borgmatic captures it in memory and never writes it to disk. pykeepassis installed at container startup rather than baked into the image, so it is covered by your normal image rebuild/update cycle viadocker compose pull.- Pin the version if you need reproducible builds:
edit
init-keepassxc-cli.shand changepip install pykeepasstopip install pykeepass==<version>.