Skip to content

fix(vhd-scanning): install trivy via PMC with GitHub fallback for unsupported SKUs#8248

Open
djsly wants to merge 7 commits intomainfrom
djsly/37444537
Open

fix(vhd-scanning): install trivy via PMC with GitHub fallback for unsupported SKUs#8248
djsly wants to merge 7 commits intomainfrom
djsly/37444537

Conversation

@djsly
Copy link
Copy Markdown
Collaborator

@djsly djsly commented Apr 7, 2026

trivy-scan.sh downloaded trivy directly from GitHub releases with a hardcoded TRIVY_VERSION=0.69.2, bypassing package management and subject to rate limiting.

Changes

  • PMC install for Ubuntu: adds Microsoft PMC prod repo (packages.microsoft.com/ubuntu/${os_version}/prod) with modern gpg --dearmor + signed-by= keyring; GPG key download wrapped in retrycmd_if_failure
  • PMC install for AzureLinux: delegates to sourced dnf_install (from cse_helpers_mariner.sh via provision_source_distro.sh) which includes dnf_makecache on retry
  • GitHub fallback for SKUs without PMC packages (CBLMariner, Flatcar, AzureContainerLinux, AzureLinuxOSGuard): preserves original curl/tar flow, version configurable via TRIVY_VERSION env var (default 0.69.2)
  • Scan invocations changed from ./trivytrivy; rm -f ./trivy at end is a no-op for PMC installs, cleanup for fallback
install_trivy() {
    case "$os_sku" in
        Ubuntu)      # apt via PMC prod repo + gpg --dearmor keyring
        AzureLinux)  # dnf_install 5 1 60 trivy  (sourced, includes makecache)
        *)           # GitHub release download (CBLMariner, Flatcar, ACL, OSGuard)
    esac
}

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the VHD post-build scanning script to stop downloading Trivy from GitHub releases and instead install it via the OS package manager (PMC-backed), then run scans using the system trivy binary.

Changes:

  • Removed hardcoded Trivy version/arch and the GitHub curl/tar install flow.
  • Added install_trivy() to install Trivy via apt (Ubuntu) or dnf (AzureLinux/Mariner).
  • Switched scan invocations from ./trivy to trivy and removed the local binary cleanup.

Replace the direct GitHub curl download of trivy with OS-native package
manager install (apt-get for Ubuntu, dnf for AzureLinux/Mariner).

Changes:
- Remove hardcoded TRIVY_VERSION and TRIVY_ARCH variables
- Add install_trivy() function using OS package managers (PMC)
- Replace ./trivy references with trivy (installed to PATH)
- Remove manual binary cleanup (rm ./trivy)
- Keep GO_ARCH detection for vuln-to-kusto-vhd binary

This eliminates GitHub rate-limiting issues and manual version bumps,
leveraging the trivy packages already available on PMC.

AB#37444537

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Ubuntu: install from PMC prod repo (deb packages)
- AzureLinux: install from PMC via dnf (azlinux3 RPMs)
- CBLMariner, Flatcar, AzureContainerLinux, AzureLinuxOSGuard:
  fall back to GitHub release download (no PMC packages available)
- Restore rm -f ./trivy cleanup for the GitHub fallback path

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 7, 2026 23:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.

- GitHub fallback: wrap curl with retrycmd_if_failure 5 10 60
- AzureLinux: add dnf_install helper with retry/timeout (matches
  apt_get_install pattern)
- Ubuntu: already uses apt_get_install with retries

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Ubuntu: replace deprecated apt-key with gpg --dearmor + signed-by
- Ubuntu: use /etc/os-release instead of lsb_release for codename
- Ubuntu: ensure ca-certificates, curl, gnupg are installed first
- GitHub fallback: make version configurable via TRIVY_VERSION env var

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 8, 2026 01:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.

- Remove local dnf_install() that shadowed the already-sourced helper
  from provision_source_distro.sh (cse_helpers_mariner.sh), which includes
  dnf_makecache on retry for better reliability
- Wrap Ubuntu GPG key download with retrycmd_if_failure for network
  resilience (curl to temp file, then gpg --dearmor)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@djsly
Copy link
Copy Markdown
Collaborator Author

djsly commented Apr 8, 2026

@copilot can you review

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 8, 2026

@copilot can you review

The current state of the code looks good to me. Here's my review summary:

✅ All CI checks passing (validate-pull-request-source, golangci-lint, Lint Shell/Bash Scripts, Go Unit Tests, Shell/Bash Script Unit Tests, Validate Components, etc.)

✅ No new shellcheck issues — the only warnings (SC2034 BLOB_URL unused, SC2068/SC2145 in the pre-existing retrycmd_if_failure echo) are all pre-existing.

dnf_install 5 1 60 trivy correctly uses the function sourced from provision_source_distro.shcse_helpers_mariner.sh, which has the expected signature retries wait_sleep timeout ...packages and calls dnf_makecache on retry.

✅ Ubuntu PMC path — uses modern gpg --dearmor + signed-by= approach; gnupg installed before use; /etc/apt/keyrings created idempotently; GPG key download wrapped in retrycmd_if_failure 5 10 60.

✅ GitHub fallbacktrivy binary extracted to $(pwd)/trivy; export PATH="$(pwd):$PATH" at line 211 makes it resolvable as trivy for all scan commands; TRIVY_VERSION is configurable via env var (defaults to 0.69.2); rm -f ./trivy at the end is a safe no-op for PMC installs and cleans up the GitHub-downloaded binary.

repo_codename detection via ${UBUNTU_CODENAME:-$VERSION_CODENAME} from /etc/os-release handles all supported Ubuntu versions (20.04/22.04/24.04).

No issues found — LGTM! 🚀

Copilot AI changed the title fix(vhd-scanning): install trivy from PMC instead of GitHub download fix(vhd-scanning): install trivy via PMC with GitHub fallback for unsupported SKUs Apr 8, 2026
Copilot finished work on behalf of djsly April 8, 2026 01:28
The VHD base image may ship with a stale Microsoft signing key after
PMC key rotations, causing apt-get update to fail with NO_PUBKEY
EB3E94ADBE1229CF. This affects both install_azure_cli and install_trivy.

Fix: download and install the latest microsoft.asc key to both
/etc/apt/trusted.gpg.d/ (for repos without signed-by) and
/etc/apt/keyrings/ (for repos with signed-by directive) before any
apt operations. Also simplify install_trivy to skip redundant key
import since the key is already refreshed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 9, 2026 01:25
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.

Comment on lines +129 to +141
# For Ubuntu, refresh the Microsoft GPG signing key before any apt operations.
# The VHD base image may ship with a stale key after PMC key rotations,
# causing apt-get update to fail with NO_PUBKEY errors.
if [ "$OS_SKU" = "Ubuntu" ]; then
echo "Refreshing Microsoft GPG signing keys"
retrycmd_if_failure 5 10 60 curl -fsSL -o /tmp/microsoft.asc https://packages.microsoft.com/keys/microsoft.asc
# trusted.gpg.d covers repos configured without a signed-by directive
cat /tmp/microsoft.asc | sudo gpg --yes --dearmor -o /etc/apt/trusted.gpg.d/microsoft.gpg
sudo chmod 644 /etc/apt/trusted.gpg.d/microsoft.gpg
# keyrings covers repos configured with signed-by=/etc/apt/keyrings/microsoft.gpg
sudo install -d -m 0755 /etc/apt/keyrings
cat /tmp/microsoft.asc | sudo gpg --yes --dearmor -o /etc/apt/keyrings/microsoft.gpg
sudo chmod 644 /etc/apt/keyrings/microsoft.gpg
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Ubuntu key refresh block assumes curl, gpg, and sudo are available and uses sudo even though this script is typically executed as root via az vm run-command. This introduces a new hard dependency for the Ubuntu 22.04 arm64 path (which installs Azure CLI via pip and doesn’t otherwise ensure these tools exist).

Consider (a) using a SUDO wrapper that’s empty when running as root / when sudo isn’t present, and (b) adding explicit preflight checks with a clear error if curl/gpg are missing (or a fallback download mechanism) so scans fail with an actionable message instead of a generic command-not-found.

Suggested change
# For Ubuntu, refresh the Microsoft GPG signing key before any apt operations.
# The VHD base image may ship with a stale key after PMC key rotations,
# causing apt-get update to fail with NO_PUBKEY errors.
if [ "$OS_SKU" = "Ubuntu" ]; then
echo "Refreshing Microsoft GPG signing keys"
retrycmd_if_failure 5 10 60 curl -fsSL -o /tmp/microsoft.asc https://packages.microsoft.com/keys/microsoft.asc
# trusted.gpg.d covers repos configured without a signed-by directive
cat /tmp/microsoft.asc | sudo gpg --yes --dearmor -o /etc/apt/trusted.gpg.d/microsoft.gpg
sudo chmod 644 /etc/apt/trusted.gpg.d/microsoft.gpg
# keyrings covers repos configured with signed-by=/etc/apt/keyrings/microsoft.gpg
sudo install -d -m 0755 /etc/apt/keyrings
cat /tmp/microsoft.asc | sudo gpg --yes --dearmor -o /etc/apt/keyrings/microsoft.gpg
sudo chmod 644 /etc/apt/keyrings/microsoft.gpg
require_command() {
local cmd="$1"
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "required command '$cmd' is not installed or not in PATH"
exit 1
fi
}
get_sudo_wrapper() {
if [ "$(id -u)" -eq 0 ]; then
echo ""
elif command -v sudo >/dev/null 2>&1; then
echo "sudo"
else
echo "sudo is required to write Microsoft apt keys when not running as root" >&2
exit 1
fi
}
# For Ubuntu, refresh the Microsoft GPG signing key before any apt operations.
# The VHD base image may ship with a stale key after PMC key rotations,
# causing apt-get update to fail with NO_PUBKEY errors.
if [ "$OS_SKU" = "Ubuntu" ]; then
SUDO="$(get_sudo_wrapper)"
require_command curl
require_command gpg
echo "Refreshing Microsoft GPG signing keys"
retrycmd_if_failure 5 10 60 curl -fsSL -o /tmp/microsoft.asc https://packages.microsoft.com/keys/microsoft.asc
# trusted.gpg.d covers repos configured without a signed-by directive
cat /tmp/microsoft.asc | ${SUDO:+$SUDO }gpg --yes --dearmor -o /etc/apt/trusted.gpg.d/microsoft.gpg
${SUDO:+$SUDO }chmod 644 /etc/apt/trusted.gpg.d/microsoft.gpg
# keyrings covers repos configured with signed-by=/etc/apt/keyrings/microsoft.gpg
${SUDO:+$SUDO }install -d -m 0755 /etc/apt/keyrings
cat /tmp/microsoft.asc | ${SUDO:+$SUDO }gpg --yes --dearmor -o /etc/apt/keyrings/microsoft.gpg
${SUDO:+$SUDO }chmod 644 /etc/apt/keyrings/microsoft.gpg

Copilot uses AI. Check for mistakes.
Comment on lines +159 to +163
retrycmd_if_failure 5 10 60 curl -fL -o "trivy_${trivy_version}_${trivy_arch}.tar.gz" \
"https://github.com/aquasecurity/trivy/releases/download/v${trivy_version}/trivy_${trivy_version}_${trivy_arch}.tar.gz"
tar -xzf "trivy_${trivy_version}_${trivy_arch}.tar.gz" --no-same-owner trivy
rm "trivy_${trivy_version}_${trivy_arch}.tar.gz"
chmod a+x trivy
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GitHub fallback downloads and executes a Trivy tarball without any integrity verification (checksum/signature). Since this runs with elevated privileges during image scanning, it’s a supply-chain risk.

If the fallback must remain, consider validating the downloaded artifact (e.g., pinned SHA256 per version/arch, or verifying upstream signatures with a pinned public key) before extracting/executing it.

Copilot uses AI. Check for mistakes.
The VHD build already installs packages-microsoft-prod.deb which
configures the PMC repo and signing keys. No need to import keys
or add repo entries manually — just apt_get_update + apt_get_install.

The GPG error in the prior run was a transient PMC key rotation issue.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants