Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 5 additions & 4 deletions .github/actions/scan-image/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ Input/output reference: [`action.yml`](./action.yml).
1. Builds and installs the `image-pipeline-evaluate` binary from this
repo (single-version contract — the action ref pins the evaluator
version).
2. Generates an SBOM with **Syft** (CycloneDX).
2. Downloads the configured VEX repositories and prepares the OpenVEX
documents for both scanners.
3. Runs **Trivy** secrets scan (no exception path — secrets fail
closed).
4. Runs **Trivy** vuln scan against the SBOM, with `--vex repo`
4. Runs **Trivy** vuln scan, with `--vex repo`
sourcing from `../../../vex/repository.yaml`.
5. Optionally runs **Grype** against the same SBOM (multi-scanner
coverage).
5. Optionally runs **Grype** with the same downloaded OpenVEX
documents (multi-scanner coverage).
6. Runs the evaluator against the merged findings + the consumer's
exception files; emits SARIF.
7. Uploads SARIF to GHAS Code Scanning (best-effort; failure does
Expand Down
47 changes: 44 additions & 3 deletions .github/actions/scan-image/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,40 @@ runs:
curl -sSfL "https://raw.githubusercontent.com/anchore/grype/${INSTALL_SHA}/install.sh" \
| sudo sh -s -- -b /usr/local/bin "v${GRYPE_VERSION}"

- name: Configure Trivy VEX repos
- name: Configure and download VEX repos
shell: bash
env:
REPO_ROOT: ${{ steps.paths.outputs.repo_root }}
GITHUB_TOKEN: ${{ github.token }}
run: |
mkdir -p ~/.trivy/vex
set -euo pipefail

mkdir -p ~/.trivy/vex reports
cp "${REPO_ROOT}/vex/repository.yaml" ~/.trivy/vex/repository.yaml

trivy vex repo download

vex_cache="${TRIVY_CACHE_DIR:-${HOME}/.cache/trivy}/vex/repositories"
if [ ! -d "${vex_cache}" ]; then
echo "::error::VEX repository cache was not created at ${vex_cache}"
exit 1
fi

: > reports/grype-vex-documents.txt
while IFS= read -r doc; do
if jq -e 'type == "object" and (.statements | type == "array")' "${doc}" >/dev/null 2>&1; then
printf '%s\n' "${doc}" >> reports/grype-vex-documents.txt
else
echo "::notice::Skipping non-OpenVEX JSON document for Grype: ${doc}"
fi
done < <(find "${vex_cache}" -type f -iname '*openvex*.json' | sort)
if [ ! -s reports/grype-vex-documents.txt ]; then
echo "::error::VEX repositories downloaded, but no OpenVEX documents were found for Grype"
exit 1
fi

echo "Prepared $(wc -l < reports/grype-vex-documents.txt | tr -d ' ') OpenVEX document(s) for Grype"

- name: Log in to source registry
if: ${{ inputs.source_registry != '' }}
shell: bash
Expand Down Expand Up @@ -152,6 +178,7 @@ runs:
--output reports/trivy.json \
--severity "${INPUT_SEVERITY}" \
--vex repo \
--skip-vex-repo-update \
--exit-code 0 \
"${INPUT_IMAGE}"
echo "::group::Trivy vuln report (table)"
Expand All @@ -164,8 +191,22 @@ runs:
env:
INPUT_IMAGE: ${{ inputs.image }}
run: |
set -euo pipefail

vex_args=()
while IFS= read -r doc; do
if [ -n "${doc}" ]; then
vex_args+=(--vex "${doc}")
fi
done < reports/grype-vex-documents.txt

if [ "${#vex_args[@]}" -eq 0 ]; then
echo "::error::No OpenVEX documents were prepared for Grype"
exit 1
fi

echo "::group::Grype vuln report (table)"
grype "${INPUT_IMAGE}" --by-cve -o table -o "json=reports/grype.json"
grype "${INPUT_IMAGE}" "${vex_args[@]}" --by-cve -o table -o "json=reports/grype.json"
echo "::endgroup::"

- name: Evaluate
Expand Down
Loading