From f88775418ada774d0ca8bb9a0a7a32d884125211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Garc=C3=ADa=20Veytia=20=28Puerco=29?= Date: Tue, 4 Jun 2024 18:52:53 -0600 Subject: [PATCH 1/2] Drop trusty REST client for SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit modifies the trusty evaluator to use the API client from stacklok/trusty-sdk-go isntead of the in tree pacakge which is now removed. Signed-off-by: Adolfo García Veytia (Puerco) --- internal/engine/eval/trusty/actions.go | 5 +- internal/engine/eval/trusty/actions_test.go | 31 ++-- internal/engine/eval/trusty/trusty.go | 32 ++-- .../engine/eval/trusty/trusty_rest_handler.go | 175 ------------------ internal/engine/eval/trusty/trusty_test.go | 95 +++++----- internal/engine/eval_status.go | 10 + 6 files changed, 97 insertions(+), 251 deletions(-) delete mode 100644 internal/engine/eval/trusty/trusty_rest_handler.go diff --git a/internal/engine/eval/trusty/actions.go b/internal/engine/eval/trusty/actions.go index db5961477f..9bdc762f0d 100644 --- a/internal/engine/eval/trusty/actions.go +++ b/internal/engine/eval/trusty/actions.go @@ -28,6 +28,7 @@ import ( "github.com/google/go-github/v61/github" "github.com/rs/zerolog" + trustytypes "github.com/stacklok/trusty-sdk-go/pkg/types" "github.com/stacklok/minder/internal/constants" "github.com/stacklok/minder/internal/engine/eval/pr_actions" @@ -201,7 +202,7 @@ type dependencyAlternatives struct { BlockPR bool // trustyReply is the complete response from trusty for this package - trustyReply *Reply + trustyReply *trustytypes.Reply } // summaryPrHandler is a prStatusHandler that adds a summary text to the PR as a comment. @@ -345,7 +346,7 @@ func (sph *summaryPrHandler) generateSummary() (string, error) { } // buildProvenanceStruct builds the provenance data structure for the PR template -func buildProvenanceStruct(r *Reply) *templateProvenance { +func buildProvenanceStruct(r *trustytypes.Reply) *templateProvenance { if r == nil || r.Provenance == nil { return nil } diff --git a/internal/engine/eval/trusty/actions_test.go b/internal/engine/eval/trusty/actions_test.go index f7e72d5483..cf2cc9e185 100644 --- a/internal/engine/eval/trusty/actions_test.go +++ b/internal/engine/eval/trusty/actions_test.go @@ -18,6 +18,7 @@ package trusty import ( "testing" + trustytypes "github.com/stacklok/trusty-sdk-go/pkg/types" "github.com/stretchr/testify/require" v1 "github.com/stacklok/minder/pkg/api/protobuf/go/minder/v1" @@ -36,23 +37,23 @@ func TestBuildProvenanceStruct(t *testing.T) { t.Parallel() for _, tc := range []struct { name string - sut *Reply + sut *trustytypes.Reply mustNil bool expected *templateProvenance }{ { name: "full-response", - sut: &Reply{ - Provenance: &Provenance{ + sut: &trustytypes.Reply{ + Provenance: &trustytypes.Provenance{ Score: 8.0, - Description: ProvenanceDescription{ - Historical: HistoricalProvenance{ + Description: trustytypes.ProvenanceDescription{ + Historical: trustytypes.HistoricalProvenance{ Tags: 10, Common: 8, Overlap: 80, Versions: 10, }, - Sigstore: SigstoreProvenance{ + Sigstore: trustytypes.SigstoreProvenance{ Issuer: "CN=sigstore-intermediate,O=sigstore.dev", Workflow: ".github/workflows/build_and_deploy.yml", SourceRepository: "https://github.com/vercel/next.js", @@ -78,11 +79,11 @@ func TestBuildProvenanceStruct(t *testing.T) { }, { name: "only-historical", - sut: &Reply{ - Provenance: &Provenance{ + sut: &trustytypes.Reply{ + Provenance: &trustytypes.Provenance{ Score: 8.0, - Description: ProvenanceDescription{ - Historical: HistoricalProvenance{ + Description: trustytypes.ProvenanceDescription{ + Historical: trustytypes.HistoricalProvenance{ Tags: 10, Common: 8, Overlap: 80, @@ -102,11 +103,11 @@ func TestBuildProvenanceStruct(t *testing.T) { }, { name: "only-sigstore", - sut: &Reply{ - Provenance: &Provenance{ + sut: &trustytypes.Reply{ + Provenance: &trustytypes.Provenance{ Score: 8.0, - Description: ProvenanceDescription{ - Sigstore: SigstoreProvenance{ + Description: trustytypes.ProvenanceDescription{ + Sigstore: trustytypes.SigstoreProvenance{ Issuer: "CN=sigstore-intermediate,O=sigstore.dev", Workflow: ".github/workflows/build_and_deploy.yml", SourceRepository: "https://github.com/vercel/next.js", @@ -132,7 +133,7 @@ func TestBuildProvenanceStruct(t *testing.T) { }, { name: "no-provenance", - sut: &Reply{}, + sut: &trustytypes.Reply{}, mustNil: true, }, } { diff --git a/internal/engine/eval/trusty/trusty.go b/internal/engine/eval/trusty/trusty.go index 3f7aea7a59..59d5ade836 100644 --- a/internal/engine/eval/trusty/trusty.go +++ b/internal/engine/eval/trusty/trusty.go @@ -22,6 +22,8 @@ import ( "strings" "github.com/rs/zerolog" + trusty "github.com/stacklok/trusty-sdk-go/pkg/client" + trustytypes "github.com/stacklok/trusty-sdk-go/pkg/types" evalerrors "github.com/stacklok/minder/internal/engine/errors" "github.com/stacklok/minder/internal/engine/eval/pr_actions" @@ -41,7 +43,7 @@ const ( type Evaluator struct { cli provifv1.GitHub endpoint string - client *trustyClient + client *trusty.Trusty } // NewTrustyEvaluator creates a new trusty evaluator @@ -55,21 +57,21 @@ func NewTrustyEvaluator(ctx context.Context, ghcli provifv1.GitHub) (*Evaluator, // If the environment variable is not set, use the default endpoint if trustyEndpoint == "" { - trustyEndpoint = trustyEndpointURL + trustyEndpoint = trusty.DefaultOptions.BaseURL zerolog.Ctx(ctx).Info().Str("trusty-endpoint", trustyEndpoint).Msg("using default trusty endpoint") } else { zerolog.Ctx(ctx).Info().Str("trusty-endpoint", trustyEndpoint).Msg("using trusty endpoint from environment") } - piCli := newPiClient(trustyEndpoint) - if piCli == nil { - return nil, fmt.Errorf("failed to create pi client") - } + trustyClient := trusty.NewWithOptions(trusty.Options{ + HttpClient: trusty.DefaultOptions.HttpClient, + BaseURL: trustyEndpoint, + }) return &Evaluator{ cli: ghcli, endpoint: trustyEndpoint, - client: piCli, + client: trustyClient, }, nil } @@ -221,9 +223,15 @@ func buildEvalResult(prSummary *summaryPrHandler) error { return nil } -func getDependencyScore(ctx context.Context, trusty *trustyClient, dep *pb.PrDependencies_ContextualDependency) (*Reply, error) { +func getDependencyScore( + ctx context.Context, trustyClient *trusty.Trusty, dep *pb.PrDependencies_ContextualDependency, +) (*trustytypes.Reply, error) { // Call the Trusty API - resp, err := trusty.SendRecvRequest(ctx, dep.Dep) + resp, err := trustyClient.Report(ctx, &trustytypes.Dependency{ + Name: dep.Dep.Name, + Version: dep.Dep.Version, + Ecosystem: trustytypes.Ecosystem(dep.Dep.Ecosystem), + }) if err != nil { return nil, fmt.Errorf("failed to send request: %w", err) } @@ -233,7 +241,7 @@ func getDependencyScore(ctx context.Context, trusty *trustyClient, dep *pb.PrDep // classifyDependency checks the dependencies from the PR for maliciousness or // low scores and adds them to the summary if needed func classifyDependency( - _ context.Context, logger *zerolog.Logger, resp *Reply, ruleConfig *config, + _ context.Context, logger *zerolog.Logger, resp *trustytypes.Reply, ruleConfig *config, prSummary *summaryPrHandler, dep *pb.PrDependencies_ContextualDependency, ) { // Check all the policy violations @@ -319,10 +327,10 @@ func classifyDependency( // readPackageDescription reads the description from the package summary and // normlizes the required values when missing from a partial Trusty response -func readPackageDescription(resp *Reply) map[string]any { +func readPackageDescription(resp *trustytypes.Reply) map[string]any { descr := map[string]any{} if resp == nil { - resp = &Reply{} + resp = &trustytypes.Reply{} } if resp.Summary.Description != nil { descr = resp.Summary.Description diff --git a/internal/engine/eval/trusty/trusty_rest_handler.go b/internal/engine/eval/trusty/trusty_rest_handler.go deleted file mode 100644 index 9d9b789ec1..0000000000 --- a/internal/engine/eval/trusty/trusty_rest_handler.go +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright 2023 Stacklok, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package trusty provides an evaluator that uses the trusty API -package trusty - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "net/url" - "strings" - "time" - - pb "github.com/stacklok/minder/pkg/api/protobuf/go/minder/v1" -) - -func urlFromEndpointAndPaths( - baseUrl string, - endpoint string, - packageName string, - ecosystem string, -) (*url.URL, error) { - u, err := url.Parse(baseUrl) - if err != nil { - return nil, fmt.Errorf("failed to parse endpoint: %w", err) - } - u = u.JoinPath(endpoint) - - // Add query parameters for package_name and package_type - q := u.Query() - q.Set("package_name", packageName) - q.Set("package_type", ecosystem) - u.RawQuery = q.Encode() - - return u, nil -} - -type trustyClient struct { - client *http.Client - baseUrl string -} - -// Alternative is an alternative package returned from the package intelligence API -type Alternative struct { - PackageName string `json:"package_name"` - Score float64 `json:"score"` - PackageNameURL string -} - -// AlternativesList is the alternatives block in the trusty API response -type AlternativesList struct { - Status string `json:"status"` - Packages []Alternative `json:"packages"` -} - -// ScoreSummary is the summary score returned from the package intelligence API -type ScoreSummary struct { - Score *float64 `json:"score"` - Description map[string]any `json:"description"` -} - -// PackageData contains the data about the queried package -type PackageData struct { - Archived bool `json:"archived"` - Deprecated bool `json:"is_deprecated"` - Malicious *MaliciousData `json:"malicious"` -} - -// Reply is the response from the package intelligence API -type Reply struct { - PackageName string `json:"package_name"` - PackageType string `json:"package_type"` - Summary ScoreSummary `json:"summary"` - Alternatives AlternativesList `json:"alternatives"` - PackageData PackageData `json:"package_data"` - Provenance *Provenance `json:"provenance"` -} - -// MaliciousData contains the security details when a dependency is malicious -type MaliciousData struct { - Summary string `json:"summary"` - Details string `json:"details"` - Published *time.Time `json:"published"` - Modified *time.Time `json:"modified"` - Source string `json:"source"` -} - -// Provenance has the package's provenance score and provenance type components -type Provenance struct { - Score float64 `json:"score"` - Description ProvenanceDescription `json:"description"` -} - -// ProvenanceDescription contians the provenance types -type ProvenanceDescription struct { - Historical HistoricalProvenance `json:"hp"` - Sigstore SigstoreProvenance `json:"provenance"` -} - -// HistoricalProvenance has the historical provenance components from a package -type HistoricalProvenance struct { - Tags float64 `json:"tags"` - Common float64 `json:"common"` - Overlap float64 `json:"overlap"` - Versions float64 `json:"versions"` -} - -// SigstoreProvenance has the sigstore certificate data when a package was signed -// using a github actions workflow -type SigstoreProvenance struct { - Issuer string `json:"issuer"` - Workflow string `json:"workflow"` - SourceRepository string `json:"source_repo"` - TokenIssuer string `json:"token_issuer"` - Transparency string `json:"transparency"` -} - -func newPiClient(baseUrl string) *trustyClient { - return &trustyClient{ - client: &http.Client{}, - baseUrl: baseUrl, - } -} - -func (p *trustyClient) newRequest(ctx context.Context, dep *pb.Dependency) (*http.Request, error) { - u, err := urlFromEndpointAndPaths(p.baseUrl, "v1/report", dep.Name, strings.ToLower(dep.Ecosystem.AsString())) - if err != nil { - return nil, fmt.Errorf("could not parse endpoint: %w", err) - } - - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, fmt.Errorf("could not create request: %w", err) - } - req = req.WithContext(ctx) - return req, nil -} - -func (p *trustyClient) SendRecvRequest(ctx context.Context, dep *pb.Dependency) (*Reply, error) { - req, err := p.newRequest(ctx, dep) - if err != nil { - return nil, fmt.Errorf("could not create request: %w", err) - } - - resp, err := p.client.Do(req) - if err != nil { - return nil, fmt.Errorf("could not send request: %w", err) - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("received non-200 response: %d", resp.StatusCode) - } - - var piReply Reply - dec := json.NewDecoder(resp.Body) - if err := dec.Decode(&piReply); err != nil { - return nil, fmt.Errorf("could not unmarshal response: %w", err) - } - - return &piReply, nil -} diff --git a/internal/engine/eval/trusty/trusty_test.go b/internal/engine/eval/trusty/trusty_test.go index 49efcc7492..6f6e6a5d55 100644 --- a/internal/engine/eval/trusty/trusty_test.go +++ b/internal/engine/eval/trusty/trusty_test.go @@ -22,6 +22,7 @@ import ( "time" "github.com/rs/zerolog" + trustytypes "github.com/stacklok/trusty-sdk-go/pkg/types" "github.com/stretchr/testify/require" "github.com/stacklok/minder/internal/engine/eval/pr_actions" @@ -50,20 +51,20 @@ func TestBuildEvalResult(t *testing.T) { Name: "requests", Version: "0.0.1", }, - trustyReply: &Reply{ + trustyReply: &trustytypes.Reply{ PackageName: "requests", PackageType: v1.DepEcosystem_DEP_ECOSYSTEM_PYPI.AsString(), - Summary: ScoreSummary{ + Summary: trustytypes.ScoreSummary{ Score: &sg, }, PackageData: struct { - Archived bool `json:"archived"` - Deprecated bool `json:"is_deprecated"` - Malicious *MaliciousData `json:"malicious"` + Archived bool `json:"archived"` + Deprecated bool `json:"is_deprecated"` + Malicious *trustytypes.MaliciousData `json:"malicious"` }{ Archived: false, Deprecated: false, - Malicious: &MaliciousData{ + Malicious: &trustytypes.MaliciousData{ Summary: "malicuous", Published: &now, }, @@ -80,10 +81,10 @@ func TestBuildEvalResult(t *testing.T) { Name: "requests", Version: "0.0.1", }, - trustyReply: &Reply{ + trustyReply: &trustytypes.Reply{ PackageName: "requests", PackageType: v1.DepEcosystem_DEP_ECOSYSTEM_PYPI.AsString(), - Summary: ScoreSummary{ + Summary: trustytypes.ScoreSummary{ Score: &sg, }, }, @@ -98,10 +99,10 @@ func TestBuildEvalResult(t *testing.T) { Name: "python-oauth", Version: "0.0.1", }, - trustyReply: &Reply{ + trustyReply: &trustytypes.Reply{ PackageName: "requests", PackageType: v1.DepEcosystem_DEP_ECOSYSTEM_PYPI.AsString(), - Summary: ScoreSummary{ + Summary: trustytypes.ScoreSummary{ Score: &sg, }, }, @@ -112,20 +113,20 @@ func TestBuildEvalResult(t *testing.T) { Name: "requestts", Version: "0.0.1", }, - trustyReply: &Reply{ + trustyReply: &trustytypes.Reply{ PackageName: "requests", PackageType: v1.DepEcosystem_DEP_ECOSYSTEM_PYPI.AsString(), - Summary: ScoreSummary{ + Summary: trustytypes.ScoreSummary{ Score: &sg, }, PackageData: struct { - Archived bool `json:"archived"` - Deprecated bool `json:"is_deprecated"` - Malicious *MaliciousData `json:"malicious"` + Archived bool `json:"archived"` + Deprecated bool `json:"is_deprecated"` + Malicious *trustytypes.MaliciousData `json:"malicious"` }{ Archived: false, Deprecated: false, - Malicious: &MaliciousData{ + Malicious: &trustytypes.MaliciousData{ Summary: "malicuous", Published: &now, }, @@ -251,17 +252,17 @@ func TestClassifyDependency(t *testing.T) { } for _, tc := range []struct { name string - score *Reply + score *trustytypes.Reply config *config mustFilter bool expected *dependencyAlternatives }{ { name: "normal-good-score", - score: &Reply{ + score: &trustytypes.Reply{ PackageName: "test", PackageType: "npm", - Summary: ScoreSummary{ + Summary: trustytypes.ScoreSummary{ Score: mkfloat(6.4), }, }, @@ -273,30 +274,30 @@ func TestClassifyDependency(t *testing.T) { }, { name: "normal-bad-score", - score: &Reply{ + score: &trustytypes.Reply{ PackageName: "test", PackageType: "npm", - Summary: ScoreSummary{ + Summary: trustytypes.ScoreSummary{ Score: mkfloat(4.0), }, }, config: defaultConfig(), expected: &dependencyAlternatives{ Reasons: []RuleViolationReason{TRUSTY_LOW_SCORE}, - trustyReply: &Reply{}, + trustyReply: &trustytypes.Reply{}, }, mustFilter: true, }, { name: "normal-malicious", - score: &Reply{ + score: &trustytypes.Reply{ PackageName: "test", PackageType: "npm", - Summary: ScoreSummary{Score: mkfloat(8.0)}, - PackageData: PackageData{ + Summary: trustytypes.ScoreSummary{Score: mkfloat(8.0)}, + PackageData: trustytypes.PackageData{ Archived: false, Deprecated: false, - Malicious: &MaliciousData{ + Malicious: &trustytypes.MaliciousData{ Summary: "it is malicious", Details: "some details", }, @@ -305,16 +306,16 @@ func TestClassifyDependency(t *testing.T) { config: defaultConfig(), expected: &dependencyAlternatives{ Reasons: []RuleViolationReason{TRUSTY_MALICIOUS_PKG}, - trustyReply: &Reply{}, + trustyReply: &trustytypes.Reply{}, }, mustFilter: true, }, { name: "normal-lowactivity", - score: &Reply{ + score: &trustytypes.Reply{ PackageName: "test", PackageType: "npm", - Summary: ScoreSummary{ + Summary: trustytypes.ScoreSummary{ Score: mkfloat(8.0), Description: map[string]any{ "activity": float64(3.0), @@ -324,16 +325,16 @@ func TestClassifyDependency(t *testing.T) { config: defaultConfig(), expected: &dependencyAlternatives{ Reasons: []RuleViolationReason{TRUSTY_LOW_ACTIVITY}, - trustyReply: &Reply{}, + trustyReply: &trustytypes.Reply{}, }, mustFilter: true, }, { name: "normal-low-provenance", - score: &Reply{ + score: &trustytypes.Reply{ PackageName: "test", PackageType: "npm", - Summary: ScoreSummary{ + Summary: trustytypes.ScoreSummary{ Score: mkfloat(8.0), Description: map[string]any{ "provenance": float64(3.0), @@ -343,7 +344,7 @@ func TestClassifyDependency(t *testing.T) { config: defaultConfig(), expected: &dependencyAlternatives{ Reasons: []RuleViolationReason{TRUSTY_LOW_PROVENANCE}, - trustyReply: &Reply{}, + trustyReply: &trustytypes.Reply{}, }, mustFilter: true, }, @@ -381,8 +382,8 @@ func TestBuildScoreMatrix(t *testing.T) { sut: dependencyAlternatives{ Dependency: &v1.Dependency{}, Reasons: []RuleViolationReason{}, - trustyReply: &Reply{ - Summary: ScoreSummary{}, + trustyReply: &trustytypes.Reply{ + Summary: trustytypes.ScoreSummary{}, }, }, }, @@ -391,8 +392,8 @@ func TestBuildScoreMatrix(t *testing.T) { sut: dependencyAlternatives{ Dependency: &v1.Dependency{}, Reasons: []RuleViolationReason{}, - trustyReply: &Reply{ - Summary: ScoreSummary{ + trustyReply: &trustytypes.Reply{ + Summary: trustytypes.ScoreSummary{ Description: map[string]any{ "activity": "a", "activity_user": "b", @@ -414,8 +415,8 @@ func TestBuildScoreMatrix(t *testing.T) { sut: dependencyAlternatives{ Dependency: &v1.Dependency{}, Reasons: []RuleViolationReason{}, - trustyReply: &Reply{ - Summary: ScoreSummary{ + trustyReply: &trustytypes.Reply{ + Summary: trustytypes.ScoreSummary{ Description: map[string]any{ "activity": "a", "activity_user": "b", @@ -437,8 +438,8 @@ func TestBuildScoreMatrix(t *testing.T) { sut: dependencyAlternatives{ Dependency: &v1.Dependency{}, Reasons: []RuleViolationReason{}, - trustyReply: &Reply{ - Summary: ScoreSummary{ + trustyReply: &trustytypes.Reply{ + Summary: trustytypes.ScoreSummary{ Description: map[string]any{ "typosquatting": float64(10), }, @@ -452,8 +453,8 @@ func TestBuildScoreMatrix(t *testing.T) { sut: dependencyAlternatives{ Dependency: &v1.Dependency{}, Reasons: []RuleViolationReason{}, - trustyReply: &Reply{ - Summary: ScoreSummary{ + trustyReply: &trustytypes.Reply{ + Summary: trustytypes.ScoreSummary{ Description: map[string]any{ "typosquatting": float64(1), }, @@ -484,16 +485,16 @@ func TestReadPackageDescription(t *testing.T) { t.Parallel() for _, tc := range []struct { name string - sut *Reply + sut *trustytypes.Reply }{ { name: "normal", - sut: &Reply{}, + sut: &trustytypes.Reply{}, }, { name: "no-provenance", - sut: &Reply{ - Summary: ScoreSummary{ + sut: &trustytypes.Reply{ + Summary: trustytypes.ScoreSummary{ Description: map[string]any{ "provenance": 1, }, diff --git a/internal/engine/eval_status.go b/internal/engine/eval_status.go index 1e4d2e82e8..a87d222d53 100644 --- a/internal/engine/eval_status.go +++ b/internal/engine/eval_status.go @@ -98,6 +98,16 @@ func (e *Executor) createEvalStatusParams( return params, nil } +// createOrUpdateEvalStatus takes care of recording the rule evaluation results. +// This function inserts into the database: +// +// - The rule evaluation parameters (profile, repo, artifact, entity, etc). +// - The rule evaluation status and details. +// - The remediation status and details. +// - The alert status and details. +// +// If the error in the evaluation status resolves to an errors.ErrEvaluationSkipSilently, +// no details are stored or logged. func (e *Executor) createOrUpdateEvalStatus( ctx context.Context, params *engif.EvalStatusParams, From 4d1a11994fb3105b1067df5d5ff7146bd89e1942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Garc=C3=ADa=20Veytia=20=28Puerco=29?= Date: Tue, 4 Jun 2024 18:55:03 -0600 Subject: [PATCH 2/2] go.mod: Pull trusty SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Adolfo García Veytia (Puerco) --- go.mod | 1 + go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/go.mod b/go.mod index 3aae6ac51c..57e95caf7c 100644 --- a/go.mod +++ b/go.mod @@ -54,6 +54,7 @@ require ( github.com/spf13/viper v1.19.0 github.com/sqlc-dev/pqtype v0.3.0 github.com/stacklok/frizbee v0.0.19 + github.com/stacklok/trusty-sdk-go v0.1.0 github.com/stretchr/testify v1.9.0 github.com/styrainc/regal v0.22.0 github.com/thomaspoignant/go-feature-flag v1.30.0 diff --git a/go.sum b/go.sum index cfe83793d0..4eda1b0287 100644 --- a/go.sum +++ b/go.sum @@ -866,6 +866,8 @@ github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs= github.com/stacklok/frizbee v0.0.19 h1:lD5O5e1lCYl6yGTtWW93m2w60TMeTJB5oLXMeaHnFHo= github.com/stacklok/frizbee v0.0.19/go.mod h1:Hvi3/ryonTgeMBG4/EtBGjfK49W0rP0P3+0RAg3kqHI= +github.com/stacklok/trusty-sdk-go v0.1.0 h1:b0m9HrAjJpyorev7vMbGf56UUMI1XyUBgd3SwnHCPh0= +github.com/stacklok/trusty-sdk-go v0.1.0/go.mod h1:OWk/FxKjjFw+mQnCKaytoYL7vMWoj+8Ep2TYsp8QSaI= github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=