Situatie
Git repositories store valuable source code and are used to build applications that work with sensitive data. If an attacker was able to compromise a GitHub account with a vulnerable repository, they could push malicious commits straight to production. Signed commits help ensure that doesn’t happen.
Solutie
Signed commits involve adding a digital signature to your commits, using a private cryptographic key, usually GPG, though it also supports SSH or X.509. Once created, you must add the signing key to both your GitHub profile, and your local Git client.
Signed commits provide an additional layer of security by ensuring that the commit has not been tampered with, and, more importantly, that it originates from a trusted source who both owns the GPG key and has the authority to access the GitHub account.
To push commits to a repository that only allows signed commits, the attacker must able to compromise the victim’s private GPG key, which usually means gaining access to their entire computer, not just their GitHub account. Since this is a fairly uncommon and difficult attack vector, signed commits provide an excellent way to verify commits are from who they say they are.
Setting Up a New GPG Key
First, you’ll need to create a new GPG key used for signing, and then you’ll need to tell both your Git client and GitHub about it.
To generate the key, you’ll need the gpg
command installed on your system. This should be there by default, but if it isn’t, you can get it from your package manager. Then, you can generate a new key:
gpg --full-generate-key
You can press enter for most of the prompts, but you must enter a passphrase, and you must enter your GitHub email address. If you want your address to be private, you can use the “no-reply” address for your GitHub account.
Then, list the keys, and export the public key block for the key ID you just created:
gpg --list-secret-keys gpg --armor --export [keyID]
Next, we’ll add it to your GitHub account. From your user settings, click “SSH and GPG Keys,” and add a new GPG key. You can also turn on Vigilant mode here, which will mark commits on GitHub not using these keys as unverified.
Set a name, and paste in the public key block you exported with gpg --export
.
Next is telling your local Git client about your key. If you use a GUI Git client like GitKraken, you may be able to simply import it, but otherwise, you’ll have to do it from the command line.
Since this is tied to your user, you’ll probably want to set it as a global config, but you can also use repository level configs. Set user.signingkey
to the GPG key ID you used to export.
git config --global user.signingkey [keyID]
Then, you’ll want to tell Git to sign all commits by default. This can be set for individual repositories if you want:
git config --global commit.gpgsign true
Otherwise, you can use the -S
flag to sign commits manually.
Enforcing Signed Commits With Branch Protection
Branch protection rules enforce restrictions and guidelines on specific branches in your repository. While they’re commonly used for enforcing a specific pull request and merge workflow, and restricting access to release branches, they can also be set up to only accept signed commits.
Only accepting signed commits provides an additional layer of security and forces every contributor to have a GPG key associated with their account.
It’s easy to create a new branch protection rule from the “Branches” tab in your repository settings. You’ll want to set the filter to “*” to include all branches.
Then select “Require signed commits.”
From now on, all commits pushed to all branches in this repository must contain GPG signing signatures.
Leave A Comment?