docs/commit-signing.md

68 lines
2.3 KiB
Markdown
Raw Normal View History

2023-08-04 21:59:58 +00:00
# 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
```