Open djspiewak opened 6 years ago
I would love to see better security for the maven publishing model. IMO the gpg web-of-trust model just requires too much effort from too many participants for it to become a viable way to authenticate binaries. Do you know of keybase.io? Maybe we could somehow leverage that as part of the verification process?
In the longer term, I'd like to see better support from repositories too (check out this thread for some inspiration on Rust's Crates.io https://github.com/rust-lang/cargo/issues/1281) and most importantly, reproducible builds becoming mainstream in the JVM world!
In the short term, I think wrapping around gpg's verify command is the way to go.
I would love to see better security for the maven publishing model. IMO the gpg web-of-trust model just requires too much effort from too many participants for it to become a viable way to authenticate binaries. Do you know of keybase.io? Maybe we could somehow leverage that as part of the verification process?
I'm a huge keybase fan. Or at least a huge fan of their core database; I'm less keen on their Slack/Dropbox/whatever-killer product. Either way, I think that would be outstanding. The web-of-trust model doesn't work very well. Some authors do have their keys signed into the strong set, and it's certainly worth respecting that in the verification process, but rejecting a signature just because it fails GPG's user hostile trust model is not the right approach.
Fundamentally, the goal is to assert that the people we think published something, did in fact publish something. I can think of a couple things we can leverage for this…
lazy val trustedKeys = settingKey[Seq[(String, Option[Set[String]])]]
, probably with some nicer syntax built around it.
trustedKeys
to be fetched from some external server. This corrupts build reproducibility, but it's almost guaranteed to be the option that organizations such as Verizon and similar would want to use. Imagine organizations enabling mandatory signing checks based on a standardized and revocable trust source, centrally controlled by the org.git
.KEYS
file. This used to be standard for Apache projects. It's not a terrible way to go, since anyone who wants to publish a fraudulent artifact would need to make a very public assertion of such. Unfortunately, it also can make builds unreproducible (if a project deletes or removes from their KEYS file). Additionally, it's opt-in (on the project side).Oh, and all of these ideas that involve "pulling the SCM information" run into the problem that we're getting that information… from the very POM that we're trying to verify for authenticity. So we're kind of stuck between a rock and a hard-place, here. I'm not sure it completely invalidates those ideas on all levels, but it does kick them out as means of verification without other changes.
Practically, our best bet is probably to start with gpg verify
. If that accepts the signature, then leave it at that. If it doesn't, then check trustedKeys
as described in the pinning section. Pre-populate the plugin with some reasonable trustedKeys
. Off the top of my head:
This has the potential to create winners and losers though due to incumbancy, so I'm somewhat tempted to only pin Scala's key.
I'll drop here some random notes that may be relevant, I hope you don't mind:
Key pinning - Remember to pin not the signature key but rather the master/primary key. OpenPGP relies on primary's key being constant and that key is used to rotate other keys for example signature keys. It's not that uncommon to rotate signature keys (for example due to vulnerabilities) and GPG properly handles that case.
Keybase Verification - it's possible to avoid third party service and still have social proofs. Keybase proofs are conceptually just two links: from key to profile and from the profile to the key, it's possible to embed profile info in the GPG key and the GPG fingerprint in a file controlled by the account holder. (proof of concepts: Linked Identities, Distributed IDs).
Fetching a KEYS File - I think it's important to refresh keys from keyservers or otherwise after fetching them from KEYS. Some GPG keys can be revoked or expired and updated on keyservers, without that there is a risk of accepting a signature made by a revoked key.
Almost no one uses this feature in sbt-pgp anyway, so I could be convinced that it's out of scope, but it would be nice to have. In a more pie-in-the-sky sense, it would be extremely nice if there were some way we could culturally encourage the Scala community (via this tooling) to verify signatures more frequently, since a large chunk of the software development trust model is dependent on this link in the chain that no one checks.