Field notes/supply chaincargo vet

cargo vet Criteria: safe-to-run vs safe-to-deploy in Rust

cargo vet fails a build until each dependency is audited, imported or exempted. What safe-to-run and safe-to-deploy promise, and how to read a red vet job honestly.

Signed by M·
Painted river ferry landing at dusk where five wooden crates wait on a dock between two lit lantern posts, a small wooden ferry moored at the end and strings of soft lights over the water
What is the difference between safe-to-run and safe-to-deploy in cargo vet?

safe-to-run means a crate can be built, run and tested on a workstation or in CI without surprising effects such as touching unrelated files or reaching untrusted networks. safe-to-deploy is stronger: an auditor reasoned about its unsafe code and powerful imports for production use with untrusted input, and it implies safe-to-run.

cargo vet is Mozilla's supply chain tool for Rust. It fails the check until every third-party crate in your graph is covered by an audit you wrote, an audit you imported from someone you trust, or an exemption you recorded on purpose. Its two built-in cargo vet criteria are safe-to-run and safe-to-deploy. Knowing exactly what each one promises is the difference between reading a red vet job as evidence and reading it as noise.

A failing cargo vet job rarely means "this crate is evil". It usually means "nobody has signed this claim, for this version, yet". That is still worth stopping for. The Trust band of Remade with Rust exists because dependency graphs deserve the same care as the code you wrote, and cargo update is not a security model.

What the two cargo vet criteria actually promise

The built-in criteria page defines both in plain language. safe-to-run says the crate can be compiled, run and tested on a local workstation or in controlled automation without surprising consequences. The examples are concrete: reading or writing sensitive or unrelated parts of the filesystem, installing software or reconfiguring the device, connecting to untrusted network endpoints, or misusing system resources such as mining cryptocurrency.

safe-to-deploy is the production promise. The crate will not introduce a serious security vulnerability to software exposed to untrusted input. Auditors are not required to read every line of logic. They must review enough to reason about all unsafe blocks and every powerful import, so that an attacker cannot steer those sections into exploitable or surprising behavior. Discretion is allowed, and the nature of it goes in the audit's notes field. For build dependencies and procedural macros, the generated code has to meet the same bar. safe-to-deploy implies safe-to-run.

That pairing is the useful mental model for cargo vet criteria: one protects the machine doing the build, the other protects the people using what you ship.

How cargo vet decides a dependency passes

A vet run walks your lockfile. For each crate version it asks which criteria the policy requires, then looks for evidence. The evidence has a small, readable vocabulary, and that vocabulary is what makes a Rust supply chain audit reviewable by someone other than its author.

The default cargo vet policy by dependency kind

According to the policy documentation, cargo vet by default checks every transitive dependency of every top-level crate on all platforms. Regular dependencies need safe-to-deploy. Dev-dependencies need safe-to-run. Build dependencies need safe-to-deploy, because the code they generate ends up in your product.

You can narrow that in config.toml. An internal tool in the same workspace as a shipped product might reasonably require only safe-to-run for its own graph. Write that decision down in the policy file rather than in a chat thread, so the next reviewer sees why the bar differs.

Audits, deltas and violations in a Rust supply chain audit

An audit entry names the criteria, the crate and either a version reviewed in full or a delta such as 1.2.0 -> 1.3.0, where only the diff was reviewed. The audit entries reference is strict about deltas: the standard is that the properties are actually preserved, not merely that the diff does not obviously break them. Optional who and notes fields record the auditor and any discretion.

A violation entry is the opposite: it says a version range does not meet a criteria. cargo vet rejects such a dependency even if it also appears in the exemptions table. That is the one case where a red result is a finding rather than a gap.

Imports and exemptions in cargo vet

Most teams shrink their backlog by importing audits. An imports entry points at another project's audits.toml, and the fetched data is pinned in imports.lock. The importing audits page notes two properties worth keeping in mind: imports are not transitive, and built-in criteria mean the same thing in every project, so an imported safe-to-run audit counts exactly like your own.

Exemptions are the honest backlog. They let a build pass for an unaudited version while making the debt visible in a file anyone can read. An exemption is not an audit. Treat a growing exemptions table as a to-do list with an owner, not as a pass. For advisories on already-known vulnerabilities, pair cargo vet with the RustSec advisory database, which answers a different question.

Reading a red cargo vet job in a real repository

Theory is easier to trust when it meets a real log. The house FFmpeg rebuild runs cargo vet inside its standalone hardening jobs, so it is a fair place to practice reading one honestly.

A cargo vet example from remade_ffmpeg_rs

remade_ffmpeg_rs keeps per-codec hardening workflows in its public workflows folder. The MP3 workflow's supply chain job is named "audit + deny + vet + SBOM (crate closure)" and pins cargo-vet 0.10.2. On November 7, as the rusty_h265 0.7.0 campaign note recorded, the pre-merge MP3 and AAC jobs reported rusty_alloc 2.4.0 missing safe-to-run in those crate closures.

On November 10 at 4:17 AM MST, the MP3 hardening run on main (run 42806226064) still concluded with a failed supply chain step. The public run summary does not show which tool inside that step failed, so this article does not claim the cause is still the same vet gap. The Miri, fuzz, lint and test jobs in that run succeeded. None of this is an MP3 decode failure.

What closes a cargo vet gap, and what does not

Three things close it honestly. Someone reviews the version against the required criteria and records it with cargo vet certify, including who and notes. Or the team imports an audit from a project it already trusts. Or the team records a visible exemption with a plan to replace it. Each leaves a trail a reader can check.

Two things do not close it. Deleting the job turns missing evidence into no evidence. Raising the policy for one crate and quietly lowering it for another moves the gap without explaining it. If a vet failure blocks a release, say so in the release notes, the same way the parser resource limits guide asks you to test refusals as carefully as successes.

Where cargo vet fits beside Deputy

cargo vet records who looked at which version for which promise. Deputy is the Remade Trust crate for owning the graph itself: keeping dependencies offline when you need to, scanning changes and deploying what you chose. MATA explains the same idea for product owners in Deputy: Rust dependencies you own and audit. Use both lenses. Audits tell you what was reviewed. Owning the graph tells you nothing changed after the review.

Start small this week. Run cargo vet on one service, read the first gap as a missing signature rather than a verdict, and decide whether it needs an audit, an import or a dated exemption. The rest of the house crates live at Remade-With-Rust on GitHub.

FAQ

Quick answers for builders evaluating this technology.

What does cargo vet check by default?

By default cargo vet requires safe-to-deploy for regular and build dependencies and safe-to-run for dev-dependencies, across every transitive crate of your top-level crates, on all platforms.

Does a failing cargo vet job mean a crate is malicious?

No. A failing vet usually means no audit, import or exemption covers that crate version for the required criteria. It is missing evidence, not a finding. A recorded violation entry is the case that marks a version as failing a criteria.

Does safe-to-deploy require a full logic review of a crate?

No. The built-in definition asks the auditor to review enough to reason about all unsafe blocks and powerful imports, so an attacker cannot manipulate them in exploitable ways. Discretion is allowed and should be written in the notes field.

Can I import cargo vet audits from another project?

Yes. An imports entry in config.toml pulls another project's audits.toml. Imports are not transitive, and built-in criteria mean the same thing everywhere, so an imported safe-to-run audit counts like your own.

How does cargo vet relate to Deputy in Remade with Rust?

They answer different questions. cargo vet records who audited which crate version for which criteria. Deputy is the Remade Trust crate for owning the dependency graph offline and reviewing changes before deploy. One can feed the other.