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
|
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
|
- name: Scan candidate for high and critical vulnerabilities
|
||||||
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0, post-incident safe SHA
|
shell: bash
|
||||||
with:
|
run: |
|
||||||
image-ref: git.finalfactory.de/heikyu/rendezvous:${{ env.RENDEZVOUS_VERSION }}
|
set -euo pipefail
|
||||||
version: v0.69.3
|
# Unfixed vulnerabilities stay in scope: the flag that would drop them
|
||||||
format: table
|
# is never passed, so the gate keeps trivy's fail-closed default.
|
||||||
exit-code: "1"
|
"$RENDEZVOUS_TRIVY" image \
|
||||||
ignore-unfixed: false
|
--exit-code 1 \
|
||||||
severity: HIGH,CRITICAL
|
--severity HIGH,CRITICAL \
|
||||||
|
--format table \
|
||||||
|
"git.finalfactory.de/heikyu/rendezvous:${RENDEZVOUS_VERSION}"
|
||||||
|
|
||||||
- name: Generate container SPDX inventory
|
- name: Generate container SPDX inventory
|
||||||
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0, post-incident safe SHA
|
shell: bash
|
||||||
with:
|
run: |
|
||||||
image-ref: git.finalfactory.de/heikyu/rendezvous:${{ env.RENDEZVOUS_VERSION }}
|
set -euo pipefail
|
||||||
version: v0.69.3
|
"$RENDEZVOUS_TRIVY" image \
|
||||||
format: spdx-json
|
--format spdx-json \
|
||||||
output: ${{ env.RENDEZVOUS_RELEASE_DIR }}/FinalFactory.Rendezvous.Container.${{ env.RENDEZVOUS_VERSION }}.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
|
- name: Finalize checksums over the publish-ready candidate
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
@@ -86,8 +86,25 @@ public sealed class ReleaseCompatibilityTests
|
|||||||
Assert.DoesNotContain("skip-duplicate", workflow, StringComparison.OrdinalIgnoreCase);
|
Assert.DoesNotContain("skip-duplicate", workflow, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("check-compatibility.sh", workflow, StringComparison.Ordinal);
|
Assert.Contains("check-compatibility.sh", workflow, StringComparison.Ordinal);
|
||||||
Assert.Contains("--platform linux/amd64", workflow, StringComparison.Ordinal);
|
Assert.Contains("--platform linux/amd64", workflow, StringComparison.Ordinal);
|
||||||
Assert.Contains("ignore-unfixed: false", workflow, StringComparison.Ordinal);
|
Assert.DoesNotContain("aquasecurity/trivy-action", workflow, StringComparison.Ordinal);
|
||||||
Assert.Contains("format: spdx-json", 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("normalize-container-sbom", workflow, StringComparison.Ordinal);
|
||||||
Assert.Contains("finalize-release-candidate.sh", workflow, StringComparison.Ordinal);
|
Assert.Contains("finalize-release-candidate.sh", workflow, StringComparison.Ordinal);
|
||||||
Assert.Contains("verify-real-consumers.sh", workflow, StringComparison.Ordinal);
|
Assert.Contains("verify-real-consumers.sh", workflow, StringComparison.Ordinal);
|
||||||
|
|||||||
Reference in New Issue
Block a user