Signing Git commits with your SSH key (2021)
calebhearth.com
calebhearth.com
* Signing your commits is a waste of time
* Signing your commits with SSH keys is bad because it conflates an ephemeral key with a permanent identity
* Signing your commits with anything but GPG isn't worth it
The first point is hard to argue against because the commenters who offered the opinion didn't give many details to understand their perspective.
The second, which is the most common sentiment so far, seems to be because people misunderstand that it doesn't have to be your push/pull key. It can be any SSH key, including a special-purpose key whose only job is to be held securely and act as a signing key.
And the third kind of suffers the same problem as the first -- not enough details are given to understand.
The signatures are stored within the commit object and the only way to resign a commit is to rewrite history. Also you can only attach one signature to a commit, though this is less of an issue.
GPG has plenty of critiques that I do agree with: horrible defaults, difficulty of use, a key model that is outdated and does not serve the plethora of uses it’s now used for, etc.
All of this adds up, tbh, that ephemeral keys are probably no worse than a GPG key. If your GPG key is compromised (or lost), you won’t be resigning your entire git history with your new key. You will simply note somewhere visible that X key was valid until Y date and Z key is the current valid key. Any commits pushed after Y date with X key are suspect.
The point being, signed git commits regardless of what type of key you use really only validate that a particular person at a particular instant in time signed that commit.
If anything, using a more ephemeral and disposable key will encourage Github/Gitlab/etc. to start thinking about key rotation on user profiles. As it stands, if you change your GPG key in Github all commits made with your previous key become invalid until you change you GPG key back. The fact you can change your key back is probably also bad.
The current state of git commit signing is useful, but that usefulness rapidly decays as the commit ages.
I shouldn't have to know what ElGamel is to sign a commit.
I use gpg to sign my commits, it was as easy to setup as git ssh keys were... I don't know what ElGamel is either.
You can also sign with a different key than your “regular” ssh key(s), and as such reduce the chance you’ll have to replace them.
Having said that, key rotation and distribution is obviously better with GPG, and I personally have been using that for years.
(disclosure: I'm a maintainer for gitsign)
I personaly use GPG. However, GPG looks complex and the ergonomics of GnuPG cli is horrible.
CLI ergonomic around working with ssh keys and ssh certificates is not great either.
And GPG/PGP at least has some standards around key distribution, web of trust, subkeys, etc.
SSH keys if used in place of GPG would have almost the same UI. It's not the problem of GPG, but of the underlying concepts.
You don't need to be deep into cryptography, just understand some basic concepts from the wikipedia article, or whatnot.
Therefore, making things easier to set up makes a greater contribution to security than strict, gold-standard security features that nobody adopts.
My only use case for gpg asymmetric encryption is encrypting my offsite backups, and various small things. In other words, I encrypt only to myself, and I like asymmetric encryption because I can keep the private key offline.
*that word is used ironically. gnupg is the devil I know, so I don't mind it much these days, but I'd love to migrate off it completely.
I guess it's a nice library, but it's no replacement for GnuPG. At least GnuPG has an actual user guide, FAQ, etc. with important concepts explained step by step.
As a GnuPG user, it would not be hard to switch for simplistic use cases without any specialized HW, I guess. I already know most of the concepts, but for new users,... I wish them luck with sq, lol. Documentation is pretty much nonexistent, and the web page for sq tool just links to library documentation.
Rust codebase is not everything.
It was very successful but it is nowhere near the security, documentation, testing, or UX standards of what we would call quality software today.
https://ubuntu.com/security/cves?q=&package=gnupg
Not sure what's the grumbling about UX. Common tasks signing/verifying/encrypting are simple. Key export/import is also straightforward. So for common tasks you learn a few (~6) CLI --options by osmosis.
Web of trust/key management stuff is mostly done via interactive UI where you're prompted for what's needed after you invoke some action. Not too bad I guess. Certainly easier to be prompted for what's needed than remembering a ton of random CLI options or fishing through manpages, for tasks that you'll do very infrequently.
I also thought the same and argued the same about UX until I had to train several large teams to use it, and found myself making piles of shell script wrappers to pacify the majority of modern devs who are intimidated by any CLI commands that do not start with npm or git.
PGP is the right spec, IMO. It is just time to shift to more mature implementations that are easier to trust the defaults of and program against.
The majority of Sequoia devs are former GnuPG devs btw. They realized the shortest path to a broadly library-first testable codebase, a memory safety, secure default ciphers, etc was starting over.
On that note I really like the FIDO ssh feature but would like to see more services support these. Arch User Repository still doesn't support these and I don't know what the status over at gitlab is now.
What I wanted is to use the external ssh keys on a Fido key [1] in combination with the commit signing feature. With that I would skip the whole gpg part of the setup and only configure git and maybe ssh. But the generated keys (they have a -sk postfix) didn’t work with the signing feature.
I have zero hesitancy to blow away a git ssh key for any reason and use different keys from different hosts which are not used for anything else.
Entangling an ephemeral key as a supposedly permanent signature would have to be for things I had no long term commitment to.
I'm a little confused. I thought this was how you're supposed to do it, so you can easily revoke access for a particular host.
Which is why this is a bit silly and I don't see why you'd do this rather than "good old" PGP.
Why can a PGP key be permanent but an SSH key not? I'm assuming both are just files and as a user you are required not to lose/give them away.
Also note that until you can individually get the good actors' public key you can't verify their commits. So it's not enough to distribute the instructions in this webpage, you also have to have a trusted key exchange. Everyone who wants to verify commits will need a copy of everyone who might sign commits' public keys.
If you trust github then you can use them as a key broker like the "User SSH Keys from GitHub" section suggests, if all of your committers are github users.
This would need to be coupled with a "reject unsigned commits" policy on push. For example - https://docs.gitlab.com/ee/user/project/repository/push_rule...
And note that the caveats that it has would require the person to log in to gitlab to not need to push (by using the webIDE instead) which leaves an audit trail there.
Similar functionality can be crafted with a pre-receive commit hook - https://docs.github.com/en/enterprise-server@3.2/admin/polic...
An example of such a hook - https://github.com/github/platform-samples/blob/master/pre-r...
Additionally you can enable "Vigilant Mode" to make it obvious when commits are untrusted.
https://github.blog/changelog/2021-04-28-flag-unsigned-commi...
commit 3c2f202543b31e9d7e2fff92a211a0f37ebcca9b (HEAD -> master)
Author: Dave <dave@meanco.com>
Date: Tue Sep 13 21:32:41 2022 -0500
I am not smart.You need expiration, permissible purpose, revocation, identity, etc embedded into a ‘key’.
Pgp is really really good at doing these things and has been though the ringer on security. Yes pgp sucks at its original Purpose (encrypting email) but it’s excellent for signing things.
from the doc:
> My signing keys (e.g. blog or Qubes code signing keys) do not have expiration dates. This is not laziness. There is a fundamental problem with using an expiration date on keys used for code signing (e.g. git tag -s), because it is unclear what the outcome should be when one verifies some old code (written and signed when the key was still valid) in the future when the key has already expired?
> Naturally we would like the old code, written and signed when the key was still valid, to continue to verify fine also in the future, after the key expires (and the developer passed away, perhaps). However, it is very problematic to prevent the attacker from creating falsified code pretending to be an old one.
How to specify a timestamp server
- run a full bitcoin node, download the full blockchain - wait several hours after the timestamp is produced for the system to publish to blockchain (which also reduces the granularity of the timestamp, within this window the system is only "as secure" as a solution trusting a single entity) - download all the commits in the Merkle tree that was signed and published, and search for the commit you are verifying within the tree
Security in practice is about tradeoffs, and I can't imagine a scenario wherein these tradeoffs would work for me without ultimately having a centralized provider verify them for me, at which point I just have complexity with no gain over the traditional trusted timestamps.
bitcoin.
merkle tree.
and some third party calendar server.
It's fine maybe this thing is so complicated that I'm not allowed to understand it. And if it's so complicated that it can't even be explained in a high level way, I don't want to use it.
If you work in a commercial environment with an authenticated central repository then all actions are logged. This is the best place to audit who-did-what.
I suppose this doesn’t work though if you have developers with legitimate reasons to push commits by other people. What would those be? Cherry picking bug fixes to a release branch? One engineer merging a branch where they’ve been collaborating with someone else? I would probably want to take ownership of the former, and the latter isn’t very common now in the era of “everything on master”.
I use an ed25519 GPG key secured in a hardware security key. It’s convenient and secure. My SSH keys are ephemeral as much as possible.
GPG has key management tools and various functionalities around signing. Minisign is another clean tool to watch for.