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.
MacOS: UsehomebrewLinux: Useapt-get,apk, etc- Windows: Get a better life, replace the entire OS with MacOS or Linux
Use the appropriate command for your OS...
- Install GPG CLI:
$ brew install gpg- Install Keybase:
Install from the website https://prerelease.keybase.io/
- 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.
- Generate new SSH keys:
$ ssh-keygen -o -t rsa -b 4096 -C "[email protected]"- Copy your public SSH key to your clipboard:
cat ~/.ssh/id_rsa.pub | pbcopy- Add the key to repos
- https://docs.gitlab.com/ee/ssh/
- https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
- 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.
- 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: [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 keychainYou 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.
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
$ cat ~/.zshenv
export GPG_TTY=$(tty)
if [ -f $HOME/.cargo/env ]; then
. "$HOME/.cargo/env"
fi- 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 <[email protected]>
Marcello DeSales <[email protected]>- Inspect the public key
- That can be used to past the keys at
$GITHUB_HOST/settings/keysGPG keys section.
- That can be used to past the keys at
$ 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 <[email protected]>" imported
gpg: Total number processed: 1
gpg: imported: 1NOTE: 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 <[email protected]>" 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$ 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 <[email protected]>
uid [ unknown] Marcello DeSales <[email protected]>
ssb rsa4096/E73E*******FF 2022-01-07 [E] [expires: 2038-01-03]- 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------ 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 <[email protected]>
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- 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 [email protected]
$ git config --global user.signingkey DC4*****25
$ git config --global commit.gpgsign trueThe 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 = [email protected]
signingkey = DC4E******B25
[commit]
gpgsign = true
[tag]
gpgsign = true
[includeIf "gitdir:~/dev/gitlab.com/supercash/"]
path = ~/.gitconfig-super.cash
[color]
ui = trueNOTE: YOU MUST SPECIFY THE
includeIfending with/
- Config for work address
cat ~/.gitconfig-super.cash
[user]
email = [email protected]In order to verify, just cd to the dir of your projects
βοΈ [email protected] π [email protected]
βΈοΈ [email protected] π [email protected] π‘ [email protected] π½ [email protected] βοΈ [email protected] π [email protected]
π€ 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
[email protected]
βοΈ [email protected] π [email protected]
βΈοΈ [email protected] π [email protected] π‘ [email protected] π½ [email protected] βοΈ [email protected] π³ [email protected] π [email protected]
π€ 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
[email protected]REF: https://docs.gitlab.com/ee/user/project/repository/gpg_signed_commits
- Go to the key settings of your repo server
- Copy your public key to your clipboard by running:
$ keybase pgp export -q C8A*****456 | pbcopyMake sure you use your actual signing key.
-
Paste your key and save.
-
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 PSTThe commit should show the signed information with gpg: on it...
- If you are allowed to create a merge request, it worked.
- commands like
git log --show-signaturewill 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 <[email protected]>
Date: Fri Jan 7 13:16:19 2022 -0800
:memo: README: update title to be shorterREF: 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 <[email protected]>
[ unknown] (2) Marcello DeSales <[email protected]>
- 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 <[email protected]>
[ unknown] (2) Marcello DeSales <[email protected]>
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 <[email protected]>
[ unknown] (2) Marcello DeSales <[email protected]>
Please note that the shown key validity is not necessarily correct
unless you restart the program.
gpg> q- 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 <[email protected]>" β
β 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 <[email protected]>" [ultimate]
gpg: aka "Marcello DeSales <[email protected]>" [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 <[email protected]>" [ultimate]
gpg: aka "Marcello DeSales <[email protected]>" [ultimate]
Author: Marcello DeSales <[email protected]>
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.mdInstall the GPG Suite, available from gpgtools.org, or from brew by running:
$ brew install --cask gpg-suiteOnce 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- You can verify all your accounts from the Keybase UI
- Still can't on Gitlab https://gitlab.com/gitlab-org/gitlab/-/issues/28209#note_804775223
Steps described at https://serverfault.com/questions/86048/how-to-backup-gpg/1040984#1040984
When installing the public/private keys in a new computer. Make sure to back them up and store them in a secure location.
- List the existing keys before transferring to another computer
- Export all what needs:
- public key
- private key
- sub private keys
- ownership
- Verify the keys
Here's the current list of keys
$ gpg -k
/Users/marcellodesales/.gnupg/pubring.kbx
-----------------------------------------
pub rsa4096 2022-01-07 [SC] [expires: 2038-01-03]
3C7A2B7BA9E2C86D5F0BFC26DC4E536EE3A84B25
uid [ultimate] Marcello DeSales <[email protected]>
uid [ultimate] Marcello DeSales <[email protected]>
sub rsa4096 2022-01-07 [E] [expires: 2038-01-03]- Choose any of the identifications of the key such as the name or email
$ gpg --export --armor [email protected] > [email protected]
$ cat ~/[email protected] | head -5 && echo "...\n...\n" && cat ~/[email protected] | tail -5
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGHYp1cBEACZ7CcPxd7cqKzgn3eYgSra1HUOqRbVM9H8fNNIl5COat/NxZb5
r3WJNHWEyyHkR2CuZuxxp7+QglmSA/iLWOGwXvbhuLMrDgObUlREHAiqs3eBaS/u
ZMLnX8zMlfi0YtAuiQTkayDNCYNTev138E+JGo58eCUEMUe+USTzmz8j9sHojuCD
...
...
fJREULTai3kRHgHSNLrd8I04beMeGYmJwOcXe3fIO4hJt7PP6X0F3Q4B+i/zaP+4
9trpzNMK2HHhLExRbsVf8ZSg5h3s5Pq+mvnimBvfNuHhqgKfIFERgH/YDl4LhHkB
vBXF3x3sBpWVJxutordywK4=
=k2Ne
-----END PGP PUBLIC KEY BLOCK------ Choose any of the identifications of the key such as the name or email
$ gpg --export-secret-keys --armor [email protected] > [email protected]
$ cat ~/[email protected] | head -5 && echo "...\n...\n" && cat ~/[email protected] | tail -5
-----BEGIN PGP PRIVATE KEY BLOCK-----
lQdGBGHYp1cBEACZ7CcPxd7cqKzgn3eYgSra1HUOqRbVM9H8fNNIl5COat/NxZb5
r3WJNHWEyyHkR2CuZuxxp7+QglmSA/iLWOGwXvbhuLMrDgObUlREHAiqs3eBaS/u
ZMLnX8zMlfi0YtAuiQTkayDNCYNTev138E+JGo58eCUEMUe+USTzmz8j9sHojuCD
...
...
3fCNOG3jHhmJicDnF3t3yDuISbezz+l9Bd0OAfov82j/uPba6czTCthx4SxMUW7F
X/GUoOYd7OT6vpr54pgb3zbh4aoCnyBREYB/2A5eC4R5AbwVxd8d7AaVlScbraK3
csCu
=d+0l
-----END PGP PRIVATE KEY BLOCK-----$ gpg --export-secret-subkeys --armor [email protected] > [email protected]_priv.asc
$ cat ~/[email protected]_priv.asc | head -5 && echo "...\n...\n" && cat ~/[email protected]_priv.asc | tail -5
-----BEGIN PGP PRIVATE KEY BLOCK-----
lQIVBGHYp1cBEACZ7CcPxd7cqKzgn3eYgSra1HUOqRbVM9H8fNNIl5COat/NxZb5
r3WJNHWEyyHkR2CuZuxxp7+QglmSA/iLWOGwXvbhuLMrDgObUlREHAiqs3eBaS/u
ZMLnX8zMlfi0YtAuiQTkayDNCYNTev138E+JGo58eCUEMUe+USTzmz8j9sHojuCD
...
...
MnyURFC02ot5ER4B0jS63fCNOG3jHhmJicDnF3t3yDuISbezz+l9Bd0OAfov82j/
uPba6czTCthx4SxMUW7FX/GUoOYd7OT6vpr54pgb3zbh4aoCnyBREYB/2A5eC4R5
AbwVxd8d7AaVlScbraK3csCu
=4eYm
-----END PGP PRIVATE KEY BLOCK-----$ gpg --export-ownertrust > ownertrust.txt
$ cat ownertrust.txt
# List of assigned trustvalues, created Fri May 24 18:52:42 2024 PDT
# (Use "gpg --import-ownertrust" to restore them)
3C7A2B7BA9E2C86D5F0BFC26DC4E536EE3A84B25:6:- Start from the public key
$ gpg --import [email protected]
gpg: directory '/Users/marcellodesales/.gnupg' created
gpg: /Users/marcellodesales/.gnupg/trustdb.gpg: trustdb created
gpg: key DC4E536EE3A84B25: public key "Marcello DeSales <[email protected]>" imported
gpg: Total number processed: 1
gpg: imported: 1ATTENTION: If you try to add the private key, you will get errors.
- Add the ownership trust first, then, add the private key... Skip this step
~ β 18:54:47
$ gpg --import [email protected]
gpg: key DC4E536EE3A84B25: "Marcello DeSales <[email protected]>" not changed
gpg: key DC4E536EE3A84B25/DC4E536EE3A84B25: error sending to agent: Bad passphrase
gpg: error building skey array: Bad passphrase
gpg: error reading '[email protected]': Bad passphrase
gpg: import from '[email protected]' failed: Bad passphrase
gpg: Total number processed: 0
gpg: unchanged: 1
gpg: secret keys read: 1- Add the ownertrust
$ gpg --import-ownertrust ownertrust.txt
gpg: inserting ownertrust of 6- Then, add the sub private keys first
$ gpg --import [email protected]_priv.asc
gpg: key DC4E536EE3A84B25: "Marcello DeSales <[email protected]>" not changed
gpg: To migrate 'secring.gpg', with each smartcard, run: gpg --card-status
gpg: key DC4E536EE3A84B25: secret key imported
gpg: Total number processed: 1
gpg: unchanged: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1- Attempting to add the private keys
$ gpg --import [email protected]
gpg: key DC4E536EE3A84B25: "Marcello DeSales <[email protected]>" 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
gpg: secret keys unchanged: 1- Show the keys
$ gpg --list-secret-keys --keyid-format LONG
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2038-01-03
[keyboxd]
---------
sec rsa4096/DC4E536EE3A84B25 2022-01-07 [SC] [expires: 2038-01-03]
3C7A2B7BA9E2C86D5F0BFC26DC4E536EE3A84B25
uid [ultimate] Marcello DeSales <[email protected]>
uid [ultimate] Marcello DeSales <[email protected]>
ssb rsa4096/E73EBAAEC18957FF 2022-01-07 [E] [expires: 2038-01-03]