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

Dependency track improvements #48

Merged
merged 26 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
af7ff59
add the ability to enrich sbom document with security scorecard score
northdpole Oct 15, 2023
627d767
lint:
northdpole Oct 15, 2023
0554b5e
fix logging
northdpole Oct 16, 2023
22355d2
fix depsdev + tests
northdpole Oct 18, 2023
4bd109f
dependency track owner tagging
northdpole Oct 18, 2023
4e8a96d
Update components/consumers/dependency-track/main.go
northdpole Oct 18, 2023
c6ed2a1
Update components/consumers/dependency-track/main_test.go
northdpole Oct 18, 2023
da7c902
Update components/consumers/dependency-track/main_test.go
northdpole Oct 18, 2023
a71558b
Update components/consumers/dependency-track/main_test.go
northdpole Oct 18, 2023
0cb0d14
Update components/consumers/dependency-track/main_test.go
northdpole Oct 18, 2023
8872537
Update components/consumers/dependency-track/main.go
northdpole Oct 18, 2023
08ea1a3
Update components/consumers/dependency-track/main_test.go
northdpole Oct 18, 2023
73deb59
Update components/enrichers/depsdev/main_test.go
northdpole Oct 18, 2023
341ba68
Update components/enrichers/depsdev/main_test.go
northdpole Oct 18, 2023
1e54471
Update components/enrichers/depsdev/main_test.go
northdpole Oct 18, 2023
38115f8
Update components/enrichers/depsdev/main_test.go
northdpole Oct 18, 2023
e23bf7b
Update components/enrichers/depsdev/main_test.go
northdpole Oct 18, 2023
bcff58b
Update components/enrichers/depsdev/main_test.go
northdpole Oct 18, 2023
ac3a3be
Update components/consumers/dependency-track/main_test.go
northdpole Oct 18, 2023
2eca5da
Update components/consumers/dependency-track/main.go
northdpole Oct 18, 2023
ad8403a
Merge branch 'main' into dependency-track-improvements
northdpole Oct 18, 2023
ad3de34
Update components/consumers/dependency-track/main_test.go
northdpole Oct 18, 2023
f68e8fa
Update components/consumers/dependency-track/main.go
northdpole Oct 18, 2023
a2ce9ab
Update components/consumers/dependency-track/main.go
northdpole Oct 18, 2023
2d5cbdc
Update components/consumers/dependency-track/main_test.go
northdpole Oct 18, 2023
136585f
Merge branch 'main' into dependency-track-improvements
northdpole Oct 20, 2023
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
4 changes: 3 additions & 1 deletion components/consumers/dependency-track/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

This producer imports SBOM results from Dracon producers into [owasp/dependency-track](https://owasp.org/www-project-dependency-track/). It ignores all other results as dependency-track does not do vulnerability management and Dracon does not have any VEX producers yet.

You can use this producer to generate or keep up to date SBOMs for your projects.
You can use this consumer to generate or keep up to date SBOMs for your projects.

This consumer recognises the annotation from the codeowners enricher and will add a project tag with each username found in the codeowners annotations.
The tag format is `Owner:<username>`

## Testing without Dracon

Expand Down
5 changes: 5 additions & 0 deletions components/consumers/dependency-track/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ patches:
value: $(params.consumer-dependency-track-token)
- name: consumer-dependency-track-project-uuid
value: $(params.consumer-dependency-track-project-uuid)
- name: consumer-dependency-track-owner-annotation
value: $(params.consumer-dependency-track-owner-annotation)
params:
- name: consumer-dependency-track-api-url
type: string
Expand All @@ -44,6 +46,9 @@ patches:
type: string
- name: consumer-dependency-track-project-uuid
type: string
- name: consumer-dependency-track-owner-annotation
type: string
default: Owner
target:
kind: Pipeline
# Add anchors to Task.
Expand Down
71 changes: 58 additions & 13 deletions components/consumers/dependency-track/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"context"
"encoding/base64"
"flag"
"fmt"
"log"
"strings"

dtrack "github.com/DependencyTrack/client-go"
"github.com/google/uuid"
Expand All @@ -14,12 +16,13 @@ import (
)

var (
authURL string
apiKey string
projectName string
projectVersion string
projectUUID string
client *dtrack.Client
authURL string
apiKey string
projectName string
projectVersion string
projectUUID string
client *dtrack.Client
ownerAnnotation string
)

func init() {
Expand All @@ -28,6 +31,7 @@ func init() {
flag.StringVar(&projectName, "projectName", "", "dependency track project name")
flag.StringVar(&projectUUID, "projectUUID", "", "dependency track project name")
flag.StringVar(&projectVersion, "projectVersion", "", "dependency track project version")
flag.StringVar(&ownerAnnotation, "ownerAnnotation", "", "if this consumer is in running after any enricher that adds ownership annotations, then provide the annotation-key for this enricher so it can tag owners as tags")
flag.Parse()
}

Expand Down Expand Up @@ -66,25 +70,38 @@ func main() {
func uploadBOMSFromEnriched(responses []*v1.EnrichedLaunchToolResponse) ([]string, error) {
var tokens []string
for _, res := range responses {
var bomIssue *v1.Issue
var bomIssue *v1.EnrichedIssue
for _, issue := range res.GetIssues() {
if issue.GetRawIssue().GetCycloneDXSBOM() != "" && bomIssue == nil {
bomIssue = issue.GetRawIssue()
} else if bomIssue != nil && *bomIssue.CycloneDXSBOM != "" {
log.Fatalf("Tool response for tool %s is malformed, we expected a single issue with an SBOM as part of the tool, got something else instead",
bomIssue = issue
} else if bomIssue != nil && bomIssue.GetRawIssue().GetCycloneDXSBOM() != "" {
log.Printf("Tool response for tool %s is malformed, we expected a single issue with an SBOM as part of the tool, got something else instead",
res.GetOriginalResults().GetToolName())
continue
}
}
cdxbom, err := cyclonedx.FromDracon(bomIssue)
cdxbom, err := cyclonedx.FromDracon(bomIssue.GetRawIssue())
if err != nil {
return tokens, err
}
token, err := uploadBOM(bomIssue.GetCycloneDXSBOM(), cdxbom.Metadata.Component.Version)
token, err := uploadBOM(bomIssue.GetRawIssue().GetCycloneDXSBOM(), cdxbom.Metadata.Component.Version)
if err != nil {
log.Fatal("could not upload bom to dependency track, err:", err)
}
log.Println("upload token is", token)
tokens = append(tokens, token)
if ownerAnnotation != "" {
log.Println("tagging owners")
owners := []string{}
for key, value := range bomIssue.Annotations {
if strings.Contains(key, ownerAnnotation) {
owners = append(owners, value)
}
}
if err := addOwnersTags(owners); err != nil {
log.Println("could not tag owners, err:", err)
}
}
}
return tokens, nil
}
Expand All @@ -97,8 +114,9 @@ func uploadBOMsFromRaw(responses []*v1.LaunchToolResponse) ([]string, error) {
if *issue.CycloneDXSBOM != "" && bomIssue == nil {
bomIssue = issue
} else if bomIssue != nil && *bomIssue.CycloneDXSBOM != "" {
log.Fatalf("Tool response for tool %s is malformed, we expected a single issue with an SBOM as part of the tool, got multiple issues with sboms instead",
log.Printf("Tool response for tool %s is malformed, we expected a single issue with an SBOM as part of the tool, got multiple issues with sboms instead",
res.GetToolName())
continue
}
}
cdxbom, err := cyclonedx.FromDracon(bomIssue)
Expand All @@ -115,6 +133,33 @@ func uploadBOMsFromRaw(responses []*v1.LaunchToolResponse) ([]string, error) {
return tokens, nil
}




northdpole marked this conversation as resolved.
Show resolved Hide resolved
northdpole marked this conversation as resolved.
Show resolved Hide resolved
northdpole marked this conversation as resolved.
Show resolved Hide resolved
northdpole marked this conversation as resolved.
Show resolved Hide resolved
func addOwnersTags(owners []string) error {
northdpole marked this conversation as resolved.
Show resolved Hide resolved
northdpole marked this conversation as resolved.
Show resolved Hide resolved
northdpole marked this conversation as resolved.
Show resolved Hide resolved
northdpole marked this conversation as resolved.
Show resolved Hide resolved
// addOwnersTags expects a map of <ownerAnnotation>-<number>:<username> tagging owners
// it then adds to the projectUUID the owners in the following tag format: Owner:<username>
uuid := uuid.MustParse(projectUUID)
project, err := client.Project.Get(context.Background(), uuid)
if err != nil {
log.Println("could not add project tags error getting project by uuid, err:", err)
return err
}
for _, owner := range owners {
found := false
for _, t := range project.Tags {
if t.Name == fmt.Sprintf("%s:%s", ownerAnnotation, owner) {
found = true
break
}
}
if !found {
project.Tags = append(project.Tags, dtrack.Tag{Name: fmt.Sprintf("%s:%s", ownerAnnotation, owner)})
}
}
_, err = client.Project.Update(context.Background(), project)
return err
}
func uploadBOM(bom string, projectVersion string) (string, error) {
if projectVersion == "" {
projectVersion = "Unknown"
Expand Down
Loading
Loading