22# SPDX-FileCopyrightText: (C) 2025 Intel Corporation
33# SPDX-License-Identifier: Apache-2.0
44
5- name : " [WindTurbine Sample App] SDLe Scans - Trivy, DBS, Bandit and Virus Scan "
6- run-name : " [WindTurbine Sample App] SDLe Scans - Trivy, DBS, Bandit and Virus Scans workflow (by @${{ github.actor }} via ${{ github.event_name }})"
5+ name : " [WindTurbine Sample App] SDLe Scans"
6+ run-name : " [WindTurbine Sample App] SDLe Scans workflow (by @${{ github.actor }} via ${{ github.event_name }})"
77
88
99# Only run at most 1 workflow concurrently per PR, unlimited for branches
@@ -13,9 +13,31 @@ concurrency:
1313
1414on :
1515 workflow_dispatch :
16+ inputs :
17+ target :
18+ description : ' Which Scans to run'
19+ type : choice
20+ options :
21+ - all-scans
22+ - trivy-fs-scan
23+ - trivy-image-scan
24+ - trivy-config-scan
25+ - trivy-dockerfile-scan
26+ - trivy-helm-scan
27+ - bandit-scan
28+ - virus-scan
29+ - dbs-scan
30+
31+ workflow_call :
32+ inputs :
33+ target :
34+ description : ' Which Scans to run'
35+ required : false
36+ type : string
1637
1738jobs :
18- trivy-scan-job :
39+ trivy-fs-scan :
40+ if : ${{ (inputs.target == 'trivy-fs-scan') || (inputs.target == 'all-scans') }}
1941 permissions :
2042 contents : read
2143 packages : read # needed for actions/checkout
@@ -80,6 +102,77 @@ jobs:
80102 trivy fs . --format template --template "@trivy-html.tpl" -o "trivy_fs_full_report_code_scan.html"
81103 trivy fs --list-all-pkgs --format template --template "@csv.tpl" --output trivy-fs-full-report.csv .
82104 trivy fs --ignore-unfixed . | tee trivy-fs-full-report-ignore-unfixed.txt
105+
106+ - name : Upload Trivy FS Scan Report
107+ continue-on-error : true
108+ if : always()
109+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
110+ with :
111+ name : Trivy Report - Filesystem Scan
112+ path : |
113+ manufacturing-ai-suite/wind-turbine-anomaly-detection/trivy*
114+
115+ trivy-image-scan :
116+ if : ${{ (inputs.target == 'trivy-image-scan') || (inputs.target == 'all-scans') }}
117+ permissions :
118+ contents : read
119+ packages : read # needed for actions/checkout
120+ runs-on : ubuntu-24.04
121+ steps :
122+ - name : Checkout Code
123+ uses : actions/checkout@v4
124+ with :
125+ persist-credentials : false
126+ - name : Install Trivy from Aqua Security APT repo
127+ run : |
128+ sudo apt-get update
129+ sudo apt-get install -y gnupg lsb-release wget apt-transport-https curl jq
130+ curl -fsSL https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg --dearmor -o /usr/share/keyrings/trivy.gpg
131+ echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -cs) main" | \
132+ sudo tee /etc/apt/sources.list.d/trivy.list > /dev/null
133+ sudo apt-get update
134+ sudo apt-get install -y trivy
135+ - name : Install Trivy
136+ continue-on-error : true
137+ shell : bash
138+ run : |
139+ pwd
140+ cd manufacturing-ai-suite/wind-turbine-anomaly-detection/
141+ trivy --version
142+ which trivy
143+ trivy image --download-db-only
144+ curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/html.tpl -o trivy-html.tpl
145+ cat << 'EOF' > csv.tpl
146+ {{ range . }}
147+ Trivy Vulnerability Scan Results ({{- .Target -}})
148+ VulnerabilityID,Severity,CVSS Score,Title,Library,Vulnerable Version,Fixed Version,Information URL,Triage Information
149+ {{ range .Vulnerabilities }}
150+ {{- .VulnerabilityID }},
151+ {{- .Severity }},
152+ {{- range $key, $value := .CVSS }}
153+ {{- if (eq $key "nvd") }}
154+ {{- .V3Score -}}
155+ {{- end }}
156+ {{- end }},
157+ {{- quote .Title }},
158+ {{- quote .PkgName }},
159+ {{- quote .InstalledVersion }},
160+ {{- quote .FixedVersion }},
161+ {{- .PrimaryURL }}
162+ {{ else -}}
163+ No vulnerabilities found at this time.
164+ {{ end }}
165+ Trivy Dependency Scan Results ({{ .Target }})
166+ ID,Name,Version,Notes
167+ {{ range .Packages -}}
168+ {{- quote .ID }},
169+ {{- quote .Name }},
170+ {{- quote .Version }}
171+ {{ else -}}
172+ No dependencies found at this time.
173+ {{ end }}
174+ {{ end }}
175+ EOF
83176
84177 - name : Trivy Image Scan
85178 continue-on-error : true
@@ -93,20 +186,20 @@ jobs:
93186 sed -i -e "s|MQTT_PUBLISHER_IMAGE=.*|MQTT_PUBLISHER_IMAGE=ia-mqtt-publisher:latest|g" .env
94187 make build
95188
96- trivy image ia-opcua-server:latest --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy_image_scan_opcua_server .html
97- trivy image ia-opcua-server:latest --ignore-unfixed --format template --template "@csv.tpl" -o trivy_image_scan_opcua_server .csv
98- trivy image --quiet --format spdx-json --output trivy_image_scan_opcua_server .spdx.json ia-opcua-server:latest
189+ trivy image ia-opcua-server:latest --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy-image-scan-opcua-server-ignore-unfixed .html
190+ trivy image ia-opcua-server:latest --ignore-unfixed --format template --template "@csv.tpl" -o trivy-image-scan-opcua-server-ignore-unfixed .csv
191+ trivy image --quiet --format spdx-json --output trivy-image-scan-opcua-server .spdx.json ia-opcua-server:latest
99192
100- trivy image --list-all-pkgs --format template --template "@csv.tpl" --output trivy-fs-opcua .csv ia-opcua-server:latest
101- trivy image --ignore-unfixed ia-opcua-server:latest | tee trivy-fs- opcua-ignore-unfixed.txt
193+ trivy image --list-all-pkgs --format template --template "@csv.tpl" --output trivy-image-scan_opcua-server-list-all-pkgs .csv ia-opcua-server:latest
194+ trivy image --ignore-unfixed ia-opcua-server:latest | tee trivy-image-scan- opcua-server -ignore-unfixed.txt
102195
103196
104- trivy image ia-mqtt-publisher:latest --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy_image_scan_mqtt_publisher .html
105- trivy image ia-mqtt-publisher:latest --ignore-unfixed --format template --template "@csv.tpl" -o trivy_image_scan_mqtt_publisher .csv
106- trivy image --quiet --format spdx-json --output trivy_image_scan_mqtt_publisher .spdx.json ia-mqtt-publisher:latest
197+ trivy image ia-mqtt-publisher:latest --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy-image-scan-mqtt-publisher-ignore-unfixed .html
198+ trivy image ia-mqtt-publisher:latest --ignore-unfixed --format template --template "@csv.tpl" -o trivy-image-scan-mqtt-publisher-ignore-unfixed .csv
199+ trivy image --quiet --format spdx-json --output trivy-image-scan-mqtt-publisher .spdx.json ia-mqtt-publisher:latest
107200
108- trivy image --list-all-pkgs --format template --template "@csv.tpl" --output trivy-fs-mqttpublisher .csv ia-mqtt-publisher:latest
109- trivy image --ignore-unfixed ia-mqtt-publisher:latest | tee trivy-fs-mqttpublisher -ignore-unfixed.txt
201+ trivy image --list-all-pkgs --format template --template "@csv.tpl" --output trivy-image-scan-mqtt-publisher-list-all-pkgs .csv ia-mqtt-publisher:latest
202+ trivy image --ignore-unfixed ia-mqtt-publisher:latest | tee trivy-image-scan-mqtt-publisher -ignore-unfixed.txt
110203
111204 echo "completed Wind Turbine Sample App Image scanning"
112205
@@ -115,54 +208,111 @@ jobs:
115208 if : always()
116209 uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
117210 with :
118- name : Trivy Scan report fs and image
211+ name : Trivy Report - Image Scan
119212 path : |
120- manufacturing-ai-suite/wind-turbine-anomaly-detection/trivy*
213+ manufacturing-ai-suite/wind-turbine-anomaly-detection/trivy-image-scan*
214+
215+ trivy-config-helm-scan :
216+ if : ${{ (inputs.target == 'trivy-config-scan') || (inputs.target == 'trivy-helm-scan') || (inputs.target == 'all-scans') }}
217+ permissions :
218+ contents : read
219+ packages : read # needed for actions/checkout
220+ runs-on : ubuntu-24.04
221+ steps :
222+ - name : Checkout Code
223+ uses : actions/checkout@v4
224+ with :
225+ persist-credentials : false
226+ - name : Install Trivy from Aqua Security APT repo
227+ run : |
228+ sudo apt-get update
229+ sudo apt-get install -y gnupg lsb-release wget apt-transport-https curl jq
230+ curl -fsSL https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg --dearmor -o /usr/share/keyrings/trivy.gpg
231+ echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -cs) main" | \
232+ sudo tee /etc/apt/sources.list.d/trivy.list > /dev/null
233+ sudo apt-get update
234+ sudo apt-get install -y trivy
235+ - name : Install Trivy
236+ continue-on-error : true
237+ shell : bash
238+ run : |
239+ pwd
240+ cd manufacturing-ai-suite/wind-turbine-anomaly-detection/
241+ trivy --version
242+ which trivy
243+ trivy image --download-db-only
244+ curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/html.tpl -o trivy-html.tpl
245+ cat << 'EOF' > csv.tpl
246+ {{ range . }}
247+ Trivy Vulnerability Scan Results ({{- .Target -}})
248+ VulnerabilityID,Severity,CVSS Score,Title,Library,Vulnerable Version,Fixed Version,Information URL,Triage Information
249+ {{ range .Vulnerabilities }}
250+ {{- .VulnerabilityID }},
251+ {{- .Severity }},
252+ {{- range $key, $value := .CVSS }}
253+ {{- if (eq $key "nvd") }}
254+ {{- .V3Score -}}
255+ {{- end }}
256+ {{- end }},
257+ {{- quote .Title }},
258+ {{- quote .PkgName }},
259+ {{- quote .InstalledVersion }},
260+ {{- quote .FixedVersion }},
261+ {{- .PrimaryURL }}
262+ {{ else -}}
263+ No vulnerabilities found at this time.
264+ {{ end }}
265+ Trivy Dependency Scan Results ({{ .Target }})
266+ ID,Name,Version,Notes
267+ {{ range .Packages -}}
268+ {{- quote .ID }},
269+ {{- quote .Name }},
270+ {{- quote .Version }}
271+ {{ else -}}
272+ No dependencies found at this time.
273+ {{ end }}
274+ {{ end }}
275+ EOF
121276
122277 - name : Trivy config scan for helm charts
123278 run : |
124279 cd manufacturing-ai-suite/wind-turbine-anomaly-detection/
125280 make gen_helm_charts
126281 cd helm
127- trivy config . >> trivy_helm .txt
282+ trivy config . >> trivy-wind-turbine-helm .txt
128283
129284 - name : Upload Scan artifact to Github
130285 uses : actions/upload-artifact@v4
131286 with :
132- name : Trivy Config Scan for Helm
133- path : manufacturing-ai-suite/wind-turbine-anomaly-detection/helm/trivy_*
287+ name : Trivy Report - Config scan for Helm
288+ path : manufacturing-ai-suite/wind-turbine-anomaly-detection/helm/trivy-wind-turbine-helm.txt
134289
135- trivy-config-opcua-dockerfile-scan :
290+ trivy-config-dockerfile-scan :
291+ if : ${{ (inputs.target == 'trivy-config-scan') || (inputs.target == 'trivy-dockerfile-scan') || (inputs.target == 'all-scans') }}
136292 permissions :
137293 contents : read
138294 packages : read # needed for actions/checkout
139- name : Scan OPCUA Dockerfile
140- strategy :
141- fail-fast : false
142- uses : open-edge-platform/edge-ai-libraries/.github/workflows/trivy-config-mode.yaml@e6e04af3dbca805db9118b85a22ad2998f7eec39
143- with :
144- dockerfile-path : manufacturing-ai-suite/wind-turbine-anomaly-detection/simulator/opcua-server/Dockerfile
145- trivy-report-format : ' json'
146- severity-levels : ' HIGH,CRITICAL'
147- output-report-path : trivy-opcua-dockerfile.json
148- name : Time Series OPCUA Dockerfile
149-
150- trivy-config-mqttpublisher-dockerfile-scan :
151- permissions :
152- contents : read
153- packages : read # needed for actions/checkout
154- name : Scan mqttpublisher Dockerfile
295+ name : Scan Dockerfiles (OPCUA & mqttpublisher)
155296 strategy :
156297 fail-fast : false
298+ matrix :
299+ include :
300+ - dockerfile-path : manufacturing-ai-suite/wind-turbine-anomaly-detection/simulator/opcua-server/Dockerfile
301+ output-report-path : trivy-opcua-dockerfile.json
302+ scan-name : Time Series OPCUA Dockerfile
303+ - dockerfile-path : manufacturing-ai-suite/wind-turbine-anomaly-detection/simulator/mqtt-publisher/Dockerfile
304+ output-report-path : trivy-mqttpublisher-dockerfile.json
305+ scan-name : Time Series mqttpublisher Dockerfile
157306 uses : open-edge-platform/edge-ai-libraries/.github/workflows/trivy-config-mode.yaml@e6e04af3dbca805db9118b85a22ad2998f7eec39
158307 with :
159- dockerfile-path : manufacturing-ai-suite/wind-turbine-anomaly-detection/simulator/mqtt-publisher/Dockerfile
308+ dockerfile-path : ${{ matrix.dockerfile-path }}
160309 trivy-report-format : ' json'
161310 severity-levels : ' HIGH,CRITICAL'
162- output-report-path : trivy-mqttpublisher-dockerfile.json
163- name : Time Series mqttpublisher Dockerfile
311+ output-report-path : ${{ matrix.output-report-path }}
312+ name : ${{ matrix.scan-name }}
164313
165314 bandit-scans :
315+ if : ${{ (inputs.target == 'bandit-scan') || (inputs.target == 'all-scans') }}
166316 permissions :
167317 contents : read
168318 packages : read # needed for actions/checkout
@@ -184,15 +334,43 @@ jobs:
184334 mkdir -p reports
185335 docker pull ghcr.io/pycqa/bandit/bandit
186336 echo "### Bandit Scan Results" >> $GITHUB_STEP_SUMMARY
187- docker run --rm -v "${{ github.workspace }}:/src" ghcr.io/pycqa/bandit/bandit -r /src/manufacturing-ai-suite/wind-turbine-anomaly-detection/ -f txt -o /src/reports/bandit-report.txt || true >> $GITHUB_STEP_SUMMARY
337+ docker run --rm -v "${{ github.workspace }}:/src" ghcr.io/pycqa/bandit/bandit -r /src/manufacturing-ai-suite/wind-turbine-anomaly-detection/ -f json -o /src/reports/bandit-report.json || true >> $GITHUB_STEP_SUMMARY
188338 echo "Please find full report in bandit-report.txt" >> $GITHUB_STEP_SUMMARY
339+ ls -al
340+ pwd
341+ - name : Convert JSON to CSV
342+ run : |
343+ python3 <<EOF
344+ import json
345+ import csv
346+
347+ with open("reports/bandit-report.json") as f:
348+ data = json.load(f)
349+
350+ with open("reports/bandit-report.csv", "w", newline="") as csvfile:
351+ fieldnames = ["filename", "line_number", "issue_text", "severity", "confidence", "test_name"]
352+ writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
353+ writer.writeheader()
354+ for issue in data.get("results", []):
355+ writer.writerow({
356+ "filename": issue["filename"],
357+ "line_number": issue["line_number"],
358+ "issue_text": issue["issue_text"],
359+ "severity": issue["issue_severity"],
360+ "confidence": issue["issue_confidence"],
361+ "test_name": issue["test_name"]
362+ })
363+ EOF
189364 - name : Upload Scan Reports
190365 uses : actions/upload-artifact@v4
191366 with :
192367 name : bandit-report
193- path : reports/bandit-report.txt
368+ path : |
369+ reports/bandit-report.json
370+ reports/bandit-report.csv
194371
195372 virus-scans :
373+ if : ${{ (inputs.target == 'virus-scan') || (inputs.target == 'all-scans') }}
196374 permissions :
197375 contents : read
198376 packages : read # needed for actions/checkout
@@ -222,6 +400,7 @@ jobs:
222400 path : reports/clamav-report.txt
223401
224402 DBS_job :
403+ if : ${{ (inputs.target == 'dbs-scan') || (inputs.target == 'all-scans') }}
225404 runs-on : ubuntu-24.04
226405 permissions :
227406 contents : read
@@ -312,4 +491,4 @@ jobs:
312491 uses : actions/upload-artifact@v4
313492 with :
314493 name : DBS_time-series-analytics
315- path : manufacturing-ai-suite/wind-turbine-anomaly-detection/dbs_scan_*
494+ path : manufacturing-ai-suite/wind-turbine-anomaly-detection/dbs_scan_*
0 commit comments