Signing .jars is worthless

Duckboards make a serpentine curve over a marsh.

If you try to deploy a new release of Clojure library with Leiningen, it prompts you to sign the .jar file with GPG. This step often causes confusion and breaks. I believe that it’s not worth the effort to make it work.

As far as I know, nobody ever verifies the signatures in a systematic way. There are a bunch of obstacles:

  • It’s unclear if any tools for verifying the signatures actually work. For example, I just tried to run lein deps :verify against a couple of projects and it reported every dependency as :unsigned. I know that some of those dependencies are signed and I verified that the .asc files exist on repo.clojars.org.
  • It’s hard to find the public keys for the library maintainers. Sometimes they upload them on the keyservers, sometimes not.
  • There’s no established way of communicating that which public keys should be trusted. If there’s a new release and it has been made with a new key, your best bet is to e-mail the maintainer and ask what is up.

It’s hard to get any security benefits from the signatures in practice. Thus it’s okay to set :sign-releases to false in your project.clj even if Leiningen’s manual does not recommend it. Something like this:

:deploy-repositories [["clojars" {:url "https://clojars.org/repo"
                                  :sign-releases false}]]

In principle, the systematic checking of signatures could provide security against a dangerous supply-chain attack: weak or leaked passwords for package manager accounts. For example, several RubyGems have been attacked this way. Most likely the signing keys would not be compromised at the same time.

There are alternative solutions, though, such as disallowing publishing packages without multi-factor authentication. Using Clojars’s deploy tokens helps a bit as well.

Right now we place a lot of trust on Clojars and Maven Central. If either of them got compromised, we all would be screwed. Package signing could be a part of a solution to mitigate that risk, but a comprehensive solution would be something like using The Update Framework. Go’s checksum database is also worth taking look at.

Finally, if you’re moved to do something about this, please do not build anything new using PGP. To quote Latacora: PGP is bad and needs to go away.


I’ve written this post in part to be proven wrong. I’m eagerly waiting for posts from y’all about how you do, in fact, systematically verify the signatures.


Comments or questions? Send me an e-mail.