• Stars
    star
    2,609
  • Rank 17,549 (Top 0.4 %)
  • Language
  • Created over 8 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Step-by-step guide on how to create a GPG key on keybase.io, adding it to a local GPG setup and using it with Git and GitHub.

Set up Keybase.io, GPG & Git to sign commits on GitHub

This is a step-by-step guide on how to create a GPG key on keybase.io, adding it to a local GPG setup and use it with Git and GitHub.

Although this guide was written for macOS, most commands should work in other operating systems as well.

There's a video published by Timothy Miller explaining some parts of this guide. Discussion on Hacker News.

Note: If you don't want to use Keybase.io, follow this guide instead. For manually transferring keys to different hosts, check out this answer on Stack Overflow.

Requirements

$ brew install gpg
$ brew install --cask keybase

You should already have an account with Keybase and be signed in locally using $ keybase login. In case you need to set up a new device first, follow the instructions provided by the keybase command during login.

Make sure your local version of Git is at least 2.0 ($ git --version) to automatically sign all your commits. If that's not the case, use Homebrew to install the latest Git version: $ brew install git.

Create a new GPG key on keybase.io

$ keybase pgp gen --multi
# Enter your real name, which will be publicly visible in your new key: Patrick Stadler
# Enter a public email address for your key: [email protected]
# Enter another email address (or <enter> when done):
# Push an encrypted copy of your new secret key to the Keybase.io server? [Y/n] Y
# â–¶ INFO PGP User ID: Patrick Stadler <[email protected]> [primary]
# â–¶ INFO Generating primary key (4096 bits)
# â–¶ INFO Generating encryption subkey (4096 bits)
# â–¶ INFO Generated new PGP key:
# â–¶ INFO   user: Patrick Stadler <[email protected]>
# â–¶ INFO   4096-bit RSA key, ID CB86A866E870EE00, created 2016-04-06
# â–¶ INFO Exported new key to the local GPG keychain

Set up Git to sign all commits

$ gpg --list-secret-keys --keyid-format LONG
# /Users/pstadler/.gnupg/secring.gpg
# ----------------------------------
# sec   4096R/E870EE00 2016-04-06 [expires: 2032-04-02]
# uid                  Patrick Stadler <[email protected]>
# ssb   4096R/F9E3E72E 2016-04-06

$ git config --global user.signingkey E870EE00
$ git config --global commit.gpgsign true

Add public GPG key to GitHub

$ open https://github.com/settings/keys
# Click "New GPG key"

# We can then use `export` with the `-q` or query flag to match on our key (the first 16 characters should do..) 
$ keybase pgp export -q CB86A866E870EE00 | pbcopy # copy public key to clipboard
# Paste key, save

Import key to GPG on another host

$ keybase pgp export
# â–¶ WARNING Found several matches:
# user: Patrick Stadler <[email protected]>
# 4096-bit RSA key, ID CB86A866E870EE00, created 2016-04-06

# user: keybase.io/ps <[email protected]>
# 4096-bit RSA key, ID 31DBBB1F6949DA68, created 2014-03-26

$ keybase pgp export -q CB86A866E870EE00 | gpg --import
$ keybase pgp export -q CB86A866E870EE00 --secret | gpg --allow-secret-key-import --import

After importing you probably want to locally trust your own key, otherwise you will see gpg: WARNING: This key is not certified with a trusted signature! when running git log --show-signature.

$ gpg --edit-key CB86A866E870EE00
gpg> trust

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

gpg> quit

Troubleshooting: gpg failed to sign the data

If you cannot sign a commit after running through the above steps, and have an error like:

$ git commit -m "My commit"
# error: gpg failed to sign the data
# fatal: failed to write commit object

You can run echo "test" | gpg --clearsign to find the underlying issue.

If the above succeeds without error, then there is likely a configuration problem that is preventing git from selecting or using the secret key. Confirm that your gitconfig user.email matches the secret key that you are using for signing.

Another solution is set up Git to use GPG program on Windows

$ git config --global user.signingkey E870EE00
$ git config --global commit.gpgsign true
$ git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"

Optional: Set as default GPG key

$ $EDITOR ~/.gnupg/gpg.conf
# Add line:
default-key E870EE00

Optional: Fix for Git UIs

If you use a UI such as Git Tower or Github Desktop, you may need to configure git to point to the specific gpg executable:

git config --global gpg.program $(which gpg)

Optional: Disable TTY

If you have problems with making autosigned commits from IDE or other software add no-tty config

$ $EDITOR ~/.gnupg/gpg.conf
# Add line:
no-tty

Optional: Setting up TTY

Depending on your personal setup, you might need to define the tty for gpg whenever your passphrase is prompted. Otherwise, you might encounter an Inappropriate ioctl for device error.

$ $EDITOR ~/.profile # or other file that is sourced every time
# Paste these lines
GPG_TTY=$(tty)
export GPG_TTY

Optional: In case you're prompted to enter the password every time

Some people found that this works out of the box w/o following these steps.

Method 1 - gpg-agent + pinentry-mac

Install pinentry-mac:

$ brew install pinentry-mac

Set up the agent:

$ $EDITOR ~/.gnupg/gpg-agent.conf
# Paste this line:
pinentry-program /usr/local/bin/pinentry-mac

Now git commit -S, it will ask your password and you can save it to macOS keychain.

pinentry

Method 2 - GPG Suite

Some people find that pinentry installed with brew does not allow the password to be saved to macOS's keychain.

If you do not see "Save in Keychain" after following Method 1, first uninstall the version of pinentry-mac installed with brew:

$ brew uninstall pinentry-mac

Now install the GPG Suite versions, available from gpgtools.org, or from brew by running:

$ brew install --cask gpg-suite

Once installed, open Spotlight and search for "GPG Suite", or open system preferences and select "GPG Suite"

Select the Default Key if it is not already selected, and ensure "Store in OS X Keychain" is checked:

gpg preferences

The gpg-agent.conf is different from Method 1:

Set up the agent:

$ $EDITOR ~/.gnupg/gpg-agent.conf
# GPG Suite should pre-populate with something similar to the following:
default-cache-ttl 600
max-cache-ttl 7200

Testing without a Git Commit

While a full end-to-end test by committing something to git will confirm for sure if things are working, a quick thing you can check is:

echo "test" | gpg --clearsign

This will output something like this if everything goes well:

$ echo "test" | gpg --clearsign
gpg: WARNING: server 'gpg-agent' is older than us (2.2.40 < 2.4.0)
gpg: Note: Outdated servers may lack important security fixes.
gpg: Note: Use the command "gpgconf --kill all" to restart them.
gpg: using "9DAC53FB18AB8C5DF0E2AA5B330CB62AE334C5E2" as default secret key for signing
gpg: problem with fast path key listing: IPC parameter error - ignored
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

test
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEmpcZZDDypeoq25Aer4d9fatgnzQFAmPmbXEACgkQr4d9fatg
nzQ/RAf9Elo6RUbb1xWdyPVHqS6Eq67eWmbJ62WriI+2ldMjj8lZp4XtcZ0KzXnO
0U4moVhZyQqBQ1syDC8UNXsTI7pzbRuZ1dzs5tjo+6UuqGfzpgurvw//3L/LxujJ
5asFq//sDNLCHFUAFDbmuWqfcMqpp/KqtaJr8EuCSb/3HSy4J8lMNGyQ4wmpQs5U
Qr5IPLq07NQrOQC3d4vXOmWqY9EZYeSbf0QWCMiErHLxm/jQY+TP88lNre99GmED
4mAD2+I5wd33MizbjfTSH/RAeT5MdLwiBzc6kVjxu4BWusPmdUgLs7vPuP3qeqMQ
q9VnL6mMsaFm0rKnID/MoOPtaghgSA==
=1T8z
-----END PGP SIGNATURE-----

More Repositories

1

flightplan

Run sequences of shell commands against local and remote hosts.
JavaScript
1,815
star
2

ticker.sh

Real-time stock tickers from the command-line.
Shell
502
star
3

metrics.sh

Collect and forward metrics using portable shell scripts
Shell
132
star
4

battery.js

A tiny wrapper for the HTML5 Battery Status API.
JavaScript
118
star
5

octofolders

The missing GitHub folder icons for Mac OS X.
97
star
6

dotfiles

For my very own convenience.
Vim Script
62
star
7

alfred-screensharing

Connect to a host in Alfred with automatic network discovery.
53
star
8

alfred-cask

Manage Homebrew Casks with Alfred.
Shell
46
star
9

alfred-mount

Use Alfred to connect to your network shares with ease.
Makefile
41
star
10

non-terminating-bash-processes

Taming non-terminating Bash processes.
Shell
40
star
11

optometrist

Your optometrists favorite color theme for Terminal.app and iTerm2.
34
star
12

alfred-top

Process management in Alfred with top and kill.
Shell
20
star
13

candy-node

Deploy Candy as a node.js application
JavaScript
20
star
14

plex-duplicates

Find duplicate movie files in Plex Media Server.
Ruby
17
star
15

dtox

Extensible data transfer objects in JavaScript.
JavaScript
11
star
16

pagerank-service

A web service providing Google PageRank results.
Ruby
10
star
17

the-cube

The Cube is an experiment with CSS3 transitions.
HTML
10
star
18

alfred-play

Intelligent global hotkeys for Music.app and Spotify with Alfred.
Makefile
9
star
19

rethinkdb-udp-charts

Real-time charts using RethinkDB changefeeds.
JavaScript
5
star
20

ff-pagerank-client

A simple Firefox extension for displaying the Google PageRank of the websites you're visiting.
JavaScript
5
star
21

octoprowl

GitHub + Prowl = Octoprowl
Ruby
4
star
22

ticker-rs

Real-time stock tickers from the command-line. Written in Rust.
Rust
4
star
23

cloudflare-webfinger

Bring your own domain to Mastodon using Cloudflare Workers.
JavaScript
4
star
24

redirectcheck-service

A web service to check the HTTP status code behind a URL.
Ruby
3
star
25

candy-go

Deploy Candy as a Go application.
Go
3
star
26

candy-gae

Candy on Google App Engine (experimental)
Python
1
star
27

pfsense-traffic

Command-line tool for displaying traffic data from pfSense
Shell
1
star
28

candy-rack

Deploy Candy as a Rack application.
Ruby
1
star
29

rancheros-uefi

UEFI bootable RancherOS image.
1
star
30

ff-redirectcheck-client

A simple Firefox extension for retrieving and displaying the HTTP status code right beside the link on a page.
JavaScript
1
star