Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4616c9f
Add reusable SBOM vulnerability workflow
TaniaGithub0401 Aug 11, 2026
803d0dd
Add SBOM workflow documentation
TaniaGithub0401 Aug 11, 2026
5027c8f
Upload vulnerability results to code scanning
TaniaGithub0401 Aug 17, 2026
078ce33
Retest reusable SBOM workflow
TaniaGithub0401 Aug 17, 2026
fa2175d
update readme SBOM vulnerability scan
TaniaGithub0401 Aug 17, 2026
9103001
Support Dockerfile and requirements inputs
TaniaGithub0401 Sep 1, 2026
feb6193
inspect sarif locations
TaniaGithub0401 Sep 1, 2026
ddefbbe
Fix SARIF locations for requirements scan
TaniaGithub0401 Sep 1, 2026
350d2fa
test python vulnerability scan
TaniaGithub0401 Sep 1, 2026
6ad5113
upload python vulnerability results to code scanning
TaniaGithub0401 Sep 1, 2026
2f9c2a5
add categories to vulnerabilities
TaniaGithub0401 Sep 1, 2026
fdd42de
add requirements-based SBOM and vulnerability scanning
TaniaGithub0401 Sep 1, 2026
0bd15ee
Update SBOM workflow documentation
TaniaGithub0401 Sep 1, 2026
86b7446
update SBOM documentation
TaniaGithub0401 Sep 1, 2026
22c00df
Compare Grype scan sources
TaniaGithub0401 Sep 8, 2026
c82350a
Summarize Docker scan comparison results
TaniaGithub0401 Sep 8, 2026
7cacccd
specific vulnerabilities
TaniaGithub0401 Sep 8, 2026
8246996
Propose SBOM vulnerability scan strategy
TaniaGithub0401 Sep 8, 2026
89a321f
Support pyproject.toml for Python scans
TaniaGithub0401 Sep 8, 2026
21cc822
Document pyproject.toml support
TaniaGithub0401 Sep 8, 2026
31dc63d
Make checkout fetch depth configurable
TaniaGithub0401 Sep 9, 2026
4447cec
Refine SBOM scan configuration and documentation
TaniaGithub0401 Sep 9, 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
125 changes: 125 additions & 0 deletions .github/workflows/sbom-vulnerability-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
name: SBOM Vulnerability Scan

on:
workflow_call:
inputs:
fetch_depth:
description: "Number of commits to fetch. Use 0 to fetch the full history and tags."
required: false
type: number
default: 1

dockerfile:
description: "Path to the Dockerfile"
required: false
type: string

requirements:
description: "Path to the requirements.txt file"
required: false
type: string

pyproject:
description: "Path to the pyproject.toml file"
required: false
type: string

fail-build:
description: "Fail the workflow when vulnerabilities above the severity cutoff are found"
required: false
default: false
type: boolean

jobs:
sbom-vulnerability-scan:
runs-on: ubuntu-latest

steps:
- name: Validate inputs
run: |
count=0

[ -n "${{ inputs.dockerfile }}" ] && count=$((count + 1))
[ -n "${{ inputs.requirements }}" ] && count=$((count + 1))
[ -n "${{ inputs.pyproject }}" ] && count=$((count + 1))

if [ "$count" -ne 1 ]; then
echo "Provide exactly one of: dockerfile, requirements, or pyproject."
exit 1
fi

- name: Checkout the code
uses: actions/checkout@v7
with:
fetch-depth: ${{ inputs.fetch_depth }}

# Docker
- name: Build the Docker image
if: inputs.dockerfile != ''
run: docker build . --file "${{ inputs.dockerfile }}" --tag localbuild/testimage:latest

- name: Generate SBOM from Docker image
if: inputs.dockerfile != ''
uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0
with:
image: localbuild/testimage:latest
artifact-name: docker.cyclonedx.json
output-file: docker.cyclonedx.json
format: cyclonedx-json

- name: Scan Docker SBOM for vulnerabilities
if: inputs.dockerfile != ''
id: docker-vulnerability-scan
uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2
with:
sbom: docker.cyclonedx.json
fail-build: ${{ inputs.fail-build }}
output-format: sarif

- name: Upload Docker vulnerability results to GitHub Security
if: inputs.dockerfile != ''
uses: github/codeql-action/upload-sarif@24ea975727876cf496b1eb0c5b36e96e01600b51 # v4.37.0
with:
sarif_file: ${{ steps.docker-vulnerability-scan.outputs.sarif }}
category: grype-docker

# Python
- name: Create Python environment from requirements
if: inputs.requirements != ''
run: |
python -m venv .venv
.venv/bin/pip install -r "${{ inputs.requirements }}"

- name: Create Python environment from pyproject
if: inputs.pyproject != ''
run: |
python -m venv .venv
.venv/bin/pip install .

- name: Generate SBOM from Python environment
if: inputs.requirements != '' || inputs.pyproject != ''
uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0
with:
path: .venv
artifact-name: python.cyclonedx.json
output-file: python.cyclonedx.json
format: cyclonedx-json

- name: Scan Python environment for vulnerabilities
if: inputs.requirements != '' || inputs.pyproject != ''
id: python-vulnerability-scan
uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2
with:
# Scan the .venv directly instead of the generated SBOM because
# the SBOM scan produced empty SARIF artifact locations, while
# the direct .venv scan provides valid locations for GitHub Code Scanning.
path: .venv
fail-build: ${{ inputs.fail-build }}
output-format: sarif

- name: Upload Python vulnerability results to GitHub Security
if: inputs.requirements != '' || inputs.pyproject != ''
uses: github/codeql-action/upload-sarif@24ea975727876cf496b1eb0c5b36e96e01600b51 # v4.37.0
with:
sarif_file: ${{ steps.python-vulnerability-scan.outputs.sarif }}
category: grype-python
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,61 @@ jobs:
secrets:
PYPI_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
```
## SBOM Vulnerability Scan

The SBOM vulnerability scan workflow generates a CycloneDX SBOM and scans
dependencies for known vulnerabilities with Grype. The workflow can be used
with a Dockerfile, a `requirements.txt` file, or a `pyproject.toml` file.

For Docker-based projects, Grype scans the SBOM generated from the Docker image.
For Python projects, a virtual environment is created from either
`requirements.txt` or `pyproject.toml`. Grype scans the virtual environment
directly because this provides valid SARIF artifact locations for GitHub Code
Scanning.

The vulnerability results are uploaded to GitHub Code Scanning.

You can use it e.g. like this:

```yaml
name: SBOM Vulnerability Scan

on:
push:
branches: [ "main" ]

jobs:
sbom-scan:
permissions:
contents: read
security-events: write

uses: mundialis/github-workflows/.github/workflows/sbom-vulnerability-scan.yml@main
with:
dockerfile: docker/actinia-core-alpine/Dockerfile
# requirements: requirements.txt
# pyproject: pyproject.toml
```

Provide exactly one of the following inputs:

- `dockerfile`: Path to the Dockerfile.
- `requirements`: Path to the requirements.txt file.
- `pyproject`: Path to the pyproject.toml file.

The calling job requires the following permissions:

- `contents: read` to check out the repository.
- `security-events: write` to upload the vulnerability results to GitHub Code Scanning.

Optional inputs:
- `fetch_depth`: Number of commits to fetch during checkout. Use `0` to fetch the full history and tags. Default: `1`.
- `fail-build`: Set to `true` if the workflow should fail when vulnerabilities above the severity
cutoff are found. Default: `false`.

The generated Docker or Python SBOM is uploaded as a workflow artifact.

The vulnerability results are available under **Security and quality** → **Code scanning**.

# pre-commit

Expand Down
Loading