Skip to content

fix(git): kill keyboxd, not just gpg-agent, before removing stale GnuPG sockets - #7206

Open
ivomarino wants to merge 1 commit into
akuity:mainfrom
ivomarino:fix/gpg-keyboxd-cleanup
Open

ivomarino wants to merge 1 commit into
akuity:mainfrom
ivomarino:fix/gpg-keyboxd-cleanup

Conversation

@ivomarino

Copy link
Copy Markdown

Fixes #7133.

reconcileGPGState runs gpgconf --kill gpg-agent, then walks GNUPGHOME and removes every leftover UNIX socket on the assumption that anything still there belongs to a daemon that just got killed. That assumption doesn't hold for keyboxd: it's a separate process from gpg-agent (added for the public keybox in modern GnuPG), so killing gpg-agent alone leaves keyboxd running while its socket gets pulled out from under it a few lines later.

The next git commit -S needs to reconnect to keyboxd, and when the timing doesn't work out, it fails with:

gpg: can't connect to the keyboxd: IPC connect call failed
gpg: error opening key DB: No Keybox daemon running
gpg: signing failed: Input/output error
fatal: failed to write commit object

Since it's a timing race, most promotions go through fine and a retry usually succeeds - which is exactly what made this hard to track down (the issue's own writeup, including a full repro script, does a great job of narrowing it to this exact mechanism).

Fix: gpgconf --kill all instead of naming gpg-agent specifically - covers whatever's actually running (gpg-agent, dirmngr, scdaemon, keyboxd) rather than one component by name.

Testing: adapted the repro loop from the issue to check the actual precondition directly (is keyboxd still alive right after the socket sweep). With the old --kill gpg-agent, it was alive every single time across two separate runs (40 and 300 iterations) - the crash itself didn't trigger in either run (it's genuinely timing-dependent, matching the report), but the unsafe state it depends on reproduced 100% of the time. With --kill all, keyboxd was gone every time, 40/40. Also ran the existing pkg/controller/git test suite, unaffected.

Didn't add a new automated test for this specific one, since exercising it meaningfully needs a real gpg/gpgconf/keyboxd on the runner and I wasn't sure that's a safe assumption for CI - happy to add one if there's an existing pattern for that in this repo I should follow.

…PG sockets

reconcileGPGState runs gpgconf --kill gpg-agent, then removes every
socket left in GNUPGHOME on the assumption that anything still there
belongs to a dead daemon. That assumption breaks with keyboxd: it is a
separate daemon from gpg-agent (introduced for the public keybox), so
killing gpg-agent alone leaves it running while its own socket gets
deleted right out from under it.

The next git commit -S has to reconnect to keyboxd, and when it loses
that race it fails with:

  gpg: can't connect to the keyboxd: IPC connect call failed
  gpg: error opening key DB: No Keybox daemon running
  gpg: signing failed: Input/output error
  fatal: failed to write commit object

Since the failure depends on exact timing, most promotions succeed and
this shows up as an intermittent signing failure that clears up on
retry - which is what made it hard to pin down.

Fix: gpgconf --kill all, which covers every component that might be
running (gpg-agent, dirmngr, scdaemon, keyboxd) instead of naming one.

Verified by adapting the repro loop from the issue: with the old
gpgconf --kill gpg-agent, keyboxd was still alive after the socket
sweep on every iteration (0/40, then 0/300 - the crash itself is timing
dependent, but the unsafe state it depends on was 100% reproducible).
With gpgconf --kill all, keyboxd was gone every time, 40/40.

Fixes akuity#7133

Signed-off-by: Ivo Marino <[email protected]>
@ivomarino
ivomarino requested a review from a team as a code owner September 15, 2026 00:55
@netlify

netlify Bot commented Sep 15, 2026

Copy link
Copy Markdown

Deploy Preview for docs-kargo-io ready!

Name Link
🔨 Latest commit 1e69873
🔍 Latest deploy log https://app.netlify.com/projects/docs-kargo-io/deploys/6aa8978526be0a00083de631
😎 Deploy Preview https://deploy-preview-7206.docs.kargo.io
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@kargo-governance-bot kargo-governance-bot Bot added kind/bug Something isn't working as intended; If unsure that something IS a bug, start a discussion instead needs/area Issue or PR needs to be labeled to indicate what parts of the code base are affected needs/priority Priority has not yet been determined; a good signal that maintainers aren't fully committed labels Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bug Something isn't working as intended; If unsure that something IS a bug, start a discussion instead needs/area Issue or PR needs to be labeled to indicate what parts of the code base are affected needs/priority Priority has not yet been determined; a good signal that maintainers aren't fully committed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

git-commit signing fails intermittently: reconcileGPGState deletes the keyboxd socket without stopping keyboxd

1 participant