The one thing I still do with GPG is signing Git tags. The Git wrapper simply signs the object's hash and makes it more difficult to properly verify the object with a specific key. I can't actually justify why I'm still doing that instead of using signify. Maybe I'll start now.
Conversation
Or are you saying you would sign the commit hash on your own and store it separately?
1
I could sign the commit on my own and store it in a Git note. I would rather have detached signatures than having it as part of the object anyway. That doesn't make sense to me. What happens if I rotate the key and want to sign the previously signed tags with the new key too?
3
2
5
Unless you're going to reverify all those commits, I'm thinking re-signing them doesn't make sense. The best verifiability starts from storing them in incorruptible (widely distributed, offline, or immutable) ways.
1
1
They're signed so that someone can come along, clone the sources and verify that those are genuinely our releases. It's not signed for our own usage. The signed tags are pushed after we've already finished using the sources for that release since our builds are ready for release.
1
2
OK, so the idea is that you have that verifiability already and use the signatures to attest your belief that the code is sound (and matches the specified release) to its consumers? Makes sense.
1
Yes, so it would make sense for us to be rotating the key and signing them all with a new key so that it's possible for people to verify a historical archive of the sources. We don't want to attest to everything that might be in a Git repository being genuine, just specific tags.
1
2
The tags are our long-term archive of the sources. The vast majority of the repositories are downstream forks with patch sets to upstream code that are ported to each new stable release. It's regularly rebased to keep it as a clean sensible patch set that's actually maintainable.
1
1
For those downstream forks, they're based off of upstream stable tags based on stable branches. There's usually an underlying upstream stable branch that switches every few months to a new one without the past few stable tags in the history since it diverged at a different point.
1
Then there are the yearly major releases (for Chromium, every 6 weeks) where we have to port to a drastically different base OS.
The upstream tags are also signed for a similar reason. Due to lack GPG support for rotation, the keys for signing new tags essentially never change.
1
Due to how Git does it, you also have no way to publish new signatures for the older tags. The value of those signatures will decline over time. Git's signed commit / tag support is also based on signing a SHA-1 hash chaining to others which is problematic and needs replacement.
Switching to a new hash for new objects wouldn't be enough. It would need to generate a new hash for every object referenced from where it starts using the new hash. The whole thing is deeply problematic and the value of using it is declining over time. It's poorly designed.
1
1
Thanks for the detailed explanation. Your own setup and goals seem great. And yeah, existing git signing shows the kinds of flaws I'd see in systems before security reviews.
If signatures are in the merkle tree I don't think their value declines over time. Later signatures (by new key) attest that the earlier ones were made at a time when the old key was trusted. The history is like its own notary chain.
3
I guess the problem is if the private key is compromised. You now lose faith in anything signed with that key, unless you know precisely when the compromise happened.
Even then, the git merkle tree can't be trusted to contain accurate timestamps.
1
1
Show replies



