-
Notifications
You must be signed in to change notification settings - Fork 50
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?
Changes from all commits
e4c034a
1f04dce
7d7448b
6c69c5c
d5d6f6e
88ba4da
ef7384f
4da9d12
e208b4a
3fd185e
f414666
0356825
9d0f2b2
bec1ad9
96ea870
91173c1
aad1c11
0629763
f41e1fd
3803a16
efa3fa5
3ccbce7
7a8a94d
e53b528
ada0207
a2cb9b9
e2dcffc
a0c70c8
57b3797
c9318ae
f1ee89d
5b1c921
cde7688
667215a
1bd8955
3a09aac
5845e1c
5356a7c
65dce19
8e038e4
7268490
6cf042a
4bdc88a
b4381c5
772f659
4ca058b
8ba939a
a1d45cc
74bf48e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# Api Library | ||
|
||
## Verifers | ||
|
||
We have exported functions for using slsa-verifier within your own Go packages | ||
|
||
- slsa-verifier/verifiers/verifier.go | ||
|
||
### Npmjs | ||
|
||
With `VerifyNpmPackageWithSigstoreTUFClient`, you can pass in your own TUF client with custom options. | ||
For example, use the embedded TUF root with `sigstoreTUF.DefaultOptions().WithForceCache()`. | ||
|
||
Example: | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
"os" | ||
|
||
sigstoreTUF "github.com/sigstore/sigstore-go/pkg/tuf" | ||
options "github.com/slsa-framework/slsa-verifier/v2/options" | ||
apiVerify "github.com/slsa-framework/slsa-verifier/v2/verifiers" | ||
apiUtils "github.com/slsa-framework/slsa-verifier/v2/verifiers/utils" | ||
) | ||
|
||
func main() { | ||
provBytes, builderID, err := doVerify() | ||
if err != nil { | ||
log.Fatalf("Verifying npm package: FAILED: %w", err) | ||
} | ||
fmt.Fprintf(os.Stderr, "builderID: %s\n", builderID.Name()) | ||
fmt.Fprintf(os.Stderr, "Verifying npm package: PASSED") | ||
fmt.Printf("%s", provBytes) | ||
} | ||
|
||
func doVerify() ([]byte, *apiUtils.TrustedBuilderID, error) { | ||
packageVersion := "0.1.127" | ||
packageName := "@ianlewis/actions-test" | ||
builderID := "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_nodejs_slsa3.yml" | ||
attestations, err := os.ReadFile("attestations.json") | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("creating sigstoreTUF client: %w", err) | ||
} | ||
tarballHash := "ab786dbef723164a605e55ff0ebe83f8e879159bd411980d4423c9b1646b858a537b4bc4d494fc8f71195db715e5c5e9ab4b8809f8b1b399cd30ac053d180ba7" | ||
provenanceOpts := &options.ProvenanceOpts{ | ||
ExpectedSourceURI: "github.com/ianlewis/actions-test", | ||
ExpectedDigest: "ab786dbef723164a605e55ff0ebe83f8e879159bd411980d4423c9b1646b858a537b4bc4d494fc8f71195db715e5c5e9ab4b8809f8b1b399cd30ac053d180ba7", | ||
ExpectedPackageName: &packageName, | ||
ExpectedPackageVersion: &packageVersion, | ||
} | ||
builderOpts := &options.BuilderOpts{ | ||
ExpectedID: &builderID, | ||
} | ||
|
||
// example: all the default ClientOpts | ||
// clientOpts, err := options.NewDefaultClientOpts() | ||
|
||
// example: get the default Sigstore TUF client that the library caches | ||
// client, err := apiUtils.GetDefaultSigstoreTUFClient() | ||
|
||
// example: force using the embedded root, without going online for a refresh | ||
// opts := sigstoreTUF.DefaultOptions().WithForceCache() | ||
|
||
// example: supply your own root | ||
// opts := sigstoreTUF.DefaultOptions().WithRoot([]byte(`{"signed":{"_type":"root","spec_version":"1.0","version":9,"expires":"2024-09-12T06:53:10Z","keys":{"1e1d65ce98b10 ...`)).WithForceCache() | ||
|
||
// example: supply your own default Sigstore TUF client | ||
opts := sigstoreTUF.DefaultOptions() | ||
client, err := sigstoreTUF.New(opts) | ||
if err != nil { | ||
return nil, fmt.Errorf("creating SigstoreTUF client: %w", err) | ||
} | ||
clientOpts := options.ClientOpts{ | ||
SigstoreTUFClient: client, | ||
} | ||
provBytes, outBuilderID, err := apiVerify.VerifyNpmPackage(context.Background(), attestations, tarballHash, provenanceOpts, builderOpts, clientOpts) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("Verifying npm package: FAILED: %w", err) | ||
} | ||
return provBytes, outBuilderID, nil | ||
} | ||
``` |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -44,6 +44,7 @@ func (v *GCBVerifier) VerifyNpmPackage(ctx context.Context, | |||||||||||||
attestations []byte, tarballHash string, | ||||||||||||||
provenanceOpts *options.ProvenanceOpts, | ||||||||||||||
builderOpts *options.BuilderOpts, | ||||||||||||||
clientOpts *options.ClientOpts, | ||||||||||||||
) ([]byte, *utils.TrustedBuilderID, error) { | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know this func is following from 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With the returned
@laurentsimon, @ianlewis , regarding #493, is it now safe to return the entire provenance, once verified? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think so.
@ramonpetgrave64 That's maybe what we discussed a few weeks ago, to have a layered approach to verification where the inner layer returns a structured "condense" / summary for callers to use. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added printing in a new commit |
||||||||||||||
return nil, nil, serrors.ErrorNotSupported | ||||||||||||||
} | ||||||||||||||
|
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.
do you want to hack on the existing API or create a cleaner / new set of APIs?
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 wouldn't call it a hack. But your other comment got me thinking I could expose the
Npm
struct externally, or make a newNpmVerifier
struct. And we could still use that TUFClient to let the user pass in their own TUF root.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.
@laurentsimon Alright I decided to do both this new struct and the variadic arguments in options.go
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.
Another question following from Laurent's - how much leeway do we have to change this API? Does it have many users currently? Would it be possible to make a new release with a breaking change? (Not saying we necessarily have to do that just wondering what the constraints are here).
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 suppose we could have lots of leeway. Personally, I'd rather we get this into v2, and then later on add the breaking changes in a new v3.