ci: pin actions to commit SHAs, guard Docker jobs from forks, scan the image, gate publish on security (SEC-06, SEC-07, SEC-14, SEC-15, SEC-16)

This commit is contained in:
Latte committed 2026-10-14 17:40:16 +02:00
1 parent 6f7a3c0e5b
commit 766968fa42
9 files changed
+679 -60

No files matched your search

+23 -7
View File
@@ -8,8 +8,12 @@
# * per-run networks named aegis-it-* that the job container is attached to
# (the integration harness joins the job container to its own per-run
# network only), plus the containers still attached to those networks;
# * containers started from the exact image refs given as arguments;
# * the exact image refs given as arguments.
# * containers started from the per-run image refs given as arguments, and
# those refs. Per-run refs are names containing "aegis-ci-" (named after the
# run id) and immutable ":sha-<commit>" tags;
# * for any other ref (shared tags such as :latest, :main, :dev, which a
# deployment on the same daemon may use) only the tag is removed. Containers
# are never touched, and an image still used by a container simply stays.
# Everything is best effort (a failing removal never fails the job).
set -uo pipefail
@@ -40,12 +44,24 @@ if [ -n "${job_ref}" ] && docker container inspect "${job_ref}" > /dev/null 2>&1
done
fi
is_per_run_ref() {
case "$1" in
*aegis-ci-* | *:sha-*) return 0 ;;
*) return 1 ;;
esac
}
for image in "$@"; do
for cid in $(docker ps -aq --filter "ancestor=${image}" 2> /dev/null); do
docker rm -f -v "${cid}" > /dev/null 2>&1 || true
done
docker rmi "${image}" > /dev/null 2>&1 || true
echo "removed image ${image}"
if is_per_run_ref "${image}"; then
for cid in $(docker ps -aq --filter "ancestor=${image}" 2> /dev/null); do
docker rm -f -v "${cid}" > /dev/null 2>&1 || true
done
docker rmi "${image}" > /dev/null 2>&1 || true
echo "removed image ${image}"
else
docker image rm "${image}" > /dev/null 2>&1 || true
echo "untagged shared ref ${image}"
fi
done
exit 0
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Install a pinned Trivy release into a directory, verifying its sha256.
#
# Usage: scripts/ci/install_trivy.sh <dest-dir>
#
# The binary ends up at <dest-dir>/trivy. To upgrade, bump TRIVY_VERSION and both
# digests from the release's trivy_<version>_checksums.txt.
set -euo pipefail
TRIVY_VERSION="0.76.0"
SHA256_X64="e24b1c51293c1b15e4ba8d45bbc7891ba053f90278ec2698f3562c993e145fe7"
SHA256_ARM64="aab21e677a7b7071fc79f1711480840754c18a1b9d9cefa7ccd06af63a0e8f4c"
dest="${1:?usage: install_trivy.sh <dest-dir>}"
case "$(uname -m)" in
x86_64 | amd64)
arch="64bit"
expected="${SHA256_X64}"
;;
aarch64 | arm64)
arch="ARM64"
expected="${SHA256_ARM64}"
;;
*)
echo "unsupported architecture: $(uname -m)" >&2
exit 1
;;
esac
archive="trivy_${TRIVY_VERSION}_Linux-${arch}.tar.gz"
url="https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/${archive}"
work="$(mktemp -d)"
trap 'rm -rf "${work}"' EXIT
curl --fail --silent --show-error --location --retry 3 --output "${work}/${archive}" "${url}"
echo "${expected} ${work}/${archive}" | sha256sum --check --status || {
echo "sha256 mismatch for ${archive}" >&2
exit 1
}
mkdir -p "${dest}"
tar -xzf "${work}/${archive}" -C "${dest}" trivy
chmod 0755 "${dest}/trivy"
"${dest}/trivy" version
+39
View File
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Scan a locally built image for known vulnerabilities with Trivy.
#
# Usage: scripts/ci/scan_image.sh <image-ref>
#
# Fails (exit 1) on HIGH or CRITICAL findings that have a fixed version. Findings
# without a fix are reported by Trivy but do not fail the scan (nothing can be done
# about them yet). Accepted findings are listed in security/trivyignore.txt, one
# vulnerability id per line with a reason, and in docs/security.md. The image is
# exported with `docker save` so Trivy needs no access to the Docker socket.
#
# Trivy itself is pinned (scripts/ci/install_trivy.sh); its vulnerability database
# is fetched fresh on every run, which is the point of scanning.
set -euo pipefail
image="${1:?usage: scan_image.sh <image-ref>}"
ignore_file="security/trivyignore.txt"
work="$(mktemp -d)"
trap 'rm -rf "${work}"' EXIT
docker save --output "${work}/image.tar" "${image}"
args=(
image
--input "${work}/image.tar"
--cache-dir "${work}/cache"
--scanners vuln
--severity HIGH,CRITICAL
--ignore-unfixed
--exit-code 1
--no-progress
--db-repository "ghcr.io/aquasecurity/trivy-db:2,public.ecr.aws/aquasecurity/trivy-db:2"
)
if [ -f "${ignore_file}" ]; then
args+=(--ignorefile "${ignore_file}")
fi
trivy "${args[@]}"