Signing GitHub Commits

Overview

The OpenMDAO master branch now only accepts verified commits to be confident that the changes come from a trusted source. To be verified, a commit must be signed with a certificate recognized by GitHub.

These instructions cover creating a GPG key, copying it to GitHub, and setting up git to sign commits.

Although it’s possible to use S/MIME to sign commits with an X.509 certificate (e.g. as found on a smartcard), the certificate must be signed by an authority already trusted by GitHub. The list of trusted CAs is the same as the one trusted by the Mozilla browser. Note: The certificates on NASA PIV badges are not signed by a CA currently trusted by GitHub.

Setting up your GPG Key with Git and GitHub

The process is documented in detail by GitHub. Here are the highlights:

  1. Install GPG if necessary

    • Source and binary releases are available at gnupg.org

    • Also available through many OS package managers. Examples:

      • MacOS: brew install gpg

      • RPM-based Linux distro: sudo yum install gnupg2 or sudo dnf install gnupg2

      • DEB-based Linux distro: sudo apt install gnupg

      • Windows: scoop bucket add nonportable, then scoop install gpg-np (Obtain Scoop)

  2. Generate a new GPG key

    • It’s important to note that the email address used for the key must be identical to your GitHub commit email address

      • Run git config --global user.email to find this if you’re unsure

      • Additional information on setting your commit email address, including using a no-reply address

    • At the end of this process, you’ll have your new GPG key copied to your clipboard

  3. Add the GPG key to your GitHub account

    • Summary:

      • Complete the instructions to find your key’s ID and configure git with it

      • Profile photo → Settings → SSH and GPG keys → New GPG key

      • Paste the key

      • Click Add GPG key

  4. Tell Git about your GPG key

    • Summary:

      • Run gpg --list-secret-keys --keyid-format=long

      • From that output, copy the long ID (16 hexadecimal digits) from the sec line of the key you just generated (or existing one you want to use), e.g.


        sec ed25519/A0B1C2D3E4F56789 2021-09-07 [SC]

      • Set your signing key:

        git config –global user.signingkey A0B1C2D3E4F56789

Signing Commits

Sign all commits by default:

git config --global commit.gpgsign true

Sign only commits for the current local repository by default:

git config --local commit.gpgsign true

Sign an individual commit:

git commit -S -m "commit message here"

GitHub has additional documentation on signing commits.

Configuring gpg-agent

It can be inconvenient to have to enter your GPG key passphrase for every commit. Invoking gpg automatically starts the gpg-agent program, which caches the key for a configurable amount of time. The $HOME/.gnupg/gpg-agent.conf file contains options for gpg-agent. Here is the complete list of gpg-agent options.

Example config file with some useful options:


# Set the time a cache entry is valid to 600 seconds. Each time a
# cache entry is accessed, the entry’s timer is reset.
default-cache-ttl 600

# Set the maximum time a cache entry is valid to 7200 seconds. After
# this a cache entry will be expired even if it has been accessed recently.
max-cache-ttl 7200

# MacOS only: Connect gpg-agent to the keychain via the pinentry program
# from GPGtools. Run "brew install pinentry-mac" to install.
pinentry-program /usr/local/bin/pinentry-mac


Pull-requesting a branch with unverified commits

If you attempt to PR a branch containing unsigned/unverified commits, merging will be blocked.

An example of a PR with unverified commits

To fix this problem, you’ll need to overwrite the unverified commits.

  1. Start by recommitting from the local repository of your development branch: git rebase -i <commit before first problematic commit>

  2. Your text editor will open up. Change every pick to edit.

  3. Save the file and exit the editor.

  4. Run git commit --amend -S, followed by git rebase --continue. Repeat until you get a message like Successfully rebased and updated refs/heads/<branchname>.

  5. Run git push --force-with-lease

Adapted from stackoverflow