Skip to content

Commit

Permalink
feat: vuln attest support (sigstore#1168)
Browse files Browse the repository at this point in the history
Signed-off-by: Batuhan Apaydın <[email protected]>
Co-authored-by: Furkan Türkal <[email protected]>
Signed-off-by: Batuhan Apaydın <[email protected]>

Co-authored-by: Furkan Türkal <[email protected]>
Signed-off-by: Batuhan Apaydın <[email protected]>
  • Loading branch information
developer-guy and Dentrax committed Dec 21, 2021
1 parent 6a4afef commit f2d5299
Show file tree
Hide file tree
Showing 6 changed files with 491 additions and 6 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ jobs:
- uses: actions/setup-go@v2
with:
go-version: '1.17.x'
- uses: imjasonh/[email protected]
with:
version: tip
- uses: imjasonh/setup-ko@main
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@master
with:
Expand Down
4 changes: 3 additions & 1 deletion cmd/cosign/cli/options/predicate.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const (
PredicateSLSA = "slsaprovenance"
PredicateSPDX = "spdx"
PredicateLink = "link"
PredicateVuln = "vuln"
)

// PredicateTypeMap is the mapping between the predicate `type` option to predicate URI.
Expand All @@ -40,6 +41,7 @@ var PredicateTypeMap = map[string]string{
PredicateSLSA: slsa.PredicateSLSAProvenance,
PredicateSPDX: in_toto.PredicateSPDX,
PredicateLink: in_toto.PredicateLinkV1,
PredicateVuln: attestation.CosignVulnProvenanceV01,
}

// PredicateOptions is the wrapper for predicate related options.
Expand All @@ -52,7 +54,7 @@ var _ Interface = (*PredicateOptions)(nil)
// AddFlags implements Interface
func (o *PredicateOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&o.Type, "type", "custom",
"specify a predicate type (slsaprovenance|link|spdx|custom) or an URI")
"specify a predicate type (slsaprovenance|link|spdx|vuln|custom) or an URI")
}

// ParsePredicateType parses the predicate `type` flag passed into a predicate URI, or validates `type` is a valid URI.
Expand Down
2 changes: 1 addition & 1 deletion doc/cosign_attest.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion doc/cosign_verify-attestation.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions pkg/cosign/attestation/attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import (
const (
// CosignCustomProvenanceV01 specifies the type of the Predicate.
CosignCustomProvenanceV01 = "cosign.sigstore.dev/attestation/v1"

// CosignVulnProvenanceV01 specifies the type of VulnerabilityScan Predicate
CosignVulnProvenanceV01 = "cosign.sigstore.dev/attestation/vuln/v1"
)

// CosignPredicate specifies the format of the Custom Predicate.
Expand All @@ -40,6 +43,37 @@ type CosignPredicate struct {
Timestamp string
}

// VulnPredicate specifies the format of the Vulnerability Scan Predicate
type CosignVulnPredicate struct {
Invocation Invocation `json:"invocation"`
Scanners []Scanner `json:"scanners"`
Metadata Metadata `json:"metadata"`
}

type Invocation struct {
Parameters interface{} `json:"parameters"`
URI string `json:"uri"`
EventID string `json:"event_id"`
BuilderID string `json:"builder.id"`
}

type DB struct {
URI string `json:"uri"`
Version string `json:"version"`
}

type Scanner struct {
URI string `json:"uri"`
Version string `json:"version"`
DB DB `json:"db"`
Result map[string]interface{} `json:"result"`
}

type Metadata struct {
ScanStartedOn time.Time `json:"scanStartedOn"`
ScanFinishedOn time.Time `json:"scanFinishedOn"`
}

// GenerateOpts specifies the options of the Statement generator.
type GenerateOpts struct {
// Predicate is the source of bytes (e.g. a file) to use as the statement's predicate.
Expand Down Expand Up @@ -71,13 +105,29 @@ func GenerateStatement(opts GenerateOpts) (interface{}, error) {
return generateSPDXStatement(predicate, opts.Digest, opts.Repo)
case "link":
return generateLinkStatement(predicate, opts.Digest, opts.Repo)
case "vuln":
return generateVulnStatement(predicate, opts.Digest, opts.Repo)
default:
stamp := timestamp(opts)
predicateType := customType(opts)
return generateCustomStatement(predicate, predicateType, opts.Digest, opts.Repo, stamp)
}
}

func generateVulnStatement(predicate []byte, digest string, repo string) (interface{}, error) {
var vuln CosignVulnPredicate

err := json.Unmarshal(predicate, &vuln)
if err != nil {
return nil, err
}

return in_toto.Statement{
StatementHeader: generateStatementHeader(digest, repo, CosignVulnProvenanceV01),
Predicate: vuln,
}, nil
}

func timestamp(opts GenerateOpts) string {
if opts.Time == nil {
opts.Time = time.Now
Expand Down
Loading

0 comments on commit f2d5299

Please sign in to comment.