mirror of
https://github.com/slsa-framework/slsa-verifier.git
synced 2026-02-14 17:49:58 +00:00
@laurentsimon Added a new image verification cmd input `--provenance-repository` This replicates the feature of the `COSIGN_REPOSITORY` environment variable when provenance is stored in a different repository/registry Order of precedence: - If input `--provenance-repository` is set, leverages the non-empty input value - If the env variable `COSIGN_REPOSITORY` is set, it is NOT consumed README edit : https://github.com/slsa-framework/slsa-verifier/pull/736/files#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R280 --------- Signed-off-by: saisatishkarra <saisatish.karra@konghq.com> Co-authored-by: laurentsimon <64505099+laurentsimon@users.noreply.github.com>
This commit is contained in:
22
README.md
22
README.md
@@ -262,6 +262,28 @@ The only requirement is that the provenance file covers all artifacts passed as
|
||||
|
||||
To verify a container image, you need to pass a container image name that is _immutable_ by providing its digest, in order to avoid [TOCTOU attacks](#toctou-attacks).
|
||||
|
||||
#### The verify-image command
|
||||
|
||||
```bash
|
||||
$ slsa-verifier verify-image --help
|
||||
Verifies SLSA provenance for an image
|
||||
|
||||
Usage:
|
||||
slsa-verifier verify-image [flags] tarball
|
||||
|
||||
Flags:
|
||||
--build-workflow-input map[] [optional] a workflow input provided by a user at trigger time in the format 'key=value'. (Only for 'workflow_dispatch' events on GitHub Actions). (default map[])
|
||||
--builder-id string [optional] the unique builder ID who created the provenance
|
||||
-h, --help help for verify-npm-package
|
||||
--print-provenance [optional] print the verified provenance to stdout
|
||||
--provenance-path string path to a provenance file
|
||||
--provenance-repository string [optional] provenance repository when stored different from image repository. When set, overrides COSIGN_REPOSITORY environment variable
|
||||
--source-branch string [optional] expected branch the binary was compiled from
|
||||
--source-tag string [optional] expected tag the binary was compiled from
|
||||
--source-uri string expected source repository that should have produced the binary, e.g. github.com/some/repo
|
||||
--source-versioned-tag string [optional] expected version the binary was compiled from. Uses semantic version to match the tag
|
||||
```
|
||||
|
||||
First set the image name:
|
||||
|
||||
```shell
|
||||
|
||||
@@ -96,6 +96,9 @@ func verifyImageCmd() *cobra.Command {
|
||||
if cmd.Flags().Changed("provenance-path") {
|
||||
v.ProvenancePath = &o.ProvenancePath
|
||||
}
|
||||
if cmd.Flags().Changed("provenance-repository") {
|
||||
v.ProvenanceRepository = &o.ProvenanceRepository
|
||||
}
|
||||
if cmd.Flags().Changed("source-branch") {
|
||||
v.SourceBranch = &o.SourceBranch
|
||||
}
|
||||
|
||||
@@ -38,8 +38,9 @@ type VerifyOptions struct {
|
||||
BuildWorkflowInputs workflowInputs
|
||||
BuilderID string
|
||||
/* Other */
|
||||
ProvenancePath string
|
||||
PrintProvenance bool
|
||||
ProvenancePath string
|
||||
ProvenanceRepository string
|
||||
PrintProvenance bool
|
||||
}
|
||||
|
||||
var _ Interface = (*VerifyOptions)(nil)
|
||||
@@ -67,6 +68,9 @@ func (o *VerifyOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVar(&o.ProvenancePath, "provenance-path", "",
|
||||
"path to a provenance file")
|
||||
|
||||
cmd.Flags().StringVar(&o.ProvenanceRepository, "provenance-repository", "",
|
||||
"image repository for provenance with format: <registry>/<repository>")
|
||||
|
||||
cmd.Flags().BoolVar(&o.PrintProvenance, "print-provenance", false,
|
||||
"[optional] print the verified provenance to stdout")
|
||||
|
||||
|
||||
@@ -30,14 +30,15 @@ type ComputeDigestFn func(string) (string, error)
|
||||
// Note: nil branch, tag, version-tag and builder-id means we ignore them during verification.
|
||||
type VerifyImageCommand struct {
|
||||
// May be nil if supplied alongside in the registry
|
||||
ProvenancePath *string
|
||||
BuilderID *string
|
||||
SourceURI string
|
||||
SourceBranch *string
|
||||
SourceTag *string
|
||||
SourceVersionTag *string
|
||||
BuildWorkflowInputs map[string]string
|
||||
PrintProvenance bool
|
||||
ProvenancePath *string
|
||||
ProvenanceRepository *string
|
||||
BuilderID *string
|
||||
SourceURI string
|
||||
SourceBranch *string
|
||||
SourceTag *string
|
||||
SourceVersionTag *string
|
||||
BuildWorkflowInputs map[string]string
|
||||
PrintProvenance bool
|
||||
}
|
||||
|
||||
func (c *VerifyImageCommand) Exec(ctx context.Context, artifacts []string) (*utils.TrustedBuilderID, error) {
|
||||
@@ -50,12 +51,13 @@ func (c *VerifyImageCommand) Exec(ctx context.Context, artifacts []string) (*uti
|
||||
}
|
||||
|
||||
provenanceOpts := &options.ProvenanceOpts{
|
||||
ExpectedSourceURI: c.SourceURI,
|
||||
ExpectedBranch: c.SourceBranch,
|
||||
ExpectedDigest: digest,
|
||||
ExpectedVersionedTag: c.SourceVersionTag,
|
||||
ExpectedTag: c.SourceTag,
|
||||
ExpectedWorkflowInputs: c.BuildWorkflowInputs,
|
||||
ExpectedSourceURI: c.SourceURI,
|
||||
ExpectedBranch: c.SourceBranch,
|
||||
ExpectedDigest: digest,
|
||||
ExpectedVersionedTag: c.SourceVersionTag,
|
||||
ExpectedTag: c.SourceTag,
|
||||
ExpectedProvenanceRepository: c.ProvenanceRepository,
|
||||
ExpectedWorkflowInputs: c.BuildWorkflowInputs,
|
||||
}
|
||||
|
||||
builderOpts := &options.BuilderOpts{
|
||||
@@ -71,6 +73,7 @@ func (c *VerifyImageCommand) Exec(ctx context.Context, artifacts []string) (*uti
|
||||
}
|
||||
|
||||
verifiedProvenance, outBuilderID, err := verifiers.VerifyImage(ctx, artifacts[0], provenance, provenanceOpts, builderOpts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@ type ProvenanceOpts struct {
|
||||
ExpectedPackageName *string
|
||||
|
||||
ExpectedPackageVersion *string
|
||||
|
||||
// ExpectedProvenanceRepository is the provenance repository that is passed from user and not verified
|
||||
ExpectedProvenanceRepository *string
|
||||
}
|
||||
|
||||
// BuildOpts are the options for checking the builder.
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/secure-systems-lab/go-securesystemslib/dsse"
|
||||
"github.com/sigstore/cosign/v2/pkg/cosign"
|
||||
"github.com/sigstore/rekor/pkg/client"
|
||||
@@ -245,8 +246,7 @@ func (v *GHAVerifier) VerifyArtifact(ctx context.Context,
|
||||
|
||||
// VerifyImage verifies provenance for an OCI image.
|
||||
func (v *GHAVerifier) VerifyImage(ctx context.Context,
|
||||
provenance []byte, artifactImage string,
|
||||
provenanceOpts *options.ProvenanceOpts,
|
||||
provenance []byte, artifactImage string, provenanceOpts *options.ProvenanceOpts,
|
||||
builderOpts *options.BuilderOpts,
|
||||
) ([]byte, *utils.TrustedBuilderID, error) {
|
||||
/* Retrieve any valid signed attestations that chain up to Fulcio root CA. */
|
||||
@@ -255,10 +255,13 @@ func (v *GHAVerifier) VerifyImage(ctx context.Context,
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Parse any provenance target repository set using environment variable COSIGN_REPOSITORY
|
||||
provenanceTargetRepository, err := ociremote.GetEnvTargetRepository()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
var provenanceTargetRepository name.Repository
|
||||
// Consume input for --provenance-repository when set
|
||||
if provenanceOpts.ExpectedProvenanceRepository != nil {
|
||||
provenanceTargetRepository, err = name.NewRepository(*provenanceOpts.ExpectedProvenanceRepository)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
registryClientOpts := []ociremote.Option{}
|
||||
@@ -276,6 +279,7 @@ func (v *GHAVerifier) VerifyImage(ctx context.Context,
|
||||
RekorPubKeys: trustedRoot.RekorPubKeys,
|
||||
CTLogPubKeys: trustedRoot.CTPubKeys,
|
||||
}
|
||||
|
||||
atts, _, err := container.RunCosignImageVerification(ctx,
|
||||
artifactImage, opts)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user