From 57a08c3b7186285ba9cda900232bf50b243fd2ef Mon Sep 17 00:00:00 2001 From: julien Date: Thu, 7 May 2026 00:17:13 +0200 Subject: [PATCH] fix(ci): replace trivy-action with manual curl install (#45) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary PR #44's `GITHUB_TOKEN` env injection didn't actually authenticate the github.com clone. Root cause: `aquasecurity/trivy-action` wraps `actions/checkout`, whose `with.token` input defaults to `${{ github.token }}` (Gitea's auto-token, useless against github.com), and that wins over our env var. The clone keeps hitting the anonymous rate limit. Rather than fight the action's internals (`INPUT_TOKEN` overrides, `git config insteadOf` injection, etc.), drop it and install Trivy directly via `curl + tar` from the GitHub release artefact. ## Side benefits - **Version pinned** (`TRIVY_VERSION=0.70.0`) — no more `@master`. Moving-target tags are exactly what bit us in #43 (the TS6 / ESLint10 / webpack-cli7 mess); not adding a new instance of the same anti-pattern. - **Predictable** — straight curl + tar, no third-party action indirection to debug. - `GITHUBCOM_TOKEN` passed as Bearer header on the curl — defensive: release artefact downloads are usually unmetered, but auth is free insurance against rate-limit surprises. ## Trade-off Trivy version bumps become manual. Renovate can't 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 [Trivy releases](https://github.com/aquasecurity/trivy/releases) every few months is acceptable. ## Test plan - [ ] `scan` job goes green on this PR — both `Install Trivy` and `Run Trivy` steps succeed. - [ ] `trivy --version` in the install step's logs reports `0.70.0`. - [ ] No regression on the `pnpm ci:audit` or `gitleaks` sub-steps of `scan`. - [ ] On `push` to main post-merge, scan stays green. --------- Co-authored-by: Julien Gautier Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/45 --- .gitea/workflows/ci.yml | 60 ++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 885224d..124c794 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -63,27 +63,51 @@ jobs: node-version-file: '.nvmrc' - run: pnpm install --frozen-lockfile - run: pnpm ci:audit - # Dependency vulnerability scan (binary tool, invoked via official - # action — Trivy is a Go binary, not an npm package, so it cannot - # live in package.json scripts as cleanly as audit/lint do). + # Dependency vulnerability scan. Trivy is a Go binary, not an npm + # package, so it cannot live in package.json scripts as cleanly + # as audit/lint do. # - # On cache miss (the act_runner cache server is currently - # unreachable from job containers — see infra/README.md "Cache - # server (deferred)"), the action falls back to `git clone - # https://github.com/aquasecurity/trivy` to fetch its install - # script. Without auth that hits github.com's 60 req/h anonymous - # rate limit and `git fetch` fails with "could not read Username". - # GITHUBCOM_TOKEN is the same zero-scope github.com PAT we use - # for Renovate (per docs/development.md "Dependency updates"). - - uses: aquasecurity/trivy-action@master - with: - scan-type: fs - ignore-unfixed: true - skip-dirs: node_modules - exit-code: '1' - severity: 'CRITICAL,HIGH' + # We deliberately avoid `aquasecurity/trivy-action`. On cache + # miss (our act_runner cache server is unreachable from job + # containers — see infra/README.md "Cache server (deferred)"), + # the action falls back to `git clone github.com/aquasecurity/ + # trivy` to fetch its install script, using `actions/checkout` + # which defaults `with.token` to `${{ github.token }}` (Gitea's + # auto-token, useless for github.com). The clone hits the + # anonymous github.com rate limit and fails with "could not + # read Username". Passing GITHUB_TOKEN as an env var doesn't + # help — actions/checkout reads it from `inputs.token`, not env. + # + # Direct curl + tar is simpler, predictable, and gives us an + # explicit version pin instead of `@master`. GITHUBCOM_TOKEN is + # passed to handle the github.com rate limit on the release + # download in the worst case (release artefacts are usually + # unmetered, but auth is free insurance). + - name: Install Trivy 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 }} + 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). - uses: gitleaks/gitleaks-action@v2 env: