fix(release): run trivy from a pinned verified binary (#1)
trivy-action checks its own repository out of github.com using the runner token; on this self-hosted Gitea that token is a Gitea token, GitHub answers "Bad credentials", and both scan steps die before trivy is installed. Download the v0.69.3 release archive directly, verify it against a sha256 digest pinned inline, and unpack only the binary into .release-work/bin, which is gitignored and excluded from the Docker build context. The gate keeps its exact semantics: --exit-code 1, --severity HIGH,CRITICAL, table output, unfixed vulnerabilities still in scope. The SPDX step writes the same filename release_artifacts.py normalize-container-sbom consumes, and TRIVY_CACHE_DIR keeps the vulnerability DB inside the work directory.
This commit is contained in:
@@ -196,23 +196,52 @@ jobs:
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Install pinned vulnerability scanner
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# trivy-action checks its own repository out of github.com with the
|
||||
# runner token, which this Gitea instance cannot mint, so the release
|
||||
# binary is fetched directly instead. The archive URL and its digest
|
||||
# are pinned inline: fetching the published checksums file at run time
|
||||
# would only prove the asset matches whatever the release currently
|
||||
# serves, which is exactly what pinning has to rule out.
|
||||
trivy_bin_dir="$RENDEZVOUS_WORK_DIR/bin"
|
||||
trivy_archive="$RENDEZVOUS_WORK_DIR/trivy_0.69.3_Linux-64bit.tar.gz"
|
||||
# .release-work is gitignored and excluded from the Docker build
|
||||
# context, so nothing unpacked here can reach an image layer.
|
||||
mkdir -p "$trivy_bin_dir" "$RENDEZVOUS_WORK_DIR/trivy-cache"
|
||||
curl --fail --location --silent --show-error --output "$trivy_archive" \
|
||||
https://github.com/aquasecurity/trivy/releases/download/v0.69.3/trivy_0.69.3_Linux-64bit.tar.gz
|
||||
echo "1816b632dfe529869c740c0913e36bd1629cb7688bd5634f4a858c1d57c88b75 $trivy_archive" \
|
||||
| sha256sum --check --strict -
|
||||
tar --extract --file "$trivy_archive" --directory "$trivy_bin_dir" trivy
|
||||
rm -f "$trivy_archive"
|
||||
chmod +x "$trivy_bin_dir/trivy"
|
||||
echo "RENDEZVOUS_TRIVY=$trivy_bin_dir/trivy" >>"$GITHUB_ENV"
|
||||
echo "TRIVY_CACHE_DIR=$RENDEZVOUS_WORK_DIR/trivy-cache" >>"$GITHUB_ENV"
|
||||
"$trivy_bin_dir/trivy" --version
|
||||
|
||||
- name: Scan candidate for high and critical vulnerabilities
|
||||
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0, post-incident safe SHA
|
||||
with:
|
||||
image-ref: git.finalfactory.de/heikyu/rendezvous:${{ env.RENDEZVOUS_VERSION }}
|
||||
version: v0.69.3
|
||||
format: table
|
||||
exit-code: "1"
|
||||
ignore-unfixed: false
|
||||
severity: HIGH,CRITICAL
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Unfixed vulnerabilities stay in scope: the flag that would drop them
|
||||
# is never passed, so the gate keeps trivy's fail-closed default.
|
||||
"$RENDEZVOUS_TRIVY" image \
|
||||
--exit-code 1 \
|
||||
--severity HIGH,CRITICAL \
|
||||
--format table \
|
||||
"git.finalfactory.de/heikyu/rendezvous:${RENDEZVOUS_VERSION}"
|
||||
|
||||
- name: Generate container SPDX inventory
|
||||
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0, post-incident safe SHA
|
||||
with:
|
||||
image-ref: git.finalfactory.de/heikyu/rendezvous:${{ env.RENDEZVOUS_VERSION }}
|
||||
version: v0.69.3
|
||||
format: spdx-json
|
||||
output: ${{ env.RENDEZVOUS_RELEASE_DIR }}/FinalFactory.Rendezvous.Container.${{ env.RENDEZVOUS_VERSION }}.spdx.json
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
"$RENDEZVOUS_TRIVY" image \
|
||||
--format spdx-json \
|
||||
--output "$RENDEZVOUS_RELEASE_DIR/FinalFactory.Rendezvous.Container.$RENDEZVOUS_VERSION.spdx.json" \
|
||||
"git.finalfactory.de/heikyu/rendezvous:${RENDEZVOUS_VERSION}"
|
||||
|
||||
- name: Finalize checksums over the publish-ready candidate
|
||||
shell: bash
|
||||
|
||||
@@ -86,8 +86,25 @@ public sealed class ReleaseCompatibilityTests
|
||||
Assert.DoesNotContain("skip-duplicate", workflow, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.Contains("check-compatibility.sh", workflow, StringComparison.Ordinal);
|
||||
Assert.Contains("--platform linux/amd64", workflow, StringComparison.Ordinal);
|
||||
Assert.Contains("ignore-unfixed: false", workflow, StringComparison.Ordinal);
|
||||
Assert.Contains("format: spdx-json", workflow, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("aquasecurity/trivy-action", workflow, StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"https://github.com/aquasecurity/trivy/releases/download/v0.69.3/trivy_0.69.3_Linux-64bit.tar.gz",
|
||||
workflow,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"1816b632dfe529869c740c0913e36bd1629cb7688bd5634f4a858c1d57c88b75",
|
||||
workflow,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("sha256sum --check --strict", workflow, StringComparison.Ordinal);
|
||||
Assert.Contains("TRIVY_CACHE_DIR=$RENDEZVOUS_WORK_DIR/trivy-cache", workflow, StringComparison.Ordinal);
|
||||
Assert.Contains("--exit-code 1", workflow, StringComparison.Ordinal);
|
||||
Assert.Contains("--severity HIGH,CRITICAL", workflow, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("--ignore-unfixed", workflow, StringComparison.Ordinal);
|
||||
Assert.Contains("--format spdx-json", workflow, StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"--output \"$RENDEZVOUS_RELEASE_DIR/FinalFactory.Rendezvous.Container.$RENDEZVOUS_VERSION.spdx.json\"",
|
||||
workflow,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("normalize-container-sbom", workflow, StringComparison.Ordinal);
|
||||
Assert.Contains("finalize-release-candidate.sh", workflow, StringComparison.Ordinal);
|
||||
Assert.Contains("verify-real-consumers.sh", workflow, StringComparison.Ordinal);
|
||||
|
||||
Reference in New Issue
Block a user