Sign Git commits
2024-05-28 | ๐ 1210 words | โฑ 13 mins | ๐งพ History | โ Ross Buggins | ๐ Ross Buggins
Sign Git commits
Known Issues / Todo
- โ This page is draft and is subject to rapid change, and may not be fully accurate or complete
Guide: Sign Git commits
Overview
Signing Git commits is a good practice and ensures the correct web of trust has been established for the distributed version control management, e.g. Bitwarden.
There are two ways to sign commits in GitHub, using a GPG or an SSH signature. Detailed information about this can be found in the following documentation. It is recommended to use the GPG method for signing commits as GPG keys can be set to expire or be revoked if needed. Below is a step-by-step guide on how to set it up.
Signing commits using GPG
Generate GPG key
If you do not have it already generate a new pair of GPG keys. Please change the passphrase (pleaseChooseYourKeyPassphrase) below and save it in your password manager.
USER_NAME="Your Name"
USER_EMAIL="your.name@email"
file=$(echo $USER_EMAIL | sed "s/[^[:alpha:]]/-/g")
mkdir -p "$HOME/.gnupg"
chmod 0700 "$HOME/.gnupg"
cd "$HOME/.gnupg"
cat > "$file.gpg-key.script" <<EOF
%echo Generating a GPG key
Key-Type: ECDSA
Key-Curve: nistp256
Subkey-Type: ECDH
Subkey-Curve: nistp256
Name-Real: $USER_NAME
Name-Email: $USER_EMAIL
Expire-Date: 0
Passphrase: pleaseChooseYourKeyPassphrase
%commit
%echo done
EOF
gpg --batch --generate-key "$file.gpg-key.script"
rm "$file.gpg-key.script"
# or do it manually by running `gpg --full-gen-key`
Make note of the ID and save the keys.
gpg --list-secret-keys --keyid-format LONG $USER_EMAIL
You should see a similar output to this:
sec nistp256/AAAAAAAAAAAAAAAA 2023-01-01 [SCA]
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid [ultimate] Your Name <your.name@email>
ssb nistp256/BBBBBBBBBBBBBBBB 2023-01-01 [E]
Export your keys.
ID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
gpg --armor --export $ID > $file.gpg-key.pub
gpg --armor --export-secret-keys $ID > $file.gpg-key
Import already existing private key. GPG keys are stored in the ~/.gnupg
directory.
gpg --import $file.gpg-key
Remove keys from the GPG agent if no longer needed.
gpg --delete-secret-keys $ID
gpg --delete-keys $ID
Configure Git
Use the following commands to set your default signing key in Git to the ID of the GPG key you generated. Replace $ID
with your actual GPG key ID from the script above.
git config --global user.signingkey $ID
Then enable automatic signing of Git commits by running:
git config --global commit.gpgsign true
Configure GitHub
To add your GPG public key to your GitHub account follow these steps:
- Navigate to your GitHub account settings.
- From the sidebar, click on โSSH and GPG keysโ.
- Click on the โNew GPG keyโ button.
- In the โTitleโ field, enter a descriptive name for the key, like โMy GitHub signing keyโ.
-
Copy the contents of your public key file and paste it into the โKeyโ field.
cat $file.gpg-key.pub
- Click โAdd GPG keyโ to save.
After completing these steps, your new signing key will be listed in the โSSH and GPG keysโ section of your GitHub profile.
Troubleshooting
If you receive the error message error: gpg failed to sign the data
, make sure you added export GPG_TTY=$(tty)
to your ~/.zshrc
or ~/.bashrc
, and restarted your terminal.
sed -i '/^export GPG_TTY/d' ~/.exports
echo "export GPG_TTY=\$TTY" >> ~/.exports
Additional settings
Configure caching git commit signature passphrase for 3 hours
source ~/.zshrc # or ~/.bashrc
mkdir -p ~/.gnupg
sed -i '/^pinentry-program/d' ~/.gnupg/gpg-agent.conf 2>/dev/null ||:
echo "pinentry-program $(whereis -q pinentry)" >> ~/.gnupg/gpg-agent.conf
sed -i '/^default-cache-ttl/d' ~/.gnupg/gpg-agent.conf
echo "default-cache-ttl 10800" >> ~/.gnupg/gpg-agent.conf
sed -i '/^max-cache-ttl/d' ~/.gnupg/gpg-agent.conf
echo "max-cache-ttl 10800" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent
git config --global credential.helper cache
#git config --global --unset credential.helper
Signing commits using SSH
Generate SSH key
You should not do this if you already have GPG signing set up. One or the other is fine, but not both.
If you do not already have SSH key access set up on your GitHub account, first generate a new SSH key. To create a new SSH key, you need to run the following command. This will generate a new SSH key of the type ed25519
and associate it with your email address. Please replace your.name@email with your actual email address.
ssh-keygen -t ed25519 -C "your.name@email" -f "~/.ssh/github-signing-key"
When you run this command, it will ask you to enter a passphrase. Choose a strong passphrase and make sure to remember it, as you will need to provide it when your key is loaded by the SSH agent.
Configure Git
If you are signing commits locally using an SSH key, you need to configure Git accordingly since it is not the default method.
Run the following command to instruct Git to use the SSH signing key format, instead of the default GPG:
git config --global gpg.format ssh
Next, specify the private key for Git to use:
git config --global user.signingkey ~/.ssh/github-signing-key
Lastly, instruct Git to sign all of your commits:
git config --global commit.gpgsign true
Configure GitHub
To add your SSH public key to your GitHub account follow these steps:
- Navigate to your GitHub account settings.
- From the sidebar, click on โSSH and GPG keysโ.
- Click on the โNew SSH keyโ button.
- In the โTitleโ field, enter a descriptive name for the key, like โMy GitHub signing keyโ.
-
Copy the contents of your public key file and paste it into the โKeyโ field.
cat ~/.ssh/github-signing-key.pub
- Ensure to select โSigning Keyโ from the โKey typeโ dropdown.
- Click โAdd SSH keyโ to save.
After completing these steps, your new signing key will be listed in the โSSH and GPG keysโ section of your GitHub profile.
Testing
To ensure your configuration works as expected, make a commit to a branch locally and push it to GitHub. When you view the commit history of the branch on GitHub, your latest commit should now display a Verified
tag, which indicates successful signing with your GPG or SSH key.