Skip to content

Commit dd962fd

Browse files
committed
NO-JIRA: chore(workflows): add Trivy scan action for container image and filesystem vulnerability scanning
1 parent 8df8860 commit dd962fd

File tree

3 files changed

+206
-35
lines changed

3 files changed

+206
-35
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
name: 'Trivy Vulnerability Scanner'
2+
description: |
3+
Run [Trivy](https://trivy.dev) vulnerability scanner on container images or filesystems.
4+
5+
Features
6+
- Supports both container image and filesystem scanning
7+
- Configurable Trivy version
8+
- Customizable scan parameters (scanners, timeout, exit codes)
9+
- Generates markdown reports
10+
- Automatically adds reports to GitHub job summary
11+
12+
Requirements
13+
- Podman must be installed and running (for image scans)
14+
- The Trivy report template must exist at the specified path
15+
- For image scans, the image must be available in the local Podman storage
16+
17+
inputs:
18+
# https://trivy.dev/docs/latest/guide/target/container_image/#vulnerabilities
19+
scan-type:
20+
description: 'Type of scan to perform: "image" or "fs" (filesystem)'
21+
required: true
22+
scan-target:
23+
description: 'Target to scan (image name or filesystem path)'
24+
required: true
25+
trivy-version:
26+
description: 'Version of Trivy to use'
27+
required: false
28+
default: '0.68.2'
29+
podman-socket:
30+
description: 'Path to Podman socket (required for image scans)'
31+
required: false
32+
default: '/var/run/podman/podman.sock'
33+
workspace-path:
34+
description: 'Workspace path for filesystem scans'
35+
required: false
36+
default: ${{ github.workspace }}
37+
report-template:
38+
description: 'Path to Trivy report template'
39+
required: false
40+
default: 'ci/trivy-markdown.tpl'
41+
scanners:
42+
description: 'Comma-separated list of scanners to use'
43+
required: false
44+
default: 'vuln'
45+
ignore-unfixed:
46+
description: 'Ignore unfixed vulnerabilities'
47+
required: false
48+
default: 'true'
49+
timeout:
50+
description: 'Scan timeout'
51+
required: false
52+
default: '30m'
53+
exit-code:
54+
description: 'Exit code when vulnerabilities are found'
55+
required: false
56+
default: '0'
57+
58+
outputs:
59+
report-file:
60+
description: 'Path to the generated report file'
61+
value: ${{ steps.scan.outputs.report-file }}
62+
63+
runs:
64+
using: 'composite'
65+
steps:
66+
- name: Setup report directory
67+
id: setup
68+
shell: bash
69+
run: |
70+
REPORT_FOLDER=${{ inputs.workspace-path }}/trivy-report
71+
REPORT_FILE=trivy-report.md
72+
REPORT_TEMPLATE=$(basename ${{ inputs.report-template }})
73+
74+
mkdir -p $REPORT_FOLDER
75+
cp ${{ inputs.report-template }} $REPORT_FOLDER/
76+
77+
echo "report-folder=$REPORT_FOLDER" >> $GITHUB_OUTPUT
78+
echo "report-file=$REPORT_FILE" >> $GITHUB_OUTPUT
79+
echo "report-template=$REPORT_TEMPLATE" >> $GITHUB_OUTPUT
80+
81+
- name: Run Trivy vulnerability scanner
82+
id: scan
83+
shell: bash
84+
run: |
85+
REPORT_FOLDER=${{ steps.setup.outputs.report-folder }}
86+
REPORT_FILE=${{ steps.setup.outputs.report-file }}
87+
REPORT_TEMPLATE=${{ steps.setup.outputs.report-template }}
88+
89+
SCAN_TARGET=${{ inputs.scan-target }}
90+
SCAN_TYPE=${{ inputs.scan-type }}
91+
92+
echo "Scanning $SCAN_TARGET ($SCAN_TYPE)"
93+
94+
# Configure scan arguments based on type
95+
if [[ "$SCAN_TYPE" == "image" ]]; then
96+
SCAN_ARGS="--image-src podman --podman-host /var/run/podman/podman.sock"
97+
PODMAN_ARGS="-v ${{ inputs.podman-socket }}:/var/run/podman/podman.sock"
98+
elif [[ "$SCAN_TYPE" == "fs" ]]; then
99+
WORKSPACE_FOLDER="/workspace"
100+
SCAN_TARGET="$WORKSPACE_FOLDER/$SCAN_TARGET"
101+
PODMAN_ARGS="-v ${{ inputs.workspace-path }}:$WORKSPACE_FOLDER"
102+
else
103+
echo "Error: Invalid scan type '$SCAN_TYPE'. Must be 'image' or 'fs'"
104+
exit 1
105+
fi
106+
107+
# Run Trivy scan in container
108+
podman run --rm \
109+
$PODMAN_ARGS \
110+
-v ${REPORT_FOLDER}:/report \
111+
docker.io/aquasec/trivy:${{ inputs.trivy-version }} \
112+
$SCAN_TYPE \
113+
$SCAN_ARGS \
114+
--scanners ${{ inputs.scanners }} \
115+
${{ inputs.ignore-unfixed == 'true' && '--ignore-unfixed' || '' }} \
116+
--exit-code ${{ inputs.exit-code }} \
117+
--timeout ${{ inputs.timeout }} \
118+
--format template --template "@/report/$REPORT_TEMPLATE" \
119+
-o /report/$REPORT_FILE \
120+
$SCAN_TARGET
121+
122+
echo "report-file=$REPORT_FOLDER/$REPORT_FILE" >> $GITHUB_OUTPUT
123+
124+
- name: Add report to job summary
125+
shell: bash
126+
run: |
127+
REPORT_FILE=${{ steps.scan.outputs.report-file }}
128+
if [[ -f "$REPORT_FILE" ]]; then
129+
cat $REPORT_FILE >> $GITHUB_STEP_SUMMARY
130+
else
131+
echo "Warning: Report file not found at $REPORT_FILE"
132+
fi

.github/workflows/build-notebooks-TEMPLATE.yaml

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -363,41 +363,12 @@ jobs:
363363
364364
- name: Run Trivy vulnerability scanner
365365
if: ${{ steps.resolve-target.outputs.target }}
366-
run: |
367-
REPORT_FOLDER=${{ github.workspace }}/report
368-
REPORT_FILE=trivy-report.md
369-
REPORT_TEMPLATE=trivy-markdown.tpl
370-
371-
mkdir -p $REPORT_FOLDER
372-
cp ci/$REPORT_TEMPLATE $REPORT_FOLDER
373-
374-
SCAN_TARGET=${{ steps.resolve-target.outputs.target }}
375-
SCAN_TYPE=${{ steps.resolve-target.outputs.type }}
376-
echo "Scanning $SCAN_TARGET ($SCAN_TYPE)"
377-
378-
if [[ "$SCAN_TYPE" == "image" ]]; then
379-
SCAN_ARGS="--image-src podman --podman-host /var/run/podman/podman.sock"
380-
PODMAN_ARGS="-v ${PODMAN_SOCK}:/var/run/podman/podman.sock"
381-
elif [[ "$SCAN_TYPE" == "fs" ]]; then
382-
WORKSPACE_FOLDER="/workspace"
383-
SCAN_TARGET="$WORKSPACE_FOLDER/$SCAN_TARGET"
384-
PODMAN_ARGS="-v ${{ github.workspace }}:$WORKSPACE_FOLDER"
385-
fi
386-
387-
# have trivy access podman socket,
388-
# https://github.com/aquasecurity/trivy/issues/580#issuecomment-666423279
389-
podman run --rm \
390-
$PODMAN_ARGS \
391-
-v ${REPORT_FOLDER}:/report \
392-
docker.io/aquasec/trivy:$TRIVY_VERSION \
393-
$SCAN_TYPE \
394-
$SCAN_ARGS \
395-
--scanners vuln --ignore-unfixed \
396-
--exit-code 0 --timeout 30m \
397-
--format template --template "@/report/$REPORT_TEMPLATE" -o /report/$REPORT_FILE \
398-
$SCAN_TARGET
399-
400-
cat $REPORT_FOLDER/$REPORT_FILE >> $GITHUB_STEP_SUMMARY
366+
uses: ./.github/actions/trivy-scan-action
367+
with:
368+
scan-type: ${{ steps.resolve-target.outputs.type }}
369+
scan-target: ${{ steps.resolve-target.outputs.target }}
370+
trivy-version: ${{ env.TRIVY_VERSION }}
371+
podman-socket: /var/run/podman/podman.sock
401372

402373
# endregion
403374

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
name: Test Trivy Scan Action
3+
"on":
4+
workflow_dispatch:
5+
pull_request:
6+
paths:
7+
- '.github/actions/trivy-scan-action/**'
8+
- '.github/workflows/test-trivy-scan-action.yaml'
9+
- 'ci/trivy-markdown.tpl'
10+
push:
11+
paths:
12+
- '.github/actions/trivy-scan-action/**'
13+
- '.github/workflows/test-trivy-scan-action.yaml'
14+
- 'ci/trivy-markdown.tpl'
15+
16+
jobs:
17+
test-scan-type-image:
18+
name: Test Image Scan
19+
runs-on: ubuntu-24.04
20+
env:
21+
TEST_IMAGE: docker.io/library/alpine:latest
22+
steps:
23+
- name: Checkout code
24+
uses: actions/checkout@v5
25+
26+
- name: Install and configure Podman
27+
run: |
28+
sudo apt-get update
29+
sudo apt-get install -y podman
30+
31+
# Start podman socket for rootful podman
32+
sudo systemctl enable --now podman.socket
33+
sudo systemctl status podman.socket
34+
35+
# Verify socket is accessible
36+
ls -la /var/run/podman/podman.sock || true
37+
38+
- name: Pull test image
39+
run: |
40+
sudo podman pull ${{ env.TEST_IMAGE }}
41+
sudo podman images
42+
43+
- name: Test Trivy scan on container image
44+
uses: ./.github/actions/trivy-scan-action
45+
with:
46+
scan-type: image
47+
scan-target: ${{ env.TEST_IMAGE }}
48+
podman-socket: /var/run/podman/podman.sock
49+
50+
test-scan-type-fs:
51+
name: Test Multiple Targets
52+
runs-on: ubuntu-24.04
53+
strategy:
54+
matrix:
55+
target:
56+
- jupyter/minimal/ubi9-python-3.12
57+
- jupyter/datascience/ubi9-python-3.12
58+
- codeserver/ubi9-python-3.12
59+
fail-fast: false
60+
steps:
61+
- name: Checkout code
62+
uses: actions/checkout@v5
63+
64+
- name: Test Trivy scan on ${{ matrix.target }}
65+
uses: ./.github/actions/trivy-scan-action
66+
with:
67+
scan-type: fs
68+
scan-target: ${{ github.workspace }}

0 commit comments

Comments
 (0)