github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/report/predicate/vuln.go (about) 1 package predicate 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "time" 8 9 "github.com/package-url/packageurl-go" 10 "golang.org/x/xerrors" 11 12 "github.com/devseccon/trivy/pkg/clock" 13 "github.com/devseccon/trivy/pkg/types" 14 ) 15 16 // CosignVulnPredicate represents the Cosign Vulnerability Scan Record. 17 // CosignVulnPredicate is based on structures in the Cosign repository. 18 // We defined them ourselves to reduce our dependence on the repository. 19 // cf. https://github.com/sigstore/cosign/blob/e0547cff64f98585a837a524ff77ff6b47ff5609/pkg/cosign/attestation/attestation.go#L45-L50 20 type CosignVulnPredicate struct { 21 Invocation Invocation `json:"invocation"` 22 Scanner Scanner `json:"scanner"` 23 Metadata Metadata `json:"metadata"` 24 } 25 26 type Invocation struct { 27 Parameters interface{} `json:"parameters"` 28 URI string `json:"uri"` 29 EventID string `json:"event_id"` 30 BuilderID string `json:"builder.id"` 31 } 32 33 type DB struct { 34 URI string `json:"uri"` 35 Version string `json:"version"` 36 } 37 38 type Scanner struct { 39 URI string `json:"uri"` 40 Version string `json:"version"` 41 DB DB `json:"db"` 42 Result types.Report `json:"result"` 43 } 44 45 type Metadata struct { 46 ScanStartedOn time.Time `json:"scanStartedOn"` 47 ScanFinishedOn time.Time `json:"scanFinishedOn"` 48 } 49 50 type VulnWriter struct { 51 output io.Writer 52 version string 53 } 54 55 func NewVulnWriter(output io.Writer, version string) VulnWriter { 56 return VulnWriter{ 57 output: output, 58 version: version, 59 } 60 } 61 62 func (w VulnWriter) Write(report types.Report) error { 63 64 predicate := CosignVulnPredicate{} 65 66 purl := packageurl.NewPackageURL("github", "aquasecurity", "trivy", w.version, nil, "") 67 predicate.Scanner = Scanner{ 68 URI: purl.ToString(), 69 Version: w.version, 70 Result: report, 71 } 72 73 now := clock.Now() 74 predicate.Metadata = Metadata{ 75 ScanStartedOn: now, 76 ScanFinishedOn: now, 77 } 78 79 output, err := json.MarshalIndent(predicate, "", " ") 80 if err != nil { 81 return xerrors.Errorf("failed to marshal cosign vulnerability predicate: %w", err) 82 } 83 84 if _, err = fmt.Fprint(w.output, string(output)); err != nil { 85 return xerrors.Errorf("failed to write cosign vulnerability predicate: %w", err) 86 } 87 return nil 88 89 }