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: