New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: VerifyNpmPackage API with supplied tuf client #768
base: main
Are you sure you want to change the base?
feat: VerifyNpmPackage API with supplied tuf client #768
Conversation
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking great, thanks so much for working on this. I have a few minor nits but overall it's looking good.
@@ -87,9 +90,9 @@ type mockSigstoreTufClient struct { | |||
fileContentMap map[string]string | |||
} | |||
|
|||
// NewMockSigstoreTufClient returns an instance of the mock client, | |||
// newMockSigstoreTufClient returns an instance of the mock client, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not for right now but in the future we might consider pulling out this mock client into its own test package so others can use it in tests (https://google.github.io/styleguide/go/best-practices.html#creating-test-helper-packages)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll be considering that. right now, the mock is very simple, so I guess folks can just copy-paste it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll followup in #773
Thanks for the review! I was also looking into logging in #772, |
This reverts commit e855e4f. Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. A few minor nits but overall LGTM
provenanceOpts *options.ProvenanceOpts, | ||
builderOpts *options.BuilderOpts, | ||
sigstoreTufClient utils.SigstoreTufClient, | ||
) ([]byte, *utils.TrustedBuilderID, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this func is following from VerifyNpmPackage
but I wonder if it should return the data in a more structured manner to make it easier for callers to inspect the fields they're interested in. At the moment, you'd have to parse the attestation yourself to get information from it (except builder id which is helpfully extracted). That's quite involved because the structure of the attestation is complex.
I think this is beyond the scope of what this PR is trying to do, so don't worry about it for these changes but maybe something to think about for the future? Even just having slsa-verifier
expose some of its functions for parsing an attestation could work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the returned []byte
, I think that's what StatementsFromBytes
is for, but its not yet implemented for npm.
- https://pkg.go.dev/github.com/slsa-framework/slsa-verifier/v2@v2.5.1/verifiers/utils#StatementFromBytes
slsa-verifier/verifiers/internal/gha/npm.go
Lines 224 to 229 in 87b5bae
func (n *Npm) verifiedProvenanceBytes() ([]byte, error) { // TODO(#493): prune the provenance and return only // verified fields. // NOTE: we currently don't verify the materials' commit sha. return []byte{}, nil }
@laurentsimon, @ianlewis , regarding #493, is it now safe to return the entire provenance, once verified?
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
@slugclub thanks again. @ianlewis @laurentsimon , please take a look |
@@ -34,6 +34,12 @@ type SLSAVerifier interface { | |||
provenanceOpts *options.ProvenanceOpts, | |||
builderOpts *options.BuilderOpts, | |||
) ([]byte, *utils.TrustedBuilderID, error) | |||
|
|||
VerifyNpmPackageWithSigstoreTUFClient(ctx context.Context, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we chatted about offline, we may want this API to take the npm verification material directly and another API responsible for fetching this target file from TUF. Then this API could verify metadata offline, and the latter API would be responsible for network calls. I think this would also make testing easier since you don't have to mock the Sigstore TUF client, just need the verification material struct initialized.
Another change, outside of the scope of this PR, would be to update https://github.com/slsa-framework/slsa-verifier/blob/main/verifiers/internal/gha/trusted_root.go to use TrustedMaterial rather than Cosign's APIs. Like you're already doing in https://github.com/slsa-framework/slsa-verifier/blob/main/verifiers/internal/gha/bundle.go#L162, rather than passing the TUF client, you would pass in the trusted root material.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Speaking about this offline again, we have our own struct to parse the material, but the spec/layout of the material isn't defined in npmjs docs. Until we can be sure that npmjs will commit to this layout, I think it's better to hide this detail from the user, or let the user stub out their own SigstoreTUFClient
.
This PR
VerifyNpmPackageWithSigstoreTufClient
method that allows supplying a SigstoreTufClient, and an io.Reader for the attestations json./docs/Api-Library.md
Offline rekor verification already works so long as the provenance is a valid sigstore bundle, though we could consider adding an explicit option to enforce offline rekor verifification.
Testing
./docs/Api-Library.md
Followups
slsa-verifier/verifiers/internal/gha/verifier.go
Line 89 in e7a8f74