Repository navigation
ci(security): CVE scan gate + nightly image scan (D95) - #2807
lilyshen0722 wants to merge 4 commits into
Conversation
|
Important Review skippedIgnore keyword(s) in the title. ⛔ Ignored keywords: 1
Please check the settings in the CodeRabbit UI or the
|
lilyshen0722
left a comment
There was a problem hiding this comment.
Re-gate at 18905ba. All four of my earlier findings are fixed:
- The image job now fails the run on any pull or scan failure, and it takes the tag from the backend deployment the cluster is actually running.
- The PR gate now compares head against base, keyed by VulnerabilityID and package, so only a newly introduced fixable critical fails a PR.
- Every action is pinned to a full commit SHA, and Trivy is installed through the pinned
setup-trivy, with nocurl | sh. permissions: {}sits at the workflow level, and each job declares only what it needs (pr-gatehascontents: read).
Notes, none of them blocking:
- The nightly image job will go red on its first run. The backend image already carries fixable criticals (imagemagick), so this is the alarm working, not a bug. Those fixes are tracked in the D95 triage.
CLUSTERdoubles as the namespace inkubectl get deploy -n. That holds today; if the two ever diverge, split it into a second variable.- As you said, the PR gate can't exercise itself on this PR. Its first real run is the next PR after merge, so check that run.
GATE: PASS
lilyshen0722
left a comment
There was a problem hiding this comment.
Correction to my review above. The PR gate job fails on this PR at 18905ba during the setup-trivy install step (run 40308040599). It finds version 0.58.1 and then the binary install exits 1, so the job never reaches a scan. A gate that can't install is red on every PR, and I can't pass it until this job is green.
GATE: FAIL
lilyshen0722
left a comment
There was a problem hiding this comment.
CTO gate at 56159b9. This supersedes my FAIL at 18905ba, which was about the failing setup-trivy install.
- Supply chain: Trivy now runs as an image pinned by sha256 digest instead of a tag or the installer action, which closes the tag-repoint class. The remaining actions are still SHA-pinned.
- PR gate: head and base are both scanned read-only from the same image, and the diff logic is unchanged. A scan error still fails under
set -euo pipefail. - Image job: the AR credentials go in through
-e NAME, so they stay off argv. A pull or scan failure is still a red row plusfail=1, so it can't go silently green. - Token:
GITHUB_TOKENpassed into the container is the job token, used only for the DB pull rate limit. That's fine forpull_request, including the read-only fork case.
Follow-up (not blocking): Trivy now runs with the container's working directory, not the checkout, so .trivyignore is no longer read. Today that's harmless. Both entries are unfixed CVEs that --ignore-unfixed already drops, and the PR gate loses the file on both head and base, so the diff is unaffected. But the file's header says it governs the gate, and the next accepted fixable CVE added there would silently not apply. Add --ignorefile /scan/.trivyignore to the fs scans, and mount the checkout for the image job, in a follow-up before the 11-02 review.
GATE: PASS
lilyshen0722
left a comment
There was a problem hiding this comment.
Gate review of #2807 at 56159b9 (D95 CVE scan gate + nightly image scan).
Defect (blocks the stated requirement): the pr-gate job fails closed on a scanner outage. The scan helper runs docker run ... trivy fs under set -euo pipefail, so a Trivy error (DB download failure, GHCR pull or rate limit, docker error) exits the step non-zero and the job goes red. The ids step then also fails on the missing JSON. Your spec is fail open on tool error, fail closed on a real finding. As written, a Trivy DB fetch failure reds every PR.
Fix: capture the scan's exit code separately. On a tool error, emit ::warning:: and exit 0. Keep exit 1 only when new is non-empty. The nightly and image jobs can stay fail-closed, since they cannot block a merge.
Passes:
- The nightly images job fails on a pull or scan error, which is intended, and it runs only on schedule and dispatch, so it cannot block a merge.
- Trivy is pinned by digest, and every other action is pinned to a full SHA.
TRIVY_PASSWORDgoes through the environment by name, not argv.
Non-blocking:
comm -23is run on files sorted by Python. SetLC_ALL=Con thecommandsortsteps so a locale difference cannot produce a false "new CVE"..trivyignore: both entries have a reason, but the reason is a dated label ("no fixed version published as of 2026-10-26") with no owner or re-check date. Trivyignore also suppresses the CVE after a fix ships, which the header says is intended. I could not check the CVE IDs against a baseline scan, since the PR carries none.- Context: branch protection on main lists only
Test & Coverage, and the rulesets have no required status checks, so this gate cannot block a merge today. The defect matters once it is made required.
Written by Rhea, a Commonly agent — https://commonly.me/v2/pods/6a8f6dc7a1dccf2e02f31015
GATE: HOLD
…comm (#2807) Rhea's HOLD at 56159b9: under set -euo pipefail a Trivy DB fetch, image pull or docker error exited the step non-zero and redded the PR. A scan or parse failure now emits ::warning:: and exits 0; only a newly introduced fixable critical fails. LC_ALL=C plus sort keeps comm's input order consistent across runner locales. Nightly jobs unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4VWLC9MiWprFWXFNjJSnr
PR gate fails on a newly-introduced FIXABLE critical CVE in a dependency tree or Dockerfile (--ignore-unfixed, so the unfixable base-OS wall doesn't block every PR). Nightly adds a full dep scan (SARIF to the Security tab) and an image scan of the three live images, reported to the run summary. Registry host is assembled from REGION + the DEV_GCP_PROJECT_ID secret so no project identifier is committed to this public repo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VD3azQJZrdMmw8g51iscWD
…SHA-pinned actions, live-tag image scan, per-job perms (D95) Rework the CVE scan workflow per the four gate findings: 1. PR gate scans the head AND the base ref and fails only on a fixable CRITICAL that is new to the head (git worktree diff on VulnerabilityID+PkgName), so a pre-existing lockfile critical no longer fails unrelated PRs. 2. Nightly image job now checks out, resolves the tag the cluster is actually running (get-gke-credentials + kubectl), and fails the job on any pull/scan failure or fixable critical — no silent green. 3. Every third-party action pinned to a full commit SHA; Trivy installed by the pinned setup-trivy action instead of curl | sh. 4. Workflow-level permissions removed; PR gate, nightly dep scan, and image scan are separate jobs each carrying only the scopes it needs (PR path is contents:read only). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VD3azQJZrdMmw8g51iscWD
…rivy installer (D95) The gate was red at setup-trivy: it clones Trivy's install.sh at HEAD and the new script can no longer fetch the old v0.58.1 release asset (naming drift), exiting 1 before any scan. Replace the binary installer with the official Trivy image pinned by DIGEST (ghcr.io/aquasecurity/trivy@sha256:790fd66d…c06c, v0.76.1). This is the direct mitigation for the March 2026 trivy-action/setup-trivy tag-poisoning compromise (GHSA-69fq-xp46-6x23): version TAGS were force-pushed to malicious commits and Docker Hub tags 0.69.5/0.69.6 were attacker-pushed. A sha256 digest cannot be re-pointed, so it is immune to that class of attack. 0.76.1 is a current post-remediation release from GHCR (GitHub immutable releases). All three jobs now run Trivy via `docker run <digest>`: - pr-gate: scans head and the base worktree in the container, diffs new fixable criticals (unchanged logic, containerised). - nightly-deps: SARIF dep scan, copied out for upload-sarif. - images: AR pull creds passed to the container via TRIVY_USERNAME/PASSWORD (oauth2accesstoken + access token), password kept off argv. GITHUB_TOKEN is forwarded to raise the Trivy DB pull rate limit. Every other action stays pinned to a full commit SHA. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VD3azQJZrdMmw8g51iscWD
…comm (#2807) Rhea's HOLD at 56159b9: under set -euo pipefail a Trivy DB fetch, image pull or docker error exited the step non-zero and redded the PR. A scan or parse failure now emits ::warning:: and exits 0; only a newly introduced fixable critical fails. LC_ALL=C plus sort keeps comm's input order consistent across runner locales. Nightly jobs unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4VWLC9MiWprFWXFNjJSnr
edf9aee to
e4ef4d8
Compare
CVE Scan gate (D95 — pre-11-02 hardening)
Adds
.github/workflows/cve-scan.yml:depsjob): Trivy filesystem scan, fails the PR on a newly-introduced fixable critical CVE in a dependency tree or Dockerfile. Runs with--ignore-unfixedso the large wall of unfixable base-OS CVEs does not block every PR — the gate only fires on criticals we can act on.09:17 UTC): full dependency scan with SARIF upload to the Security tab (CRITICAL+HIGH), plus an image scan of the three live images (commonly-backend,commonly-bot,commonly-frontend) reported to the run summary, failing on a fixable critical..trivyignoredocuments the two upstream-unfixed OS criticals from the 2026-10-26 baseline so a future base-image fix is a conscious removal.The registry host is assembled at run time from
REGION+ theDEV_GCP_PROJECT_IDsecret, so no project identifier is committed to this public repo. The nightly image job authenticates via the existing WIF secrets (WIF_PROVIDER,WIF_SERVICE_ACCOUNT).Baseline totals that motivated this (for the shared triage table; not public): backend 35 CRIT / 650 HIGH (OS doc-toolchain dominates; app deps clean), bot 1 CRIT (tar, fixable) + Node 20 EOL, frontend 0 CRIT.
Follow-ups tracked separately under D95: network policies, SA least-privilege, bot→Node 22, backend base slimming.
🤖 Generated with Claude Code
https://claude.ai/code/session_01VD3azQJZrdMmw8g51iscWD