Conversation
Patch signing was deliberately off. The reasoning was sound as far as it went: the public key was unpublished, so a signature nobody could verify was pure cost, and `gpg --send-keys` could not publish it -- failing with "Invalid argument" over both hkp:// and hkps://, which looked like the end of it. It was not. The block is on gpg's own keyserver transport, not on the host. Plain HTTPS to keys.openpgp.org goes straight through, and that server accepts uploads over its VKS API at POST /vks/v1/upload. The key is published and email-verified now, so vks/v1/by-email resolves it and a maintainer can find it from the From: header alone. That removes the only thing the earlier decision rested on, so this reverses it. Signing is gated on the secret key being present locally -- not on a hostname, not on a flag. signing_key_fingerprint() looks for a secret key matching the identity, and configure_patch_signing() writes nothing at all when there is none. That single condition is what keeps the installer safe to run in a container, on a restricted devserver, or on a laptop the key has not reached yet. The e2e images assert the negative case: sendemail configured, and patatt.signingkey empty, because no container holds the key. An explicitly set user.signingKey or patatt.signingkey is never clobbered -- a work key or a hardware token means what it says. commit.gpgsign is left alone, since signing mailing-list patches is a different decision from signing every commit in every repo on the machine. The cross-platform seam turned out narrower than expected: only the pinentry differs. gpg.conf is committed and identical everywhere; gpg-agent.conf is generated per host and gitignored, because it carries an absolute path -- pinentry-mac on macOS, a graphical prompt where there is a display, and pinentry-curses over ssh and on headless boxes, which is the case that actually matters. .zshrc exports GPG_TTY, without which that curses prompt fails with "Inappropriate ioctl for device" instead of prompting. ~/.gnupg is forced to 700 in two places: configure_gnupg makes it, and the FILES loop's mkdir -p would otherwise have created it with the umask default, which gpg refuses to use. bin/gpg-setup covers what the installer cannot derive: --check, --publish over the HTTPS API rather than the blocked transport, --export/--import to move the secret key between machines as a symmetrically encrypted transfer file, --enable-signing, and --test. --test drives patatt rather than gpg alone, because gpg working does not prove b4 will sign. It deliberately does not look for a patatt binary: b4 imports patatt as a library and Homebrew keeps it in a private venv, so `command -v patatt` finds nothing on a perfectly healthy setup, and an earlier version of this check reported "skipped" at exactly the moment the answer mattered. It reads b4's interpreter out of its shebang instead, and degrades to a diagnosis rather than a traceback if patatt's internals move. This also folds in the pending mail-pass work it depends on, since git send-email resolves the SMTP password through the same accessor: --store and --check subcommands, a warning when the input is not 16 characters (a 10-character account password got stored by mistake once, and IMAP and SMTP both reject it), and libsecret for apt and dnf so secret-tool exists on Linux at all. sendemail.smtppass is actively unset if found, because b4 only falls back to `git credential fill` when it is empty. Verified: shellcheck clean and 100/100 bats, both run via npx since brew is not writable on this machine. Signing proven end to end -- patatt signs a message and self-validates it as openpgp against the local keyring. Not verified: the --export/--import path has never been exercised against a real second machine, only the logic around it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Patch signing was deliberately off. The reasoning was sound as far as it went:
the public key was unpublished, so a signature nobody could verify was pure
cost, and
gpg --send-keyscould not publish it -- failing with "Invalidargument" over both hkp:// and hkps://, which looked like the end of it.
It was not. The block is on gpg's own keyserver transport, not on the host.
Plain HTTPS to keys.openpgp.org goes straight through, and that server accepts
uploads over its VKS API at POST /vks/v1/upload. The key is published and
email-verified now, so vks/v1/by-email resolves it and a maintainer can find it
from the From: header alone. That removes the only thing the earlier decision
rested on, so this reverses it.
Signing is gated on the secret key being present locally -- not on a hostname,
not on a flag. signing_key_fingerprint() looks for a secret key matching the
identity, and configure_patch_signing() writes nothing at all when there is
none. That single condition is what keeps the installer safe to run in a
container, on a restricted devserver, or on a laptop the key has not reached
yet. The e2e images assert the negative case: sendemail configured, and
patatt.signingkey empty, because no container holds the key. An explicitly set
user.signingKey or patatt.signingkey is never clobbered -- a work key or a
hardware token means what it says. commit.gpgsign is left alone, since signing
mailing-list patches is a different decision from signing every commit in every
repo on the machine.
The cross-platform seam turned out narrower than expected: only the pinentry
differs. gpg.conf is committed and identical everywhere; gpg-agent.conf is
generated per host and gitignored, because it carries an absolute path --
pinentry-mac on macOS, a graphical prompt where there is a display, and
pinentry-curses over ssh and on headless boxes, which is the case that actually
matters. .zshrc exports GPG_TTY, without which that curses prompt fails with
"Inappropriate ioctl for device" instead of prompting. ~/.gnupg is forced to
700 in two places: configure_gnupg makes it, and the FILES loop's mkdir -p
would otherwise have created it with the umask default, which gpg refuses to
use.
bin/gpg-setup covers what the installer cannot derive: --check, --publish over
the HTTPS API rather than the blocked transport, --export/--import to move the
secret key between machines as a symmetrically encrypted transfer file,
--enable-signing, and --test. --test drives patatt rather than gpg alone,
because gpg working does not prove b4 will sign. It deliberately does not look
for a patatt binary: b4 imports patatt as a library and Homebrew keeps it in a
private venv, so
command -v patattfinds nothing on a perfectly healthysetup, and an earlier version of this check reported "skipped" at exactly the
moment the answer mattered. It reads b4's interpreter out of its shebang
instead, and degrades to a diagnosis rather than a traceback if patatt's
internals move.
This also folds in the pending mail-pass work it depends on, since git
send-email resolves the SMTP password through the same accessor: --store and
--check subcommands, a warning when the input is not 16 characters (a
10-character account password got stored by mistake once, and IMAP and SMTP
both reject it), and libsecret for apt and dnf so secret-tool exists on Linux
at all. sendemail.smtppass is actively unset if found, because b4 only falls
back to
git credential fillwhen it is empty.Verified: shellcheck clean and 100/100 bats, both run via npx since brew is not
writable on this machine. Signing proven end to end -- patatt signs a message
and self-validates it as openpgp against the local keyring. Not verified: the
--export/--import path has never been exercised against a real second machine,
only the logic around it.