Skip to content

Build1 publisherNot yet confirmed elsewhere2 min readPublished

Rust's Miri fix leaves CI secrets sitting in GitHub Actions caches built before it

Rust's nightly of 22 September 2026 stops Miri copying environment variables into the target/ directories CI jobs cache. Caches saved earlier still hold any secret a Miri step saw, so teams have to delete them and rotate those credentials.

The Engineer · Build desk

How we use AISend a correction

Illustration accompanying Rust's Miri fix leaves CI secrets sitting in GitHub Actions caches built before it
Generated illustration

What happened

  • To spot build-relevant changes between runs, cargo miri recorded its entire invocation environment in a file inside target/.
  • The advisory says a project is exposed if it runs cargo miri with secrets in the environment, caches target/ via actions/cache or Swatinem/rust-cache, and lets pull requests read it.
  • According to the advisory, an attacker who took a secret this way could make later commits to hide the theft. A clean workflow log therefore proves nothing.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • decision Upgrading Miri only protects future runs, so every affected repository needs cache deletion scheduled as its own task, separate from the toolchain bump.
  • exposure Every credential passed to a Miri step while target/ was cached has to be treated as read, because neither deleting caches nor reviewing logs can show it was not.
  • constraint With no CVE assigned, teams that triage from CVE feeds will not be alerted and have to pick the advisory up from the Rust project itself.
  • precedent Any other tool that writes its invocation environment into a cached build directory can leak the same way, so secret-bearing jobs that cache build output need the same review.

The Rust project published its advisory on 21 September 2026 [1]. A dev.to write-up of that advisory describes the fix as an allowlist. Starting with the nightly dated 22 September 2026, Miri writes out only CARGO_* variables, minus CARGO_*_TOKEN, plus OUT_DIR [2]. The exclusion is the careful part. Token variables also start with CARGO_, so a plain prefix rule would have kept the token variables in Cargo's own namespace [15].

The allowlist changes what Miri writes on its next run. It does nothing to cache entries that are already stored, so the write-up lists cache deletion as a separate step after the toolchain update [8]. The vulnerable example in the write-up shows why the upgrade on its own leaves those entries in use. It caches `target` under `key: miri-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}` [14]. That key is built from the runner OS and the lockfile hash. Moving to the fixed nightly changes neither, so the first run after the upgrade asks for the same key the old Miri filled [16]. A workflow still pinned to a nightly from before 22 September keeps writing out the full environment [17].

Deleting a cache removes the stored copy. It does not touch a copy that a pull request run has already restored, and under GitHub's scoping rules a pull request run could restore caches built on the default branch [5]. If a secret was in one of those caches, the safe assumption is that someone read it. Rotation is the write-up's third step for that reason [18].

The scope is narrower than every cache in CI. Registry and Miri sysroot caches were never the problem. The target/ directory was [10]. The secret did not have to show up in code, test output or logs to be written to disk, so searching old logs will not find the exposure [9]. What needs rotating is every credential a cargo miri step got as an environment variable while that job's target/ was being cached.

For new runs, the write-up recommends never giving Miri production secrets. If a test really needs a credential, it suggests a dummy value or a scoped, revocable test credential with no real permissions [11]. Its other recommendation is to stop caching target/ on any job that can see secrets [12].

What to watch

  • Whether a CVE is later assigned, which would bring the Miri advisory into CVE-driven scanners and compliance trackers.
  • Whether other cargo subcommands or build tools turn out to snapshot their environment into target/ the way cargo miri did.
  • Whether Swatinem/rust-cache or common Rust CI templates change their defaults for caching target/ on jobs that receive secrets.

Clarity's read

What the record supports and how the coverage leans. The claims behind it follow.

Reality

Evidence50
Adoption
Insufficient
Hype gap+5
Incentives
Insufficient
Confidence55
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [1]

    The Rust project published an advisory on 21 September 2026 reporting that Miri, Rust's interpreter for detecting undefined behavior, was writing every environment variable it saw into the target/ directory.

    ReportedSupportedSource: dev.to write-up of the Rust advisoryView cited source
  2. [2]

    The nightly toolchain dated 22 September 2026 stops Miri persisting arbitrary environment variables, keeping only CARGO_* (excluding CARGO_*_TOKEN) and OUT_DIR.

    ReportedSupportedSource: dev.to write-up of the Rust advisoryView cited source
  3. [3]

    No CVE was assigned to the Miri advisory.

    ReportedSupportedSource: dev.to write-upView cited source

Sources

1 independent publisher whose own reporting we read for this story.

  1. dev.to

    1 article · October 7, 2026

    Miri Was Leaking CI Secrets Through GitHub Actions Caches: What to Clean Up

Share your take

Let Clarity write the post for you.

Signed-in readers get a short post drafted on this story in the register they choose — narrative, analytical, or a direct position — editable to the last word before it goes anywhere. The share buttons at the top of this story work without an account.

Topics and entities

Follow any of these and your For You feed starts watching them — no settings page required.

Entities

Loading related stories