Skip to content

feat(ci): rescan main's images weekly and route drift to a tracking issue - #1717

Merged
FelixTJDietrich merged 1 commit into
mainfrom
ci/rescan-main-images
Sep 1, 2026
Merged

feat(ci): rescan main's images weekly and route drift to a tracking issue#1717
FelixTJDietrich merged 1 commit into
mainfrom
ci/rescan-main-images

Conversation

@FelixTJDietrich

Copy link
Copy Markdown
Collaborator

Description

Adds rescan-main-images.yml: a weekly, non-blocking rescan of the images built from main's
HEAD against the release vulnerability policy, with findings routed to a single tracking issue.

Container vulnerabilities are time-dependent, not commit-dependent. The gate #1710 added runs where
an image is built, so it catches a finding some change introduced and cannot catch one published
after the code merged clean — which is exactly what blocked v0.75.0, and what nothing notices today
until a release fails. rescan-release-images.yml already covers published releases on this
cadence; this covers what main would release today.

Fixes #1706

What is reused, and what is new

Reused as-is, not re-derived:

  • scripts/check-release-vulnerabilities.ts and security/vulnerability-policy.json. One
    evaluator, one policy. scan-main-images.ts invokes that script rather than importing or
    reimplementing it, so the .policy.json result files this run produces are byte-shaped exactly
    like the build gate's and the release rescan's.
  • fix(ci): scan images against the vulnerability policy where they are built #1710's linux/amd64 digest resolution — index first, single-manifest fallback, digest shape
    asserted — lifted into selectPlatformDigest, where it is now tested against a real index, a
    single manifest, and the unknown/unknown attestation manifest a multi-arch push also publishes.
  • rescan-release-images.yml's shape: weekly cron, workflow_dispatch, non-cancelling
    concurrency group, setup-release-security-tools without Syft, artifact upload of the reports.

New:

  • scripts/scan-main-images.ts — resolves each inventory image's :main tag to its linux/amd64
    digest, scans it, evaluates the policy. A finding never fails the run; an unreachable registry, a
    missing tag or a malformed report does. The evaluator is run silenced, because a green job
    carrying ::error:: annotations is how a team learns to read past them — but if it exits without
    writing a result file (a malformed report or policy, not a finding) it is re-run with output and
    the run fails, since unlike a CVE that is fixed by a commit.
  • scripts/report-vulnerability-drift.ts — the issue upsert, in kyverno sync-trivy-issues shape.
    Creates when findings appear, edits in place and comments when the finding set changes, writes
    nothing when it has not
    , and closes when it clears. It identifies its own issue by an HTML
    marker carrying a fingerprint of the finding set, not by title: a title is editable, and a run
    that cannot recognise its own issue opens a duplicate every week until someone turns the schedule
    off. The fingerprint deliberately excludes the scan timestamp and run link, or every week would
    look like a change.

Composite action: yes, and why

The Trivy database fetch — retry loop, mirror fallback, freshness assertion, metadata copy — was
about to exist in a fourth copy, and only #1710's carried the
public.ecr.aws/aquasecurity/trivy-db fallback and the note that the :2 schema tag tracks the
Trivy version in setup-release-security-tools. That is the same class of drift this whole effort
is removing, so it is now .github/actions/download-trivy-db with two optional inputs
(max-age-hours, metadata-path) covering all four call sites. release.yml and
rescan-release-images.yml adopt it and gain the mirror fallback; reusable-docker-build.yml's
scan job loses ten lines. It is roughly line-neutral — the win is that the fallback and the schema
pin are stated once instead of in one place out of four.

Changeset

None. verify-changesets scopes SHIPPED_PATHS to server, webapp and docker; this PR touches
only .github/, scripts/ and docs/, so git diff --name-only ... -- server webapp docker is
empty and the check does not require one.

How to test

CI covers this. 46 node:test cases across scripts/scan-main-images.test.ts (13),
scripts/report-vulnerability-drift.test.ts (20) and the new/extended scripts/ci-contract.test.ts
assertions (3 new tests, existing one updated), including:

  • the upsert does not open a second issue when the findings are unchanged, takes over the oldest
    tracking issue rather than the newest, closes every tracking issue when the policy clears, and
    never adopts an unrelated open security issue;
  • the rendered body is byte-identical for the same findings scanned in a different order;
  • every path that evaluates the policy names security/vulnerability-policy.json, and exactly one
    such file is committed;
  • no workflow downloads the Trivy database outside the composite action, and every workflow that
    publishes or signs a scan result refuses a database over 24 h old.

pnpm run format and pnpm run check both pass.

The workflow can be exercised before the first Monday with workflow_dispatch.

Checklist

  • My changeset summary reads as an operator/user-facing note — n/a, no shipped code changed
  • If operators must act, the changeset and migration entry give actionable upgrade instructions
  • I did not commit generated-artifact changes that this PR did not cause

…ssue

Container vulnerabilities are time-dependent, not commit-dependent. The gate
added in #1710 runs where an image is built, so it catches a finding some
change introduced and cannot catch one published after the code merged clean —
which is what blocked v0.75.0, and what nothing notices today until a release
fails.

`rescan-main-images.yml` scans `<image>:main` on the same weekly cadence as the
supported-release rescan, through the same `check-release-vulnerabilities.ts`
and the same `security/vulnerability-policy.json`. It is not blocking: findings
go to one tracking issue, opened when they appear, edited in place and
commented when the set changes, silent when it has not, and closed when it
clears. It recognises its own issue by an HTML marker carrying a fingerprint of
the finding set, so it cannot open a duplicate every week and cannot adopt an
unrelated issue.

The Trivy database fetch was about to exist in a fourth copy, with only one of
them carrying the ECR mirror fallback, so it is now one `download-trivy-db`
composite action with optional freshness and metadata inputs. The release and
the release rescan adopt it and gain the fallback.

Closes #1706

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved automatically: @FelixTJDietrich is listed in the REVIEW_POLICY_MAINTAINERS repository variable, which the repository treats as satisfying the review requirement. See the review policy in docs/contributor/ci-cd.mdx.

@github-project-automation github-project-automation Bot moved this from Backlog to In Review in Hephaestus Sep 1, 2026
@github-actions github-actions Bot added documentation Improvements or additions to documentation ci GitHub Actions, workflows, build pipeline changes size:XXL This PR changes 1000+ lines, ignoring generated files. feature New feature or enhancement labels Sep 1, 2026
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

📚 Documentation Preview

Preview has been removed (PR closed)

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

🧩 Storybook Preview

Preview has been removed (PR closed)

@FelixTJDietrich
FelixTJDietrich added this pull request to the merge queue Sep 1, 2026
@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 59 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 0b359d88-3305-4a5b-8f99-df1458a0277f

📥 Commits

Reviewing files that changed from the base of the PR and between 795f71b and 7b5d158.

📒 Files selected for processing (12)
  • .github/actions/download-trivy-db/action.yml
  • .github/workflows/release.yml
  • .github/workflows/rescan-main-images.yml
  • .github/workflows/rescan-release-images.yml
  • .github/workflows/reusable-docker-build.yml
  • docs/contributor/ci-cd.mdx
  • docs/contributor/release-management.mdx
  • scripts/ci-contract.test.ts
  • scripts/report-vulnerability-drift.test.ts
  • scripts/report-vulnerability-drift.ts
  • scripts/scan-main-images.test.ts
  • scripts/scan-main-images.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 1, 2026
@FelixTJDietrich
FelixTJDietrich added this pull request to the merge queue Sep 1, 2026
Merged via the queue into main with commit 63bcaf9 Sep 1, 2026
43 checks passed
@FelixTJDietrich
FelixTJDietrich deleted the ci/rescan-main-images branch September 1, 2026 16:40
@github-project-automation github-project-automation Bot moved this from In Review to Done in Hephaestus Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci GitHub Actions, workflows, build pipeline changes documentation Improvements or additions to documentation feature New feature or enhancement size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

feat(ci): rescan main's images on a schedule so CVE drift surfaces before a release

1 participant