Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
58142ce
Add JSON vulnerability scan outputs
TaniaGithub0401 Sep 9, 2026
b22bf61
Add OpenVEX report generation
TaniaGithub0401 Sep 9, 2026
1fccdef
Use vexctl container for OpenVEX generation
TaniaGithub0401 Sep 9, 2026
4aa62fa
Test compatible vexctl version
TaniaGithub0401 Sep 9, 2026
e3ec1c8
repport to json
TaniaGithub0401 Sep 9, 2026
a05a7ae
Validate generated OpenVEX report
TaniaGithub0401 Sep 9, 2026
9dae6ef
Add Python OpenVEX report generation
TaniaGithub0401 Sep 9, 2026
476c31e
Fix Python Grype JSON output reference
TaniaGithub0401 Sep 14, 2026
47f8ac5
Align OpenVEX workflow with latest main
TaniaGithub0401 Sep 14, 2026
913100b
Add CycloneDX VEX generation
TaniaGithub0401 Sep 15, 2026
70969e9
Integrate Dependency-Track VEX reporting
TaniaGithub0401 Sep 15, 2026
e0dbef8
Refactor Dependency-Track integration
TaniaGithub0401 Sep 15, 2026
5229a9c
Extend Dependency-Track VEX reporting to Python
TaniaGithub0401 Sep 15, 2026
132d7eb
Remove legacy OpenVEX workflow steps
TaniaGithub0401 Sep 15, 2026
205b2af
Merge main into add-openvex-cra-reporting
TaniaGithub0401 Sep 16, 2026
003f5d5
Add CSAF VEX generation to Dependency-Track reporting
TaniaGithub0401 Sep 16, 2026
74118a6
Retry Dependency-Track analysis when generating CSAF
TaniaGithub0401 Sep 16, 2026
9917115
Add CSAF validation to Dependency-Track reporting
TaniaGithub0401 Sep 16, 2026
eff62f7
CSAF validator startup diagnostics
TaniaGithub0401 Sep 16, 2026
dab9bc6
Fix CSAF validator startup
TaniaGithub0401 Sep 16, 2026
65bdf02
Improve CSAF validation error reporting
TaniaGithub0401 Sep 16, 2026
2cab6c9
Inspect CSAF validator response structure
TaniaGithub0401 Sep 21, 2026
118d55c
Fix CSAF validator request
TaniaGithub0401 Sep 21, 2026
b6209a6
Show CSAF validator request errors
TaniaGithub0401 Sep 21, 2026
b3fd95e
Fix CSAF validator request payload
TaniaGithub0401 Sep 21, 2026
98b0a2e
check csaf validation
TaniaGithub0401 Sep 21, 2026
3721643
Install Hunspell for CSAF validation
TaniaGithub0401 Sep 21, 2026
ff449f2
Improve CSAF validator error handling
TaniaGithub0401 Sep 21, 2026
19f9d17
Configure Hunspell dictionary for CSAF validation
TaniaGithub0401 Sep 21, 2026
9d9601a
Report failed CSAF validation tests
TaniaGithub0401 Sep 21, 2026
692a409
Report CSAF validation error messages
TaniaGithub0401 Sep 21, 2026
9fb4c0b
Check CSAF validation errors excluding references
TaniaGithub0401 Sep 21, 2026
c4c0070
Omit empty references from CSAF document
TaniaGithub0401 Sep 21, 2026
98113d5
Simplify CSAF validation handling
TaniaGithub0401 Sep 21, 2026
8930fd2
Skip CSAF validation when no report is generated
TaniaGithub0401 Sep 21, 2026
492b48d
Add Dependency-Track VEX and CSAF reporting workflow
TaniaGithub0401 Sep 21, 2026
9ee86c6
Fix Dependency-Track action reference
TaniaGithub0401 Sep 22, 2026
3fc0e72
Update SBOM vulnerability scan documentation
TaniaGithub0401 Sep 22, 2026
2cffb6a
Merge remote-tracking branch 'origin/main' into add-csaf-reporting
TaniaGithub0401 Sep 23, 2026
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
108 changes: 106 additions & 2 deletions .github/actions/dependency-track-report/action.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Dependency-Track Report
description: Upload an SBOM to Dependency-Track, generate CycloneDX VEX, and apply it
description: Upload an SBOM to Dependency-Track, manage CycloneDX VEX, and generate and validate CSAF VEX

inputs:
sbom-file:
Expand Down Expand Up @@ -169,4 +169,108 @@ runs:
if [ "$http_code" != "200" ]; then
echo "Dependency-Track VEX upload failed with HTTP $http_code."
exit 1
fi
fi

- name: Generate CSAF VEX
id: generate-csaf
shell: bash
env:
DTRACK_URL: ${{ inputs.dependency-track-url }}
DTRACK_API_KEY: ${{ inputs.api-key }}
DTRACK_FINDINGS_FILE: /tmp/dtrack-findings.json
SBOM_PATH: ${{ inputs.sbom-file }}
CSAF_OUTPUT: /tmp/csaf-vex.json
CSAF_PUBLISHER_NAME: mundialis
CSAF_PUBLISHER_NAMESPACE: https://mundialis.de
run: |
finding_count=$(jq 'length' /tmp/dtrack-findings.json)

if [ "$finding_count" -eq 0 ]; then
echo "No findings were reported by Dependency-Track. CSAF VEX generation is not required."
echo "has-csaf=false" >> "$GITHUB_OUTPUT"
exit 0
fi

python "$GITHUB_ACTION_PATH/generate_csaf.py"

if [ -s /tmp/csaf-vex.json ]; then
echo "has-csaf=true" >> "$GITHUB_OUTPUT"
echo "CSAF VEX generated successfully."
else
echo "has-csaf=false" >> "$GITHUB_OUTPUT"
echo "Dependency-Track reported findings, but none had an analysis state that could be included in the CSAF VEX."
fi

- name: Set up Node.js for CSAF validator
if: steps.generate-csaf.outputs.has-csaf == 'true'
uses: actions/setup-node@v7
with:
node-version: '24'

- name: Install Hunspell for CSAF validator
if: steps.generate-csaf.outputs.has-csaf == 'true'
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y hunspell hunspell-en-us

sudo ln -sf /usr/share/hunspell/en_US.aff /usr/share/hunspell/en.aff
sudo ln -sf /usr/share/hunspell/en_US.dic /usr/share/hunspell/en.dic

- name: Start CSAF validator
if: steps.generate-csaf.outputs.has-csaf == 'true'
shell: bash
run: |
npx --yes @secvisogram/csaf-validator-service \
> /tmp/csaf-validator.log 2>&1 &

echo $! > /tmp/csaf-validator.pid

for attempt in {1..30}; do
if curl -sf http://localhost:8082/docs > /dev/null 2>&1; then
exit 0
fi

sleep 1
done

echo "CSAF validator did not start."
cat /tmp/csaf-validator.log
exit 1

- name: Validate CSAF VEX
if: steps.generate-csaf.outputs.has-csaf == 'true'
shell: bash
run: |
http_code=$(jq -n \
--slurpfile doc /tmp/csaf-vex.json \
'{
document: $doc[0],
tests: [
{
name: "full",
type: "preset"
}
]
}' \
| curl -sS -X POST \
"http://localhost:8082/api/v1/validate" \
-H "Content-Type: application/json" \
--data-binary @- \
-o /tmp/csaf-validation-result.json \
-w "%{http_code}")

if [ "$http_code" != "200" ]; then
echo "CSAF Validator service request failed with HTTP code $http_code."
echo "Validator error:"
jq -r '.message // .error // "Unknown validator error"' \
/tmp/csaf-validation-result.json
exit 1
fi

if [ "$(jq -r '.isValid' /tmp/csaf-validation-result.json)" != "true" ]; then
echo "CSAF VEX validation failed."
exit 1
fi

echo "CSAF VEX validation succeeded."
71 changes: 71 additions & 0 deletions .github/actions/dependency-track-report/dependency_track.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import json
import os
import time
import urllib.error
import urllib.parse
import urllib.request


DTRACK_URL = os.environ.get(
"DTRACK_URL",
"http://localhost:8080",
)

DTRACK_API_KEY = os.environ.get("DTRACK_API_KEY")


def validate_config():
if not DTRACK_API_KEY:
raise SystemExit("DTRACK_API_KEY is not set")


def get_analysis(finding):
component = finding["component"]
vulnerability = finding["vulnerability"]

params = urllib.parse.urlencode(
{
"project": component["project"],
"component": component["uuid"],
"vulnerability": vulnerability["uuid"],
}
)

url = f"{DTRACK_URL}/api/v1/analysis?{params}"

request = urllib.request.Request(
url,
headers={
"X-Api-Key": DTRACK_API_KEY,
"Accept": "application/json",
},
)

max_attempts = 5

for attempt in range(1, max_attempts + 1):
try:
with urllib.request.urlopen(
request,
timeout=15,
) as response:
return json.load(response)

except urllib.error.HTTPError as error:
if error.code == 404 and attempt < max_attempts:
time.sleep(2)
continue

print(
"Warning: Dependency-Track analysis "
f"request failed with HTTP {error.code}."
)
return {}

except urllib.error.URLError:
print(
"Warning: Could not reach Dependency-Track."
)
return {}

return {}
Loading
Loading