slsa icon indicating copy to clipboard operation
slsa copied to clipboard

Could npm use VSAs instead of a custom 'publish' attestation?

Open TomHennen opened this issue 2 years ago • 14 comments

npm has a custom publish attestation as a part of implementing this RFC.

I wonder if it would be possible to use a VSA instead? Perhaps with some tweaks to the spec?

My understanding is that the publish attestation is meant to say "the npm registry allowed this package" which is very similar to what the VSA is trying to get across. There may be some concern around npm not wanting to make an assertion about something's SLSA level, in which case I wonder if it would be helpful to add a SLSA_LEVEL_UNEVALUATED for the verifiedLevels field?

@feelepxyz, @laurentsimon, @joshuagl WDYT?

TomHennen avatar Apr 05 '23 16:04 TomHennen

Thanks for filing this Tom! It would certainly be nice if we can standardise on fewer attestations where possible.

It might be useful to sketch out what an npm VSA would look like in this issue? cc @kommendorkapten

"_type": "https://in-toto.io/Statement/v1",
"subject": [{
  "name": "pkg:npm/@scope/[email protected]",
  "digest": {"sha512": "41o0P/CEffYGDqvo2pHQXRBOfFOxvYY3WkwkQTy..."}
}],

// Predicate
"predicateType": "https://slsa.dev/verification_summary/v1-rc2",
"predicate": {
  "verifier": {
    "id": "https://registry.npmjs.org"
  },
  "timeVerified": "1985-04-12T23:20:50.52Z",
  "resourceUri": "pkg:npm/@scope/[email protected]",
  "policy": {
    // global policy of checks npm performs prior to admitting a package
    "uri": "https://github.com/npm/package-acceptance.policy", 
    "digest": {"sha256": "1234..."}
  },
  "inputAttestations": [
    {
      // uri of the npm SLSA provenance
      "uri": "https://example.com/provenances/example-1.2.3.tar.gz.intoto.jsonl", 
      "digest": {"sha256": "abcd..."}
    }
  ],
  "verificationResult": "PASSED",
  "verifiedLevels": ["SLSA_LEVEL_UNEVALUATED"],
  "slsaVersion": "1.0"
}

joshuagl avatar Apr 05 '23 16:04 joshuagl

Oh yeah great!

     // TBD: what would an appropriate policy URI being if the artifact is not being verified?
     // Could be a URI describing the authn checks performed by the registry?

I think that we should consider that the artifact itself is verified, after all the registry did decide to admit it. I think it would be fine to reference some global policy though?

  "verificationResult": "UNVERIFIED",

Per the above point I think this should arguably just be PASSED as the registry did decide to admit the thing.

TomHennen avatar Apr 05 '23 16:04 TomHennen

Per the above point I think this should arguably just be PASSED as the registry did decide to admit the thing.

+1 I also think the verification status should be about the entire policy passing or failing, not just levels.

laurentsimon avatar Apr 05 '23 16:04 laurentsimon

     // TBD: what would an appropriate policy URI being if the artifact is not being verified?
     // Could be a URI describing the authn checks performed by the registry?

I think that we should consider that the artifact itself is verified, after all the registry did decide to admit it. I think it would be fine to reference some global policy though?

That seems sane and inline with what I was thinking, a global/uniform policy which describes the checks npm makes before accepting a package into the registry. 👍

  "verificationResult": "UNVERIFIED",

Per the above point I think this should arguably just be PASSED as the registry did decide to admit the thing.

Good call.

I've updated the JSON snippet in my comment above https://github.com/slsa-framework/slsa/issues/801#issuecomment-1497776568

joshuagl avatar Apr 05 '23 16:04 joshuagl

It's also conceivable that a registry would have custom policies for some packages and they could indicate that in the policy field, but it's certainly not required that each package have its own policy.

TomHennen avatar Apr 05 '23 17:04 TomHennen

In my mind these are two distinct concepts:

  • VSA = attestation by (someone) that a particular artifact met SLSA expectations for a particular package name, whether or not it was actually published
  • Publish = attestation by the registry that a particular artifact was published under a particular package name and version, regardless of how it was authorized (SLSA or not)

MarkLodato avatar Apr 05 '23 17:04 MarkLodato

I think with the introduction of verifiedLevels as a list VSAs aren't restricted to describing if something just met SLSA expectations, they can describe much more than that.

Internally we're using it as a generic token that the artifact is approved. It seems like it could easily do the same thing for others? Are there any downsides to doing so?

TomHennen avatar Apr 05 '23 19:04 TomHennen

Sorry, I didn't mean to be overly SLSA specific. Rather, I was pointing out that "approved" is not the same as "published". Would it be confusing if we use the same format to represent these two different concepts?

MarkLodato avatar Apr 05 '23 19:04 MarkLodato

Something I'm realizing is that VSAs don't have a good naming convention on the resource-uri, and it's probably optional to verify the resource-uri during verification (unless the naming convention is clear). At least, in the VSA we internally generate, it's not always easy to make sense out of the resource-uri.

On the other hand, the main goal of the publish attestation is to enforce this mapping between provenance and package, so verification MUST check it.

That's one argument for not re-purposing the VSA, because having this difference means it will be non-obvious for users, and harder for us to build safe verification APIs.

laurentsimon avatar Apr 05 '23 23:04 laurentsimon

Yeah I think each ecosystem would need to establish their own convention for resources in VSAs.

My weak suggestion for npm would be to use purls with the package name and version (but not hash which is already in the VSA). e.g. pkg:npm/[email protected]

TomHennen avatar Apr 06 '23 12:04 TomHennen

I created https://github.com/slsa-framework/slsa/issues/808 to improve guidance on purl construction in the VSA.

What I like about the npm publish attestation is that it always contains a version, which lets users prevent rollback attacks if they want to. (in slsa-verifier, we provide a --package-version option for it)

laurentsimon avatar Apr 06 '23 15:04 laurentsimon

I believe that having an explicit publish attestation allows for a simpler mental model to reason about during verification, as pointed out the concepts are slightly different. Then a VSA could be created to signal that both the build provenance and the publish attestations has been verified by a given policy.

The registry does not perform a deep evaluation of the provenance, I would compare it to more like a smoke test, that all the provided digests and signatures are consistent. Future improvements could change this to e.g. verify that certain attributes of the provenance matches the expected ones.

On a related note, this was discussed last week during Sigstore's clients group meeting, and other ecosystems expressed in generalizing the publish attestations we use for npm. The current attestation is not strictly bound to npm, so I think it might actually work in a general sense. So my counter-ask would be how the SLSA team feel about owning the specification for a publish attestation?

kommendorkapten avatar Apr 11 '23 11:04 kommendorkapten

So my counter-ask would be how the SLSA team feel about owning the specification for a publish attestation?

This would make sense to me. I'm not sure if it needs to be SLSA specific attestation, but it would certainly make sense as an in-toto attestation.

TomHennen avatar Apr 11 '23 14:04 TomHennen

This would make sense to me. I'm not sure if it needs to be SLSA specific attestation, but it would certainly make sense as an in-toto attestation.

Agreed, most important is that we can share the predicate type across multiple ecosystems.

kommendorkapten avatar Apr 11 '23 14:04 kommendorkapten