Git: The complete guide to sign your commits with an SSH key
Tags: git, ssh, tutorial
Published: 2024-04-07 16:48:01

Please read the introduction I wrote about why signing your git commits

{% embed https://dev.to/ccoveille/why-and-not-only-how-signing-your-commits-4nja %}

To configure Git to sign commits with SSH keys, follow these steps:

## Ensure Compatibility

Make sure you have Git version 2.34 or later, as SSH signature verification is available from this version onwards. 

To check your git version, you can run the following command.

```console
$ git --version
git version 2.43.2
```

You also need OpenSSH 8.8 or newer. Signing is available since version 8.1, but was broken with 8.7. So version 8.8 or newer is recommended.

To check your ssh version, you can run the following command

```console
$ ssh -V
OpenSSH_8.9 ...
```

## Generate or Use an Existing SSH Key

If you don't already have an SSH key, generate a new one. You can use an existing SSH key for signing commits and tags. The recommended types for the SSH key are ED25519 or RSA 2.

{% embed https://dev.to/ccoveille/how-to-generate-a-secure-and-robust-ssh-key-in-2024-3f4f %}

{% embed https://dev.to/ccoveille/how-to-secure-an-existing-ssh-key-with-a-passphrase-pkc %}


## Configure Git to Use SSH for Signing:

Set Git to use SSH for signing by running the following command:

```shell
git config --global gpg.format ssh
```

Commit signing was historically available with GPG. Git configuration evolved to use ssh format. It explains the strange setting about `gpg.format=ssh`

Specify the public SSH key to use as the signing key. Replace /PATH/TO/.SSH/KEY.PUB with the actual path to your public key:

```shell
git config --global user.signingkey /PATH/TO/.SSH/KEY.PUB
```

For example, if your key is located at ~/.ssh/id_ed25519.pub, the command would be:

```shell
git config --global user.signingkey ~/.ssh/id_ed25519.pub
```

You may see how telling you to add the 

To verify SSH signatures locally, you'll need to create an allowed signers file and configure Git to use it.

You can choose to configure this globally, for example:

```shell
echo "$(git config --get user.email) namespaces=\"git\" $(cat ~/.ssh/id_ed25519.pub)" >> ~/.ssh/allowed_signers
```

You can now tell git to use this file when checking your keys.

```shell
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
```

## Sign Commits

To sign a commit, use the -S flag with the git commit command:

```shell
git commit -S -m "Your commit message"
```

Remember, Git uses the private key for signing. If your configuration uses a public key, Git will ask for the private key from the `ssh-agent`

So from now, every single commit you made are signed.

## Sign Tags

```shell
git tag -s <whatever>
```

Here you can see the tag signing using `-s` while `git commit` uses `-S`. `git commit -s` is used for something else the "signoff" thing.

## Automatically Sign Commits && Tags

If you prefer not to use the sign flag every time, you can configure Git to automatically sign your commits and tags

```shell
git config --global commit.gpgsign true
git config --global tag.gpgsign true
```

## Verify Commits: Ensure that your commits are verified. 

Signature verification uses the `allowed_signers` file to associate emails and SSH keys. For help to configure this file, refer to the documentation on verifying commits locally.

```shell
git log --show-signature
```

## About Signoff

You need to use --signoff with Git when:

- You are contributing to a project that requires a [Developer Certificate of Origin (DCO)](https://developercertificate.org/) for commits. The DCO is a statement that you have the right to submit the work under the same license as the project and that you are doing so under that license. The --signoff option adds a Signed-off-by: line at the end of the commit message, indicating that you certify the DCO.

- You are working in a repository where the commit signoff policy is enabled, requiring users to automatically sign off on the commits they make. This can be managed through GitHub's web interface, where organization owners and repository admins can enforce this requirement.

The `--signoff` option is particularly useful in open-source projects to ensure that contributions are properly attributed and that the project's license is adhered to. It also helps in tracking who did what in the project, especially when patches are involved.

You can add a setting to automatically sign off your commit when they are signed

```shell
git config --global format.signoff true
```

## TL; DR;

```shell
git config --global gpg.format ssh
git config --global user.signingkey ~/PATH/TO/.SSH/KEY.PUB
echo "$(git config --get user.email) namespaces=\"git\" $(cat ~/PATH/TO/.SSH/KEY.PUB)" >> ~/.ssh/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
git config --global commit.gpgsign true
git config --global tag.gpgsign true
git config --global format.signoff true
```

In the next article, I will explain how to configure GitHub to display the "verified" badge aside your commits

{% embed https://dev.to/ccoveille/how-to-get-the-verified-badge-on-github-with-ssh-key-signing-3kbe %}