Skip to content

Commit 238f423

Browse files
committed
merged with component dependencies update
2 parents 48bee1c + b3c27db commit 238f423

95 files changed

Lines changed: 3463 additions & 1409 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/devguard-scanner.yaml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ jobs:
6262
with:
6363
asset-name: l3montree-cybersecurity/projects/devguard/assets/devguard
6464
api-url: https://api.main.devguard.org
65-
fail-on-risk: never
66-
fail-on-cvss: never
65+
fail-on-risk: high
66+
fail-on-cvss: high
6767
web-ui: https://main.devguard.org
6868
continue-on-open-code-risk: true
6969
secrets:
@@ -85,8 +85,8 @@ jobs:
8585
asset-name: l3montree-cybersecurity/projects/devguard/assets/devguard
8686
api-url: https://api.main.devguard.org
8787
web-ui: https://main.devguard.org
88-
fail-on-cvss: never
89-
fail-on-risk: never
88+
fail-on-cvss: high
89+
fail-on-risk: high
9090
nix-cache-substituter: https://nix.garage.l3montree.cloud
9191
nix-cache-public-key: nix.garage.l3montree.cloud:MGlzfPQKA91/zxw91CN+GP7NpjAAwmKvWXlDYgeeI8k=
9292
nix-cache-s3-bucket: nix
@@ -111,8 +111,8 @@ jobs:
111111
asset-name: l3montree-cybersecurity/projects/devguard/assets/devguard
112112
api-url: https://api.main.devguard.org
113113
web-ui: https://main.devguard.org
114-
fail-on-cvss: never
115-
fail-on-risk: never
114+
fail-on-cvss: high
115+
fail-on-risk: high
116116
nix-cache-substituter: https://nix.garage.l3montree.cloud
117117
nix-cache-public-key: nix.garage.l3montree.cloud:MGlzfPQKA91/zxw91CN+GP7NpjAAwmKvWXlDYgeeI8k=
118118
nix-cache-s3-bucket: nix
@@ -136,8 +136,8 @@ jobs:
136136
asset-name: l3montree-cybersecurity/projects/devguard/assets/devguard-postgresql
137137
api-url: https://api.main.devguard.org
138138
web-ui: https://main.devguard.org
139-
fail-on-cvss: never
140-
fail-on-risk: never
139+
fail-on-cvss: high
140+
fail-on-risk: high
141141
nix-cache-substituter: https://nix.garage.l3montree.cloud
142142
nix-cache-public-key: nix.garage.l3montree.cloud:MGlzfPQKA91/zxw91CN+GP7NpjAAwmKvWXlDYgeeI8k=
143143
nix-cache-s3-bucket: nix

.github/workflows/vulndb.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
- name: Export the vulnerability database archive
5454
run: |
5555
# writes the database snapshot files and bundles them into a single tar.zst archive
56-
go run ./cmd/devguard-cli/main.go vulndb export
56+
go run ./cmd/devguard-cli/main.go vulndb export --diff-to-previous
5757
5858
- name: Install Cosign
5959
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0

cmd/devguard-cli/commands/vulndb_import.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ import (
1414
)
1515

1616
func newImportCommand() *cobra.Command {
17-
var full bool
1817
var batchSize int
1918
var bulk bool
2019
var limitedToTables []string
2120
var debug bool
21+
var localArchive bool
2222

2323
importCmd := &cobra.Command{
2424
Use: "import",
@@ -28,11 +28,11 @@ func newImportCommand() *cobra.Command {
2828
shared.LoadConfig() // nolint
2929
migrateDB()
3030
opts := shared.ImportOptions{
31-
Full: full,
3231
BatchSize: batchSize,
3332
Bulk: bulk,
3433
LimitedToTables: limitedToTables,
3534
Debug: debug,
35+
LocalArchive: localArchive,
3636
}
3737
app := fx.New(
3838
fx.NopLogger,
@@ -59,16 +59,19 @@ func newImportCommand() *cobra.Command {
5959
},
6060
}
6161

62-
importCmd.Flags().BoolVar(&full, "full", false, "Force a full import, ignoring the last-import watermark")
6362
importCmd.Flags().IntVar(&batchSize, "batchSize", 5000, "Number of OSV entries per batch (default 5000)")
6463
importCmd.Flags().BoolVar(&bulk, "bulk", false, "Load all gob data into RAM before writing (faster but uses ~2-3 GB memory)")
6564
importCmd.Flags().StringSliceVar(&limitedToTables, "limitedToTables", []string{}, "Comma-separated list of tables to limit the import to (e.g. --limitedToTables=cves,exploits,malicious_packages)")
6665
importCmd.Flags().BoolVar(&debug, "debug", false, "Enable debug logging")
66+
importCmd.Flags().BoolVar(&localArchive, "local-archive", false, "Read from vulndb.tar.zst in the current directory instead of pulling from OCI")
6767

6868
return importCmd
6969
}
7070

7171
func newExportCommand() *cobra.Command {
72+
var diffToPrevious bool
73+
var localArchive bool
74+
7275
exportCmd := &cobra.Command{
7376
Use: "export",
7477
Short: "Export the vulnerability database to an OCI artifact",
@@ -84,6 +87,9 @@ func newExportCommand() *cobra.Command {
8487
services.ServiceModule,
8588
vulndb.Module,
8689
fx.Invoke(func(svc shared.VulnDBService) error {
90+
if diffToPrevious {
91+
return svc.ExportRCWithDiff(context.Background(), localArchive)
92+
}
8793
return svc.ExportRC(context.Background())
8894
}),
8995
)
@@ -101,5 +107,10 @@ func newExportCommand() *cobra.Command {
101107
},
102108
}
103109

110+
exportCmd.Flags().BoolVar(&diffToPrevious, "diff-to-previous", false,
111+
"Compute a QuickDiff against the previous export so importers on the last version can skip staging entirely")
112+
exportCmd.Flags().BoolVar(&localArchive, "local-archive", false,
113+
"Use vulndb.tar.zst in the current directory for the baseline import instead of pulling from OCI")
114+
104115
return exportCmd
105116
}

cmd/devguard/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,10 @@ func initTracer(sampleRate float64) {
294294
}
295295

296296
opts := []sdktrace.TracerProviderOption{
297-
sdktrace.WithSampler(sdktrace.TraceIDRatioBased(sampleRate)),
297+
// ParentBased honors the sampled flag from an incoming traceparent header, so a specific
298+
// request can be force-traced regardless of the ratio by setting the flag to 01:
299+
// curl -H "traceparent: 00-$(openssl rand -hex 16)-$(openssl rand -hex 8)-01" <url>
300+
sdktrace.WithSampler(sdktrace.ParentBased(sdktrace.TraceIDRatioBased(sampleRate))),
298301
sdktrace.WithResource(res),
299302
}
300303
for _, p := range processors {

controllers/artifact_controller.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ func (c *ArtifactController) Create(ctx shared.Context) error {
109109

110110
var body requestBody
111111

112+
userAgent := ctx.Request().UserAgent()
113+
112114
if err := ctx.Bind(&body); err != nil {
113115
return err
114116
}
@@ -150,7 +152,7 @@ func (c *ArtifactController) Create(ctx shared.Context) error {
150152
}
151153
currentUserID := shared.GetSession(ctx).GetUserID()
152154

153-
_, _, newState, err := c.ScanNormalizedSBOM(ctx.Request().Context(), tx, org, project, asset, assetVersion, artifact, bom, currentUserID)
155+
_, _, newState, err := c.ScanNormalizedSBOM(ctx.Request().Context(), tx, org, project, asset, assetVersion, artifact, bom, currentUserID, &userAgent)
154156

155157
if err != nil {
156158
tx.Rollback()
@@ -190,7 +192,7 @@ func (c *ArtifactController) Create(ctx shared.Context) error {
190192
ArtifactName: artifact.ArtifactName,
191193
},
192194
SBOM: exportedBOM,
193-
}); err != nil {
195+
}, &userAgent); err != nil {
194196
slog.Error("could not handle SBOM updated event", "err", err)
195197
} else {
196198
slog.Info("handled SBOM updated event", "assetVersion", assetVersion.Name, "assetID", assetVersion.AssetID)
@@ -199,7 +201,7 @@ func (c *ArtifactController) Create(ctx shared.Context) error {
199201
}
200202

201203
c.FireAndForget(func() {
202-
err := c.dependencyVulnService.SyncIssues(linkedCtx, org, project, asset, assetVersion, newState)
204+
err := c.dependencyVulnService.SyncIssues(linkedCtx, org, project, asset, assetVersion, newState, &userAgent)
203205
if err != nil {
204206
slog.Error("could not create issues for vulnerabilities", "err", err)
205207
}
@@ -238,6 +240,8 @@ func (c *ArtifactController) DeleteArtifact(ctx shared.Context) error {
238240
org := shared.GetOrg(ctx)
239241
project := shared.GetProject(ctx)
240242

243+
userAgent := ctx.Request().UserAgent()
244+
241245
// we need to sync the vulnerabilities after deleting the artifact
242246
// maybe we need to close some: https://github.com/l3montree-dev/devguard/issues/1496
243247
// fetch all vulnerabilities which ONLY belong to this artifact
@@ -258,7 +262,7 @@ func (c *ArtifactController) DeleteArtifact(ctx shared.Context) error {
258262
linkedCtx := trace.ContextWithSpan(context.Background(), trace.SpanFromContext(reqCtx))
259263
if len(syncVulns) > 0 {
260264
c.FireAndForget(func() {
261-
err := c.dependencyVulnService.SyncIssues(linkedCtx, org, project, asset, assetVersion, syncVulns)
265+
err := c.dependencyVulnService.SyncIssues(linkedCtx, org, project, asset, assetVersion, syncVulns, &userAgent)
262266
if err != nil {
263267
slog.Error("could not sync issues for vulnerabilities after artifact deletion", "err", err)
264268
}
@@ -299,6 +303,7 @@ func (c *ArtifactController) UpdateArtifact(ctx shared.Context) error {
299303
}
300304

301305
reqCtx := ctx.Request().Context()
306+
userAgent := ctx.Request().UserAgent()
302307

303308
artifact, err := c.artifactService.ReadArtifact(reqCtx, nil, artifactName, assetVersion.Name, asset.ID)
304309
if err != nil {
@@ -360,7 +365,7 @@ func (c *ArtifactController) UpdateArtifact(ctx shared.Context) error {
360365
return echo.NewHTTPError(500, "could not update sbom").WithInternal(err)
361366
}
362367

363-
_, _, vulns, err = c.ScanNormalizedSBOM(reqCtx, tx, org, project, asset, assetVersion, artifact, sbom, shared.GetSession(ctx).GetUserID())
368+
_, _, vulns, err = c.ScanNormalizedSBOM(reqCtx, tx, org, project, asset, assetVersion, artifact, sbom, shared.GetSession(ctx).GetUserID(), &userAgent)
364369
if err != nil {
365370
slog.Error("could not scan sbom after updating it", "err", err)
366371
return echo.NewHTTPError(500, "could not scan sbom after updating it").WithInternal(err)
@@ -395,7 +400,7 @@ func (c *ArtifactController) UpdateArtifact(ctx shared.Context) error {
395400
ArtifactName: artifactName,
396401
},
397402
SBOM: exportedBOM,
398-
}); err != nil {
403+
}, &userAgent); err != nil {
399404
slog.Error("could not handle SBOM updated event", "err", err)
400405
} else {
401406
slog.Info("handled SBOM updated event", "assetVersion", assetVersion.Name, "assetID", assetVersion.AssetID)
@@ -404,7 +409,7 @@ func (c *ArtifactController) UpdateArtifact(ctx shared.Context) error {
404409
}
405410

406411
c.FireAndForget(func() {
407-
err := c.dependencyVulnService.SyncIssues(linkedCtx, org, project, asset, assetVersion, vulns)
412+
err := c.dependencyVulnService.SyncIssues(linkedCtx, org, project, asset, assetVersion, vulns, &userAgent)
408413
if err != nil {
409414
slog.Error("could not create issues for vulnerabilities", "err", err)
410415
}

controllers/asset_controller.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ func (a *AssetController) Update(ctx shared.Context) error {
329329

330330
org := shared.GetOrg(ctx)
331331
project := shared.GetProject(ctx)
332+
userAgent := ctx.Request().UserAgent()
332333
if enableTicketRangeUpdated || justification != "" {
333334
//check if we have already created the labels in gitlab, if not create them
334335
// do NOT update the asset in the database yet, we do this after the ticket sync
@@ -353,7 +354,7 @@ func (a *AssetController) Update(ctx shared.Context) error {
353354
return
354355
}
355356

356-
if err := a.dependencyVulnService.SyncAllIssues(linkedCtx, org, project, asset, defaultAssetVersion); err != nil {
357+
if err := a.dependencyVulnService.SyncAllIssues(linkedCtx, org, project, asset, defaultAssetVersion, &userAgent); err != nil {
357358
slog.Warn("could not sync tickets", "err", err)
358359
}
359360
})

controllers/dependency_vuln_controller.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,11 @@ func (controller DependencyVulnController) Mitigate(ctx shared.Context) error {
233233
}
234234

235235
thirdPartyIntegrations := shared.GetThirdPartyIntegration(ctx)
236-
236+
userAgent := ctx.Request().UserAgent()
237237
if err = thirdPartyIntegrations.HandleEvent(ctx.Request().Context(), shared.ManualMitigateEvent{
238238
Ctx: ctx,
239239
Justification: j.Comment,
240-
}); err != nil {
240+
}, &userAgent); err != nil {
241241
return echo.NewHTTPError(500, "could not mitigate dependencyVuln").WithInternal(err)
242242
}
243243

@@ -309,6 +309,7 @@ func (controller DependencyVulnController) SyncDependencyVulns(ctx shared.Contex
309309
assetVersion := shared.GetAssetVersion(ctx)
310310
org := shared.GetOrg(ctx)
311311
project := shared.GetProject(ctx)
312+
userAgent := ctx.Request().UserAgent()
312313

313314
type vulnReq struct {
314315
VulnID uuid.UUID `json:"vulnId"`
@@ -355,7 +356,7 @@ func (controller DependencyVulnController) SyncDependencyVulns(ctx shared.Contex
355356

356357
linkedCtx := trace.ContextWithSpan(context.Background(), trace.SpanFromContext(ctx.Request().Context()))
357358
controller.FireAndForget(func() {
358-
err := controller.dependencyVulnService.SyncIssues(linkedCtx, org, project, asset, assetVersion, vulns)
359+
err := controller.dependencyVulnService.SyncIssues(linkedCtx, org, project, asset, assetVersion, vulns, &userAgent)
359360
if err != nil {
360361
slog.Error("could not create issues for vulnerabilities", "err", err)
361362
}
@@ -405,7 +406,8 @@ func (controller DependencyVulnController) CreateEvent(ctx shared.Context) error
405406
justification := status.Justification
406407
mechanicalJustification := status.MechanicalJustification
407408

408-
ev, err := controller.dependencyVulnService.CreateVulnEventAndApply(ctx.Request().Context(), nil, asset.ID, userID, &dependencyVuln, dtos.VulnEventType(statusType), justification, mechanicalJustification, assetVersion.Name)
409+
userAgent := ctx.Request().UserAgent()
410+
ev, err := controller.dependencyVulnService.CreateVulnEventAndApply(ctx.Request().Context(), nil, asset.ID, userID, &dependencyVuln, dtos.VulnEventType(statusType), justification, mechanicalJustification, assetVersion.Name, &userAgent)
409411
if err != nil {
410412
return err
411413
}
@@ -424,7 +426,7 @@ func (controller DependencyVulnController) CreateEvent(ctx shared.Context) error
424426
err = thirdPartyIntegration.HandleEvent(ctx.Request().Context(), shared.VulnEvent{
425427
Ctx: ctx,
426428
Event: ev,
427-
})
429+
}, &userAgent)
428430
// we do not want the transaction to be rolled back if the third party integration fails
429431
if err != nil {
430432
// just log the error
@@ -469,7 +471,8 @@ func (controller DependencyVulnController) BatchCreateEvent(ctx shared.Context)
469471
continue
470472
}
471473

472-
ev, err := controller.dependencyVulnService.CreateVulnEventAndApply(ctx.Request().Context(), nil, asset.ID, userID, &dependencyVuln, eventType, status.Justification, status.MechanicalJustification, assetVersion.Name)
474+
userAgent := ctx.Request().UserAgent()
475+
ev, err := controller.dependencyVulnService.CreateVulnEventAndApply(ctx.Request().Context(), nil, asset.ID, userID, &dependencyVuln, eventType, status.Justification, status.MechanicalJustification, assetVersion.Name, &userAgent)
473476
if err != nil {
474477
slog.Error("could not create event for dependencyVuln", "err", err, "vulnID", vulnID)
475478
continue
@@ -486,7 +489,7 @@ func (controller DependencyVulnController) BatchCreateEvent(ctx shared.Context)
486489
if err := thirdPartyIntegration.HandleEvent(ctx.Request().Context(), shared.VulnEvent{
487490
Ctx: ctx,
488491
Event: ev,
489-
}); err != nil {
492+
}, &userAgent); err != nil {
490493
slog.Error("could not handle event", "err", err)
491494
}
492495

controllers/external_reference_controller.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ func (c *ExternalReferenceController) Sync(ctx shared.Context) error {
187187
org := shared.GetOrg(ctx)
188188
project := shared.GetProject(ctx)
189189
userID := shared.GetSession(ctx).GetUserID()
190+
userAgent := ctx.Request().UserAgent()
190191

191192
artifacts, err := c.artifactRepository.GetByAssetIDAndAssetVersionName(ctx.Request().Context(), nil, asset.ID, assetVersion.Name)
192193
if err != nil {
@@ -198,7 +199,7 @@ func (c *ExternalReferenceController) Sync(ctx shared.Context) error {
198199
tx := c.artifactRepository.Begin(ctx.Request().Context())
199200
defer tx.Rollback()
200201

201-
_, _, vulns, err := c.RunArtifactSecurityLifecycle(ctx.Request().Context(), tx, org, project, asset, assetVersion, artifact, userID)
202+
_, _, vulns, err := c.RunArtifactSecurityLifecycle(ctx.Request().Context(), tx, org, project, asset, assetVersion, artifact, userID, &userAgent)
202203
if err != nil {
203204
tx.Rollback()
204205
slog.Error("could not scan sbom after syncing external sources", "err", err, "artifact", artifact.ArtifactName)
@@ -213,7 +214,7 @@ func (c *ExternalReferenceController) Sync(ctx shared.Context) error {
213214

214215
linkedCtx := trace.ContextWithSpan(context.Background(), trace.SpanFromContext(ctx.Request().Context()))
215216
c.FireAndForget(func() {
216-
if err := c.dependencyVulnService.SyncIssues(linkedCtx, org, project, asset, assetVersion, vulns); err != nil {
217+
if err := c.dependencyVulnService.SyncIssues(linkedCtx, org, project, asset, assetVersion, vulns, &userAgent); err != nil {
217218
slog.Error("could not create issues for vulnerabilities", "err", err)
218219
}
219220
})

controllers/first_party_vuln_controller.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ func (c FirstPartyVulnController) Mitigate(ctx shared.Context) error {
105105
return echo.NewHTTPError(400, "invalid firstPartyVulnID")
106106
}
107107

108+
userAgent := ctx.Request().UserAgent()
109+
108110
thirdPartyIntegrations := shared.GetThirdPartyIntegration(ctx)
109111

110112
var j struct {
@@ -119,7 +121,7 @@ func (c FirstPartyVulnController) Mitigate(ctx shared.Context) error {
119121
if err = thirdPartyIntegrations.HandleEvent(ctx.Request().Context(), shared.ManualMitigateEvent{
120122
Justification: j.Justification,
121123
Ctx: ctx,
122-
}); err != nil {
124+
}, &userAgent); err != nil {
123125
return echo.NewHTTPError(500, "could not mitigate firstPartyVuln").WithInternal(err)
124126
}
125127

@@ -190,15 +192,16 @@ func (c FirstPartyVulnController) CreateEvent(ctx shared.Context) error {
190192

191193
mechanicalJustification := status.MechanicalJustification
192194

193-
ev, err := c.firstPartyVulnService.UpdateFirstPartyVulnState(ctx.Request().Context(), nil, userID, &firstPartyVuln, statusType, justification, mechanicalJustification)
195+
userAgent := ctx.Request().UserAgent()
196+
ev, err := c.firstPartyVulnService.UpdateFirstPartyVulnState(ctx.Request().Context(), nil, userID, &firstPartyVuln, statusType, justification, mechanicalJustification, &userAgent)
194197
if err != nil {
195198
return err
196199
}
197200

198201
err = thirdPartyIntegration.HandleEvent(ctx.Request().Context(), shared.VulnEvent{
199202
Ctx: ctx,
200203
Event: ev,
201-
})
204+
}, &userAgent)
202205
// we do not want the transaction to be rolled back if the third party integration fails
203206
if err != nil {
204207
// just log the error

0 commit comments

Comments
 (0)