Skip to content

Support keyboxd-backed GnuPG key storage for JGit commit signing #234

@DavidBakerEffendi

Description

@DavidBakerEffendi

Description

Summary

JGit's in-process GPG commit signing (BouncyCastle-based signer) fails on a machine where GnuPG is configured with use-keyboxd. Native git commit -S works on the same machine, and IntelliJ works because it shells out to native Git/GPG. This suggests JGit's key discovery relies on legacy keyring files (e.g., pubring.kbx) or cannot access keys when they are served via keyboxd.

Suggested direction

Add a robust discovery backend that (1) detects keyboxd-backed configurations, (2) resolves/validates the provided key ID by querying the system gpg in a machine-readable way (e.g., gpg --list-secret-keys --with-colons, honoring gpg.program/GNUPGHOME where applicable), and (3) optionally supports a hybrid mode where JGit can delegate key resolution (and possibly signing) to external gpg when direct keyring access is unavailable, to match native Git behavior and avoid forcing users onto native command workarounds.

Motivation

We’re building a code development platform where cryptographic signing of code changes (e.g., GPG-signed commits) is important for establishing authorship and integrity across the entire workflow—local development, remote environments, CI, and release pipelines.

Keyboxd is becoming the default and would be valuable to support for end users without having to manage security concerns around native Git calls, especially since we have built most of the Git-related code from JGit already.

Related issue that currently uses native Git commands as a workaround: BrokkAi/brokk#2249

Alternatives considered

  • Provide/auto-select a signing implementation that shells out to external gpg (like native Git) when key discovery via BC is not possible. Shelling out to native Git is currently our workaround.
  • Document limitations clearly and provide recommended config/workarounds (e.g., export keys to an OpenPGP keyring file). -> I have struggled to find an existing issue on this topic outside of tell the user to "disable use-keyboxd"

Additional context

Environment

  • JGit version: 7.5.0.202512021534-r
  • Java: Temurin 21.0.8
  • OS: macOS Tahoe (v26.2)
  • GnuPG:
gpg (GnuPG) 2.4.8
libgcrypt 1.11.2
Copyright (C) 2025 g10 Code GmbH
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
  • Installation method: Homebrew
  • gpgconf --list-components:
gpg:OpenPGP:/opt/homebrew/Cellar/gnupg/2.4.8/bin/gpg
gpgsm:S/MIME:/opt/homebrew/Cellar/gnupg/2.4.8/bin/gpgsm
keyboxd:Public Keys:/opt/homebrew/Cellar/gnupg/2.4.8/libexec/keyboxd
gpg-agent:Private Keys:/opt/homebrew/Cellar/gnupg/2.4.8/bin/gpg-agent
scdaemon:Smartcards:/opt/homebrew/Cellar/gnupg/2.4.8/libexec/scdaemon
dirmngr:Network:/opt/homebrew/Cellar/gnupg/2.4.8/bin/dirmngr
pinentry:Passphrase Entry:/opt/homebrew/opt/pinentry/bin/pinentry

GnuPG configuration

  • ~/.gnupg/common.conf contains: use-keyboxd
  • ~/.gnupg contents :
-rw-r-----   1 dave  staff    12 Dec 31 08:30 common.conf
-rw-r--r--   1 dave  staff    48 Aug 18 13:33 gpg-agent.conf
drwx------   3 dave  staff    96 Aug 18 13:28 openpgp-revocs.d
drwx------@  4 dave  staff   128 Aug 18 13:28 private-keys-v1.d
drwxr-x---@  5 dave  staff   160 Dec 31 08:30 public-keys.d
-rw-------@  1 dave  staff    32 Dec 30 19:24 pubring.kbx.bak
srwx------   1 dave  staff     0 Dec 31 08:30 S.gpg-agent
srwx------   1 dave  staff     0 Dec 31 08:30 S.gpg-agent.browser
srwx------   1 dave  staff     0 Dec 31 08:30 S.gpg-agent.extra
srwx------   1 dave  staff     0 Dec 31 08:30 S.gpg-agent.ssh
srwx------   1 dave  staff     0 Dec 31 08:30 S.keyboxd
srwx------   1 dave  staff     0 Dec 31 08:30 S.scdaemon
-rw-------@  1 dave  staff  1280 Aug 18 13:28 trustdb.gpg
  • Is pubring.kbx present? No
  • Is private-keys-v1.d/ present? Yes

Git config relevant to signing (repo or global):

git config --show-origin --get commit.gpgSign # true
git config --show-origin --get user.signingkey # (set to my key)
git config --show-origin --get gpg.program # (empty string)
git config --show-origin --get gpg.format # openpgp

Diagnostics from minimal reproducible code

--- GPG Diagnostic Info ---
user.home: /Users/dave
Resolved gnupgHome: /Users/dave/.gnupg
GNUPGHOME (seen by JGit): /Users/dave/.gnupg
gnupgHome exists: true
gnupgHome isDirectory: true
pubring.kbx exists: false
pubring.gpg exists: false
public-keys.d exists: true
trustdb.gpg exists: true
.gnupg contents: [S.gpg-agent.extra, S.gpg-agent.ssh, common.conf, private-keys-v1.d, S.keyboxd, S.gpg-agent, public-keys.d, gpg-agent.conf, S.scdaemon, pubring.kbx.bak, trustdb.gpg, openpgp-revocs.d, S.gpg-agent.browser]
Available secret keys via gpg:
 - David Baker Effendi ([REDACTED] Signing Key) <[REDACTED]> ([REDACTED])
Requested key is 40-char fingerprint. Derived long ID: [REDACTED]
Matched requested key against available keys: [REDACTED]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions