Skip to content

Commit ec69566

Browse files
committed
refactor: parameterize DefectDojo integration with per-branch scan isolation
Enable independent security scan tracking per git branch in DefectDojo. Previously, all branches shared a single engagement per product, causing scan results to overwrite each other — scanning release/1.0 would replace main findings. Now each branch gets its own isolated engagement via automatic name suffixing (e.g., code-security-main, code-security-release/1.0). DefectDojo object model per codebase: Product Type: KubeRocketCI (configurable via DD_PRODUCT_TYPE_NAME) └── Product: <CODEBASE_NAME> ├── Engagement: code-security-main │ ├── Test: Semgrep JSON Report (branch_tag: main) │ └── Test: Gitleaks Scan (branch_tag: main) └── Engagement: code-security-release/1.0 ├── Test: Semgrep JSON Report (branch_tag: release/1.0) └── Test: Gitleaks Scan (branch_tag: release/1.0) Re-scanning a branch only affects its own engagement. New branches are auto-created on first scan via auto_create_context. The branch_tag field on each Test provides audit traceability. Technical changes: - Add DD_PRODUCT_TYPE_NAME, DD_ENGAGEMENT_NAME, DD_VERSION, DD_BRANCH_TAG params across security, image-scan, and image-scan-remote tasks - Construct engagement name as DD_ENGAGEMENT_NAME-CODEBASE_BRANCH in the security task for branch isolation - Merge redundant PROJECT_NAME into CODEBASE_NAME (always same value) - Rename PROJECT_BRANCH to CODEBASE_BRANCH for naming consistency - Use curl --data-urlencode for GET requests to handle special characters in branch names (e.g., release/1.0) - Conditionally pass version and branch_tag to reimport-scan API to avoid overwriting existing DefectDojo metadata with empty values - Remove hardcoded product_type_name=Tenant and engagement_name values Signed-off-by: Sergiy Kulanov <sergiy_kulanov@epam.com>
1 parent 845a788 commit ec69566

File tree

7 files changed

+116
-59
lines changed

7 files changed

+116
-59
lines changed

charts/pipelines-library/templates/pipelines/security/security-scan-bitbucket.yaml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,9 @@ spec:
7474
runAfter:
7575
- init-values
7676
params:
77-
- name: DD_PRODUCT_NAME
78-
value: $(tasks.init-values.results.TENANT_NAME)
79-
- name: DD_ENGAGEMENT_NAME
80-
value: "$(params.CODEBASE_NAME)-$(params.git-source-revision)"
81-
- name: PROJECT_NAME
77+
- name: CODEBASE_NAME
8278
value: $(params.CODEBASE_NAME)
83-
- name: PROJECT_BRANCH
79+
- name: CODEBASE_BRANCH
8480
value: $(params.git-source-revision)
8581
workspaces:
8682
- name: source

charts/pipelines-library/templates/pipelines/security/security-scan-gerrit.yaml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,9 @@ spec:
6969
runAfter:
7070
- init-values
7171
params:
72-
- name: DD_PRODUCT_NAME
73-
value: $(tasks.init-values.results.TENANT_NAME)
74-
- name: DD_ENGAGEMENT_NAME
75-
value: "$(params.CODEBASE_NAME)-$(params.git-source-revision)"
76-
- name: PROJECT_NAME
72+
- name: CODEBASE_NAME
7773
value: $(params.CODEBASE_NAME)
78-
- name: PROJECT_BRANCH
74+
- name: CODEBASE_BRANCH
7975
value: $(params.git-source-revision)
8076
workspaces:
8177
- name: source

charts/pipelines-library/templates/pipelines/security/security-scan-github.yaml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,9 @@ spec:
7474
runAfter:
7575
- init-values
7676
params:
77-
- name: DD_PRODUCT_NAME
78-
value: $(tasks.init-values.results.TENANT_NAME)
79-
- name: DD_ENGAGEMENT_NAME
80-
value: "$(params.CODEBASE_NAME)-$(params.git-source-revision)"
81-
- name: PROJECT_NAME
77+
- name: CODEBASE_NAME
8278
value: $(params.CODEBASE_NAME)
83-
- name: PROJECT_BRANCH
79+
- name: CODEBASE_BRANCH
8480
value: $(params.git-source-revision)
8581
workspaces:
8682
- name: source

charts/pipelines-library/templates/pipelines/security/security-scan-gitlab.yaml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,9 @@ spec:
7474
runAfter:
7575
- init-values
7676
params:
77-
- name: DD_PRODUCT_NAME
78-
value: $(tasks.init-values.results.TENANT_NAME)
79-
- name: DD_ENGAGEMENT_NAME
80-
value: "$(params.CODEBASE_NAME)-$(params.git-source-revision)"
81-
- name: PROJECT_NAME
77+
- name: CODEBASE_NAME
8278
value: $(params.CODEBASE_NAME)
83-
- name: PROJECT_BRANCH
79+
- name: CODEBASE_BRANCH
8480
value: $(params.git-source-revision)
8581
workspaces:
8682
- name: source

charts/pipelines-library/templates/tasks/image-scan-remote.yaml

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ spec:
2525
`repository/image:tag` or `repository/image`.
2626
- name: COMPONENT_NAME
2727
type: string
28-
description: Name of the component to which the images belong.
29-
Pipeline will use this name to create/update the appropriate
30-
Engagement with scan reports in DefectDojo.
28+
description: Name of the codebase/component to which the images belong.
29+
Used as the DefectDojo product name for scan report tracking.
3130
- name: BASE_IMAGE_AWS_CLI
3231
type: string
3332
description: AWS CLI image
@@ -49,6 +48,22 @@ spec:
4948
type: string
5049
description: The name of the Grype scan report
5150
default: image-scan-grype-report.json
51+
- name: DD_PRODUCT_TYPE_NAME
52+
type: string
53+
description: DefectDojo product type name
54+
default: "KubeRocketCI"
55+
- name: DD_ENGAGEMENT_NAME
56+
type: string
57+
description: DefectDojo engagement name
58+
default: "container-security"
59+
- name: DD_VERSION
60+
type: string
61+
description: Version that will be set on the DefectDojo Test object
62+
default: ""
63+
- name: DD_BRANCH_TAG
64+
type: string
65+
description: Branch or tag that was scanned, recorded on the DefectDojo Test object
66+
default: ""
5267
- name: ci-defectdojo
5368
type: string
5469
description: Name of the secret holding the DefectDojo CI integration data
@@ -145,19 +160,25 @@ spec:
145160
secretKeyRef:
146161
key: url
147162
name: $(params.ci-defectdojo)
148-
- name: DD_PRODUCT_NAME
149-
valueFrom:
150-
fieldRef:
151-
fieldPath: metadata.namespace
152163
script: |
153164
#!/usr/bin/env sh
154165
set -e
155166
156-
PRODUCT_ID=$(curl -s -X GET "${DD_HOST_URL}/api/v2/products/?name_exact=${DD_PRODUCT_NAME}" \
167+
PRODUCT_ID=$(curl -s -G "${DD_HOST_URL}/api/v2/products/" \
168+
--data-urlencode "name_exact=$(params.COMPONENT_NAME)" \
157169
-H "accept: application/json" \
158170
-H "Authorization: Token ${DD_TOKEN}" \
159171
| jq -r '.results[0].id')
160172
173+
DD_VERSION_ARG=""
174+
DD_BRANCH_TAG_ARG=""
175+
if [ -n "$(params.DD_VERSION)" ]; then
176+
DD_VERSION_ARG="-F version=$(params.DD_VERSION)"
177+
fi
178+
if [ -n "$(params.DD_BRANCH_TAG)" ]; then
179+
DD_BRANCH_TAG_ARG="-F branch_tag=$(params.DD_BRANCH_TAG)"
180+
fi
181+
161182
for IMAGE in "$@"; do
162183
COMPONENT_NAME=$(basename "${IMAGE%%:*}")
163184
@@ -178,19 +199,23 @@ spec:
178199
-F "verified=false" \
179200
-F "scan_type=${SCAN_TYPE}" \
180201
-F "file=@${REPORT_NAME};type=application/json" \
181-
-F "product_type_name=Tenant" \
182-
-F "product_name=${DD_PRODUCT_NAME}" \
183-
-F "engagement_name=$(params.COMPONENT_NAME)" \
202+
-F "product_type_name=$(params.DD_PRODUCT_TYPE_NAME)" \
203+
-F "product_name=$(params.COMPONENT_NAME)" \
204+
-F "engagement_name=$(params.DD_ENGAGEMENT_NAME)" \
184205
-F "auto_create_context=true" \
185206
-F "close_old_findings=true" \
186207
-F "push_to_jira=false" \
187208
-F "environment=Development" \
188-
-F "test_title=${COMPONENT_NAME}" \
189-
-F "tags=${IMAGE%:*}"
209+
-F "test_title=${SCAN_TYPE}" \
210+
-F "tags=${IMAGE%:*}" \
211+
${DD_VERSION_ARG} \
212+
${DD_BRANCH_TAG_ARG}
190213
done
191214
done
192215
193-
ENGAGEMENT_ID=$(curl -s -X GET "${DD_HOST_URL}/api/v2/engagements/?product=${PRODUCT_ID}&name=$(params.COMPONENT_NAME)" \
216+
ENGAGEMENT_ID=$(curl -s -G "${DD_HOST_URL}/api/v2/engagements/" \
217+
--data-urlencode "product=${PRODUCT_ID}" \
218+
--data-urlencode "name=$(params.DD_ENGAGEMENT_NAME)" \
194219
-H "accept: application/json" \
195220
-H "Authorization: Token ${DD_TOKEN}" \
196221
| jq -r '.results[0].id')

charts/pipelines-library/templates/tasks/image-scan.yaml

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,24 @@ spec:
3939
type: string
4040
description: The name of the Grype scan report
4141
default: image-scan-grype-report.json
42-
- name: DD_PRODUCT_NAME
42+
- name: CODEBASE_NAME
4343
type: string
44+
- name: DD_PRODUCT_TYPE_NAME
45+
type: string
46+
description: DefectDojo product type name
47+
default: "KubeRocketCI"
4448
- name: DD_ENGAGEMENT_NAME
4549
type: string
50+
description: DefectDojo engagement name
51+
default: "container-security"
52+
- name: DD_VERSION
53+
type: string
54+
description: Version that will be set on the DefectDojo Test object
55+
default: ""
56+
- name: DD_BRANCH_TAG
57+
type: string
58+
description: Branch or tag that was scanned, recorded on the DefectDojo Test object
59+
default: ""
4660
- name: ci-defectdojo
4761
type: string
4862
description: name of the secret holding the DefectDojo CI integration data
@@ -89,6 +103,15 @@ spec:
89103
#!/usr/bin/env sh
90104
set -e
91105
106+
DD_VERSION_ARG=""
107+
DD_BRANCH_TAG_ARG=""
108+
if [ -n "$(params.DD_VERSION)" ]; then
109+
DD_VERSION_ARG="-F version=$(params.DD_VERSION)"
110+
fi
111+
if [ -n "$(params.DD_BRANCH_TAG)" ]; then
112+
DD_BRANCH_TAG_ARG="-F branch_tag=$(params.DD_BRANCH_TAG)"
113+
fi
114+
92115
for REPORT_NAME in $(params.TRIVY_SCAN_REPORT) $(params.GRYPE_SCAN_REPORT)
93116
do
94117
SCAN_TYPE=""
@@ -108,13 +131,15 @@ spec:
108131
-F "verified=false" \
109132
-F "scan_type=${SCAN_TYPE}" \
110133
-F "file=@${REPORT_NAME};type=application/json" \
111-
-F "product_type_name=Tenant" \
112-
-F "product_name=$(params.DD_PRODUCT_NAME)" \
134+
-F "product_type_name=$(params.DD_PRODUCT_TYPE_NAME)" \
135+
-F "product_name=$(params.CODEBASE_NAME)" \
113136
-F "engagement_name=$(params.DD_ENGAGEMENT_NAME)" \
114137
-F "auto_create_context=true" \
115138
-F "close_old_findings=true" \
116139
-F "push_to_jira=false" \
117140
-F "environment=Development" \
118-
-F "test_title=security-scan"
141+
-F "test_title=${SCAN_TYPE}" \
142+
${DD_VERSION_ARG} \
143+
${DD_BRANCH_TAG_ARG}
119144
done
120145
{{ end }}

charts/pipelines-library/templates/tasks/security.yaml

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,26 @@ spec:
4242
- name: GITLEAKS_SCAN_REPORT
4343
type: string
4444
default: "gitleaks-report.json"
45-
- name: DD_PRODUCT_NAME
45+
- name: CODEBASE_NAME
4646
type: string
47+
description: Project name, used as DefectDojo product name and Dependency-Track project name
4748
default: ""
48-
- name: DD_ENGAGEMENT_NAME
49-
type: string
50-
default: ""
51-
- name: PROJECT_NAME
52-
description: That is the name of the project that will be updated/created on the dependency track side
49+
- name: CODEBASE_BRANCH
50+
description: Git branch or tag being scanned
5351
default: ''
5452
type: string
55-
- name: PROJECT_BRANCH
56-
description: That is the branch of the project that will be updated/created on the dependency track side
57-
default: ''
53+
- name: DD_PRODUCT_TYPE_NAME
54+
type: string
55+
description: DefectDojo product type name
56+
default: "KubeRocketCI"
57+
- name: DD_ENGAGEMENT_NAME
5858
type: string
59+
description: DefectDojo engagement name
60+
default: "code-security"
61+
- name: DD_VERSION
62+
type: string
63+
description: Version that will be set on the DefectDojo Test object
64+
default: ""
5965
- name: ci-dependency-track
6066
type: string
6167
description: Name of the secret holding the ci-dependency-track api token
@@ -121,9 +127,9 @@ spec:
121127
key: url
122128
optional: true
123129
- name: PROJECT_NAME
124-
value: $(params.PROJECT_NAME)
130+
value: $(params.CODEBASE_NAME)
125131
- name: PROJECT_BRANCH
126-
value: $(params.PROJECT_BRANCH)
132+
value: $(params.CODEBASE_BRANCH)
127133
image: $(params.BASE_IMAGE_CDXGEN)
128134
name: cdxgen
129135
computeResources: {}
@@ -161,11 +167,24 @@ spec:
161167
exit 0
162168
fi
163169
164-
PRODUCT_ID=$(curl -s -X GET "${DD_HOST_URL}/api/v2/products/?name_exact=$(params.DD_PRODUCT_NAME)" \
170+
PRODUCT_ID=$(curl -s -G "${DD_HOST_URL}/api/v2/products/" \
171+
--data-urlencode "name_exact=$(params.CODEBASE_NAME)" \
165172
-H "accept: application/json" \
166173
-H "Authorization: Token ${DD_TOKEN}" \
167174
| jq -r '.results[0].id')
168175
176+
ENGAGEMENT_NAME="$(params.DD_ENGAGEMENT_NAME)"
177+
DD_BRANCH_TAG_ARG=""
178+
if [ -n "$(params.CODEBASE_BRANCH)" ]; then
179+
ENGAGEMENT_NAME="${ENGAGEMENT_NAME}-$(params.CODEBASE_BRANCH)"
180+
DD_BRANCH_TAG_ARG="-F branch_tag=$(params.CODEBASE_BRANCH)"
181+
fi
182+
183+
DD_VERSION_ARG=""
184+
if [ -n "$(params.DD_VERSION)" ]; then
185+
DD_VERSION_ARG="-F version=$(params.DD_VERSION)"
186+
fi
187+
169188
for REPORT_NAME in $(params.SEMGREP_SCAN_REPORT) $(params.GITLEAKS_SCAN_REPORT)
170189
do
171190
SCAN_TYPE=""
@@ -185,17 +204,21 @@ spec:
185204
-F "verified=false" \
186205
-F "scan_type=${SCAN_TYPE}" \
187206
-F "file=@${REPORT_NAME};type=application/json" \
188-
-F "product_type_name=Tenant" \
189-
-F "product_name=$(params.DD_PRODUCT_NAME)" \
190-
-F "engagement_name=$(params.DD_ENGAGEMENT_NAME)" \
207+
-F "product_type_name=$(params.DD_PRODUCT_TYPE_NAME)" \
208+
-F "product_name=$(params.CODEBASE_NAME)" \
209+
-F "engagement_name=${ENGAGEMENT_NAME}" \
191210
-F "auto_create_context=true" \
192211
-F "close_old_findings=true" \
193212
-F "push_to_jira=false" \
194213
-F "environment=Development" \
195-
-F "test_title=security"
214+
-F "test_title=${SCAN_TYPE}" \
215+
${DD_VERSION_ARG} \
216+
${DD_BRANCH_TAG_ARG}
196217
done
197218
198-
ENGAGEMENT_ID=$(curl -s -X GET "${DD_HOST_URL}/api/v2/engagements/?product=${PRODUCT_ID}&name=$(params.DD_ENGAGEMENT_NAME)" \
219+
ENGAGEMENT_ID=$(curl -s -G "${DD_HOST_URL}/api/v2/engagements/" \
220+
--data-urlencode "product=${PRODUCT_ID}" \
221+
--data-urlencode "name=${ENGAGEMENT_NAME}" \
199222
-H "accept: application/json" \
200223
-H "Authorization: Token ${DD_TOKEN}" \
201224
| jq -r '.results[0].id')

0 commit comments

Comments
 (0)