Security: always-on¶
Every *-security component —
go-security,
rust-security,
tofu-security,
svelte-security,
skill-security — carries no
changes input. Every scanner in every one of them runs on every merge
request, no matter which files that MR touches. This was a deliberate
policy decision made alongside change-detection, not
an oversight — the whole security category is exempt from it.
The reasoning¶
Change-detection exists to skip work that provably can't have been affected
by an MR's diff — no point running go-test on a documentation-only
change. Security scanning doesn't fit that logic, for a reason specific to
what it's checking:
A dependency's vulnerability status isn't a function of the diff — it's a
function of time. A CVE can be published against a library your project
already depends on, on a day when nobody touched a single line of code.
govulncheck, cargo-deny, osv-scanner, and the rest exist precisely to
catch that: every MR re-checks the current dependency tree against the
current advisory database, regardless of what changed. If security
scanning were change-detected, a docs-only MR merged the day after a CVE
drops would sail through unscanned — exactly the MR you'd want the scanner
to catch.
There's also no fallback to rely on: the schedule-never guard (every
component except renovate-self
skips scheduled pipelines) means there is no nightly re-scan picking up
what an MR-time filter might have skipped. Change-detected security would
mean some CVEs are never caught until the next change to a matching file
— which could be a long time.
The accepted cost: an expensive scanner like govulncheck runs even on an
MR that only touches a README. That's a deliberate trade — maximum posture
over marginal runner-time savings, for a category where the savings would
come at the cost of a real security blind spot.
Secrets, specifically¶
Secret scanning (gitleaks, present in every *-security component) has
the same always-on property for an even more direct reason — a secret
committed anywhere in the diff needs to be caught in that MR, not
deferred by a change filter that happened not to match the file it landed
in. Every gitleaks job is additionally scoped to the MR's own commit
range ($CI_MERGE_REQUEST_DIFF_BASE_SHA..$CI_COMMIT_SHA) rather than
scanning full history on every run — a shared runner's cached refs from
other branches can otherwise trip a false positive, an unrelated problem
that this scoping avoids without weakening the always-on guarantee. See
2026-06-08-gitleaks-scan-scoping-v0.10.3.md.
What this doesn't mean¶
Always-on doesn't mean unconfigurable. Every scanner in every
*-security component is its own job, so a consumer can opt one out
individually (<job>: { rules: [{ when: never }] }) if it genuinely
doesn't apply — but the default, out of the box, is every scanner, every
MR, no filter.
See also¶
- Change-detection — the mechanism this category is exempt from.
- Reference:
go-security,rust-security,tofu-security,svelte-security,skill-security - Spec:
2026-06-23-change-detection(Resolved section),2026-06-08-gitleaks-scan-scoping-v0.10.3