skip to content
System Design in the Smoking Room
(AI translated)

Signing commits and why you'd bother

/ 3 min read

Table of contents

Why you’d bother

Few people stop to think that Gitlab, Github, Gitea, Bitbucket and other source-hosting hubs, when they show who authored a commit, lean on two simple fields that you filled in the first time you pushed something from a new box.

Terminal window
git config --global user.name "<Your name>"
git config --global user.email "<Your email>"

And that’s fine, because it just works. The thing is, there’s little stopping some bad actor from impersonating you (after all, both the name and the email are public and sit under every commit), or stopping someone from grandly claiming that, say, Linus Torvalds himself took part in developing an is-odd fork for Rust.

And in general, signing commits is considered good practice — if you’ve ever taken part in developing some big Open Source project, you’ve almost certainly run into it.

Signing commits

For pretty much any hub the flow goes roughly like this:

  1. Generate a key (SSH, GPG or some other supported one)
  1. Attach it to your account

  2. Set up your local git client to work with a specific key

  3. (Optional) Set up git so that commits get signed automatically

Let’s run through each of the points briefly.

Generating a key

GPG

Install gpg and in the terminal run:

Terminal window
gpg --full-generate-key

Then, in interactive mode:

  • Pick the key type, or hit Enter to go with the default

  • Specify the key size, or Enter for the default

  • Specify the key’s lifetime, or just Enter so the key never goes stale

  • Enter our info

  • Enter a passphrase for the key, or Enter so signing works without one

Done! The key is created, and now you can check via gpg that it exists:

Terminal window
$ gpg --list-secret-keys --keyid-format=long
/home/anon/.gnupg/secring.gpg
------------------------------------
sec 4096R/3AA5C34371567BD2 2025-03-10 [expires: never]
uid Anon <anon@example.com>
ssb 4096R/4BB6D45482678BE3 2025-03-10

In this example, the value we care about is 3AA5C34371567BD2. Let’s get the public part for this key:

Terminal window
gpg --armor --export 3AA5C34371567BD2
# Prints the GPG key ID, in ASCII armor format

You can now copy the public part of the key.

Attaching to your account

Github

  1. On any Github page, click your profile photo and pick the Settings gear.

  2. Under the Access section find GPG and SSH keys and go there

  3. Scroll down to the GPG keys section and hit New GPG key

  4. Give it a name — for example, the name of the device this key belongs to — copy the key from the last step and paste it into the field. Hit Add GPG key

  5. All set! The key shows up in the list and is attached to your account.

Gitlab

TODO

Configuring git

Do this after generating the key in the step above. Get the list of existing keys:

Terminal window
$ gpg --list-secret-keys --keyid-format=long
/home/anon/.gnupg/secring.gpg
------------------------------------
sec 4096R/3AA5C34371567BD2 2025-03-10 [expires: never]
uid Anon <anon@example.com>
ssb 4096R/4BB6D45482678BE3 2025-03-10

In this example we’ll use the value 3AA5C34371567BD2.

Set this key for a specific repo:

Terminal window
git config user.signingkey 3AA5C34371567BD2

or the same thing for all repositories by default:

Terminal window
git config --global user.signingkey 3AA5C34371567BD2

Optional Set up git so that all commits and tags get signed with our signature:

Terminal window
# Commits
git config --global commit.gpgsign true
# Tags
git config --global tag.gpgSign true

Wrapping up

All in all it’s a completely optional thing if you’re developing solo, but pretty important for big Open-source projects. I’d say it’s worth setting up just for the sake of general know-how.