Skip to content

devops: load the signing key from the Keychain, an empty agent prompts - #79

Merged
landsman merged 2 commits into
mainfrom
git-signing-keychain
Aug 12, 2026
Merged

devops: load the signing key from the Keychain, an empty agent prompts#79
landsman merged 2 commits into
mainfrom
git-signing-keychain

Conversation

@landsman

Copy link
Copy Markdown
Owner

gpg.format = ssh signs through ssh-keygen -Y sign, which asks ssh-agent for the private half of user.signingkey and only falls back to reading the key file — and prompting — when the agent has not got it. macOS starts every login with an empty agent, so that fallback is the normal case: the first commit after a reboot asks for a passphrase, usually from the IDE, which has nowhere to ask. Verified both directions on this Mac: with the key in the agent ssh-keygen -Y sign signs silently, with SSH_AUTH_SOCK unset it prompts.

  • make git stores the passphrase in the login Keychain with ssh-add --apple-use-keychain, Darwin only — the flag is Apple's.
  • os/macos/.zshrc loads it back with --apple-load-keychain, guarded on ssh-add -l so a shell that already has a populated agent pays one fork and no Keychain round trip.
  • A note in the README saying why both halves are needed.

make qa passes.

`gpg.format = ssh` signs through `ssh-keygen -Y sign`, which asks ssh-agent for
the private half of user.signingkey and only falls back to reading the key file
— and prompting — when the agent has not got it. macOS starts every login with
an empty agent, so that fallback is the normal case: the first commit after a
reboot asks for a passphrase, usually from the IDE, which has nowhere to ask.

`make git` now stores the passphrase with --apple-use-keychain, and the macOS
rc loads it back with --apple-load-keychain, guarded on the agent already
holding keys.
@landsman

Copy link
Copy Markdown
Owner Author

@claude do the review in here

@claude

claude Bot commented Aug 12, 2026

Copy link
Copy Markdown

Claude finished @landsman's task in 1m 49s —— View job


Review

  • Gather context (diff, changed files)
  • Understand the request
  • Review Makefile changes
  • Review os/macos/.zshrc changes
  • Review README.md changes
  • Post final review

Went through the diff (git diff origin/main...HEAD) across all three files. This is a small, well-scoped change and I didn't find any correctness bugs. Notes:

Makefile (git target, Makefile:337-355)

  • Ordering is right: the .pub/private-key existence check still runs and can still exit 1 before the new ssh-add --apple-use-keychain "$$priv" line, so a missing key isn't silently skipped.
  • if [ "$$(uname -s)" = Darwin ] guard is correct and matches the existing style used elsewhere for platform-specific behavior.
  • Minor, non-blocking: if ssh-add --apple-use-keychain "$$priv" fails (e.g. wrong passphrase entered, or the user hits Ctrl-C at the prompt), the recipe doesn't check its exit status and just continues on to write the git config. That's probably fine — worst case is the pre-PR behavior (first commit prompts) — but a || echo "keychain add failed, first commit will prompt" would make the failure visible instead of silent. Not a blocker.

os/macos/.zshrc (os/macos/.zshrc:63-70)

  • ssh-add -l >/dev/null 2>&1 || ssh-add --apple-load-keychain 2>/dev/null is a sound guard — exit 0 (has identities) skips the Keychain round trip as described.
  • Edge case (not a bug, just worth noting): if SSH_AUTH_SOCK isn't set at all, ssh-add -l exits 2 (can't connect to agent) rather than 1 (empty agent), which also falls through to the --apple-load-keychain branch — same as the empty-agent case, so behavior is still correct, just via a slightly different path than the comment implies.
  • Placement (after the alias-loading block, before mise activate zsh) is fine — no ordering dependency with mise.
  • Already covered by make lint, which runs zsh -n os/macos/.zshrc — confirmed this target does parse this exact file.

README.md

  • The new "Commit signing needs the agent, not the key file" note accurately describes what the Makefile/.zshrc changes do and why (ssh-keygen -Y sign → agent → fallback-to-file-and-prompt), consistent with the PR description.

General

  • Correctly scoped to Darwin only, with a one-line explanation of why Linux doesn't need this (desktop keyring unlocks the agent differently) — matches this repo's convention of writing down why a platform is excluded rather than leaving a silent gap.
  • Comment style (@# line comments in the Makefile, verbose rationale blocks) matches existing conventions in this file.

Nothing here blocks merging — the one suggestion (surfacing an ssh-add failure) is optional polish, not a defect.

A Ctrl-C at the passphrase prompt left `make git` finishing quietly, and the
only sign of it is the next reboot prompting for a passphrase again — which
reads as the signing setup never having worked. Still not fatal: the rest of
the target is worth writing either way.
@landsman
landsman merged commit 8429aec into main Aug 12, 2026
3 checks passed
@landsman
landsman deleted the git-signing-keychain branch August 12, 2026 10:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant