Repository navigation
feat(wbfy): enforce cargo's native min-publish-age in Rust repositories #1256
Description
Background and goal
The Renovate preset in willbooster-configs holds crates.io updates back for 7 days with minimumReleaseAge and turns off cargo lockfile maintenance and automerge (WillBooster/willbooster-configs#1098). That check only looks at the dependency Renovate is updating. When Renovate runs cargo update to regenerate Cargo.lock, a new transitive crate from that update can still resolve to a version published minutes ago. The August 2026 crates.io attack (arrayref / internment / append-only-vec, with malicious releases removed less than 90 minutes after publication) shows this can really happen: https://thehackernews.com/2026/08/rust-supply-chain-attack-puts-build.html
Cargo now has a native setting that closes this gap. Stabilization PR rust-lang/cargo#17335 (RFC 3923) merged into milestone 1.100.0:
# .cargo/config.toml
[registry]
global-min-publish-age = "7 days"With the default resolver.incompatible-publish-age = "deny", any resolution (cargo update, cargo add, cargo generate-lockfile) skips crates.io versions younger than 7 days, including transitive ones. Goal: every Rust repository in the organization resolves dependencies with this setting, and we don't write a custom pubtime check in CI.
Behavior
- In a repository with a
Cargo.toml, wbfy writes.cargo/config.tomlnext to it with[registry] global-min-publish-age = "7 days", the same age the Renovate preset uses. - The Rust toolchain those repositories pin is at least 1.100, so the setting is enforced. Older cargo just warns about the unknown key and ignores it.
- To push an urgent update through, run
CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allow cargo update -p <crate>by hand.
Acceptance criteria
- In a wbfy-applied Rust repository, running
cargo updatewith a crates.io version younger than 7 days available does not select that version. - A Renovate cargo update PR in such a repository does not add a transitive crate version younger than 7 days to
Cargo.lock.
Scope and non-goals
- Out of scope: re-checking versions already in
Cargo.lock. Cargo accepts locked entries whatever their age, and no CI gate will be added for them. The operational rule "update Rust dependencies only through Renovate PRs (automerge disabled)" covers hand-edited lockfiles and lockfiles resolved with an older cargo. - Out of scope: git and path dependencies, which have no
pubtime.
Design constraints
- Blocked until Rust 1.100 is released to stable (stable is currently 1.98.1).
docs/expected-repository-rules.mdlists the new expectations: the.cargo/config.tomlsetting, the minimum toolchain, and the Renovate-only rule for Rust dependency updates.
Open questions
- Which cargo does Renovate use to regenerate
Cargo.lock? Does it take the version fromrust-toolchain.toml, or does the willbooster-configs preset needconstraints: { rust: ">=1.100" }? The fix doesn't work until this is confirmed. - How should wbfy handle a repository that already has its own
.cargo/config.toml? Options: add only the key, skip with a warning, or treat the file as canonical wbfy output.
Activity
[-]Rust CI に Cargo.lock の新規/変更 crate の公開日時ゲートを追加する[/-][+]feat(wbfy): enforce cargo's native min-publish-age in Rust repositories[/+]