The aquasecurity/trivy-action GitHub Action got compromised. I had 9+ repos running it on every PR and daily scans — all potentially exposed.
Here’s how I ripped it out and replaced it with something I control.
The Incident
Security advisories started flying about aquasecurity/trivy-action being compromised by an attacker. The repo was unstable for weeks — you couldn’t even trust pinning to a specific commit hash because the attacker had pushed malicious code to multiple refs.
Two options: wait for Aqua Security to fix it, or stop depending on it entirely.
What I Did
I built a composite GitHub Action that vendors the Trivy binary directly:
# .github/actions/trivy-scan/action.yml
runs:
using: composite
steps:
- name: Download Trivy
shell: bash
run: |
TRIVY_VERSION="${{ inputs.trivy-version }}"
curl -sfL "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz" \
| tar -xzf - -C /usr/local/bin trivy
- name: Run Scan
shell: bash
run: trivy ${{ inputs.scan-type }} ${{ inputs.target }} --format ${{ inputs.format }}
No third-party action. Download the binary from the official GitHub release (signed, checksummed), cache it, run it directly.
The Migration
Migrating 9 repos meant updating every workflow file. I added:
- Global kill switch — one toggle to disable all scans across repos
- Per-repo kill switch —
TRIVY_SCAN_ENABLEDvariable per repo - Discord notifications — scan results post to a shared channel
- Vulnerability tracker integration — findings uploaded for tracking
Each repo needed a PR to swap the action reference and update the input format. Some repos had custom trivy.yaml configs that needed adjusting because the old action passed arguments differently than the raw binary.
The Download URL Gotcha
One thing that wasted an hour: the Trivy release archive naming convention isn’t consistent. I initially used Linux-X64 in the URL, but the actual archive is named Linux-64bit. A subtle difference that produces a clean 404 with no helpful error message.
Takeaway
Third-party GitHub Actions are a supply chain risk. If an action runs on every PR across your repos, its compromise is your compromise. Vendoring the binary (downloading it yourself from a known release URL) removes the middleman entirely. The action’s convenience isn’t worth the blast radius.