Some people blog to vent. Some people blog to educate others, a way of giving back to the community. For others, it's a marketing effort, to help make themselves known by putting lots of popular keywords in their posts. This particular blog post serves another purpose: to remind me of a set of steps in order for GitHub commits to show up as verified.
I contribute to a few open source projects on GitHub and over the last several months have seen an increasing number of commits with a little "Verified" symbol next to them. I researched GitHub's documentation and some blog posts and learned that git commits can be spoofed, or submitted by someone else in your name. To prevent that, you can sign your commits, upload your signature to your GitHub account, then tell GitHub to only allow commits that match that signature. For GitHub accounts with multiple contributors, or if you develop from multiple computers, you can configure several signatures. These actions require a complex set of steps to get set up but once it is, it's automated and will give you peace of mind knowing you won't suffer the horror of a malicious contributor. The GitHub documentation on signing commits is pretty good and is mostly what I used to get this set up.
I develop on Windows but use Git Bash to manage git repositories, often using SourceTree to view differences and add several files to a commit with a GUI. So this blog (remember, this is mostly for me to remember the steps) lists the steps for this type of environment and using the latest version of Git Bash on recently updated Windows 10. However, the information here is pretty common and with a little reading, you'll be able to make the few changes that might be necessary for your situation--or to push commits to a different repository other than GitHub.
1. Verify your email address
Commits are signed with your email address (actually, they can contain multiple email addresses). A signature can also include your name and a comment but at least one email address, associated with your GitHub account, is required as it identifies you as the author of the commit. GitHub must verify the email address is actually yours, otherwise the signature would be useless. It's a simple process and has likely already been done. When an email address is added to your GitHub account, it sends a message to you requesting verification. Simply follow the instructions in the email to get it verified with GitHub.
You can see which email addresses are already added to your account and verified by going to your account settings and clicking on the Emails section. You can add others and also resend a verification email at any time.
2. Generate a signing key
Signatures are created with a pair of keys, one private and one public--the private one stays safely on your computer; the public one will get uploaded to your GitHub account in the next step. When you push the commit, GitHub checks to see if it can parse the signature with one of your uploaded keys, if so, the commit is marked verified.
There are many tools that can generate a public key. Git Bash comes with gpg, a command-line tool that can create signing keys for use in git right from the command-line:
(depending on the version you have)
This will prompt you for a few parameters on how to generate the key:
- Algorithm - accept the default of RSA and RSA
- Key Size - enter 4096
- Expiration - select 0 for never expiring
Then it asks you for the information that will be in the key:
- Real name - I use my real name, others use an alias
- Email address - enter your GitHub-verified email address; you can optionally use the GitHub "no-reply" address created for you
- Comment - this is optional and not visible on GitHub but is shown when you list the keys in Git Bash
EDIT: In early 2022, GitHub stopped supporting DSA keys and added stricter requirements for generating SSH keys (read the article). The new command to generate acceptable keys with all options is:
ssh-keygen -t ed25519 -C "email@example.com"
Read more about Generating SSH Keys on GitHub.
Once this is all set, it asks for a passphrase which helps protect the key from being used by anyone else. Your signing key is now ready to be used.
3. Upload your public key
With a signing signature prepared, you need to upload the public key to GitHub. To do that, export an ASCII version of the key with the gpg tool. First, list the keys that you have so you can identify the key to export:
gpg --list-secret-keys --keyid-format=long
In the first line, the hex number after the slash is the key identifier you will use in the next few steps. In the screenshot above, that identifier is
D792C422260CFA4C. Use that to export the public key:
gpg --armor --export D792C422260CFA4C
A big block of text, starting with "-----BEGIN PGP PUBLIC KEY BLOCK-----" and ending with "
-----END PGP PUBLIC KEY BLOCK-----" is displayed. Copy that whole block, including the "BEGIN" and "END" lines, then go to your GitHub account settings, click on the SSH and GPG keys section, scroll down to GPG Keys, click New GPG Key, paste the block, then click Add GPG key. Now you'll see a list of your uploaded GPG keys, each listing the email address with which it's associated and the Key ID.
4. Sign your commits
You could've started signing your commits before uploading the public key (in fact, if you don't use GitHub but still sign commits that step would obviously be irrelevant). Personally, I like getting that step out of the way before I start signing commits.
commit command has an optional
--gpg-sign (or shortened to just
-S) parameter that tells git to create a signed commit. If you want every commit signed but don't want to have to explicitly list
-S each time, you can configure git to automatically sign all commits by setting it in the configuration:
git config --global commit.gpgsign true
If you have multiple GPG keys, you can tell git which one to use by default (you can override the default on any particular commit with the
git config --global user.signingkey D792C422260CFA4C
(replace "D792C422260CFA4C" with your sign key identifier).
There it is. Now you can get back to coding as usual but now as you
git commit and
git push to GitHub, your commits will be marked Verified.
. . .
To learn how to cache the pass-phrase so you don't have to type it in every time, read my next blog entry.