Skip to content

Show and verify commit signature status in gg - #2

Draft
faun wants to merge 2 commits into
mainfrom
gg-verify-signatures
Draft

Show and verify commit signature status in gg#2
faun wants to merge 2 commits into
mainfrom
gg-verify-signatures

Conversation

@faun

@faunfaun commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Why

gg grew a %G? column so each unmerged commit's signature state sits next to its hash. That column could not work as shipped: commits here are ssh-signed through 1Password, and git cannot attempt verification of an ssh signature without gpg.ssh.allowedSignersFile. So every gg run printed error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification once per commit and reported every commit as N, which is exactly what a genuinely unsigned commit reports. The column was worse than useless, it was misleading.

What changed

  • install/01_configure_git_signing.sh (new): generates ~/.config/git/allowed_signers from the ssh signing keys registered on GitHub. Writes via mktemp + mv, so a failed or empty API response leaves an existing file untouched, and skips with a message when gh, user.email, or github.user is missing. Re-run with ./install.sh --force 01_configure_git_signing after registering a new key.
  • config/git/config: points gpg.ssh.allowedSignersFile at that file. Side benefit: git verify-commit, git log --show-signature, and git merge --verify-signatures start working too.
  • shrc/git.sh: new git_can_verify_signatures helper; gg interpolates the %G? token only when verification is actually possible, so a machine without the signers file shows no column rather than a column of misleading Ns.

Keys come from GitHub rather than ~/.ssh because history carries four signing keys from different machines and GitHub has all four. Reading the local key alone would leave anything signed elsewhere reading U. The generated file stays out of this repo on purpose: the repo is public, and the moment it grew a colleague's key it would be publishing their address. Other people's commits reading U is the correct outcome.

Verification

CheckResult
./install.sh 01_configure_git_signingWrote 4 signing keys
git verify-commit HEADGood "git" signature for git@faun.me ..., exit 0
%G? over last 300 commits267 G, 33 N (genuinely unsigned), 0 U, 0 error: lines
gg on a branch with unmerged commits* 44a439d G Faun: Split operations guide..., no errors
Guard, signers file moved asidehelper returns 1, gg prints no column and no error
Failure path (bogus github.user)404 handled, existing file intact
zsh test/warp_test.zsh27 passed, 0 failed

Confirmed along the way that verification works despite gpg.ssh.program = op-ssh-sign: git picks the verification backend from each signature's own payload rather than from gpg.format, and uses ssh-keygen for ssh signatures.

faun added 2 commits August 11, 2026 14:50
Verifying commits is a habit worth making visible, so surface each
commit's signature state right next to the hash instead of having to
run a separate verification pass. The comment records what the codes
mean and the SSH caveat, since N reads as "unsigned" whether the
commit really is unsigned or git simply lacks an allowed signers file
to check against.
The column landed with the SSH caveat recorded but not resolved, so
every line of gg output was preceded by an error and every commit read
as N. Commits here are ssh-signed through 1Password, and git cannot
attempt verification of an ssh signature without an allowed signers
file, which makes the status indistinguishable from a genuinely
unsigned commit. Configure the file and the column starts saying
something: G for mine, N for unsigned, U for a signer I have no key
for.
The keys come from the ssh signing keys registered on GitHub rather
than from ~/.ssh, because history carries four of them from different
machines and GitHub has all four. Reading the local key alone would
leave anything signed elsewhere reading U. The generated file stays
out of this repo: it is public, and the moment it grew a colleague's
key it would be publishing their address. Re-run the install step
with --force after registering a new key.
gg also drops the %G? token entirely when verification is impossible,
so a machine without a signers file shows no column rather than a
column of misleading Ns.
Sign up for freeto 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

@faun