ethpm/ethpm-spec

Signed packages

Closed this issue · 9 comments

What is wrong

Consumers of packages have no specified way of verifying that a package is authentic. This is due to the lack of a defined way to sign a package.

How can it be fixed

Signatures cannot be embedded within a package since we want package authors to be able to sign the full package contents.

Best idea I have is to define an alternate spec for a signature envelope in which a package can be embedded.

Could just lay out a directory of signatures signing off on a commit in the tree/git that this points to...but I suppose that assumes a git module is in there...should we assume .git?

I don't feel comfy assuming anything about git. I'd really like this to be utterly generic but to do that I need to do some research on how other ecosystems do this.

It feels like every ecosystem assumes git, svn and mercurial. 🤷‍♂️ But idk. Git is the original decentralized protocol for these things. And it seems to have a hold in every other package manager that I'm aware of.

Looking at the JWA spec which defines what signature schemes are allowed and how they should be serialized: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-3

Looks like our ECDSA curve 256k1 is not supported which isn't a blocker but it does mean that we can't expect tooling to support it out-of-the-box. I'm thinking that we mirror the spec for the P256 curve which is supported.

So in general, my proposal is to use the JWS-JS extension of JWS with support for a custom signature type for 256k1.

So this is the first limb I'm going to go out on and would like to explore our leveraging the blockchain to provide authentication mechanisms. So two things:

  1. Posting packages into a smart contract index provides a natural signature process.
  2. Package tampering can be handled through hashing tightly packed source code.

Here's what I propose and I hope it isn't too broad seeing that it encompasses more than just the signing but needs to be put into context. I'll start with a very basic example of a single contract or library, like a math library, no dependencies. The packaging tool will take the source code starting at the contract declaration ie library BasicMathLib {... nothing before because we're just interested in the source right now. The code should be packed, excluding comments, removing linebreaks etc, and hashed. This hash represents untampered code. Later on, when publishing the package on-chain, this hash will be associated with the code and the msg.sender will be the signer of this hash. The whole layout of the on-chain index is outside of the scope here, but this is just an example of how this would be used. When a package is retrieved from the uri, the tool would perform this process on the retrieved package and compare the hash to the hash posted in the package index.

@pipermerriam i would advise against trying to make a custom set and standardizing it. We are about to be headed into a realm where different signature are able to be used are we not?

Something else to consider here reference the above comment. Signatures based on author validate only that a credible author posted this code correct? This isn't good enough for Ethereum applications. Obviously Parity is credible, it says nothing about the underlying code. Any change in code should be valid based on its own credentials. The strongest mechanism we have right now to validate source is the audits referenced in #68 . If we go the way where we allow audits to be posted in on-chain indexes, we can then tie the hashed source directly to the hashed source that was audited. This would provide near bullet proof authenticity and validation.

After speaking with @pipermerriam, we have decided to "close, won't fix"

In lieu of loading up this spec with JSON web signatures and extensions, it seems favorable to prefer second-layer solutions, leveraging the existing content-addressable hashes and upcoming attestation standards.