Skip to content

Instantly share code, notes, and snippets.

@buu-nguyen
Forked from Kranzes/guide.md
Last active November 5, 2024 18:04
Show Gist options
  • Save buu-nguyen/b9b7b9ac578b114d87c7cf1b5f4c7339 to your computer and use it in GitHub Desktop.
Save buu-nguyen/b9b7b9ac578b114d87c7cf1b5f4c7339 to your computer and use it in GitHub Desktop.
Local Development Git setup

Setup git global config

git config --global commit.gpgSign true
git config --global tag.gpgSign true
git config --global user.name "YOUR_NAME"
git config --global user.email "YOUR_EMAIL"

Confirm that you have set the identification correctly in Git:

git config --global --list

Authenticate with SSH key

Ignore this part and go to Authenticate with Resident SSH key if you want to use Resident SSH Key.

Generating the key

KEY_NAME="YOUR_KEY_NAME"
EMAIL="YOUR_EMAIL"
ssh-keygen -t ed25519 -O application=ssh:$KEY_NAME -C $EMAIL -f ~/.ssh/$KEY_NAME

Let's dive into the different parameters.

  • -t ed25519 is the key type.
  • -O application=ssh:$KEY_NAME names the key, so you can identify it more easily later, very handy if you generate a few.
  • -C $EMAIL comment the key with your email.

Adding the new keys

Now that you have generated a key which you can use, you will need to add it to your current ssh-agent session. You can do that by first starting the agent like so:

ssh-add ~/.ssh/$KEY_NAME

Authenticating with GitHub

In order to authenticate with GitHub you will have to add your new public key to your GitHub profile over at -> github.com/settings/keys. You can copy the public key to clipboard by running

pbcopy < ~/.ssh/$KEY_NAME.pub

Testing authentication

Now that we've added our ssh key to GitHub we can test that the setup works correctly by running:

ssh -T git@github.com

If this worked correctly you should be greeted by a "welcoming message".

NOTE: In order to make sure that you are using the new SSH key consider moving out existing keys from the ~/.ssh directory just for this test.

Authenticate with Resident SSH key

Ignore this part if you use normal SSH Key and already follow Authenticate with SSH key

Initial checks

Start by checking that there aren't any previous ssh keys inside the FIDO2 authenticator of your YubiKey. You can check if they exist by running the command below:

ykman fido credentials list

If the command above outputs a string mentioning "ssh" or "openssh", then you have already got a key generated and store on your YubiKey.

Generating the key

KEY_NAME="YOUR_KEY_NAME"
EMAIL="YOUR_EMAIL"
ssh-keygen -t ed25519-sk -O application=ssh:$KEY_NAME -O no-touch-required -O resident -C $EMAIL -f $KEY_NAME

Let's dive into the different parameters.

  • -t ed25519-sk is the key type, two options are possible ecdsa-sk and ed25519-sk (sk stands for security key). If you do not know which one to choose, stick with ed25519-sk.
  • -O application=ssh:$KEY_NAME names the key, so you can identify it more easily later, very handy if you generate a few.
  • -O no-touch-required prevents you from having to touch the YubiKey every time you want to use the key.
  • -O resident tells OpenSSH to store the key on the YubiKey.
  • -C $EMAIL comment the key with your email.

Adding the new keys

Now that you have generated a key which you can use, you will need to add it to your current ssh-agent session. You can do that by first starting the agent like so:

  • Add the key on the YubiKey temporarily to our current session with the command below:
ssh-add -K
  • If you would like to have it permanently available on the system you can run the command:
ssh-keygen -K
KEY_NAME="YOUR_KEY_NAME"
mv $KEY_NAME_rk ~/.ssh/$KEY_NAME
mv $KEY_NAME_rk.pub ~/.ssh/$KEY_NAME.pub
ssh-add ~/.ssh/$KEY_NAME

This retrieves our ssh key from our YubiKey and puts the private (still protected by YubiKey) and public key in the current working directory, then rename them accordingly to id_ed25519_sk and id_ed25519_sk.pub, then place them in your ~/.ssh directory so ssh can detect them.

Authenticating with GitHub

In order to authenticate with GitHub you will have to add your new public key to your GitHub profile over at -> github.com/settings/keys. You can copy the public key to clipboard by running

pbcopy < ~/.ssh/$KEY_NAME.pub

Testing authentication

Now that we've added our ssh key to GitHub we can test that the setup works correctly by running:

ssh -T git@github.com

If this worked correctly you should be greeted by a "welcoming message".

NOTE: In order to make sure that you are using the new SSH key consider moving out existing keys from the ~/.ssh directory just for this test.

Based on this blogpost.

To sign Git commits, you need a gpg key. GPG stands for GNU Privacy Guard and is the de facto implementation of the OpenPGP message format. PGP stands for ‘Pretty Good Privacy’ and is a standard to sign and encrypt messages.

Setting up

Install with Homebrew:

$ brew install gpg pinentry-mac

Create config files for gpg and the gpg-agent. The agent will make sure you don’t have to type in your GPG passphrase for every commit. Extend cache ttl to make sure your credentials are ‘kept alive’.

# Create GPG directory (if it doesn't exist)
mkdir -p ~/.gnupg

# Configure GPG
cat << EOF > ~/.gnupg/gpg.conf
use-agent
EOF

cat << EOF > ~/.gnupg/gpg-agent.conf
default-cache-ttl 34560000
max-cache-ttl 34560000
pinentry-program /opt/homebrew/bin/pinentry-mac
EOF

Note: if you’re on Intel, /opt/homebrew should be /usr/local.

Create GPG keypair

Now that your environment is properly set up, we need to generate a public/private GPG keypair.

gpg --full-gen-key

A wizard is printed to your terminal. You should configure as follows:

  • Kind of key: 4 (RSA, sign only)
  • Keysize: 4096
  • Expiration: 2y (your key will expire after 2 years; you should set a reminder somewhere)
  • Real name: <your github username>
  • Email address: <your email address>

Note: I heartily recommend setting your email address to your 'noreply' GitHub address: username@users.noreply.github.com. You can find your email address on the GitHub Email settings page. Note that if you created a GitHub account after July 2017, your address will also have an ID prefixed to your username; read more here.

The final step in setting up the GPG keypair is typing a passphrase. Make sure it is strong and you have it safely stored in your password vault (I recommend Bitwarden). Whoever has your passphrase can sign your commits and there is no way to prove it wasn’t you.

After creating the keypair, output similar to the following is printed to your terminal:

pub   rsa4096 2021-11-12 [SC] [expires: 2023-11-12]
      AAABBBCCCDDDEEEFFF1112223334445556667778
uid                      username <username@users.noreply.github.com>

The string of characters is your key ID. To confirm you can sign messages with your newly created key, enter in your terminal:

echo 'it works' | gpg --clearsign

A message similar to this should appear:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

it works
-----BEGIN PGP SIGNATURE-----
<many characters>
-----END PGP SIGNATURE-----

Adding to Git

We need to add your key to your git config, and to GitHub. First, you need to find the key ID. The (short) ID uses the last 8 characters of the key that was printed to the terminal before. You can retrieve it:

gpg --list-secret-keys --keyid-format SHORT

Outputs:

/Users/username/.gnupg/pubring.kbx
----------------------------------
sec   rsa4096/56667778 2021-11-12 [SC] [expires: 2023-11-12]
      AAABBBCCCDDDEEEFFF1112223334445556667778
uid         [ultimate] username <username@users.noreply.github.com>

The 56667778 bit after rsa4096/ is your short key ID. We need it to configure Git to sign commits and tags. Replace the YOUR_KEY_ID value below with your own key ID:

KEY_ID=YOUR_KEY_ID
git config --global user.signingkey $KEY_ID

Finally, you need to add your public GPG key to GitHub. Again, make sure to replace the ID with your own ID:

gpg --armor --export $KEY_ID

Outputs:

-----BEGIN PGP PUBLIC KEY BLOCK-----

<many characters>
-----END PGP PUBLIC KEY BLOCK-----

You need to copy the whole block and add it to GitHub. If you’re not sure what to copy, use this command:

gpg --armor --export $KEY_ID | pbcopy

The | pbcopy part will pipe the output of the first part directly to your copy-paste memory.

Go to the GitHub SSH and GPG keys section, click [New GPG key] and paste into the box. Click [Add GPG key], and you’re done!

After getting this done, and after having made your first signed commit, you can see the ‘Verified’ badge on GitHub for that commit (see an example here). Your GPG key ID will be shown when the badge is clicked.

Visual Studio Code

If you use Visual Studio Code, you can turn on signing by changing a setting.

Open VSCode, go to Preferences > Settings, and search for git.enableCommitSigning. Turn this setting on, and you’re good to go.

Troubleshooting

1. Kill the agent

If for some reason you can’t sign, simply kill the agent. It will restart when needed:

gpgconf --kill gpg-agent

2. Older/remote shells

On older MacOS versions or certain (remote) shells, you might encounter the error inappropriate ioctl for device. (This error might also turn up if you haven’t configured the GPG_TTY environment variable correctly, see above for instructions.) More context here. You can fix this by using the so called ‘loopback’ option to enter your passphrase directly on the CLI.

Edit gpg.conf and add:

pinentry-mode loopback

Edit gpg-agent.conf and add:

allow-loopback-pinentry

Now, when the agent wants your passphrase it will simply render a basic password input on the CLI:

echo 'it works' | gpg --clearsign
Enter passphrase:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment