Git Signing commits in a private repo



  • Linus mentioned in 2009 that "Signing each commit is totally stupid".

    Has the common view evolved on this subject since then ? Doesn't it protect against someone usurping your identity to commit something into your git repo ?

    Thanks



  • It's still mostly pointless.

    Signing commits makes it possible to check if the commit was signed with a particular key. In return, this lets you infer whether the commit was created by a particular person. This can have value, for example if person A publishes a commit signed by person B. But this is only useful on a social level.

    It does not affect the security of a git repository itself.

    • Integrity is already ensured through Git's blockchain-like Merkle-tree structure. If I know that a commit dd71cae49e1ba0e09034ecca51b0d3ceb44280eb exists, Git can verify the integrity of that commit and the entire history leading to that commit.
    • Git servers typically have access controls that limit who can push to the server. This access control is entirely unrelated to commit signatures. Git can also work entirely without multiple people sharing push-access to the same repository – its decentralized design makes it possible for people to publish their own repositories from which others can pull.

    Some Git web interfaces like GitHub uncritically take the commit metadata and associate the commit with an account. For example, this makes it possible for everyone to create unsigned https://github.com/Amog-OS/AmogOS/commit/4f503a0 that GitHub links to Linus Torvald's account.

    But what does this mean?

    • That Git is insecure? Absolutely not.
    • That GitHub is insecure? For some definitions of security, maybe.
    • That GitHub doesn't clearly convey the trustworthiness of the data they display in the web interface? Yes, that's a more appropriate take. Because of this, GitHub has introduced a https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits . If Torvalds were to enable vigilant mode on his account, other people would see an “unverified” badge for unsigned commits created in his name – or created by himself that he didn't bother to sign.

    If you have a piece of software and want to know if you can trust the software, signatures can be part of a solution. But this requires threat models involving untrustworthy third parties.

    • If I download the Linux source from https://github.com/torvalds/linux and trust GitHub, it doesn't really matter to me if the commits are signed or not.
    • If I download the Linux Git repository from a shady website, but Linus Torvalds tells me through a trustworthy channel that he authored commit 8bb7eca972ad531c9b149c0a51ab43a417385813, I can verify that this commit and all commits and all files reachable from that starting point are the same as those Torvalds saw himself.
    • If I download the Linux Git repository from a shady website, and Linus Torvalds signs all of his commits, and I know Torvald's public key he uses for these signatures, then I could also verify that his commits have not been tampered with. But this isn't really simpler than the previous scenarios.

    Where signatures do play a role is not to ensure integrity of the repository, but as proof of identity for the author or committer. Contributing to a project has legal consequences regarding copyright, or the project may require reviews by certain people. The Linux project uses a Signed-off-by line in commit messages, which works on a trust basis. It would also be possible to use signed commits instead, but that would require (a) a way to add more signatures to a commit without changing the hash ID of a commit,1 and (b) an easy way to know who has which public key. Running a public key infrastructure that works for ordinary people is a pretty difficult problem, with common consumer-oriented solutions like the Signal messenger mostly relying on “trust on first use” that merely show a subtle warning when the key changes. The GPG community tried to build a web of trust via in-person key signing parties parties, but the value of such verifications is doubtful.

    1. There might be a sequence of commits A → B → C, where A is the HEAD commit that references other commits. All commits are signed. I want to add a signature to commit C. This will create a different commit C' which has a different hash for C, so that it is not part of the history referenced by A. I could rebase and record a new history A' → B' → C', but now the signatures on A and B would no longer apply. So working with signed commits can be tricky and break some workflows. A different design for signatures could work, e.g. if signatures are recorded in separate objects so that I could create a history Signature(A,B,C) → A → B → C.

    I don't sign my commits because I don't trust myself to do proper key management, and because the signature provides very little useful information to other people.




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2