Checking Licenses and Bans With Cargo Deny Config Explained
cargo-deny checks advisories, licenses, banned crates and registry sources from one deny.toml. See a working configuration, how to read failures and how to add exceptions with a reason.

A pull request adds a convenient crate. It pulls in forty others, one of them under a license your company's lawyers have not approved and another with a published advisory. Nobody reads the lock file diff, so it merges. cargo-deny is the gate that reads it for you. This post gives a working deny.toml and explains each section. It is the policy half of dependency risk in Rust, and a component of the security baseline.
cargo-deny 0.16, Rust 1.90.
Start
cargo install cargo-deny --locked
cargo deny init
cargo deny checkinit writes a commented deny.toml with the defaults. The sections below show the parts worth setting.
A practical configuration
[advisories]
version = 2
yanked = "deny"
ignore = [
# { id = "RUSTSEC-YYYY-NNNN", reason = "not reachable: we never call the affected parser" },
]
[licenses]
version = 2
allow = [
"MIT",
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"Unicode-3.0",
]
confidence-threshold = 0.9
[bans]
multiple-versions = "warn"
wildcards = "deny"
deny = [
{ crate = "openssl", reason = "we use rustls; avoids a C dependency" },
]
[sources]
unknown-registry = "deny"
unknown-git = "deny"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]advisories
Reads the RustSec database. yanked = "deny" fails on withdrawn versions. Vulnerabilities and unsound code are errors by default, so do not allow them silently. Each ignore must say why; "not reachable" needs a reviewer who can confirm it.
licenses
An explicit allow list. When a new dependency has GPL-3.0 or MPL-2.0 and you have not approved it, the check fails and names the crate:
error[rejected]: failed to satisfy license requirements
┌─ some-crate 1.2.3
│ license = "GPL-3.0"
│ rejected: license is not explicitly allowedYou then decide: pick another crate, ask legal, or add the license. Dual licensed crates (MIT OR Apache-2.0) pass if one side is allowed.
bans
multiple-versions = "warn" lists crates that appear twice at different versions, which bloats builds and sometimes signals an out-of-date dependency. wildcards = "deny" rejects * version requirements. The deny list bans specific crates with a reason that appears in the failure.
sources
Only allow crates.io (the sparse protocol URL is used by default; check what init generated for your Cargo version). Git dependencies get through only if listed in allow-git.
In CI
- uses: EmbarkStudios/cargo-deny-action@v2or cargo deny check after installing. Run the advisories check on a schedule as well, since new advisories appear for unchanged code (GitHub Actions for Rust).
Exceptions
Put them in the file, not in a comment in a pull request. A dated reason lets you remove the ignore when the upstream fix lands.
Limits
It knows the database and the metadata, and nothing about your code's reachability. Licenses declared in crate metadata can be wrong. For reviewing the actual source of dependencies, see cargo vet. The tool's book is at embarkstudios.github.io/cargo-deny.


