Making a commit verified involves signing it cryptographically using a GPG key.
Why Sign Git Commits?
Before we get into the how let’s talk for a moment about why you should sign your Git commits. Besides the desire to get that green “Verified” badge on your work on GitHub, there are some concrete benefits.
When you commit a change with Git, it accepts as author whatever value you want. This means you could claim to be whoever you want when you create a commit.
For example, here’s a repo I just created. As you can see, my esteemed colleague and friend @MartinWoodward from GitHub committed in it right away:
There’s only one problem: Martin did not do that; I did.
To make GitHub (and everyone) believe that Martin authored that really terrible commit, I just had to run git config user.name
and git config user.email
with values that match Martin's. Those are not hard to get at all. It only took me one minute to clone one of his repos and then run git log
in it.
From the point of view of Git, this is actually working as intended. The committer details are designed just to identify who of your collaborators made a change and are not meant to be used for authenticating people. Being able to impersonate other committers does not introduce a vulnerability per se. For example, just by setting my user.name
to Martin's, I do not get the ability to push code to his repositories. GitHub would require me to authenticate with his credentials before I could do that.
However, while this is not a security vulnerability per se, it can cause other issues. When you see an unsigned commit, you have no guarantee that:
The author is really the person whose name is on the commit
The code change you see is really what the author wrote (i.e., it’s not been tampered with)
Making a habit of signing your Git commits instead gives you the ability to prove that you were the author of a specific code change. It also gives you the ability to ensure that no one can modify your commit (or its metadata, such as the time you claimed it was made at) in the future.
The more sensitive the code you’re working on (e.g., things related to security, or mission-critical applications), the more you should pay attention. Attacks on the software supply chain are getting more common, and their potential consequences more dangerous. The FBI has warned us.
Here’s how two hypothetical attacks on the software supply chain could look, with unsigned commits. First, imagine the case of a disgruntled employee who might purposely want to introduce a backdoor into an app they’re working on (on a repo they already have write access to), so they impersonate one of their teammates when submitting the code, to keep the blame away from themself.
Another example is someone creating a malicious pull request in an open-source project. They could make it look like someone else (for example, someone with a great reputation) co-authored it, to make it more likely that the PR will be accepted (if you maintain open-source libraries, you know how time-consuming it can be to fully, thoroughly review every PR).
Please note that just because you sign your Git commits, it doesn’t stop others from impersonating you. I have been regularly signing my commits for about a year, but you could still make a code change and put my name on it. There’s no way I can stop you from doing that. However, whoever reads your code won’t see my digital signature (or the “Verified” badge), and so they at least have the ability to question the authenticity of that commit or its integrity. On the other hand, people who do follow my repositories can see that I’ve authored all the commits in the last year.
For your own projects, if your Git hosting service allows that, you can also require a policy that all commits must be signed. On GitHub, that’s done with protected branches.