/git-credential-keepassxc

Helper that allows Git (and shell scripts) to use KeePassXC as credential store

Primary LanguageRustGNU General Public License v3.0GPL-3.0

git-credential-keepassxc

GitHub Actions Status License: GPL v3 crates.io version

git-credential-keepassxc is a Git credential helper that allows Git (and shell scripts) to get/store logins from/to KeePassXC.

It communicates with KeePassXC using keepassxc-protocol, which was originally designed for browser extensions.

How to install

Quick

  1. Install Rust compiler via rustup or your favourite package manager
  2. Run cargo install --locked git-credential-keepassxc and it will be installed to Cargo installation root

Pre-Built Binaries (Experimental)

Experimental pre-built binaries are available at the GitHub release page.

*-minimal ones are built with no optional features, and *-full ones are built with all.

Optional features

git-credential-keepassxc has the following optional features:

Feature Description
all Enable all features
notification Desktop notifications, helpful if git-credential-keepassxc is used in scripts
yubikey Allow encrypting configuration file using YubiKey HMAC-SHA1
strict-caller Enforce caller limiting when associated databases exist (see Limiting callers for details!)

You can use cargo-update to make the features persistent across updates.

# install cargo-update first
$ cargo install --locked cargo-update
# enable and persist features
$ cargo install --locked --features <FEATURE>... git-credential-keepassxc
# note the different order of package name and --feature (singular) flag
$ cargo install-update-config git-credential-keepassxc --enforce-lock --feature <FEATURE>...

# later when you update
$ cargo install-update git-credential-keepassxc

Configuration

Similar to the browser extensions, git-credential-keepassxc needs to be associated with KeePassXC first:

# enable browser integration in KeePassXC settings, then
$ git-credential-keepassxc caller me  # only required if compiled with strict-caller, see Limiting callers
$ git-credential-keepassxc configure
$ git config --global --replace-all credential.helper 'keepassxc --git-groups'

A dedicated group (by default Git) will be created. If you want to use credentials from other groups, please check out Filtering results.

For more options, run git-credential-keepassxc -h to show the help message.

Limiting callers

git-credential-keepassxc allows you to limit callers of the program:

# don't forget to add yourself first
$ git-credential-keepassxc caller me
Gonna save current caller to allowed callers list:
{
  "path": "/usr/bin/zsh",
  "uid": 1000,
  "gid": 1000,
  "canonicalize": false
}
Press Enter to continue...
# then add Git
$ git-credential-keepassxc caller add --uid "$(id -u)" --gid "$(id -g)" "$(command -v git)"
# you may also need to add other executables in /usr/lib/git-core/
# run `git config --global --replace-all credential.helper 'keepassxc -vv --git-groups'` to enable logs if any Git subcommand is blocked

$ sh -c 'printf "url=https://example.com\nusername=foo\n" | git-credential-keepassxc get'
May 10 12:51:56.108 ERRO /usr/bin/bash (uid=1000, gid=1000) is not allowed to call git-credential-keepassxc, Caused by: N/A
$ printf 'url=https://example.com\nusername=foo\n' | git credential fill
May 10 12:52:53.995 WARN Request get-logins failed. Error: No logins found, Error Code: 15
May 10 12:52:53.995 ERRO Request get-logins failed, Caused by: N/A, Message: Request get-logins failed

# disable this function
$ git-credential-keepassxc caller clear

Note: If you've enabled strict-caller, you must add caller profiles before configuring databases, otherwise you won't be able to run git-credential-keepassxc afterwards.

Encrypting KeePassXC keys using YubiKey

By default the keys for authentication are stored in plaintext, which can be particularly dangerous if you've allowed clients to retrieve any credentials without confirmation.

git-credential-keepassxc is capable of encrypting these keys using YubiKey HMAC-SHA1 Challenge-Response. First make sure you've enabled the yubikey feature, then:

# encrypt using YubiKey slot 2 and a randomly generated challenge
$ git-credential-keepassxc encrypt challenge-response

To decrypt the keys:

$ git-credential-keepassxc decrypt

For more details, see: wiki/Encryption

Filtering results

By group names

--group <GROUP>. This option can be repeated. This is the name of the group itself. Paths are not supported.

By dedicated Git group names

--git-groups. This uses the names of the groups created by git-credential-keepassxc configure [--group <GROUP>].

Note if you have more than one database, it's recommended to use the same group name, as this option filters all results using all the group names.

By an advanced string field

  1. In KeePassXC, go to Tools -> Settings -> Browser Integration -> Advanced, enable Return advanced string fields which start with "KPH: " (this is enabled by default)
  2. Open the entry you'd like to hide
  3. Go to Advanced
  4. Add an additional attribute KPH: git (the space after colon is required) of which the value is false

A note on git-credential-keepassxc store

Since git-credential-keepassxc store consists of looking up existing entries and then updating or creating one, these filters can also stop it from updating certain entries.

This is important as Git may call git-credential-keepassxc store after validating a password, and it can update your login password entry rather than the API token one.

Scripting

git-credential-keepassxc can also help manage credentials in shell scripts. You can send a request via standard input in the git-credential input/output format then process the response.

Accepted fields in input (unknown fields are ignored):

  • url
  • username
  • password (store requests only)

Responses are in the same format. Alternatively get, totp, and generate-password responses can also be formatted in JSON with --json flag; get and totp also support --raw flag.

For instance, to connect to a Remote Desktop service:

#!/usr/bin/env -S bash -euET -o pipefail -O inherit_errexit

trap 'notify-send "RDP Failure" "Failed to connect to Remote Desktop service"' ERR

HOST="example.com"
PORT="3389"
USERNAME="Administrator"
PASSWORD="$(printf 'url=rdp://%s:%s\nusername=%s\n' "$HOST" "$PORT" "$USERNAME" | git-credential-keepassxc get | sed -n 's/^password=//p')"

xfreerdp /v:"$HOST:$PORT" /cert-tofu /cert:ignore \
    /size:2560x1620 /smart-sizing /scale:140 /scale-desktop:140 /scale-device:140 \
    +compression /compression-level:2 +clipboard +themes +wallpaper \
    /t:Example +decorations /u:"$USERNAME" /p:"$PASSWORD"

Troubleshooting and more

Wiki