6

I am setting up a new machine and would prefer to use keybase for various pgp activities like signing commits. I can run a command like

$ keybase pgp sign -m foo > x
$ gpg --verify x 2>&1 | grep -oF 'Good signature'
Good signature

I could sign things directly with gpg, but it's convenient to let keybase manage the thing. So can I somehow make git use keybase?

Git configuration doesn't seem to have a way to customize the gpg command that it uses to sign commits. All you can do is provide the key. Is there any way to do it?

kojiro
  • 74,557
  • 19
  • 143
  • 201
  • i stopped using the keybase when zoom bought it. if you want to host your prox and use the git https://github.com/woss/git-pgp-remote-sign – woss Feb 06 '22 at 17:35

2 Answers2

3

Thanks to the link in Xavier's answer I learned that I can override the gpg program with the gpg.program configuration:

git config --global gpg.program /path/to/something

So I can use this to write a wrapper around keybase.

But git is, as it turns out, pretty finicky about what that something is. Git expects to partially parse the output that results from the --fd-status flag, which causes gpg to output special status codes at an alternate filehandle.

Fortunately, at least for my first pass, git doesn't parse everything that gpg produces, so I was able to emulate it. Here's a gist with a functional wrapper, and here's the meat of it:

# Copy the commit message from stdin to a file. 
d=$(mktmp -d "${TMPDIR:-/tmp}/gitsig.XXXXXXXXX")
cat > "$d/commit.msg"

# Have Keybase write the signature to another file.
keybase pgp sign --detached \
                 --key "$1" \
                 --infile "$d/commit.msg" \
                 --outfile "$d/commit.sig"

# Have gpg verify the signature right away.
# Capture its status in a file.
gpg --verify --status-fd=2 \
    "$d/commit.sig" "$d/commit.msg" \
    > /dev/null 2> "$d/gpgstatus.txt"

# Copy the KEY_CONSIDERED lines to stderr. Git wants that.
grep '^\[GNUPG:\] KEY_CONSIDERED' "$d/gpgstatus.txt" >&2

# Produce a minimal SIG_CREATED line to stderr. Git also wants that.
printf '[GNUPG:] SIG_CREATED ' >&2
kojiro
  • 74,557
  • 19
  • 143
  • 201
  • It is awesome that you did this! That said, by showing me the complex and brittle solution required for direct signing with keybase you've convinced me to just use gnupg :) – Dav Clark Nov 12 '21 at 22:02
1

There is a doc here on how to do it (with github) https://github.com/pstadler/keybase-gpg-github

Xavier
  • 3,919
  • 3
  • 27
  • 55
  • That tells me there's a `gpg.program`, which is super helpful. However, overriding this program is not trivial because in [version 2.10](https://github.com/git/git/blob/53f9a3e157dbbc901a02ac2c73346d375e24978c/Documentation/RelNotes/2.10.0.txt#L183) git implemented support for `gpg --status-fd`, which takes precedence over the unix exit status of gpg. Unfortunately, I haven't figured out the magic status output git expects gpg to give it to accept the signature output yet. This may take some time... – kojiro Oct 18 '19 at 02:01