Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add SBOM in sync-request metadata #43

Merged
merged 1 commit into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
23 changes: 18 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down Expand Up @@ -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=
Expand All @@ -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=
Expand All @@ -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=
Expand All @@ -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=
Expand Down Expand Up @@ -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=
Expand Down
65 changes: 65 additions & 0 deletions policy/policy_handler/legacy/builder.go
Original file line number Diff line number Diff line change
@@ -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 {
Copy link
Contributor

@rnorton5432 rnorton5432 Jan 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already handled in this package here, do we specifically need to pass the sbom from the cli tool to the evaluator?

Fwiw, scout-cli-plugin also already does this mock, which takes precedence in go-skill if passed (so if the fields need to be expanded we can update scout-cli-plugin once instead of updating this repo and all policy repos).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we would like to use the existing SBOM struct as a standardised API for synchronous policy evaluation.

That struct encapsulates basically all the useful information that we have about a given image, so we can make changes to policies and introduce new policies without needing to rely on any CLI changes to pass new data.

It also gives us a way of getting local attestations (with the help of containerd) into policy evaluation.

Copy link
Contributor

@rnorton5432 rnorton5432 Jan 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I see the idea now. And now that I think about it, I agree it's the right move as well.

Two follow-up thoughts then:

  • This won't be a "legacy" thing if it's how we're planning to do local eval in the long-run, so let's not put it in the legacy package.
  • Let's try to remove the corresponding mocking logic from go-skill and scout-cli-plugin as we are given opportunities to, so that we don't end up holding onto them for some cross-project version combinations.
    • The packages query mock in this repo will need to remain to support old CLI versions.
    • The user query mock in this repo is released and used by non-root-user-skill, so we'll need to hold onto it for a while as well.
    • The packages mock in scout-cli-plugin that I linked above is not used by any released skills, to my knowledge. Once this PR is merged, I'll make sure policy-vulnerabilities is updated to use the SBOM version, and the mock is removed.

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,
},
},
}
}
99 changes: 99 additions & 0 deletions policy/policy_handler/legacy/builder_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
})
}
}
15 changes: 15 additions & 0 deletions policy/policy_handler/legacy/get_user.go
Original file line number Diff line number Diff line change
@@ -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,
}
}
7 changes: 7 additions & 0 deletions policy/policy_handler/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion policy/policy_handler/local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading
Loading