68 lines
2.3 KiB
Markdown
68 lines
2.3 KiB
Markdown
|
# Commit signing
|
||
|
|
||
|
Signing all commits has significant value when you do it universally, and
|
||
|
all the more when you have CI that expects it.
|
||
|
|
||
|
## Rationale
|
||
|
|
||
|
### Eliminate CI as an attack surface
|
||
|
|
||
|
Once you have a CI system that rejects any unsigned commits, you avoid an
|
||
|
attacker with git access being able to explore or execute code on these systems
|
||
|
at all.
|
||
|
|
||
|
### Unambiguous Authorship
|
||
|
|
||
|
Short of enforced signing, anyone can commit with the email of anyone else. A
|
||
|
typical VCS like Git has no way to protect against this.
|
||
|
|
||
|
If someone submits 5 very similar PRs, one might review the first one in detail
|
||
|
then not inspect the rest quite as close, because humans. By contrast however
|
||
|
if 4 of the 5 are signed, suddenly the outlier is suspect, could be from
|
||
|
someone else entirely, and will get additional scrutiny.
|
||
|
|
||
|
A dishonest or disgruntled employee could easily rewrite history to make a
|
||
|
mistake appear to have been committed by someone else, instead of having to
|
||
|
come to terms with it.
|
||
|
|
||
|
When engineers all sign their commits both at work and in open source projects,
|
||
|
it avoids reputation hijacking where someone might commit malicious code to
|
||
|
a repo with a naive maintainer hoping they will blindly trust your name without
|
||
|
careful inspection.
|
||
|
|
||
|
### Distributed Accountability
|
||
|
|
||
|
Only signing tags implies you are approving the whole history
|
||
|
|
||
|
By signing only tags you place the full burden of reviewing all history and
|
||
|
every line of code between releases on the individual cutting a release. In a
|
||
|
large codebase this is an unreasonable expectation.
|
||
|
|
||
|
Having signing and review at every PR between releases distributes
|
||
|
responsibility more fairly. When you sign a commit or sign a merge commit after
|
||
|
a PR you are signing only that one chunk of code or subset of changes and
|
||
|
creating a smaller set of checks and balances through the release cycle.
|
||
|
|
||
|
### Proof of code-review
|
||
|
|
||
|
Once a merge to master is done, CI should fail to build unless the merge commit
|
||
|
itself at HEAD is signed, and signed by someone different than the authors of
|
||
|
the included commits.
|
||
|
|
||
|
## Setup
|
||
|
|
||
|
### Git
|
||
|
|
||
|
Adjust your ~/.gitconfig to be similar to the following:
|
||
|
|
||
|
```
|
||
|
[user]
|
||
|
email = john@doe.com
|
||
|
name = John H. Doe
|
||
|
signingKey = 6B61ECD76088748C70590D55E90A401336C8AAA9 # get from 'gpg --list-keys --with-colons'
|
||
|
[commit]
|
||
|
gpgSign = true
|
||
|
[gpg]
|
||
|
program = gpg2
|
||
|
```
|