Hacker News new | past | comments | ask | show | jobs | submit login
Use KeePassXC to sign your Git commits (mendhak.com)
79 points by thunderbong 9 months ago | hide | past | favorite | 25 comments



I tend to agree with the argument Linus put forward a long time ago, saying that there is little reason to sign commits instead of tags in git.

* Commit references the tree. If you sign the entire commit object – which is what you want, not leaving a way to change something about the commit without invalidating the signature – you sign the file tree as you saw it and implicitly all its history. Might as well sign the tag then.

* Signatures separable from the commit have a benefit of allowing someone other than the author and committer at the time to certify authenticity of the file tree. For example, if the key needs to be rotated later, you can slap a new signature over the previous one.

* Signing every single commit is tedious, so you're bound to get it automated at some point. Now your signatures are worth less because your keys are always around to indiscriminately, automatically sign whatever.


I kind of agree with this argument, too.

The process of signing a commit is used in a kind of wrong manner, I suppose, because of your mentioned points.

The "view of the file tree as you saw it" basically implies that signed commits aren't worth anything if the code is refactored or changed later, which inevitably it will.

Using tags as a reference point, however, is the idea of snapshotting a mutually agreed state between multiple parties working on the project.

I think you could take this a little further, and use it to implement a Q&A workflow, where e.g. a code review team and a testing team should sign a specific snapshot as "working as we saw it", and that could integrate very well if you e.g. have a semantic version epoche of your project.


Tags are commonly used for library development, but are effectively never used for application development. Signing commits for application development makes a lot of sense, since no one uses tags.

> It's bound to get automated at some point

Definitely — it already is automated. Git can sign commits using your SSH key automatically, and assuming you have something like ssh-agent running, you aren't going to need to enter your password or tap your Yubikey or whatever every time. That doesn't mean it's worthless for application development. While the developer machine being compromised is still a risk, it still mitigates man-in-the-middle attacks where your repository is compromised, or a pipeline betweeen your repo and the build machines are compromised, and an attacker can spoof commits. With signed commits, the attack wouldn't work: you don't need a chain of trust in between build servers and dev machines, you just need to trust the dev machines and the build servers. Everything in between is unable to modify the tree without getting caught.

Signing tags doesn't provide extra security, either; if the dev machine is compromised, ultimately the dev who is signing the commits can't trust their own machine to tell them what's on disk and what they're signing. And if the build server is compromised, you can't trust it to ignore unsigned commits, or commits where the signatures don't match.


The last point can be mitigated by a hardware based security key(nitrokey,yubikey,etc).

Key would then by not on your device so extraction would be difficult or impossible.

You would need to touch the key to grant the sign request which would prevent any signing without you noticing.


It's more about the slippery slope of security vs convenience.

I do git rebase -i often. Do I want to touch my yubikey exactly 37 times for the 37 commits amended, or do I want to touch it once and just trust the software for the next N seconds to sign only these commits and not anything else?

Now, if I'm the verifier, do I trust the signer to do it properly? Or the half their commits are actually made by their cat and automatically signed?

Signing a tag is a relatively rare and very deliberate action. A more secure approach is less likely to impact convenience, reducing the chance of compromising security because it was inconvenient.


I think that's precisely the point. You wouldn't want to touch your security key every time you commit anything. Given the (intentional) high friction, it's probably best left for operations that are high value, such as tags or releases


I think ssh keys signing goes a long way to point 3. I haven't looks if you can (or if it matters) to sign with an ssh certificate, but that would be useful to add some context to the signature too.


The point he was making was not about the tech or tools to sign commits.

It was about the laziness of humans not actually reading the code thoroughly when they sign it, and therefore negating the point of ledging/signing the state of the project.


I am a little confused. Some time back, I added my github ssh key to KeePassXC, and checked the option to Add key to the ssh agent when I unlock my database.

I can then just sign my commits. I don't recall doing any of these settings at all.


signed with ssh key instead


What’s the reason I would want to do this? Is there a specific threat I need to be aware of with regard to threat vector on git commits?


We are on computers, so everything can be changed all the time. E.g. there could be malware that changes a cloned git repos commits before you compile the software.

If the commits are signed that malware would have to know the private key of that dev to do that, which is one additional hurdle that makes this kind of attack way harder to pull off.


What is "this"?

- If "sign with SSH instead of GPG", the answer is convenience.

- If "sign commits", the answer is authentication of the user of the commit.

Encryption part isn't relevant as you get that already regardless with https/ssh protocols when communicating with the git server.

As for why you want to authenticate the user, the better question to ask, is, why wouldn't you? No one can push any commit on your behalf. In some cases it is extremely important because certain branches might be protected due to automated CI/CD pipelines that contain secrets. Without enforcing verification of authenticity, a user might push a commit pretending to be a different user, which exposes those secrets. One might say "well, then you have a bigger problem in your organization", which leads to the restated question of "why not?". It just one of those things we do, like health care workers washing their hands.


Ideally your CD system would refuse to deploy commits signed with keys it doesn't recognise, but I've never seen that implemented.


In Gentoo, I believe we already reject pushing unsigned commits.


SBOM/chain of custody all the way back to an individual doing a commit.


This is the opposite of a specific threat vector


Software supply chain attacks not specific enough?


Not in terms of specific threat model.


Threat: attacker can commit malicious code to a repository by impersonation.

Mitigation: verify commit signatures.


I have a similar setup with Bitwarden. I've managed GPG keys manually for commit/tag signing before and switched to a consolidated setup using SSH keys for almost everything.

Managing GPG keys on multiple computers was hell. Forwarding SSH agent changed how I distribute my keys, and helped reduce the amount of places keys are distributed to and kept in memory.

I've been meaning to write about that workflow because it really streamlined how I manage keys.


Honestly, I don't get the point of it. SSH keys, unlike PGP keys, are meant to be disposable and don't carry any identity information. If anything, I'd rather use my PGP keys with SSH (an option available for about a decade I think).


People don't get the security concepts. Probably, just a lot of people wanted signed commits because they somehow "better", but couldn't get PGP to work.

But they use SSH keys to push to GitHub anyway, so someone added the option to use SSH keys to sign Git commits. Now everyone can have a green "Verified" symbol on their commits.

It's worth less, but it looks better!


Checklist security in a nutshell.

Does it have a checkmark? Yes? Must be secure then.


Most users are using `git` with some sort of server, and authenticating their development system(s) to that server with SSH. Git-over-SSH support is built in to `git`. Using the same key to that already identifies and authenticates you to the server is more convenient than needing a second, parallel PKI set up.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: