Skip to content

Instantly share code, notes, and snippets.

@marcellodesales
Forked from jplew/README.md
Last active April 3, 2023 01:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcellodesales/4beda0a503c5ff38b1fe4e66997b5e4d to your computer and use it in GitHub Desktop.
Save marcellodesales/4beda0a503c5ff38b1fe4e66997b5e4d to your computer and use it in GitHub Desktop.
How to Setup SSH and GPG keys with Gitlab

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

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 Gitlab.

Requirements

  • MacOS: Use homebrew
  • Linux: Use apt-get, apk, etc
  • Windows: Get a better life, replace the entire OS with MacOS or Linux

Use the appropriate command for your OS...

  1. Install GPG CLI:
$ brew install gpg
  1. Install Keybase:

Install from the website https://prerelease.keybase.io/

  1. You should now have both the keycloak CLI and the Keybase desktop app (/Applications/Keybase). Open the Keybase app, create an account and sign in.

Add your public SSH key to Gitlab:

  1. Generate new SSH keys:
$ ssh-keygen -o -t rsa -b 4096 -C "email@host.type"
  1. Copy your public SSH key to your clipboard:
cat ~/.ssh/id_rsa.pub | pbcopy
  1. Add the key to repos
  1. Test that this worked by cloning a repo using the git:// protocol

This should succeed if you are a member of the repo and that you can clone the repo read/write permissions.

Create a new GPG key using the Keybase CLI

  1. Generate a new PGP key and write it to your local secret keychain:
$ 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: patrick.stadler@gmail.com
# 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 <patrick.stadler@gmail.com> [primary]
# ▶ INFO Generating primary key (4096 bits)
# ▶ INFO Generating encryption subkey (4096 bits)
# ▶ INFO Generated new PGP key:
# ▶ INFO   user: Patrick Stadler <patrick.stadler@gmail.com>
# ▶ INFO   4096-bit RSA key, ID CB86A866E870EE00, created 2016-04-06
# ▶ INFO Exported new key to the local GPG keychain

You will be prompted to set a passphrase. Create a strong, 31-character password using your Keychain Access app (see reference image above).

Enter it twice to confirm. Since you will likely need it again, store this password somewhere secure, like as a Secure Note in Keychain Access, or in a password manager like LastPass.

Export and Import from Keybase

Keybase Commands: https://book.keybase.io/docs/cli#basics Explanation: https://davidwinter.dev/managing-gpg-with-keybase/ NOTE: Make sure to set export GPG_TTY=$(tty) before starting

  • Login and verify user (Note that if the desktop version is available you are all logged in)
$ keybase login
$ keybase whoami
marcellodesales
$ keybase status
Username:      marcellodesales
Logged in:     yes

Device:
    name:      Mac Device - Work **** M1 MAC
    ID:        92b8a65*****01318
    status:    active
...
...
  • Look for the key required
$ keybase pgp list
Keybase Key ID:  0101cd33c5162998afc99ae6ec76f1bea8709b1046dc036a23ce356a4e47947588ae0a
PGP Fingerprint: 3c7a2b7ba9e2c86d5f0bfc26dc4e536ee3a84b25
PGP Identities:
   Marcello DeSales <marcello.desales@gmail.com>
   Marcello DeSales <marcello@super.cash>
  • Inspect the public key
    • That can be used to past the keys at $GITHUB_HOST/settings/keys GPG keys section.
$ keybase pgp export -q 3c7a2b7ba9e2c86d5f0bfc26dc4e536ee3a84b25
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: https://keybase.io/download
Version: Keybase Go 5.9.0 (darwin)

xsFNBGHYp1cBEACZ7CcPxd7cqKzgn3eYgSra1HUOqRbVM9H8fNNIl5COat/NxZb5
r3WJNHWEyyHkR2CuZuxxp7+QglmSA/iLWOGwXvbhuLMrDgObUlREHAiqs3eBaS/u
...
...
  • Export the public
$ keybase pgp export -q 3c7a2b7ba9e2c86d5f0bfc26dc4e536ee3a84b25 | gpg --import
gpg: key DC4E536EE3A84B25: public key "Marcello DeSales <marcello.desales@gmail.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1

NOTE: You must have the env GPG_TTY=$(tty) so that the prompt shows up in the terminal to import the private key Sometimes the prompt will not show if this is not set

$ keybase pgp export -q 3c7a2b7ba9e2c86d5f0bfc26dc4e536ee3a84b25 --secret | gpg --allow-secret-key-import --import
gpg: key DC4E536EE3A84B25: "Marcello DeSales <marcello.desales@gmail.com>" not changed
gpg: key DC4E536EE3A84B25: secret key imported
gpg: Total number processed: 1
gpg:              unchanged: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1

Associate Email to GPG Key

List secrets

$ gpg --list-secret-key --keyid-form LONG
/Users/marcellodesales/.gnupg/pubring.kbx
-----------------------------------------
sec   rsa4096/DC*****25 2022-01-07 [SC] [expires: 2038-01-03]
      3C7A2B7B***********6EE3A84B25
uid                 [ unknown] Marcello DeSales <marcello.desales@gmail.com>
uid                 [ unknown] Marcello DeSales <marcello@super.cash>
ssb   rsa4096/E73E*******FF 2022-01-07 [E] [expires: 2038-01-03]

Get Public GPG Signature

  • keybase
keybase pgp export -q DC4E******25 | pbcopy
  • gpg
$ gpg --armor --export DC*****B25
-----BEGIN PGP PUBLIC KEY BLOCK-----

mQINBGHYp1cBEACZ7CcPxd7cqKzgn3eYgSra1HUOqRbVM9H8fNNIl5COat/NxZb5
r3WJNHWEyyHkR2CuZuxxp7+QglmSA/iLWOGwXvbhuLMrDgObUlREHAiqs3eBaS/u
...
...
9trpzNMK2HHhLExRbsVf8ZSg5h3s5Pq+mvnimBvfNuHhqgKfIFERgH/YDl4LhHkB
vBXF3x3sBpWVJxutordywK4=
=k2Ne
-----END PGP PUBLIC KEY BLOCK-----

Set up Git to sign all commits

  1. Obtain your signing key via the GPG CLI:
$ gpg --list-secret-keys --keyid-format LONG

/Users/jplew/.gnupg/pubring.kbx
-------------------------------
sec   rsa4096/C8AB98F11Y123456 2018-06-02 [SC] [expires: 2034-05-29]
      B21DBAB6AA037F5641504A8CC2DB56E29C562080
uid                 [ unknown] JP Lew <jp@cto.ai>
ssb   rsa4096/ZZ1Z1234556FAPPO 2018-06-02 [E] [expires: 2034-05-29]

Your signingkey is the 16-character string on the sec line, following rsa4096/.

gpg --list-secret-keys --keyid-format LONG | grep sec  | awk '{ print $2 }' | awk -F"/" '{ print $2 }'
DC4*****25
  1. Add your signing key and user info to your global Git config file. To do this this, you can either:
$ git config --global user.name "Marcello DeSales"
$ git config --global user.email myemail@mydomain.com
$ git config --global user.signingkey DC4*****25
$ git config --global commit.gpgsign true

Update Config ~/.gitconfig

REF: https://stackoverflow.com/questions/4220416/can-i-specify-multiple-users-for-myself-in-gitconfig/43654115#43654115

The final product should look like this:

  • Default config is with open-source email address
  • Work email address stays in separate config
    • cat ~/.gitconfig
    • It can also have its own section for the signing
[user]
    name = Marcello DeSales
    email = marcello.desales@gmail.com
    signingkey = DC4E******B25

[commit]
    gpgsign = true

[tag]
    gpgsign = true

[includeIf "gitdir:~/dev/gitlab.com/supercash/"]
    path = ~/.gitconfig-super.cash

[color]
    ui = true

NOTE: YOU MUST SPECIFY THE includeIf ending with /

  • Config for work address
    • cat ~/.gitconfig-super.cash
[user]
    email = marcello@super.cash

In order to verify, just cd to the dir of your projects

☁️  aws-cli@2.2.32 🔖 aws-iam-authenticator@0.5.3
☸️  kubectl@1.22.4 📛 kustomize@v4.3.0 🎡 helm@3.7.0 👽 argocd@2.2.0 ✈️  glooctl@1.9.0  🐙 docker-compose@1.29.2
👤 AWS_PS1_PROFILE 🗂️   🌎 sa-east-1
🏗  1.21.2-eks-0389ca3 🔐 arn:aws:eks:sa-east-1:806101772216:cluster/eks-ppd-prd-super-cash 🍱 default
~/dev/github.com/marcellodesales/Systems-Design on  master! 📅 01-07-2022 ⌚14:18:19
$ git config user.email
marcello.desales@gmail.com

☁️  aws-cli@2.2.32 🔖 aws-iam-authenticator@0.5.3
☸️  kubectl@1.22.4 📛 kustomize@v4.3.0 🎡 helm@3.7.0 👽 argocd@2.2.0 ✈️  glooctl@1.9.0 🐳 docker@20.10.11 🐙 docker-compose@1.29.2
👤 AWS_PS1_PROFILE 🗂️   🌎 sa-east-1
🏗  1.21.2-eks-0389ca3 🔐 arn:aws:eks:sa-east-1:806101772216:cluster/eks-ppd-prd-super-cash 🍱 default
~/dev/gitlab.com/supercash/apps-web/maceio-shopping-tickets-web on  develop! 📅 01-07-2022 ⌚14:17:43
$ git config user.email
marcello@super.cash

Add your public GPG key to Git Servers

REF: https://docs.gitlab.com/ee/user/project/repository/gpg_signed_commits

  1. Go to the key settings of your repo server
  1. Copy your public key to your clipboard by running:
$ keybase pgp export -q C8A*****456 | pbcopy

Make sure you use your actual signing key.

  1. Paste your key and save.

  2. Test that this worked by signing a git commit and submitting a merge request.

$ cd myrepo
$ git touch newfile.txt
$ git commit -m "make a GPG signed commit"
$ git --no-pager show --show-signature
commit 0d9c2366a58c985b3ce31c32ad092ecf0a0ba378 (HEAD -> feature/pipeline-with-deployment-cloudfront)
gpg: Signature made Fri Jan  7 13:16:19 2022 PST

The commit should show the signed information with gpg: on it...

  1. If you are allowed to create a merge request, it worked.

Trust the Key

Problem

  • commands like git log --show-signature will show the problem
$ git --no-pager show --show-signature
commit 0d9c2366a58c985b3ce31c32ad092ecf0a0ba378 (HEAD -> feature/pipeline-with-deployment-cloudfront)
gpg: Signature made Fri Jan  7 13:16:19 2022 PST
gpg:                using RSA key 3C7A****B25
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Author: Marcello DeSales <marcello.desales@gmail.com>
Date:   Fri Jan 7 13:16:19 2022 -0800

    :memo: README: update title to be shorter

Solution

REF: https://serverfault.com/questions/569911/how-to-verify-an-imported-gpg-key/569923#569923

  • List the key ID
$ gpg --list-secret-keys --keyid-format LONG | grep sec  | awk '{ print $2 }' | awk -F"/" '{ print $2 }'
DC4*****B25
  • Edit the key
$ gpg --edit-key DC4****B25
gpg (GnuPG) 2.3.4; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa4096/DC4****25
     created: 2022-01-07  expires: 2038-01-03  usage: SC
     trust: unknown       validity: unknown
ssb  rsa4096/E73******7FF
     created: 2022-01-07  expires: 2038-01-03  usage: E
[ unknown] (1). Marcello DeSales <marcello.desales@gmail.com>
[ unknown] (2)  Marcello DeSales <marcello@super.cash>
  • On the prompt, type trust
gpg> trust
sec  rsa4096/DC4*****25
     created: 2022-01-07  expires: 2038-01-03  usage: SC
     trust: unknown       validity: unknown
ssb  rsa4096/E73EBAAEC18957FF
     created: 2022-01-07  expires: 2038-01-03  usage: E
[ unknown] (1). Marcello DeSales <marcello.desales@gmail.com>
[ unknown] (2)  Marcello DeSales <marcello@super.cash>

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

sec  rsa4096/DC4****25
     created: 2022-01-07  expires: 2038-01-03  usage: SC
     trust: ultimate      validity: unknown
ssb  rsa4096/E73****7FF
     created: 2022-01-07  expires: 2038-01-03  usage: E
[ unknown] (1). Marcello DeSales <marcello.desales@gmail.com>
[ unknown] (2)  Marcello DeSales <marcello@super.cash>
Please note that the shown key validity is not necessarily correct
unless you restart the program.

gpg> q

Verify signed commits

  • Set the commit prompt to ask for the passthrase of signature once it finishes the commit
export GPG_TTY=$(tty)`
  • Make a new commit... It will ask for the passphrase of the key
	       ┌───────────────────────────────────────────────────────────────┐
	       │ Please enter the passphrase to unlock the OpenPGP secret key: │
	       │ "Marcello DeSales <marcello.desales@gmail.com>"               │
	       │ 4096-bit RSA key, ID DC*****25,                               │
	       │ created 2022-01-07.                                           │
	       │                                                               │
	       │                                                               │
	       │ Passphrase: _________________________________________________ │
	       │                                                               │
	       │         <OK>                                   <Cancel>       │
	       └───────────────────────────────────────────────────────────────┘
  • Upon entering the passphrase, the commit works... Now you can verify it is signed
# https://stackoverflow.com/questions/3357280/print-commit-message-of-a-given-commit-in-git/54886099#54886099
$ git --no-pager show --show-signature -s --format=%s
gpg: Signature made Sun Jul  3 19:08:06 2022 PDT
gpg:                using RSA key 33F17EFF7BD0A66A8C533A41A0CDC02D297930BF
gpg: Good signature from "Marcello DeSales <marcello.desales@viasat.com>" [ultimate]
gpg:                 aka "Marcello DeSales <marcello.desalesjr@viasat.com>" [ultimate]
:tada: :memo: Add readme initial for the project

$ git --no-pager show --show-signature
commit 0d9c2366a58c985b3ce31c32ad092ecf0a0ba378 (HEAD -> feature/pipeline-with-deployment-cloudfront)
gpg: Signature made Fri Jan  7 13:16:19 2022 PST
gpg:                using RSA key 3C7A2B7BA9*******84B25
gpg: Good signature from "Marcello DeSales <marcello.desales@gmail.com>" [ultimate]
gpg:                 aka "Marcello DeSales <marcello@super.cash>" [ultimate]
Author: Marcello DeSales <marcello.desales@gmail.com>
Date:   Fri Jan 7 13:16:19 2022 -0800

    :memo: README: update title to be shorter

diff --git a/README.md b/README.md
index 28748c1..652b6be 100644
--- a/README.md
+++ b/README.md

Optional: Manage your GPG keys using GPG Suite

Install the GPG Suite, available from gpgtools.org, or from brew by running:

$ brew install --cask gpg-suite

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

Select the Default Key if it is not already selected, and ensure "Store in OS X Keychain" is checked (see reference image above):

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

Keybase Verifications

Keybase Encrypt/Decrypt, Sign/Verify

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment