fix(ci): replace trivy-action with manual curl install
CI / commits (pull_request) Successful in 1m36s
CI / check (pull_request) Successful in 1m46s
CI / scan (pull_request) Failing after 3m34s
CI / a11y (pull_request) Successful in 2m5s
CI / perf (pull_request) Successful in 3m17s

Setting `GITHUB_TOKEN` env on `aquasecurity/trivy-action@master` did
not authenticate the github.com clone (#44 attempted that). Reason:
the action wraps `actions/checkout`, whose `with.token` input
defaults to `${{ github.token }}` (Gitea's auto-token, not our
github.com PAT), and that input wins over the GITHUB_TOKEN env
variable. The clone keeps hitting the anonymous rate limit.

Rather than chase the action's internals (INPUT_TOKEN tricks, git
config insteadOf, etc.), drop the wrapper entirely and install
Trivy directly via `curl + tar` from the GitHub release artefact.

Side benefits:
- Pinned version (`TRIVY_VERSION=0.70.0`) — no more `@master`,
  which is itself an anti-pattern (moving target, surprise breaking
  changes are exactly what bit us in #43).
- Predictable behaviour, fewer indirections to debug.
- GITHUBCOM_TOKEN passed as Bearer header on the curl — handles
  the rate limit on release downloads as defence-in-depth (release
  artefacts are usually unmetered, but the auth is free).

Trivy version bumps are now manual (Renovate cannot track this pin
out of the box). A custom regex manager in renovate.json could be
added later if the cadence justifies it; for now manual review of
https://github.com/aquasecurity/trivy/releases is fine.
This commit is contained in:
Julien Gautier
2026-05-06 23:58:32 +02:00
parent 6153c81602
commit 3172c0353b
+42 -18
View File
@@ -63,27 +63,51 @@ jobs:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
- run: pnpm install --frozen-lockfile - run: pnpm install --frozen-lockfile
- run: pnpm ci:audit - run: pnpm ci:audit
# Dependency vulnerability scan (binary tool, invoked via official # Dependency vulnerability scan. Trivy is a Go binary, not an npm
# action — Trivy is a Go binary, not an npm package, so it cannot # package, so it cannot live in package.json scripts as cleanly
# live in package.json scripts as cleanly as audit/lint do). # as audit/lint do.
# #
# On cache miss (the act_runner cache server is currently # We deliberately avoid `aquasecurity/trivy-action`. On cache
# unreachable from job containers — see infra/README.md "Cache # miss (our act_runner cache server is unreachable from job
# server (deferred)"), the action falls back to `git clone # containers — see infra/README.md "Cache server (deferred)"),
# https://github.com/aquasecurity/trivy` to fetch its install # the action falls back to `git clone github.com/aquasecurity/
# script. Without auth that hits github.com's 60 req/h anonymous # trivy` to fetch its install script, using `actions/checkout`
# rate limit and `git fetch` fails with "could not read Username". # which defaults `with.token` to `${{ github.token }}` (Gitea's
# GITHUBCOM_TOKEN is the same zero-scope github.com PAT we use # auto-token, useless for github.com). The clone hits the
# for Renovate (per docs/development.md "Dependency updates"). # anonymous github.com rate limit and fails with "could not
- uses: aquasecurity/trivy-action@master # read Username". Passing GITHUB_TOKEN as an env var doesn't
with: # help — actions/checkout reads it from `inputs.token`, not env.
scan-type: fs #
ignore-unfixed: true # Direct curl + tar is simpler, predictable, and gives us an
skip-dirs: node_modules # explicit version pin instead of `@master`. GITHUBCOM_TOKEN is
exit-code: '1' # passed to handle the github.com rate limit on the release
severity: 'CRITICAL,HIGH' # download in the worst case (release artefacts are usually
# unmetered, but auth is free insurance).
- name: Install Trivy
env: env:
# Bump deliberately when a security advisory or new feature
# warrants it. Renovate cannot manage this pin out of the
# box (it is not a package-manager-tracked dep); a custom
# regex manager could be added later if the cadence justifies
# it. For now, manual updates from
# https://github.com/aquasecurity/trivy/releases.
TRIVY_VERSION: '0.70.0'
GITHUB_TOKEN: ${{ secrets.GITHUBCOM_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUBCOM_TOKEN }}
run: |
curl -sfL \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-o /tmp/trivy.tar.gz \
"https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz"
tar -xzf /tmp/trivy.tar.gz -C /usr/local/bin trivy
trivy --version
- name: Run Trivy
run: |
trivy fs \
--ignore-unfixed \
--skip-dirs node_modules \
--exit-code 1 \
--severity CRITICAL,HIGH \
.
# Secret scan, same reasoning (gitleaks is a Go binary). # Secret scan, same reasoning (gitleaks is a Go binary).
- uses: gitleaks/gitleaks-action@v2 - uses: gitleaks/gitleaks-action@v2
env: env: