cargo deny runs four checks on your Rust dependency graph: advisories (known vulnerabilities, unmaintained and yanked crates), bans (specific crates and duplicate versions), licenses (what each crate allows) and sources (where each crate came from). Running cargo deny check executes all four with defaults.
The four checks in one table
| Check | Question it answers | Typical failure |
|---|---|---|
| advisories | Does any crate have a published security advisory, or is it unmaintained or yanked? | A RUSTSEC entry matches a locked version |
| bans | Is a crate on my deny list, or do I carry several versions of one crate? | Two major versions of the same parser |
| licenses | Is every license in the graph one my company allows? | A license outside your allow list appears |
| sources | Did every crate come from a registry or git repo I approved? | A git dependency nobody reviewed |
The tool's own documentation describes these four classes of check on the crate graph, and says cargo deny check runs all of them using defaults for anything you have not configured.
Why four checks instead of one
A vulnerability scanner only answers the first question. Supply chain trouble also arrives through a crate you never meant to use, a second copy of a library with an old bug, a license you cannot ship, or a dependency pulled straight from a git branch. Each of those is a different kind of failure, so they get separate switches and separate severity settings.
Each check can be set to deny (fail the run), warn, or allow, where the options exist. That lets you start gently and tighten over time.
A sensible rollout order
- Create a starter
deny.toml, then runcargo deny checkonce to see the baseline. Do not gate on it yet. - Turn advisories into a hard failure first. Known vulnerabilities are the clearest signal and the easiest to explain to a team.
- Add sources next. Set unknown registries and unknown git sources to deny so a new dependency source needs a deliberate config change.
- Add licenses with an explicit allow list that legal has signed off.
- Finish with bans. Duplicate versions are noisy in big graphs, so start at warn.
You can also run one check at a time, for example cargo deny check advisories, which is handy when you want a fast job on every pull request and a slower full run nightly.
What it does not do
cargo deny reads the graph from your lockfile and metadata. It does not tell you whether the vulnerable function is actually called, and it does not read the source of a build script. Treat it as policy enforcement on inventory, not as a code review.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how a flat inventory of packages becomes the input for every check above.
Quick check
Does cargo deny replace cargo audit?
They overlap on advisories, since both use the RustSec database by default. cargo deny adds bans, licenses and sources, so many teams use it as the single gate.
Do I need a deny.toml to run it?
No. Without one, defaults apply, but a committed file makes the policy reviewable and repeatable.
Is cargo deny a Safeguard feature?
No, it is an open source tool maintained by others. It is one of several ways to enforce dependency policy in Rust.
Safeguard can inventory your dependencies with SBOM and dependency scanning, apply policies and gates in pull requests, and you can try a free scan at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.