Unverified Commit c6ef101b authored by anarcat's avatar anarcat
Browse files

expand header for #81, reformat

parent 9ddfeac6
Loading
Loading
Loading
Loading
+126 −43
Original line number Diff line number Diff line
@@ -931,97 +931,180 @@ transfer only some users.

## Git repository integrity solutions

> This section is a copy of a comment in [ticket
> This section is a summary of the discussion in [ticket
> tpo/tpa/gitlab#81](https://gitlab.torproject.org/tpo/tpa/gitlab/-/issues/81).

As I hinted in the summary, I think the solution to this problem, for both GitLab and Gitolite, is to use cryptographic signatures using preciously protected keys. We already use OpenPGP extensively in the Tor infrastructure, and it's well integrated in git, so it's an obvious candidate. Various projects have different approaches regarding this:

## Guix: sign all commits

[Guix uses OpenPGP to sign commits](https://guix.gnu.org/blog/2020/securing-updates/), using an approach that is basically like this:

> 1. The repository contains a .guix-authorizations file that lists the OpenPGP key fingerprints of authorized committers.
> 2. A commit is considered authentic if and only if it is signed by one of the keys listed in the .guix-authorizations file of each of its parents. This is the authorization invariant.
Some developers expressed concerns about using GitLab as a canonical
location for source code repositories, mainly because of the much
broader attack surface GitLab provides, compared to the legacy,
[gitolite-based infrastructure](howto/git), especially considering
that the web application basically has write access to everything.

One solution to this problem is to use cryptographic signatures. We
already use OpenPGP extensively in the Tor infrastructure, and it's
well integrated in git, so it's an obvious candidate. But it's not
necessarily obvious how OpenPGP would be used to sign code inside Tor,
so this section provides a short review of existing solutions in that
space.

### Guix: sign all commits

[Guix uses OpenPGP to sign commits](https://guix.gnu.org/blog/2020/securing-updates/), using an approach that is
basically:

> 1. The repository contains a .guix-authorizations file that lists
>    the OpenPGP key fingerprints of authorized committers.
> 2. A commit is considered authentic if and only if it is signed by
>    one of the keys listed in the .guix-authorizations file of each
>    of its parents. This is the authorization invariant.
>
> \[...\] Since .guix-authorizations is a regular file under version control, granting or revoking commit authorization does not require special support.
> \[...\] Since .guix-authorizations is a regular file under version
> control, granting or revoking commit authorization does not require
> special support.

Note the big caveat:

> It has one downside: it prevents pull-request-style workflows. Indeed, merging the branch of a contributor not listed in .guix-authorizations would break the authorization invariant. It’s a good tradeoff for Guix because our workflow relies on patches carved into stone tablets (patch tracker), but it’s not suitable for every project out there.
> It has one downside: it prevents pull-request-style
> workflows. Indeed, merging the branch of a contributor not listed in
> .guix-authorizations would break the authorization invariant. It’s a
> good tradeoff for Guix because our workflow relies on patches carved
> into stone tablets (patch tracker), but it’s not suitable for every
> project out there.

Also note there's a bootstrapping problem in their design:

> which commit do we pick as the first one where we can start verifying the authorization invariant?
> Which commit do we pick as the first one where we can start
> verifying the authorization invariant?

They solve this with an out of band "*channel introduction*" mechanism which declares a good hash and a signing key.
They solve this with an out of band "*channel introduction*" mechanism
which declares a good hash and a signing key.

This also requires a custom client. But it serves as a good example of an extreme approach (validate everything) one could take.
This also requires a custom client. But it serves as a good example of
an extreme approach (validate everything) one could take.

## Arista: sign all commits in Gerrit
### Arista: sign all commits in Gerrit

Arista wrote a blog post called [Commit Signing with Git at Enterprise Scale](https://eos.arista.com/commit-signing-with-git-at-enterprise-scale/) ([archive](https://web.archive.org/web/20201020180304/https://eos.arista.com/commit-signing-with-git-at-enterprise-scale/)) which takes a radically different approach.
Arista wrote a blog post called [Commit Signing with Git at Enterprise
Scale](https://eos.arista.com/commit-signing-with-git-at-enterprise-scale/) ([archive](https://web.archive.org/web/20201020180304/https://eos.arista.com/commit-signing-with-git-at-enterprise-scale/)) which takes a radically different approach.

 * all OpenPGP keys are centrally managed (which solves the "web of trust" mess) in a [Vault](https://www.vaultproject.io/)
 * Gerrit is the gatekeeper: for patches to be merged, they must be signed by a trusted key
 * all OpenPGP keys are centrally managed (which solves the "web of
   trust" mess) in a [Vault](https://www.vaultproject.io/)
 * Gerrit is the gatekeeper: for patches to be merged, they must be
   signed by a trusted key

It is a rather obtuse system: because the final patches are rebased on top of the history, the git signatures are actually lost so they have a system to keep a reference to the Gerrit change id in the git history, which does have a copy of the OpenPGP signature.
It is a rather obtuse system: because the final patches are rebased on
top of the history, the git signatures are actually lost so they have
a system to keep a reference to the Gerrit change id in the git
history, which does have a copy of the OpenPGP signature.

## Gerwitz: sign all commits or at least merge commits
### Gerwitz: sign all commits or at least merge commits

Mike Gerwitz wrote an [article in 2012](https://mikegerwitz.com/2012/05/a-git-horror-story-repository-integrity-with-signed-commits) (which he warns is out of date) but which already correctly identified the issues with merge and rebase workflows. He argues there is a way to implement the desired workflow by signing *merges*: because maintainers are the one committing merge requests to the tree, they are in a position to actually sign the code provided by third-parties. Therefore it can be assume that if a merge commit is signed, then the code it imported is also signed.
Mike Gerwitz wrote an [article in 2012](https://mikegerwitz.com/2012/05/a-git-horror-story-repository-integrity-with-signed-commits) (which he warns is out of
date) but which already correctly identified the issues with merge and
rebase workflows. He argues there is a way to implement the desired
workflow by signing *merges*: because maintainers are the one
committing merge requests to the tree, they are in a position to
actually sign the code provided by third-parties. Therefore it can be
assume that if a merge commit is signed, then the code it imported is
also signed.

The article also provides a crude checking script for such a scenario.

Obviously, in the case of GitLab, it would make the "merge" button less useful, as it would break the trust chain.
Obviously, in the case of GitLab, it would make the "merge" button
less useful, as it would break the trust chain. But it's possible to
merge "out of band" (in a local checkout) and push the result, which
GitLab generally correctly detect as closing the merge request.

## Torwalds: signed tags
### Torwalds: signed tags

Linus Torwalds, the (current) maintainer of the Linux kernel, simply signs the release tags. In an article called "[what does a pgp signature on a git commit prove?](https://people.kernel.org/monsieuricon/what-does-a-pgp-signature-on-a-git-commit-prove)", Konstantin Ryabitsev (the kernel.org sysadmin), provides a good primer on OpenPGP signing in git. It also shows how to validate Linux releases by checking the tag and argues this is sufficient to ensure trust.
Linus Torwalds, the original author and maintainer of the Linux
kernel, simply signs the release tags. In an article called "[what
does a pgp signature on a git commit prove?](https://people.kernel.org/monsieuricon/what-does-a-pgp-signature-on-a-git-commit-prove)", Konstantin Ryabitsev
(the `kernel.org` sysadmin), provides a good primer on OpenPGP signing
in git. It also shows how to validate Linux releases by checking the
tag and argues this is sufficient to ensure trust.

## Vick: git signatures AKA git notes
### Vick: git signatures AKA git notes

The [git-signatures](https://github.com/hashbang/git-signatures/) project, authored by [Lance R. Vick](https://github.com/lrvick), makes it possible to "*attach an arbitrary number of GPG signatures to a given commit or tag.*":
The [git-signatures](https://github.com/hashbang/git-signatures/) project, authored by [Lance R. Vick](https://github.com/lrvick), makes
it possible to "*attach an arbitrary number of GPG signatures to a
given commit or tag.*":

> Git already supports commit signing. These tools are intended to compliment that support by allowing a code reviewer and/or release engineer attach their signatures as well.
> Git already supports commit signing. These tools are intended to
> compliment that support by allowing a code reviewer and/or release
> engineer attach their signatures as well.

Downside: third-party tool not distributed with git and not packaged in Debian.
Downside: third-party tool not distributed with git and not packaged
in Debian.

The idea of using git-notes was also [proposed by Owen Jacobsen](https://grimoire.ca/git/detached-sigs/).

## Walters: extended validation tags
### Walters: extended validation tags

The [git-evtag](https://github.com/cgwalters/git-evtag) projects from Colin Walters tries to address the perceived vulnerability of the SHA-1 hash by implementing a new signing procedure for tags, based on SHA-512 and OpenPGP.
The [git-evtag](https://github.com/cgwalters/git-evtag) projects from Colin Walters tries to address the
perceived vulnerability of the SHA-1 hash by implementing a new
signing procedure for tags, based on SHA-512 and OpenPGP.

## Ryabitsev: b4 and patch attestations
### Ryabitsev: b4 and patch attestations

Konstantin Ryabitsev (the kernel.org sysadmin, again) proposed a new cryptographic scheme to sign patches in Linux, he called "[patch attestation](https://people.kernel.org/monsieuricon/introducing-b4-and-patch-attestation)". The protocol is designed to survive mailing list transports, rebases and all sorts of mangling. It does not use GnuPG and is based on a Trust On First Use (TOFU) model.
Konstantin Ryabitsev (the kernel.org sysadmin, again) proposed a new
cryptographic scheme to sign patches in Linux, he called "[patch
attestation](https://people.kernel.org/monsieuricon/introducing-b4-and-patch-attestation)". The protocol is designed to survive mailing list
transports, rebases and all sorts of mangling. It does not use GnuPG
and is based on a Trust On First Use (TOFU) model.

The model is not [without critics](https://lwn.net/Articles/813646/#Comments).

## Ryabitsev: Secure Scuttlebutt
### Ryabitsev: Secure Scuttlebutt

A more exotic proposal is to [use the Secure Scuttlebutt (SSB) protocol](https://people.kernel.org/monsieuricon/patches-carved-into-developer-sigchains) instead of emails to exchange (and also, implicitly) sign git commits. There is even a [git-ssb](https://github.com/clehner/git-ssb) implementation, although it's hard to see because it's been migrated to .... SSB!
A more exotic proposal is to [use the Secure Scuttlebutt (SSB)
protocol](https://people.kernel.org/monsieuricon/patches-carved-into-developer-sigchains) instead of emails to exchange (and also, implicitly) sign
git commits. There is even a [git-ssb](https://github.com/clehner/git-ssb) implementation, although
it's hard to see because it's been migrated to .... SSB!

Obviously, this is not quite practical and is shown only as a more radical example, as a stand-in for the other end of the decentralization spectrum.
Obviously, this is not quite practical and is shown only as a more
radical example, as a stand-in for the other end of the
decentralization spectrum.

## Other caveats
### Other caveats

Also note that git has limited security guarantees regarding checksums, since it uses SHA-1, but [that is about to change](https://lwn.net/Articles/823352/). Most Git implementations also have protections against collisions, see for example [this article from GitHub](https://github.com/blog/2338-sha-1-collision-detection-on-github-com).
Also note that git has limited security guarantees regarding
checksums, since it uses SHA-1, but [that is about to change](https://lwn.net/Articles/823352/). Most
Git implementations also have protections against collisions, see for
example [this article from GitHub](https://github.com/blog/2338-sha-1-collision-detection-on-github-com).

There are, of course, a large number of usability (and some would say security) issues with OpenPGP (or, more specifically, the main implementation, GnuPG). There has even been [security issues with signed Git commits](https://mgorny.pl/articles/attack-on-git-signature-verification.html), specifically.
There are, of course, a large number of usability (and some would say
security) issues with OpenPGP (or, more specifically, the main
implementation, GnuPG). There has even been [security issues with
signed Git commits](https://mgorny.pl/articles/attack-on-git-signature-verification.html), specifically.

So I would also be open to [alternative signature verification schemes](https://blog.gtank.cc/modern-alternatives-to-pgp/). Unfortunately, none of those are implemented in git, as far as I can tell.
So I would also be open to [alternative signature verification
schemes](https://blog.gtank.cc/modern-alternatives-to-pgp/). Unfortunately, none of those are implemented in git, as
far as I can tell.

There are, however, alternatives to GnuPG itself. [This article from Saoirse Shipwreckt](https://boats.gitlab.io/blog/post/signing-commits-without-gpg/) shows how to verify commits without GnuPG, for example. That still relies on OpenPGP keys of course...
There are, however, alternatives to GnuPG itself. [This article from
Saoirse Shipwreckt](https://boats.gitlab.io/blog/post/signing-commits-without-gpg/) shows how to verify commits without GnuPG, for
example. That still relies on OpenPGP keys of course...

... which brings us to the web of trust and key distribution problems. The OpenPGP community is in this problematic situation right now where the traditional key distribution mechanisms (the old keyserver network) has been under attack and is not as reliable as it should be. This brings the question of keyring management, but that is already being discussed in tpo/tpa/team#29671.
... which brings us to the web of trust and key distribution
problems. The OpenPGP community is in this problematic situation right
now where the traditional key distribution mechanisms (the old
keyserver network) has been under attack and is not as reliable as it
should be. This brings the question of keyring management, but that is
already being discussed in [tpo/tpa/team#29671](https://gitlab.torproject.org/tpo/tpa/team/-/issues/29671).

Finally, note that OpenPGP keys are not permanent: they can be revoked, or expired. Dealing with this problem has its specific [set of solutions](https://karl.kornel.us/2017/10/welp-there-go-my-git-signatures/) as well.
Finally, note that OpenPGP keys are not permanent: they can be
revoked, or expired. Dealing with this problem has its specific [set
of solutions](https://karl.kornel.us/2017/10/welp-there-go-my-git-signatures/) as well.

## Related
### Related

 * [gitid](https://github.com/Luiserebii/gitid): easier identity management for git
 * [signed git pushes](https://people.kernel.org/monsieuricon/signed-git-pushes)
 * [TUF](https://theupdateframework.io/): generic verification mechanism, used by Docker, no known
   Git implementation just yet
 * [jcat](https://github.com/hughsie/libjcat): used by fwupd
 * [git-signify](https://leahneukirchen.org/dotfiles/bin/git-signify): using [signify](https://github.com/aperezdc/signify), a non-OpenPGP alternative

# FAQ