Want to prove that you actually committed the code attributed to your name in git repositories (and get that nice Verified stamp on your commit on GitHub or GitLab)? So did I. I followed the instructions on GitHub (which are remarkably similar to those on GitLab) but found that my commits using PyCharm still didn’t include the signature. Here’s how to get it working.
Create your key
- Create your key
- You’ll be asked some questions; answer as you see appropriate. Choose RSA and RSA, and use 4096 bits (this is also recommended by GitLab). I also like to set an expiry on my keys – I set this to 2 years below. Note that your email address must match an email address verified on your GitHub / GitLab account(s).
Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (3072) 4096 Requested keysize is 4096 bits Please specify how long the key should be valid. <...> Key is valid for? (0) 1y Key expires at Mon 27 Jul 2020 05:38:19 PM EDT Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: Peaks And Protocols Email address: email@example.com Comment: This is an example key You selected this USER-ID: "Peaks And Protocols (This is an example key) <firstname.lastname@example.org>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o <...> gpg: key 990B8E9D86ED660F marked as ultimately trusted gpg: revocation certificate stored as '/home/jrokeach/.gnupg/openpgp-revocs.d/1C0476B1F7659A7F063F6637990B8E9D86ED660F.rev' public and secret key created and signed. pub rsa4096 2019-07-28 [SC] [expires: 2020-07-27] 1C0476B1F7659A7F063F6637990B8E9D86ED660F uid Peaks And Protocols (This is an example key) <email@example.com> sub rsa4096 2019-07-28 [E] [expires: 2020-07-27]
- Grab your key ID from the line below
pub; in the above example, it’s
1C0476B1F7659A7F063F6637990B8E9D86ED660F. Use this for
gpg --armor --export <keyid>
$ gpg --armor --export 1C0476B1F7659A7F063F6637990B8E9D86ED660F -----BEGIN PGP PUBLIC KEY BLOCK----- mQINBF0+FfwBEACzb3Phra1NAEPWObG4aUz9v3zebOJI9qDP1sD4G3HlyDRfh4Tn acSxIZHtQV8vLtDl+vmjj4PxW3NLZJCZmbLWIbikmVjZDMSxsfnVxTEUxF8itvk1 <truncated>uH4p2BUQNBF/gunvxyQVXjrA+JC4fc/zuvvrJ12MQL6qCs2GuiwnB g0MHLAz4TkSHR7nt7bC8LP6bovl8FP14FN6xlXusbAQ0ckHB+OcMYH9GjH7WhgHo -----END PGP PUBLIC KEY BLOCK-----
- Copy the full exported public key, including the
-----BEGIN PGP PUBLIC KEY BLOCK-----and
-----END PGP PUBLIC KEY BLOCK-----lines, and paste them into as a new GPG key on GitHub and/or GitLab as appropriate.
Tell Git to sign your commits
Now that you have a key, and you’ve associated it with yourself on GitHub/GitLab, you’ll need to tell Git to actually sign your commits.
- Get your key ID by running
. In the following example, the key ID is
gpg --list-secret-keys --keyid-format LONG <your_email>
$ gpg --list-secret-keys --keyid-format LONG firstname.lastname@example.org sec rsa4096/990B8E9D86ED660F 2019-07-28 [SC] [expires: 2020-07-27] 1C0476B1F7659A7F063F6637990B8E9D86ED660F uid [ultimate] Peaks And Protocols (This is an example key) <email@example.com> ssb rsa4096/0ABF70532FBB4582 2019-07-28 [E] [expires: 2020-07-27]
- Tell git to use your key globally. Run
git config --global user.signingkey<Key ID>
- Optionally, tell git to use your key for a single repository. Within the directory of your git project, run
git config user.signingkey <Key ID>. I use this to sign different projects with my personal and work email addresses.
- Now, tell git to always sign your commits:
git config --global commit.gpgsign true. Of course, you could also tell git to sign each commit individually,
Make key signing work without TTY
So, we’ve gotten far enough that we can sign commits, but PyCharm or other similar apps won’t work yet. There’s some great discussion on StackOverflow that led me to this solution.
- Create a new file named
gpg-no-tty.shwith the contents (replacing
</path/to/gpg>, of course:
echo passphrase | "</path/to/gpg>" --passphrase-fd 0 --batch --no-tty --yes "$@"
- Allow this file to be executed:
chmod +x gpg-no-tty.sh
- Tell git to always use this file to execute gpg (replacing
git config --global gpg.program </path/to/gpg-no-tty.sh>
Now try out a commit in your IDE, and you should see it works! You can verify with
git log -n 1 --show-signature, or just view it once you push to GitHub/GitLab.