mirror of
https://github.com/slsa-framework/slsa-verifier.git
synced 2026-08-26 09:37:19 +00:00
We've long had the problem that slsa-verifier has too many dependencies. This PR replaces `"github.com/sigstore/cosign/v2/cmd/cosign/cli/fulcio"` with `"github.com/sigstore/sigstore/pkg/fulcioroots"`, removing lot's of unneeded transitive dependencies like `"github.com/aws/aws-sdk-go-v2"` and `"github.com/Azure/go-autorest/autorest"` from our `go.mod`. ## Investigation At [deps.dep](https://deps.dev/go/github.com%2Fslsa-framework%2Fslsa-verifier%2Fv2/v2.4.1/dependencies/graph?filter=aws), we can see that the indirect dependencies of `aws/aws-sdk-go-v2` come from `cosign/cosign`. <img width="1110" alt="image" src="https://github.com/slsa-framework/slsa-verifier/assets/32398091/3de1adf4-29ac-4bec-a511-0ae191c3141c"> That's a good start, but this gives us only module-wide dependencies, not package-level dependencies. We can instead use `go mod why <pkg>` to get the package-level dependency chain. Now we know that it's our `gha` package that imports a fulcio package, which imports an aws package. ``` ➜ slsa-verifier git:(main) ✗ go mod why github.com/aws/aws-sdk-go-v2/ # github.com/aws/aws-sdk-go-v2 github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha github.com/sigstore/cosign/v2/cmd/cosign/cli/fulcio github.com/sigstore/cosign/v2/cmd/cosign/cli/options github.com/awslabs/amazon-ecr-credential-helper/ecr-login github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api github.com/aws/aws-sdk-go-v2/config github.com/aws/aws-sdk-go-v2/internal/ini github.com/aws/aws-sdk-go-v2 ``` Looking at our `gha` package we can see that the required methods from fulcio are `Get()` and `GetIntermediates()`. Looking at the source codes, we see that `"github.com/sigstore/cosign/v2/cmd/cosign/cli/fulcio"`'s implementation of these methods is the same as `"github.com/sigstore/sigstore/pkg/fulcioroots"`'s implementation. So we chose the latter's implementation, which happens to require fewer module-level dependencies. - https://github.com/sigstore/cosign/blob/546f1c5b91ef58d6b034a402d0211d980184a0e5/cmd/cosign/cli/fulcio/fulcio.go#L16 - https://github.com/sigstore/cosign/blob/546f1c5b91ef58d6b034a402d0211d980184a0e5/internal/pkg/cosign/fulcio/fulcioroots/fulcioroots.go#L16 - https://github.com/sigstore/sigstore/blob/25dd9f3e52ec1e666b3c913edd1a0b7aa236b246/pkg/fulcioroots/fulcioroots.go#L17 ## Testing - unit tests continue to pass - manual test to verify a provenance with the steps in our [readme](https://github.com/slsa-framework/slsa-verifier?tab=readme-ov-file#npm-packages-built-using-the-slsa3-nodejs-builder) ## Future Work The sigstore-go library is meant to be a more long-term solution, for replacing much of the sigstore-related functionality that slsa-verifier implements directly. Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
77 lines
2.0 KiB
Go
77 lines
2.0 KiB
Go
package gha
|
|
|
|
import (
|
|
"context"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"sync/atomic"
|
|
|
|
"github.com/sigstore/cosign/v2/pkg/cosign"
|
|
"github.com/sigstore/sigstore/pkg/fulcioroots"
|
|
serrors "github.com/slsa-framework/slsa-verifier/v2/errors"
|
|
)
|
|
|
|
// TrustedRoot struct that holds the verification material necessary
|
|
// to validate items. MUST be populated out of band.
|
|
type TrustedRoot struct {
|
|
// RekorPubKeys is a map from log ID to public keys containing metadata.
|
|
RekorPubKeys *cosign.TrustedTransparencyLogPubKeys
|
|
|
|
// SctPubKeys is a map from log ID to public keys for the SCT.
|
|
CTPubKeys *cosign.TrustedTransparencyLogPubKeys
|
|
|
|
// Certificate pool for Fulcio roots.
|
|
FulcioRoot *x509.CertPool
|
|
|
|
// Certificate pool for Fulcio intermediates
|
|
FulcioIntermediates *x509.CertPool
|
|
}
|
|
|
|
func getTrustedRoot(ctx context.Context) (*TrustedRoot, error) {
|
|
rekorPubKeys, err := cosign.GetRekorPubs(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("%w: %s", serrors.ErrorRekorPubKey, err)
|
|
}
|
|
|
|
ctPubKeys, err := cosign.GetCTLogPubs(ctx)
|
|
if err != nil {
|
|
// this is unexpected, hold on to this error.
|
|
return nil, fmt.Errorf("%w: %s", serrors.ErrorInternal, err)
|
|
}
|
|
|
|
roots, err := fulcioroots.Get()
|
|
if err != nil {
|
|
// this is unexpected, hold on to this error.
|
|
return nil, fmt.Errorf("%w: %s", serrors.ErrorInternal, err)
|
|
}
|
|
intermediates, err := fulcioroots.GetIntermediates()
|
|
if err != nil {
|
|
// this is unexpected, hold on to this error.
|
|
return nil, fmt.Errorf("%w: %s", serrors.ErrorInternal, err)
|
|
}
|
|
|
|
return &TrustedRoot{
|
|
FulcioRoot: roots,
|
|
FulcioIntermediates: intermediates,
|
|
RekorPubKeys: rekorPubKeys,
|
|
CTPubKeys: ctPubKeys,
|
|
}, nil
|
|
}
|
|
|
|
// Cache the TUF roots to reduce traffic and read contention on the cached file.
|
|
var manager atomic.Value
|
|
|
|
func TrustedRootSingleton(ctx context.Context) (*TrustedRoot, error) {
|
|
root := manager.Load()
|
|
if root != nil {
|
|
return root.(*TrustedRoot), nil
|
|
}
|
|
trustedRoot, err := getTrustedRoot(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
manager.Store(trustedRoot)
|
|
return trustedRoot, nil
|
|
}
|