23 Minutes Is Shorter Than Your CI Queue
Six vendor analyses landed after the fact; none help the build that resolved the registry at minute nine. The only controls that run at attacker speed sit at resolution and build time.
The window defeats the control, not the payload
Nearly every supply-chain control most teams bought runs at scan time. Advisory feeds, scanner index refreshes, vendor writeups, dependency-review bots. Every one of them fires after resolution has already happened. Risky.Biz counted six vendors publishing analyses of the malicious versions, and none of that reaches a pipeline that pulled the crate while the versions were live. The controls that run at attacker speed are earlier and duller: cargo build --locked or --frozen enforced in CI, vendored dependencies, and an internal mirror with a 24-48 hour promotion delay on new versions. The promotion delay is the only control guaranteed to have been correct here. It converts a minutes-scale attack into a non-event.
The ecosystem fix that does not generalize
npm 12 disabling install scripts by default is good engineering, and StubMaker replicating from RubyGems into npm is exactly why it was needed. It also does nothing for the Rust, Ruby, or Python surface. Cargo's equivalent primitive is build.rs and procedural macros, which are arbitrary code execution at build time by design, and nobody is disabling that. Run the inventory before writing the policy: for each ecosystem in the build, name the hook that executes attacker-controlled code before the first test runs. That list is build.rs, proc macros, gem native extensions, setup.py. Assuming a registry-level fix in one ecosystem covers the others is how this window stays open.
Blast radius is the runner's IAM role
A build-time payload inherits whatever ambient cloud credentials the runner holds. That is why the North Korean attribution matters operationally. It moves the expected payload off crypto-mining and onto credential and cloud-token harvesting. Egress filtering plus short-lived, narrowly scoped build credentials downgrades a supply-chain compromise from a cloud-account incident to rebuilding an artifact. Where runners hold a long-lived role with deploy permissions, the 23 minutes were not the incident. The role is.
Where the reporting converges
Three independent threads land on the same repricing. Risky.Biz has registry compromise measured in minutes. CyberScoop has federal agencies reporting AI-generated exploitation scripts in active use against industrial controllers with no accompanying CVE, so there is nothing to bump and the remediation is topology. The Hacker News puts the concentration of risk in code nobody on the team wrote and nobody can patch. The shared mechanism is that time-from-opportunity-to-working-attack has compressed below the cycle time of every human process built to respond to it. Patch cadence was calibrated against human exploit-development latency. That baseline is gone.
So build provenance stops being a maturity goal and becomes an incident-response prerequisite. The responder's question is not "are we patched." It is "what exact dependency set went into this image, and when was it resolved." Teams that could answer in minutes closed this incident quickly. Teams that could not are still guessing, and guessing here means either rebuilding everything or accepting unbounded risk on a build that may be clean.
If "what exact dependency set went into this image" takes more than an hour to answer, the 23-minute window is unanswerable and you are choosing between a full rebuild and hope.
What to do
Reconstruct every artifact built Thursday against a known-good lockfile, diff the resulting images by end of week, and rotate any credentials present in those CI runners.
Enforce cargo build --locked in CI and stand up an internal crates.io mirror with a 24-48 hour promotion delay for new versions this sprint.
Enumerate build-time code execution per ecosystem you ship in — build.rs, proc macros, gem extensions, setup.py — and scope build credentials to the minimum this quarter.