diff --git a/go.mod b/go.mod index c87d0c0..d2e5efe 100644 --- a/go.mod +++ b/go.mod @@ -5,16 +5,22 @@ go 1.19 require ( cloud.google.com/go/logging v1.8.1 cloud.google.com/go/storage v1.31.0 + github.com/google/go-containerregistry v0.18.0 github.com/google/uuid v1.3.1 github.com/hasura/go-graphql-client v0.9.3 github.com/mitchellh/hashstructure/v2 v2.0.1 - github.com/sirupsen/logrus v1.9.0 - github.com/stretchr/testify v1.8.1 + github.com/sirupsen/logrus v1.9.3 + github.com/stretchr/testify v1.8.4 golang.org/x/oauth2 v0.13.0 google.golang.org/api v0.147.0 olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 ) +require ( + github.com/kr/text v0.2.0 // indirect + github.com/package-url/packageurl-go v0.1.1 // indirect +) + require ( cloud.google.com/go v0.110.8 // indirect cloud.google.com/go/compute v1.23.0 // indirect @@ -28,7 +34,8 @@ require ( github.com/google/s2a-go v0.1.7 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect - github.com/klauspost/compress v1.10.3 // indirect + github.com/klauspost/compress v1.16.5 // indirect + github.com/openvex/go-vex v0.2.5 github.com/pmezard/go-difflib v1.0.0 // indirect go.opencensus.io v0.24.0 // indirect golang.org/x/crypto v0.14.0 // indirect diff --git a/go.sum b/go.sum index 77239c2..1324092 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -74,6 +75,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-containerregistry v0.18.0 h1:ShE7erKNPqRh5ue6Z9DUOlk04WsnFWPO6YGr3OxnfoQ= +github.com/google/go-containerregistry v0.18.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= @@ -96,8 +99,12 @@ github.com/hasura/go-graphql-client v0.9.3 h1:Xi3fqa2t9q4nJ2jM2AU8nB6qeAoMpbcYDi github.com/hasura/go-graphql-client v0.9.3/go.mod h1:AarJlxO1I59MPqU/TC7gQP0BMFgPEqUTt5LYPvykasw= github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= @@ -109,11 +116,16 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openvex/go-vex v0.2.5 h1:41utdp2rHgAGCsG+UbjmfMG5CWQxs15nGqir1eRgSrQ= +github.com/openvex/go-vex v0.2.5/go.mod h1:j+oadBxSUELkrKh4NfNb+BPo77U3q7gdKME88IO/0Wo= +github.com/package-url/packageurl-go v0.1.1 h1:KTRE0bK3sKbFKAk3yy63DpeskU7Cvs/x/Da5l+RtzyU= +github.com/package-url/packageurl-go v0.1.1/go.mod h1:uQd4a7Rh3ZsVg5j0lNyAfyxIeGde9yrlhjF78GzeW0c= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -122,8 +134,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= @@ -222,8 +235,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/policy/policy_handler/legacy/builder.go b/policy/policy_handler/legacy/builder.go new file mode 100644 index 0000000..792b3e9 --- /dev/null +++ b/policy/policy_handler/legacy/builder.go @@ -0,0 +1,65 @@ +package legacy + +import ( + "github.com/atomist-skills/go-skill/policy/types" + "olympos.io/encoding/edn" +) + +func BuildLocalEvalMocks(sb *types.SBOM) map[edn.Keyword]edn.RawMessage { + m := map[edn.Keyword]edn.RawMessage{} + if sb == nil { + return m + } + + m[ImagePackagesByDigestQueryName], _ = edn.Marshal(MockImagePackagesByDigestForLocalEval(sb)) + + if sb.Source.Image != nil && sb.Source.Image.Config != nil { + m[GetUserQueryName], _ = edn.Marshal(MockGetUserForLocalEval(sb.Source.Image.Config.Config.User)) + } + + return m +} + +func MockImagePackagesByDigestForLocalEval(sb *types.SBOM) ImagePackagesByDigestResponse { + vulns := map[string][]Vulnerability{} + for _, tuple := range sb.Vulnerabilities { + vulnsForPurl := []Vulnerability{} + for _, v := range tuple.Vulnerabilities { + vulnsForPurl = append(vulnsForPurl, Vulnerability{ + Cvss: Cvss{ + Severity: &v.Cvss.Severity, + Score: &v.Cvss.Score, + }, + FixedBy: &v.FixedBy, + Source: v.Source, + SourceID: v.SourceId, + URL: &v.Url, + VulnerableRange: v.VulnerableRange, + }) + } + vulns[tuple.Purl] = vulnsForPurl + } + + pkgs := []Packages{} + for _, a := range sb.Artifacts { + pkgs = append(pkgs, Packages{ + Package: PackageWithLicenses{ + Licenses: a.Licenses, + Name: a.Name, + Namespace: &a.Namespace, + Version: a.Version, + Purl: a.Purl, + Type: a.Type, + Vulnerabilities: vulns[a.Purl], + }, + }) + } + + return ImagePackagesByDigestResponse{ + ImagePackagesByDigest: &ImagePackagesByDigest{ + ImagePackages: ImagePackages{ + Packages: pkgs, + }, + }, + } +} diff --git a/policy/policy_handler/legacy/builder_test.go b/policy/policy_handler/legacy/builder_test.go new file mode 100644 index 0000000..d84d971 --- /dev/null +++ b/policy/policy_handler/legacy/builder_test.go @@ -0,0 +1,99 @@ +package legacy + +import ( + "reflect" + "testing" + + "github.com/atomist-skills/go-skill/policy/types" + v1 "github.com/google/go-containerregistry/pkg/v1" + "olympos.io/encoding/edn" +) + +func Test_BuildLocalEvalMocks(t *testing.T) { + type args struct { + sb *types.SBOM + } + tests := []struct { + name string + args args + want map[edn.Keyword]edn.RawMessage + }{ + { + name: "Without SBOM", + args: args{ + sb: nil, + }, + want: map[edn.Keyword]edn.RawMessage{}, + }, + { + name: "With SBOM", + args: args{ + sb: &types.SBOM{ + Source: types.Source{ + Image: &types.ImageSource{ + Config: &v1.ConfigFile{ + Config: v1.Config{ + User: "root", + }, + }, + }, + }, + Artifacts: []types.Package{ + { + Name: "pkg1", + }, + }, + }, + }, + want: map[edn.Keyword]edn.RawMessage{ + "image-packages-by-digest": []byte(`{:imagePackagesByDigest{:imagePackages{:packages[{:package{:licenses nil :name"pkg1":namespace"":version"":purl"":type"":vulnerabilities nil}}]}}}`), + "get-user": []byte(`{:docker.image/user"root"}`), + }, + }, + { + name: "SBOM without image source", + args: args{ + sb: &types.SBOM{ + Source: types.Source{ + Image: nil, + }, + Artifacts: []types.Package{ + { + Name: "pkg1", + }, + }, + }, + }, + want: map[edn.Keyword]edn.RawMessage{ + "image-packages-by-digest": []byte(`{:imagePackagesByDigest{:imagePackages{:packages[{:package{:licenses nil :name"pkg1":namespace"":version"":purl"":type"":vulnerabilities nil}}]}}}`), + }, + }, + { + name: "SBOM without image config file", + args: args{ + sb: &types.SBOM{ + Source: types.Source{ + Image: &types.ImageSource{ + Config: nil, + }, + }, + Artifacts: []types.Package{ + { + Name: "pkg1", + }, + }, + }, + }, + want: map[edn.Keyword]edn.RawMessage{ + "image-packages-by-digest": []byte(`{:imagePackagesByDigest{:imagePackages{:packages[{:package{:licenses nil :name"pkg1":namespace"":version"":purl"":type"":vulnerabilities nil}}]}}}`), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := BuildLocalEvalMocks(tt.args.sb); !reflect.DeepEqual(got, tt.want) { + t.Errorf("BuildLocalEvalMocks() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/policy/policy_handler/legacy/get_user.go b/policy/policy_handler/legacy/get_user.go new file mode 100644 index 0000000..fa03826 --- /dev/null +++ b/policy/policy_handler/legacy/get_user.go @@ -0,0 +1,15 @@ +package legacy + +const ( + GetUserQueryName = "get-user" +) + +type DockerImageUser struct { + ImageUser string `edn:"docker.image/user,omitempty"` +} + +func MockGetUserForLocalEval(user string) DockerImageUser { + return DockerImageUser{ + ImageUser: user, + } +} diff --git a/policy/policy_handler/local.go b/policy/policy_handler/local.go index 6ece648..7654461 100644 --- a/policy/policy_handler/local.go +++ b/policy/policy_handler/local.go @@ -3,10 +3,12 @@ package policy_handler import ( "context" "fmt" + "github.com/atomist-skills/go-skill" "github.com/atomist-skills/go-skill/policy/data" "github.com/atomist-skills/go-skill/policy/goals" "github.com/atomist-skills/go-skill/policy/policy_handler/legacy" + "github.com/atomist-skills/go-skill/policy/types" "olympos.io/encoding/edn" ) @@ -16,6 +18,7 @@ type SyncRequestMetadata struct { QueryResults map[edn.Keyword]edn.RawMessage `edn:"fixedQueryResults"` Packages []legacy.Package `edn:"packages"` // todo remove when no longer used User string `edn:"imgConfigUser"` // The user from the image config blob // todo remove when no longer used + SBOM *types.SBOM `edn:"sbom"` } func WithLocal() Opt { @@ -56,6 +59,10 @@ func buildLocalDataSources(ctx context.Context, req skill.RequestContext, _ goal return nil, fmt.Errorf("failed to unmarshal SyncRequest metadata: %w", err) } + if srMeta.SBOM != nil { + srMeta.QueryResults = legacy.BuildLocalEvalMocks(srMeta.SBOM) + } + fixedQueryResults := map[string][]byte{} for k, v := range srMeta.QueryResults { fixedQueryResults[string(k)] = v diff --git a/policy/policy_handler/local_test.go b/policy/policy_handler/local_test.go index eb5d2c9..452715d 100644 --- a/policy/policy_handler/local_test.go +++ b/policy/policy_handler/local_test.go @@ -2,11 +2,12 @@ package policy_handler import ( "context" + "testing" + "github.com/atomist-skills/go-skill" "github.com/atomist-skills/go-skill/policy/goals" "github.com/stretchr/testify/assert" "olympos.io/encoding/edn" - "testing" ) type TestQueryResultFields struct { diff --git a/policy/types/graphql_types.go b/policy/types/graphql_types.go new file mode 100644 index 0000000..b1a0aa4 --- /dev/null +++ b/policy/types/graphql_types.go @@ -0,0 +1,73 @@ +package types + +import "github.com/openvex/go-vex/pkg/vex" + +type BaseImage struct { + CreatedAt string `graphql:"createdAt" json:"created_at,omitempty"` + Digest string `graphql:"digest" json:"digest,omitempty"` + Repository BaseImageRepository `graphql:"repository" json:"repository"` + Tags []struct { + Current bool `graphql:"current" json:"current"` + Name string `graphql:"name" json:"name,omitempty"` + Supported bool `graphql:"supported" json:"supported"` + } `graphql:"tags" json:"tags,omitempty"` + DockerFile struct { + Commit struct { + Repository struct { + Org string `graphql:"orgName" json:"org,omitempty"` + Repo string `graphql:"repoName" json:"repo,omitempty"` + } `graphql:"repository" json:"repository,omitempty"` + Sha string `graphql:"sha" json:"sha,omitempty"` + } `json:"commit,omitempty"` + Path string `graphql:"path" json:"path,omitempty"` + } `graphql:"dockerFile" json:"docker_file,omitempty"` + PackageCount int `graphql:"packageCount" json:"package_count,omitempty"` + VulnerabilityReport *VulnerabilityReport `graphql:"vulnerabilityReport" json:"vulnerability_report"` + Platform struct { + Arch string `graphql:"architecture"` + OS string `graphql:"os"` + Variant string `graphql:"variant"` + } `graphql:"platform"` +} +type VulnerabilitiesByPurl struct { + Purl string `graphql:"purl" json:"purl,omitempty"` + Vulnerabilities []Vulnerability `graphql:"vulnerabilities" json:"vulnerabilities,omitempty"` +} + +type Vulnerability struct { + Source string `graphql:"source" json:"source,omitempty"` + SourceId string `graphql:"sourceId" json:"source_id,omitempty"` + Description string `graphql:"description" json:"description,omitempty"` + VulnerableRange string `graphql:"vulnerableRange" json:"vulnerable_range,omitempty"` + FixedBy string `graphql:"fixedBy" json:"fixed_by,omitempty"` + Url string `graphql:"url" json:"url,omitempty"` + Cvss struct { + Score float32 `graphql:"score" json:"score,omitempty"` + Severity string `graphql:"severity" json:"severity,omitempty"` + Vector string `graphql:"vector" json:"vector,omitempty"` + Version string `graphql:"version" json:"version,omitempty"` + } `graphql:"cvss" json:"cvss,omitempty"` + Cwes []Cwe `graphql:"cwes" json:"cwes,omitempty"` + VexStatements []vex.VEX `graphql:"-" json:"vex_statements,omitempty"` +} + +type BaseImageRepository struct { + Badge string `graphql:"badge" json:"badge,omitempty"` + Host string `graphql:"hostName" json:"host,omitempty"` + Repo string `graphql:"repoName" json:"repo,omitempty"` + SupportedTags []string `graphql:"supportedTags" json:"supported_tags,omitempty"` + PreferredTags []string `graphql:"preferredTags" json:"preferred_tags,omitempty"` +} + +type VulnerabilityReport struct { + Critical int `graphql:"critical" json:"critical,omitempty"` + High int `graphql:"high" json:"high,omitempty"` + Medium int `graphql:"medium" json:"medium,omitempty"` + Low int `graphql:"low" json:"low,omitempty"` + Unspecified int `graphql:"unspecified" json:"unspecified,omitempty"` + Total int `graphql:"total" json:"total,omitempty"` +} +type Cwe struct { + CweId string `graphql:"cweId" json:"cwe_id,omitempty"` + Name string `graphql:"description" json:"name,omitempty"` +} diff --git a/policy/types/types.go b/policy/types/types.go new file mode 100644 index 0000000..00d86d7 --- /dev/null +++ b/policy/types/types.go @@ -0,0 +1,141 @@ +package types + +import v1 "github.com/google/go-containerregistry/pkg/v1" + +type SBOM struct { + Source Source `json:"source"` + Artifacts []Package `json:"artifacts"` + Vulnerabilities []VulnerabilitiesByPurl `json:"vulnerabilities,omitempty"` + Secrets []Secret `json:"secrets,omitempty"` + Descriptor Descriptor `json:"descriptor"` +} + +type Source struct { + Type string `json:"type"` + Image *ImageSource `json:"image,omitempty"` + FileSystem *FileSystemSource `json:"file_system,omitempty"` + BaseImages []BaseImageMatch `json:"base_images,omitempty"` + Provenance *Provenance `json:"provenance,omitempty"` +} + +type Package struct { + Type string `json:"type"` + Namespace string `json:"namespace,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + Purl string `json:"purl"` + Author string `json:"author,omitempty"` + Description string `json:"description,omitempty"` + Licenses []string `json:"licenses,omitempty"` + Url string `json:"url,omitempty"` + Size int `json:"size,omitempty"` + InstalledSize int `json:"installed_size,omitempty"` + Locations []Location `json:"locations"` + Files []Location `json:"files,omitempty"` + Parent string `json:"parent,omitempty"` +} +type Secret struct { + Source SecretSource `json:"source"` + Findings []SecretFinding `json:"findings"` +} +type SecretSource struct { + Type string `json:"type"` + Location *Location `json:"location,omitempty"` +} + +type SecretFinding struct { + RuleID string `json:"rule_id"` + Category string `json:"category"` + Title string `json:"title"` + Severity string `json:"severity"` + StartLine int `json:"start_line,omitempty"` + EndLine int `json:"end_line,omitempty"` + Match string `json:"match"` +} +type Descriptor struct { + Name string `json:"name"` + Version string `json:"version"` + SbomVersion string `json:"sbom_version"` +} + +type Location struct { + Path string `json:"path,omitempty"` + Ordinal int `json:"ordinal,omitempty"` + Digest string `json:"digest,omitempty"` + DiffID string `json:"diff_id,omitempty"` +} + +type ImageSource struct { + Name string `json:"name"` + Digest string `json:"digest"` + Tags *[]string `json:"tags,omitempty"` + Manifest *v1.Manifest `json:"manifest,omitempty"` + Config *v1.ConfigFile `json:"config,omitempty"` + RawManifest string `json:"raw_manifest"` + RawConfig string `json:"raw_config"` + Distro Distro `json:"distro"` + Platform Platform `json:"platform"` + Size int64 `json:"size"` + Details *BaseImage `json:"details,omitempty"` +} +type Distro struct { + OsName string `json:"os_name,omitempty"` + OsVersion string `json:"os_version,omitempty"` + OsDistro string `json:"os_distro,omitempty"` +} +type Platform struct { + Os string `json:"os"` + Architecture string `json:"architecture"` + Variant string `json:"variant,omitempty"` +} +type FileSystemSource struct { + Name string `json:"name,omitempty"` + Path string `json:"path"` + Size int64 `json:"size"` +} + +type BaseImageMatch struct { + DiffIds []string `graphql:"matches" json:"diff_ids,omitempty"` + Images []BaseImage `graphql:"images" json:"images,omitempty"` +} + +type Provenance struct { + SourceMap *SourceMap `json:"source_map,omitempty"` + VCS *VCS `json:"vcs,omitempty"` + BaseImage *ProvenanceBaseImage `json:"base_image,omitempty"` + Stream *Stream `json:"stream,omitempty"` +} + +type SourceMap struct { + Instructions []InstructionSourceMap `json:"instructions,omitempty"` + Dockerfile string `json:"dockerfile,omitempty"` + Sha string `json:"sha,omitempty"` +} + +type VCS struct { + Revision string `json:"revision,omitempty"` + Source string `json:"source,omitempty"` +} + +type ProvenanceBaseImage struct { + Name string + Tag string + Digest string + Platform *v1.Platform +} + +type Stream struct { + Name string `json:"name,omitempty"` +} + +type InstructionSourceMap struct { + Digests []string `json:"digests,omitempty"` + DiffIDs []string `json:"diff_ids,omitempty"` + Instruction string `json:"instruction,omitempty"` + Source string `json:"source,omitempty"` + Path string `json:"path,omitempty"` + StartLine int `json:"start_line,omitempty"` + StartColumn int `json:"start_column,omitempty"` + EndLine int `json:"end_line,omitempty"` + EndColumn int `json:"end_column,omitempty"` +}