Document not found (404)
+This URL is invalid, sorry. Please use the navigation bar or search to continue.
+ +diff --git a/404.html b/404.html new file mode 100644 index 000000000..fc6abc332 --- /dev/null +++ b/404.html @@ -0,0 +1,211 @@ + + +
+ + +This URL is invalid, sorry. Please use the navigation bar or search to continue.
+ +[advisories]
sectionContains all of the configuration for cargo deny check advisories
[advisories]
+db-path = "~/.cargo/advisory-dbs"
+db-urls = ["https://github.com/RustSec/advisory-db"]
+ignore = [
+ "RUSTSEC-0000-0000",
+ "crate@0.1",
+ { crate = "yanked", reason = "a new version has not been released" },
+]
+
+db-urls
field (optional)URLs to one or more advisory databases.
+Default: RustSec Advisory DB
+db-path
field (optional)Path to the root directory into which one or more advisory databases are cloned into.
+This value supports basic shell expansion:
+~
- Expands to home::home_dir
$VARNAME
- Expands to std::env::var("VARNAME")
${VARNAME}
- Expands to std::env::var("VARNAME")
${VARNAME:-fallback}
- Expands to std::env::var("VARNAME")
or the fallback value if it doesn't exist (everything between the :-
and }
)$CARGO_HOME
- Expands to std::env::var("CARGO_HOME")
if it exists, otherwise expands to $(home::home_dir())/.cargo
Note that the path must be valid utf-8, after expansion.
+Default: $CARGO_HOME/advisory-dbs
version
field (optional)version = 2
+
+The version field is (at the time of this writing) no longer used, the following fields have been removed and will now emit errors.
+vulnerability
- Removed, all vulnerability advisories now emit errors.unmaintained
- Removed, all unmaintained advisories now emit errors.unsound
- Removed, all unsound advisories now emit errors.notice
- Removed, all notice advisories now emit errors.severity-threshold
- Removed, all vulnerability advisories now emit errors.As before, if you want to ignore a specific advisory, add it to the ignore
field.
yanked
field (optional)Determines what happens when a crate with a version that has been yanked from its source registry is encountered.
+deny
- Will emit an error with the crate name and version that was yanked, and fail the check.warn
(default) - Prints a warning with the crate name and version that was yanked, but does not fail the check.allow
- Prints a note about the yanked crate, but does not fail the check.ignore
field (optional)ignore = [
+ "RUSTSEC-0000-0000",
+ { id = "RUSTSEC-0000-0000", reason = "this vulnerability does not affect us as we don't use the particular code path" },
+ "yanked@0.1.1",
+ { crate = "yanked-crate@0.1.1", reason = "a semver compatible version hasn't been published yet" },
+]
+
+Every advisory in the advisory database contains a unique identifier, eg. RUSTSEC-2019-0001
. Putting an identifier in this array will cause the advisory to be treated as a note, rather than a warning or error.
In addition, yanked crate versions can be ignored by specifying a PackageSpec with an optional reason
.
git-fetch-with-cli
field (optional)Similar to cargo's net.git-fetch-with-cli, this field allows you to opt-in to fetching advisory databases with the git CLI rather than using gix
.
false
(default) - Fetches advisory databases via gix
true
- Fetches advisory databases using git
. Git must be installed and in PATH
.maximum-db-staleness
field (optional)A duration in RFC3339 format that specifies the maximum amount of time that can pass before the database is considered stale and an error is emitted. This is only checked when advisory database fetching has been disabled via the --offline
or check --disable-fetch
flags, as otherwise the database is always cloned or fetched to be up to date with the remote git repository.
The default if not specified is the same value that cargo-audit
uses, and cargo-deny
has been using, which is P90D
, or 90 days.
The RFC3339 duration format is...not well documented. The official grammar is as follows:
+ dur-second = 1*DIGIT "S"
+ dur-minute = 1*DIGIT "M" [dur-second]
+ dur-hour = 1*DIGIT "H" [dur-minute]
+ dur-time = "T" (dur-hour / dur-minute / dur-second)
+ dur-day = 1*DIGIT "D"
+ dur-week = 1*DIGIT "W"
+ dur-month = 1*DIGIT "M" [dur-day]
+ dur-year = 1*DIGIT "Y" [dur-month]
+ dur-date = (dur-day / dur-month / dur-year) [dur-time]
+
+ duration = "P" (dur-date / dur-time / dur-week)
+
+However, as far as I can tell, there are no official spec compliance tests one can run for the duration formation, and several parsers I found written in other languages seemed to...not actually properly follow the grammar, so the implementation in cargo-deny may be wrong according to the spec, but at least it will be consistently wrong.
+Note that while the spec supports ,
as a decimal separator, for simplicity cargo-deny only supports .
as a decimal separator.
One final note, there are 2 units available in the format that are not exact, namely, year 'Y' and month 'M'. It's not recommended to use either of them for that reason, but if you do they are calculated as follows.
+vulnerability
A vulnerability
advisory was detected for a crate.
notice
A notice
advisory was detected for a crate.
unmaintained
An unmaintained
advisory was detected for a crate.
unsound
An unsound
advisory was detected for a crate.
yanked
A crate using a version that has been yanked from the registry index was detected.
+index-failure
An error occurred trying to read or update the registry index (typically crates.io) so cargo-deny was unable to check the current yanked status for any crate.
+advisory-not-detected
An advisory in advisories.ignore
didn't apply to any crate. This could happen if the advisory was withdrawn, or the version of the crate no longer falls within the range of affected versions the advisory applies to.
unknown-advisory
An advisory in advisories.ignore
wasn't found in any of the configured advisory databases, usually indicating a typo, as advisories, at the moment, are never deleted from the database, at least the canonical advisory-db.
The advisories check is used to detect issues for crates by looking in an advisory database.
+cargo deny check advisories
+
+Security vulnerabilities are generally considered "not great" by most people, luckily, Rust has a great advisory database which cargo-deny can use to check that you don't have any crates with (known) security vulnerabilities.
+You can also use your own advisory databases instead of, or in addition to, the above default, as long as it follows the same format.
+The advisory database also contains advisories for unmaintained crates, which in most cases users will want to avoid in favor of more actively maintained crates.
+[bans]
sectionContains all of the configuration for cargo deny check bans
[bans]
+multiple-versions = "deny"
+wildcards = "deny"
+allow-wildcard-paths = true
+highlight = "simplest-path"
+workspace-default-features = "warn"
+external-default-features = "deny"
+allow = [
+ { name = "all-versionsa" },
+ "version-rangea:<0.1.1",
+ "specific-versionb@0.1.2",
+ "any-version",
+]
+deny = [
+ "specific-versiond@0.1.9",
+ { name = "all-versionsd", wrappers = [
+ "specific-versiona",
+ ], reason = "we want to get rid of this crate but there is still one user of it" },
+]
+skip-tree = [{ name = "blah", depth = 20 }]
+
+[bans.workspace-dependencies]
+duplicates = "allow"
+include-path-dependencies = false
+unused = "allow"
+
+[[bans.skip]]
+name = "rand"
+version = "=0.6.5"
+
+[[bans.features]]
+name = "featured-krate"
+version = "1.0"
+deny = ["bad-feature"]
+allow = ["good-feature"]
+exact = true
+reason = "`bad-feature` is bad"
+
+[bans.build]
+allow-build-scripts = [{ name = "all-versionsa" }]
+executables = "warn"
+interpreted = "deny"
+script-extensions = ["cs"]
+enable-builtin-globs = true
+include-dependencies = true
+include-workspace = true
+include-archives = true
+
+[[bans.build.bypass]]
+name = "allversionsa"
+build-script = "5392f0e58ad06e089462d93304dfe82337acbbefb87a0749a7dc2ed32af04af7"
+required-features = ["feature-used-at-build-time"]
+allow-globs = ["scripts/*.cs"]
+allow = [
+ { path = "bin/x86_64-linux", checksum = "5392f0e58ad06e089462d93304dfe82337acbbefb87a0749a7dc2ed32af04af7" },
+]
+
+multiple-versions
field (optional)Determines what happens when multiple versions of the same crate are encountered.
+deny
- Will emit an error for each crate with duplicates and fail the check.warn
(default) - Prints a warning for each crate with duplicates, but does not fail the check.allow
- Ignores duplicate versions of the same crate.multiple-versions-include-dev
field (optional)If true
, dev-dependencies
are included when checking for multiple versions of crates. By default this is false, and any crates that are only reached via dev dependency edges are ignored when checking for multiple versions. Note that this also means that skip
and skip
tree are not used, which may lead to warnings about unused configuration.
wildcards
field (optional)Determines what happens when a dependency is specified with the *
(wildcard) version.
deny
- Will emit an error for each crate specified with a wildcard version.warn
(default) - Prints a warning for each crate with a wildcard version, but does not fail the check.allow
- Ignores all wildcard version specifications.allow-wildcard-paths
field (optional)If specified, alters how the wildcard
field behaves:
dependencies
in private crates will no longer emit a warning or error.dev-dependencies
in both public and private crates will no longer emit a warning or error.dependencies
and build-dependencies
in public crates will continue to produce warnings and errors.Being limited to private crates is due to crates.io not allowing packages to be published with path
or git
dependencies except for dev-dependencies
.
workspace-dependencies
field (optional)Used to configure how [workspace.dependencies]
are treated.
[bans.workspace-dependencies]
+duplicates = 'deny'
+include-path-dependencies = true
+unused = 'deny'
+
+duplicates
field (optional)Determines what happens when more than 1 direct workspace dependency is resolved to the same crate and 1 or more declarations do not use workspace = true
deny
(default) - Will emit an error for each dependency declaration that does not use workspace = true
warn
- Will emit a warning for each dependency declaration that does not use workspace = true
, but does not fail the check.allow
- Ignores checking for workspace = true
for dependencies in workspace cratesinclude-path-dependencies
field (optional)If true, path dependencies will be included in the duplication check, otherwise they are completely ignored.
+unused
field (optional)Determines what happens when a dependency in [workspace.dependencies]
is not used in the workspace.
deny
(default) - Will emit an error for each dependency that is not actually used in the workspace.warn
- Will emit a warning for each dependency that is not actually used in the workspace, but does not fail the check.allow
- Ignores checking for unused workspace dependencies.highlight
field (optional)When multiple versions of the same crate are encountered and multiple-versions
is set to warn
or deny
, using the -g <dir>
option will print out a dotgraph of each of the versions and how they were included into the graph. This field determines how the graph is colored to help you quickly spot good candidates for removal or updating.
lowest-version
- Highlights the path to the lowest duplicate version. Highlighted in simplest-path
- Highlights the path to the duplicate version with the fewest number of total edges to the root of the graph, which will often be the best candidate for removal and/or upgrading. Highlighted in .all
- Highlights both the lowest-version
and simplest-path
. If they are the same, they are only highlighted in .deny
field (optional)deny = ["package-spec"]
+
+Determines specific crates that are denied. Each entry uses the same PackageSpec as other parts of cargo-deny's configuration.
+wrappers
field (optional)deny = [{ crate = "crate-you-don't-want:<=0.7.0", wrappers = ["this-can-use-it"] }]
+
+This field allows specific crates to have a direct dependency on the banned crate but denies all transitive dependencies on it.
+deny-multiple-versions
field (optional)multiple-versions = 'allow'
+deny = [{ crate = "crate-you-want-only-one-version-of", deny-multiple-versions = true }]
+
+This field allows specific crates to deny multiple versions of themselves, but allowing or warning on multiple versions for all other crates. This field cannot be set simultaneously with wrappers
.
deny.reason
field (optional)deny = [{ crate = "package-spec", reason = "the reason this crate is banned"}]
+
+This field provides the reason the crate is banned as a string (eg. a simple message or even a url) that is surfaced in diagnostic output so that the user does not have to waste time digging through history or asking maintainers why this is the case.
+deny.use-instead
field (optional)deny = [{ crate = "openssl", use-instead = "rustls"}]
+
+This is a shorthand for the most common case for banning a particular crate, which is that your project has chosen to use a different crate for that functionality.
+allow
field (optional)deny = ["package-spec"]
+
+Determines specific crates that are allowed. If the allow
list has one or more entries, then any crate not in that list will be denied, so use with care. Each entry uses the same PackageSpec as other parts of cargo-deny's configuration.
allow.reason
field (optional)allow = [{ crate = "package-spec", reason = "the reason this crate is allowed"}]
+
+This field provides the reason the crate is allowed as a string (eg. a simple message or even a url) that is surfaced in diagnostic output so that the user does not have to waste time digging through history or asking maintainers why this is the case.
+external-default-features
field (optional)Determines the lint level used for when the default
feature is enabled on a crate not in the workspace. This lint level will can then be overridden on a per-crate basis if desired.
For example, if an-external-crate
had the default
feature enabled it could be explicitly allowed.
[bans]
+external-default-features = "deny"
+
+[[bans.features]]
+crate = "an-external-crate"
+allow = ["default"]
+
+workspace-default-features
field (optional)The workspace version of external-default-features
.
[bans]
+external-default-features = "allow"
+
+[[bans.features]]
+crate = "a-workspace-crate"
+deny = ["default"]
+
+features
field (optional)[[bans.features]]
+crate = "featured-krate:1.0"
+deny = ["bad-feature"]
+allow = ["good-feature"]
+exact = true
+
+Allows specification of crate specific allow/deny lists of features. Each entry uses the same PackageSpec as other parts of cargo-deny's configuration.
+features.deny
field (optional)Denies specific features for the crate.
+features.allow
field (optional)Allows specific features for the crate, enabled features not in this list are denied.
+features.exact
field (optional)If specified, requires that the features in allow
exactly match the features enabled on the crate, and will fail if features are allowed that are not enabled.
skip
field (optional)skip = [
+ "package-spec",
+ { crate = "package-spec", reason = "an old version is used by crate-x, see <PR link> for updating it" },
+]
+
+When denying duplicate versions, it's often the case that there is a window of time where you must wait for, for example, PRs to be accepted and new version published, before 1 or more duplicates are gone. The skip
field allows you to temporarily ignore a crate during duplicate detection so that no errors are emitted, until it is no longer need.
It is recommended to use specific version constraints for crates in the skip
list, as cargo-deny will emit warnings when any entry in the skip
list no longer matches a crate in your graph so that you can cleanup your configuration.
Each entry uses the same PackageSpec as other parts of cargo-deny's configuration.
+skip-tree
field (optional)skip-tree = [
+ "windows-sys<=0.52", # will skip this crate and _all_ direct and transitive dependencies
+ { crate = "windows-sys<=0.52", reason = "several crates use the outdated 0.42 and 0.45 versions" },
+ { crate = "windows-sys<=0.52", depth = 3, reason = "several crates use the outdated 0.42 and 0.45 versions" },
+]
+
+When dealing with duplicate versions, it's often the case that a particular crate acts as a nexus point for a cascade effect, by either using bleeding edge versions of certain crates while in alpha or beta, or on the opposite end of the spectrum, a crate is using severely outdated dependencies while much of the rest of the ecosystem has moved to more recent versions. In both cases, it can be quite tedious to explicitly skip
each transitive dependency pulled in by that crate that clashes with your other dependencies, which is where skip-tree
comes in.
skip-tree
entries are similar to skip
in that they are used to specify a crate name and version range that will be skipped, but they also have an additional depth
field used to specify how many levels from the crate will also be skipped. A depth of 0
would be the same as specifying the crate in the skip
field.
Note that by default, the depth
is infinite.
Each entry uses the same PackageSpec as other parts of cargo-deny's configuration.
+NOTE: skip-tree
is a very big hammer, and should be used with care.
build
field (optional)The build
field contains configuration for raising diagnostics for crates that execute at compile time, either because they have a build script, or they are a procedural macro. The configuration is (currently) focused on diagnostics around specific file types, as configured via extension glob patterns, as well as executables, either native or in the form of interpreted shebang scripts.
While the intention of this configuration is to raise awareness of crates that have or use precompiled binaries or scripts, or otherwise contain file types that you want to be aware of, the compile time crate linting supplied by cargo-deny does NOT protect you from actively malicious code.
+A quick run down of things that cargo-deny WILL NOT DETECT.
+include!()
for code that is benign in one version, then replaces it with something malicious without triggering a checksum mismatch on the build script contents itself.So all this is to say, cargo-deny
(currently) is only really useful for analyzing when crates have native executables, and/or the crate maintainers have either forgotten or purposefully left helper scripts for their CI/release management/etc in the crate source that are not actually ever executed automatically.
allow-build-scripts
field (optional)Specifies all the crates that are allowed to have a build script. If this option is omitted, all crates are allowed to have a build script, and if this option is set to an empty list, no crate is allowed to have a build script.
+executables
field (optional)This controls how native executables are handled. Note this check is done by actually reading the file headers from disk so that this check works on Windows as well, ie the executable bit is irrelevant.
+deny
(default) - Emits an error when native executables are detected.warn
- Prints a warning when native executables are detected, but does not fail the check.allow
- Prints a note when native executables are detected, but does not fail the check.This check currently only handles the major executable formats.
+ +interpreted
field (optional)This controls how interpreted scripts are handled. Note this check is done by actually reading the file header from disk so that this check works on Windows as well, ie the executable bit is irrelevant.
+deny
- Emits an error when interpreted scripts are detected.warn
- Prints a warning when interpreted scripts are detected, but does not fail the check.allow
(default) - Prints a note when interpreted scripts are detected, but does not fail the check.script-extensions
field (optional)If supplied scans crates that execute at compile time for any files with the specified extension(s), emitting an error for every one that matches.
+enable-builtin-globs
field (optional)If true
, enables the builtin glob patterns for common languages that tend to by installed on most developer machines, such as python.
# List of "common" patterns for scripting languages or easily executable
+# compiled languages that could be used for local execution with build scripts
+# or proc macros. Obviously this list is not and never can be complete since
+# in most cases extensions are only for humans and most tools will happily
+# execute scripts/code they can regardless of extension (eg. shell scripts),
+# and besides that, an _actually_ malicious crate could generate files on demand,
+# download from a remote location, or, really, anything
+globs = [
+ "*.bat", "*.cmd", # batch
+ "*.go", # Go `go run <file.go>`
+ "*.java", # Java `java <file.java>`
+ "*.js", "*._js", "*.es", "*.es6", # javascript
+ "*.pl", "*.perl", "*.pm", # perl
+ "*.6pl", "*.6pm", "*.p6", "*.p6l", "*.p6m", "*.pl6", "*.pm6", "*.t", # perl 6
+ "*.ps1", "*.psd1", "*.psm1", # powershell
+ "*.py", # python
+ "*.rb", # ruby
+ "*.sh", "*.bash", "*.zsh", # shell
+]
+
+include-dependencies
field (optional)By default, only the crate that executes at compile time is scanned, but if set to true
, this field will check this crate as well as all of its dependencies. This option is disabled by default, as this will tend to only find CI scripts that people leave in their published crates.
include-workspace
field (optional)If true
, workspace crates will also be scanned. This defaults to false as you presumably have some degree of trust for your own code.
include-archives
field (optional)If true
, archive files (eg. Windows .lib, Unix .a, C++ .o object files etc) are also counted as native code. This defaults to false, as these tend to need to be linked before they can be executed.
bypass
field (optional)While all the previous configuration is about configuration the global checks that run on compile time crates, the allow
field is how one can suppress those lints on a crate-by-crate basis.
Each entry uses the same PackageSpec as other parts of cargo-deny's configuration.
+[build.bypass]
+crate = "crate-name"
+
+build-script
and required-features
field (optional)If set to a valid, 64-character hexadecimal SHA-256, the build-script
field will cause the rest of the scanning to be bypassed if the crate's build script's checksum matches the user specified checksum AND none of the features specified in the required-features
field are enabled. If the checksum does not match, the calculated checksum will be emitted as a warning, and the crate will be scanned as if a checksum was not supplied.
NOTE: These options only applies to crate with build scripts, not proc macros, as proc macros do not have a single entry point that can be easily checksummed.
+[[build.bypass]]
+name = "crate-name"
+build-script = "5392f0e58ad06e089462d93304dfe82337acbbefb87a0749a7dc2ed32af04af7"
+
+allow-globs
field (optional)Bypasses scanning of files that match one or more of the glob patterns specified. Note that unlike the script-extensions
field that applies to all crates, these globs can match anything, not just extensions.
[build]
+script-extensions = ["cs"]
+
+[[build.bypass]]
+crate = "crate-name"
+allow-globs = [
+ "scripts/*.cs",
+]
+
+bypass.allow
field (optional)Bypasses scanning a single file.
+[build]
+executables = "deny"
+
+[[build.bypass]]
+crate = "crate-name"
+allow = [
+ { path = "bin/x86_64-linux", checksum = "5392f0e58ad06e089462d93304dfe82337acbbefb87a0749a7dc2ed32af04af7" }
+]
+
+path
fieldThe path, relative to the crate root, of the file to bypass scanning.
+checksum
field (optional)The 64-character hexadecimal SHA-256 checksum of the file. If the checksum does not match, an error is emitted.
+ +banned
A crate which is explicitly banned was detected.
+allowed
A crate which is explicitly allowed was detected.
+not-allowed
When using bans.allow
, a crate was detected that wasn't in that list.
duplicate
One or more duplicate versions of the same crate were detected.
+skipped
A crate version that matched an entry in bans.skip
was encountered.
wildcard
A crate was included via a wildcard dependency by one or more crates.
+workspace-duplicate
A direct workspace dependency was referred to more than once and all declarations did not use workspace = true
unresolved-workspace-dependency
We were unable to determine the exact crate a workspace dependency (or patch) was resolved to. This most likely indicates a bug in cargo-deny.
+unused-workspace-dependency
A [workspace.dependencies]
was declared, but not actually used anywhere in the workspace.
unmatched-skip
A crate version in bans.skip
was not encountered.
unnecessary-skip
A crate specified in bans.skip
was in the graph, but that crate only had one version, making the skip
entry useless.
allowed-by-wrapper
A crate in bans.deny
was allowed since it was directly depended on by a wrappers
crate.
unmatched-wrapper
A crate in bans.deny
had one or more wrappers
crates, but a crate not in that list had a direct dependency on the banned crate.
skipped-by-root
A crate was skipped from being checked as a duplicate due to being transitively referenced by a crate version in bans.skip-tree
.
unmatched-root
A crate version in bans.skip-tree
was not encountered.
build-script-not-allowed
A crate which has been denied because it has a build script but is not part of the bans.allow-build-script
list.
exact-features-mismatch
A crate's features do not exactly match the configured feature set, and bans.features.exact
is true
.
feature-banned
An enabled crate feature is present in the bans.features.deny
list.
unknown-feature
A feature in either bans.features.deny
or bans.features.allow
does not exist for the crate.
default-feature-enabled
The default
feature was enabled on a crate, and the bans.external-default-features
or bans.workspace-default-features
was configured.
path-bypassed
A path specified by bans.build.bypass.allow.path
was bypassed, optionally ensuring its contents matched a SHA-256 checksum.
path-bypassed-by-glob
A path was bypassed due to matching one or more glob patterns.
+checksum-match
The SHA-256 checksum calculated for the contents of a file matched the checksum in the configuration.
+checksum-mismatch
The SHA-256 checksum calculated for the contents of a file did not match the checksum in the configuration.
+denied-by-extension
The file extension matched either a user specified or builtin extension.
+detected-executable
A native executable was detected.
+detected-executable-script
An interpreted script was detected.
+unable-to-check-path
An I/O error occurred when opening or reading a file from disk.
+features-enabled
One or more required-features
were enabled, causing the build-script
bypass to be ignored.
unmatched-bypass
A crate bypass did not match any crate in the graph.
+unmatched-path-bypass
A path bypass did not match a file in the crate.
+unmatched-glob
A glob bypass did not match any files in the crate.
+ +The bans check is used to deny (or allow) specific crates, as well as detect and handle multiple versions of the same crate.
+cargo deny check bans
+
+Sometimes, certain crates just don't fit in your project, so you have to remove them. However, nothing really stops them from sneaking back in due to innocuous changes like doing a cargo update
and getting it transitively, or even forgetting to set default-features = false, features = ["feature-without-the-thing"]
when the crate is pulled in via the default features of a crate you already depend on, in your entire workspace.
For example, we previously depended on OpenSSL as it is the "default" for many crates that provide TLS. This was extremely annoying as it required us to have OpenSSL development libraries installed on Windows, for both individuals and CI. We moved all of our dependencies to use the much more streamlined native-tls
or ring
crates instead, and now we can make sure that OpenSSL doesn't return from the grave by accident.
The larger your project and number of external dependencies, the likelihood that you will have multiple versions of the same crate rises. This is due to two fundamental aspects of the Rust ecosystem.
+This tradeoff of allowing multiple version of the same crate is one of the reasons that cargo is such a pleasant experience for many people new to Rust, but as with all tradeoffs, it does come with costs.
+Normally, you will not really notice that you have multiple versions of the same crate unless you constantly watch your build log, but as mentioned above, it does introduce paper cuts into your workflows.
+The intention of duplicate detection in cargo-deny is not to "correct" cargo's behavior, but rather to draw your attention to duplicates so that you can make an informed decision about how to handle the situation.
+The top level config for cargo-deny, by default called deny.toml
.
[graph]
+# cargo-deny is really only ever intended to run on the "normal" tier-1 targets
+targets = [
+ "x86_64-unknown-linux-gnu",
+ "aarch64-unknown-linux-gnu",
+ "x86_64-unknown-linux-musl",
+ "aarch64-apple-darwin",
+ "x86_64-apple-darwin",
+ "x86_64-pc-windows-msvc",
+]
+all-features = true
+
+[advisories]
+version = 2
+ignore = [
+]
+
+[bans]
+multiple-versions = "deny"
+wildcards = 'deny'
+deny = [
+ { crate = "git2", use-instead = "gix" },
+ { crate = "openssl", use-instead = "rustls" },
+ { crate = "openssl-sys", use-instead = "rustls" },
+ "libssh2-sys",
+ { crate = "cmake", use-instead = "cc" },
+ { crate = "windows", reason = "bloated and unnecessary", use-instead = "ideally inline bindings, practically, windows-sys" },
+]
+skip = [
+ { crate = "hashbrown@0.14.5", reason = "gix uses this old version" },
+]
+skip-tree = [
+ { crate = "windows-sys@0.52.0", reason = "a foundational crate for many that bumps far too frequently to ever have a shared version" },
+ { crate = "thiserror@1.0.69", reason = "gix depends on both the 1.0 and 2.0 versions" },
+]
+
+[sources]
+unknown-registry = "deny"
+unknown-git = "deny"
+
+[licenses]
+# We want really high confidence when inferring licenses from text
+confidence-threshold = 0.93
+allow = [
+ "Apache-2.0",
+ "Apache-2.0 WITH LLVM-exception",
+ "MIT",
+ "MPL-2.0",
+ "BSD-3-Clause",
+ "ISC",
+ "Unicode-3.0",
+]
+exceptions = [
+ # Use exceptions for these as they only have a single user
+ { allow = ["Zlib"], crate = "tinyvec" },
+ { allow = ["Unicode-DFS-2016"], crate = "unicode-ident" },
+ { allow = ["OpenSSL"], crate = "ring" },
+]
+
+# Sigh
+[[licenses.clarify]]
+crate = "ring"
+# SPDX considers OpenSSL to encompass both the OpenSSL and SSLeay licenses
+# https://spdx.org/licenses/OpenSSL.html
+# ISC - Both BoringSSL and ring use this for their new files
+# MIT - "Files in third_party/ have their own licenses, as described therein. The MIT
+# license, for third_party/fiat, which, unlike other third_party directories, is
+# compiled into non-test libraries, is included below."
+# OpenSSL - Obviously
+expression = "ISC AND MIT AND OpenSSL"
+license-files = [{ path = "LICENSE", hash = 0xbd0eed23 }]
+
+[[licenses.clarify]]
+crate = "webpki"
+expression = "ISC"
+license-files = [{ path = "LICENSE", hash = 0x001c7e6c }]
+
+# Actually "ISC-style"
+[[licenses.clarify]]
+crate = "rustls-webpki"
+expression = "ISC"
+license-files = [{ path = "LICENSE", hash = 0x001c7e6c }]
+
+graph
field (optional)The graph tables provides configuration options for how the dependency graph that the various checks are executed against is constructed.
+[graph]
+targets = [
+ "x86_64-unknown-linux-gnu",
+ { triple = "aarch64-apple-darwin" },
+ { triple = "x86_64-pc-windows-msvc", features = ["sse2"] },
+]
+exclude = ["some-crate@0.1.0"]
+all-features = true
+no-default-features = false
+features = ["some-feature"]
+exclude-dev = true
+
+targets
field (optional)By default, cargo-deny will consider every single crate that is resolved by cargo, including target specific dependencies eg
+[target.x86_64-pc-windows-msvc.dependencies]
+winapi = "0.3.8"
+
+[target.'cfg(target_os = "fuchsia")'.dependencies]
+fuchsia-cprng = "0.1.1"
+
+But unless you are actually targeting x86_64-fuchsia
or aarch64-fuchsia
, the fuchsia-cprng
is never actually going to be compiled or linked into your project, so checking it is pointless for you.
The targets
field allows you to specify one or more targets which you actually build for. Every dependency link to a crate is checked against this list, and if none of the listed targets satisfy the target constraint, the dependency link is ignored. If a crate has no dependency links to it, it is not included into the crate graph that the checks are executed against.
targets.triple
field (optional) or "<triple_string>"
The target triple for the target you wish to filter target specific dependencies with. If the target triple specified is not one of the targets builtin to rustc
, the configuration check for that target will be limited to only the raw [target.<target-triple>.dependencies]
style of target configuration, as cfg()
expressions require us to know the details about the target.
targets.features
field (optional)Rust cfg()
expressions support the target_feature = "feature-name"
predicate, but at the moment, the only way to actually pass them when compiling is to use the RUSTFLAGS
environment variable. The features
field allows you to specify 1 or more target_feature
s you plan to build with, for a particular target triple. At the time of this writing, cargo-deny does not attempt to validate that the features you specify are actually valid for the target triple, but this is planned.
exclude
field (optional)Just as with the --exclude
command line option, this field allows you to specify one or more Package ID specifications that will cause the crate(s) in question to be excluded from the crate graph that is used for the operation you are performing.
Note that excluding a crate is recursive, if any of its transitive dependencies are only referenced via the excluded crate, they will also be excluded from the crate graph.
+all-features
field (optional)If set to true
, --all-features
will be used when collecting metadata.
no-default-features
field (optional)If set to true
, --no-default-features
will be used when collecting metadata.
features
field (optional)If set, and --features
is not specified on the cmd line, these features will be used when collecting metadata.
exclude-dev
field (optional)If set to true
, all dev-dependencies
, even one for workspace crates, are not included in the crate graph used for any of the checks. This option can also be enabled on cmd line with --exclude-dev
either before or after the check
subcommand.
exclude-unpublished
field (optional)If set to true
, workspace crates marked as publish = false
will not be used as roots in the dependency graph, meaning they, and any dependencies they have that aren't directly or indirectly referenced by workspace crates that are published, will be excluded from the dependency graph that checks are executed against.
output
field (optional)feature-depth
field (optional)The maximum depth that features will be displayed when inclusion graphs are included in diagnostics, unless specified via --feature-depth
on the command line. Only applies to diagnostics that actually print features. If not specified defaults to 1
.
Many configuration options require a package specifier at a minimum, which we'll describe here. The options that use package specifiers will be called out in their individual documentation. We'll use the bans.deny
option in the following examples.
If the particular only requires a package spec at a minimum, then the string format can be used, which comes in three forms.
+# Will match any version of the simple crate
+deny = ["simple"]
+
+The simplest string is one which is just the crate name. In this case, the version requirement used when checking will be *
meaning it will match against all versions of that crate in the graph.
# Will match only this versions of the simple crate that match the predicate(s)
+deny = ["simple:<=0.1,>0.2"]
+
+If you want to apply version requirements (predicates) to the crate, simply append them following a :
separator.
# Will match only this exact version of the simple crate
+deny = [
+ "simple@0.1.0",
+ # This is semantically equivalent to the above
+ "simple:=0.1.0",
+]
+
+The exact form is a specialization of the version requirements, where the semver after the @
is transformed to be = (Exact).
deny = [
+ { crate = "simple@0.1.0" }, # equivalent to "simple@0.1.0"
+ { crate = "simple", wrappers = ["example"] },
+]
+
+The crate format is a replacement for the old name
and/or version
table format. It uses the string format described above in a single crate
key.
deny = [
+ { name = "simple" },
+ { name = "simple", version = "*" }
+ { name = "simple", wrappers = ["example"] }
+]
+
+The old format uses a required name
key and an optional version
key. This format is deprecated and should not be used.
[licenses]
sectionSee the licenses config for more info.
+[bans]
sectionSee the bans config for more info.
+[advisories]
sectionSee the advisories config for more info.
+[sources]
sectionSee the sources config for more info.
+ +cargo-deny supports several different classes of checks that can be performed on your project's crate graph. By default, cargo deny check
will execute all of the supported checks, falling back to the default configuration for that check if one is not explicitly specified.
Checks the license information for each crate.
+Checks for specific crates in your graph, as well as duplicates.
+Checks advisory databases for crates with security vulnerabilities, or that have been marked as Unmaintained
, or which have been yanked from their source registry.
Checks the source location for each crate.
+ +[licenses]
sectionContains all of the configuration for cargo deny check license
.
[licenses]
+unused-allowed-license = "warn"
+confidence-threshold = 0.95
+allow = [
+ "EUPL-1.2",
+ "Apache-2.0 WITH LLVM-exception",
+]
+
+[licenses.private]
+ignore = true
+registries = ["sekrets"]
+
+[[licenses.exceptions]]
+allow = ["Zlib"]
+name = "adler32"
+version = "0.1.1"
+
+[[licenses.clarify]]
+name = "ring"
+expression = "MIT AND ISC AND OpenSSL"
+license-files = [
+ { path = "LICENSE", hash = 0xbd0eed23 }
+]
+
+All identifiers used in the license configuration section are expected to be valid SPDX v2.1 short identifiers, either from version 3.11 of the SPDX License List, or use a custom identifier by prefixing it with LicenseRef-
.
allow = [
+ # The Apache license identifier
+ "Apache-2.0",
+ # A custom license identifier
+ "LicenseRef-Embark-Custom",
+]
+
+# Custom license refs can be specified for crates which don't use a license
+# in the SPDX list
+[[licenses.clarify]]
+crate = "a-crate"
+expression = "LicenseRef-Embark-Custom"
+license-files = [
+ { path = "LICENSE", hash = 0x001c7e6c },
+]
+
+License identifiers can also be coupled with an optional exception by appending WITH <exception-id>
to the license identifier. Licenses coupled with exceptions are considered distinct from the same license without the exception.
allow = [
+ # The Apache license identifier
+ "Apache-2.0",
+ # The Apache license + LLVM-exception
+ "Apache-2.0 WITH LLVM-exception",
+]
+
+include-dev
field (optional)If true
, licenses are checked even for dev-dependencies
. By default this is false as dev-dependencies
are not used by downstream crates, nor part of binary artifacts.
version
field (optional)version = 2
+
+The version field is (at the time of this writing) no longer used, the following fields have been removed and will now emit errors.
+unlicensed
- Removed, if a crate is unlicensed you should open an issue/PR to fix it, and in the meantime, you may add a clarification.deny
- Removed, all licenses are denied unless explicitly allowedcopyleft
- Removed, all licenses are denied unless explicitly allowedallow-osi-fsf-free
- Removed, all licenses are denied unless explicitly alloweddefault
- Removed, all licenses are denied unless explicitly allowedallow
field (optional)The licenses that are explicitly allowed.
+The GNU licenses are, of course, different from all the other licenses in the SPDX list which makes them annoying to deal with. When supplying one of the above licenses, to either allow
or deny
, you must not use the suffixes -only
or -or-later
, as they can only be used by the license holder themselves to decide under which terms to license their code.
So, for example, if you wanted to disallow GPL-2.0
licenses, but allow GPL-3.0
licenses, you could use the following configuration.
[licenses]
+allow = [ "GPL-3.0" ]
+
+This gets worse with the GFDL licenses, which also have an invariants
modifier. Before licenses are checked they are normalized to make them consistent for all licenses.
Let's use GFDL-1.2
to show how license requirements are normalized.
GFDL-1.2-invariants-only
=> GFDL-1.2-invariants
GFDL-1.2-invariants-or-later
=> GFDL-1.2-invariants+
GFDL-1.2-no-invariants-only
=> GFDL-1.2
GFDL-1.2-no-invariants-or-later
=> GFDL-1.2+
GFDL-1.2-only
=> GFDL-1.2
GFDL-1.2-or-later
=> GFDL-1.2+
So, for example, if you wanted to allow all version (1.1, 1.2, and 1.3), but only invariants for 1.3 you could use the following configuration.
+[licenses]
+allow = [ "GFDL-1.1", "GFDL-1.2", "GFDL-1.3", "GFDL-1.3-variants"]
+
+exceptions
field (optional)The license configuration generally applies to the entire crate graph, but this means that allowing any one license applies to all possible crates, even if only 1 crate actually uses that license. The exceptions
field is meant to allow additional licenses only for particular crates, to make a clear distinction between licenses which you are fine with everywhere, versus ones which you want to be more selective about, and not have implicitly allowed in the future.
This field uses PackageSpecs to select the crate the exception applies to.
+In some cases it's useful to have global cargo-deny config and project-local exceptions. This can be accomplished with a project exceptions file in any of these locations relative to your top level Cargo.toml
manifest file.
cargo-deny
will look for the following files: <cwd>/deny.exceptions.toml
, <cwd>/.deny.exceptions.toml
and <cwd>/.cargo/deny.exceptions.toml
Only the exceptions field should be set:
+exceptions = [
+ # Each entry is the crate and version constraint, and its specific allow list.
+ { allow = ["CDDL-1.0"], crate = "inferno" },
+]
+
+allow
fieldThis is the exact same as the general allow
field.
[licenses]
+allow = [
+ "Apache-2.0",
+ "MIT",
+]
+exceptions = [
+ # This is the only crate that cannot be licensed with either Apache-2.0
+ # or MIT, so we just add an exception for it, meaning we'll get a warning
+ # if we add another crate that also requires this license
+ { crate = "cloudabi", allow = ["BSD-2-Clause"] },
+]
+
+confidence-threshold
field (optional)cargo-deny
uses askalono to determine the license of a LICENSE file. Due to variability in license texts because of things like authors, copyright year, and so forth, askalano assigns a confidence score to its determination, from 0.0
(no confidence) to 1.0
(perfect match). The confidence threshold value is used to reject the license determination if the score does not match or exceed the threshold.
0.0
- 1.0
(default 0.8
)
clarify
field (optional)In some exceptional cases, a crate will not have easily machine readable license information, and would by default be considered "unlicensed" by cargo-deny. As a (hopefully) temporary patch for using the crate, you can specify a clarification for the crate by manually assigning its SPDX expression, based on one or more files in the crate's source. cargo-deny will use that expression for as long as the source files in the crate exactly match the clarification's hashes.
+This field uses PackageSpecs to select the crate the clarification applies to.
+[[licenses.clarify]]
+crate = "webpki"
+expression = "ISC"
+license-files = [
+ { path = "LICENSE", hash = 0x001c7e6c },
+]
+
+expression
fieldThe SPDX license expression you are specifying as the license requirements for the crate.
+license-files
fieldContains one or more files that will be checked to ensure the license expression still applies to a version of the crate.
+path
fieldThe crate relative path to a file to be used as a source of truth.
+hash
fieldAn opaque hash calculated from the file contents. This hash can be obtained from the output of the license check when cargo-deny can't determine the license of the file in question.
+private
field (optional)It's often not useful or wanted to check for licenses in your own private workspace crates. So the private field allows you to do so.
+ignore
fieldIf true
, workspace members will not have their license expression checked if they are not published.
# Cargo.toml
+[package]
+name = "sekret"
+license = "¯\_(ツ)_/¯"
+publish = false # "private"!
+
+# deny.toml
+[licenses]
+# The sekret package would be ignored now
+private = { ignore = true }
+
+registries
fieldA list of private registries you may publish your workspace crates to. If a workspace member only publishes to private registries, it will also be ignored if private.ignore = true
# Cargo.toml
+[package]
+name = "sekret"
+license = "¯\_(ツ)_/¯"
+publish = ["sauce"]
+
+# deny.toml
+[licenses]
+# Still ignored!
+private = { ignore = true, registries = ["sauce"] }
+
+ignore-sources
fieldA list of registries that crates can be sourced from that will not have their licenses checked.
+# deny.toml
+[licenses.private]
+ignore = true
+ignore-sources = ["https://sekretz.com/super/secret-index"]
+
+unused-allowed-license
field (optional)Determines what happens when one of the licenses that appears in the allow
list is not encountered in the dependency graph.
warn
(default) - A warning is emitted for each license that appears in license.allow
but which is not used in any crate.allow
- Unused licenses in the licenses.allow
list are ignored.deny
- An unused license in the licenses.allow
list triggers an error, and cause the license check to fail.rejected
One or more licenses for a crate were rejected because they were not configured to be allowed.
+accepted
The license expression for a crate was allowed, though there may be warnings.
+unlicensed
No license expression could be found for a crate and it is considered unlicensed.
+skipped-private-workspace-crate
A workspace member is publish = false
and was skipped.
license-not-encountered
A license in licenses.allow
was not found in any crate.
This diagnostic can be silenced by configuring the licenses.unused-allowed-license
field to "allow".
license-exception-not-encountered
A licenses.exception
was not used as the crate it applied to was not encountered.
The licenses check is used to verify that every crate you use has license terms you find acceptable. cargo-deny does this by evaluating the license requirements specified by each crate against the configuration you've specified, to determine if your project meets that crate's license requirements.
+cargo deny check licenses
+
+cargo-deny uses SPDX license expressions to interpret the license requirements of a crate. In the event that it cannot obtain an SPDX license expression directly from metadata, it tries to +derive such within the confidence threshold you specify. Note that cargo-deny currently does not exhaustively search the entirety of the source code of every crate to find every possible license that could be attributed to the crate. There are many edge cases to that approach, and human ingenuity, or even human error, can always outwit a statically-compiled program.
+cargo-deny makes a good-faith assumption each crate correctly defines its license requirements. In the (in our experience, rare) circumstance such data cannot be gathered automatically, it provides a mechanism for manually specifying the license requirements for crates.
+The source of the SPDX expression used to evaluate the crate's licensing requirement is obtained in the following order:
+license
field from the crate's Cargo.toml manifest will be used if it exists.license-file
field, as well as all other LICENSE(-*)?
files will be parsed to determine the SPDX license identifier, and then all of those identifiers will be joined with the AND
operator, meaning that you must accept all of the licenses detected.Importantly, this precedence, combined with the trust that licensing data is handled correctly, means the following edge cases are not handled. This is not an exhaustive list, but are rather a sample of the kinds of things a program is not able to completely prevent, even if more checks are added:
+LICENSE
. There is no guarantee such placements inside a package would lose their legal force, even if there is other licensing data that cargo-deny may detect first and assume is comprehensive.[sources]
sectionContains all of the configuration for cargo deny check sources
[sources]
+unknown-registry = "allow"
+unknown-git = "deny"
+required-git-spec = "tag"
+allow-registry = [
+ "https://sekretz.com/registry/index",
+ "sparse+https://fake.sparse.com",
+]
+allow-git = [
+ "https://notgithub.com/orgname/reponame.git",
+]
+private = [
+ "https://internal-host/repos",
+]
+[sources.allow-org]
+github = [
+ "yourghid",
+ "YourOrg",
+]
+gitlab = [
+ "gitlab-org",
+]
+bitbucket = [
+ "atlassian",
+]
+
+unknown-registry
field (optional)Determines what happens when a crate from a crate registry that is not in the allow-registry
list is encountered.
deny
- Will emit an error with the URL of the source, and fail the check.warn
(default) - Prints a warning for each crate, but does not fail the check.allow
- Prints a note for each crate, but does not fail the check.unknown-git
field (optional)Determines what happens when a crate from a git repository not in the allow-git
list is encountered.
deny
- Will emit an error with the URL of the repository, and fail the check.warn
(default) - Prints a warning for each crate, but does not fail the check.allow
- Prints a note for each crate, but does not fail the check.required-git-spec
(optional)Determines which specifiers are required for git sources. Git sources are a convenient way to use patched code temporarily, but they have downsides for long term maintenance, as the specifier you use for the source determines what happens when you do a cargo update
, and in the default case, this means you essentially have a wildcard dependency on the repository.
This configuration value allows you to control what specifiers you want to allow for your git sources to reduce surprises. The following values are listed in order from least to most specific, and using a less specific specifier will also allow all of the more specific ones.
+any
(default) - Allows all git specs, including the default of not having
+any specifier, which tracks the latest commit on the master
branch of the repobranch
- Allows the branch = "<branch_name>"
specifier.tag
- Allows the tag = "<tag_name>"
specifier.rev
- Allows the rev = "<commit_sha>"
specifier.allow-git
field (optional)Configure which git urls are allowed for crate sources. If a crate's source is not in one of the listed urls, then the unknown-git
setting will determine how it is handled. Note that the url must match exactly, though .git
is stripped if it exists to match the logic of cargo.
[sources]
+allow-git = [
+ "https://github.com/EmbarkStudios/cargo-deny",
+]
+
+private
field (optional)Similarly to allow-git
, allows you to configure urls, however, unlike allow-git
which is meant for a single, exact, url, private
urls actually allow any git repo url which matches the host and begins with the same path. This field is primarily meant to support the use of internal/private git hosts (usually on a VPN) without needing to specify each individual repo. Of course, this can be used to also just allow every repo on Github, but this is not recommended. 😉
[sources]
+private = [
+ "https://super-duper-sekret",
+]
+
+allow-registry
field (optional)The list of registries that are allowed. If a crate is not found in one of the listed registries, then the unknown-registry
setting will determine how it is handled.
If not specified, this list will by default contain the crates.io registry, equivalent to this:
+[sources]
+allow-registry = [
+ "https://github.com/rust-lang/crates.io-index",
+]
+
+To not allow any crates registries, set it to empty:
+[sources]
+unknown-registry = "deny"
+allow-registry = []
+
+allow-org
field (optional)Generally, I think most projects in the Rust space probably follow a similar procedure as we do when they want to fix a bug or add a feature to one of their dependencies, which is basically.
+path
dependency to the cloned forkpath
dependency to a git
dependency and point it to your fork for others/CI to be able to use the same changes easilygit
source to point to the original repogit
source and instead point at the new version of the crate with your changesWhen working in a company or organization, it is often the case that all crates will be forked to a shared organization account rather than a personal Github account. However, if you lint your git sources, every new and deleted fork needs to keep that list updated, which is tedious, even if all the forks fall under the same organization (in Github terminology), even though presumably only people you trust have permission to create forks there, and you would like to just blanket trust any repo under that org.
+The allow-org
object allows you to specify multiple organizations or users in several VCS providers to more easily configure git sources for your projects.
github
field (optional)Allows you to specify multiple github.com
organizations to allow as git sources.
[sources.allow-org]
+github = ["YourCoolOrgGoesHere"]
+
+gitlab
field (optional)Allows you to specify multiple gitlab.com
organizations to allow as git sources.
[sources.allow-org]
+gitlab = ["YourCoolOrgGoesHere"]
+
+bitbucket
field (optional)Allows you to specify multiple bitbucket.org
organizations to allow as git sources.
[sources.allow-org]
+bitbucket = ["YourCoolOrgGoesHere"]
+
+
+ git-source-underspecified
A git
source uses a specification that doesn't meet the minimum specifier required by sources.required-git-spec
.
allowed-source
A crate source is explicitly allowed by sources.allow-git
or sources.allow-registry
.
allowed-by-organization
A crate source was explicitly allowed by an entry in sources.allow-org
.
source-not-allowed
A crate's source was not explicitly allowed.
+unmatched-source
An allowed source in sources.allow-git
or sources.allow-registry
was not encountered.
unmatched-organization
An allowed source in sources.allow-org
was not encountered.
The sources check ensures crates only come from sources you trust.
+cargo deny check sources
+
+Cargo can retrieve crates from a variety of sources, namely registries, git repositories, or local file paths. This is great in general and very flexible for development. But, especially when re-routing dependencies to git repositories, increasing the amount of sources that a project has to trust may be something a repository wants to explicitly opt-in to.
+See Why npm lockfiles can be a security blindspot for injecting malicious modules for the motivating reason for why this check was added.
+A project may want to only support local file dependencies, such as having all dependencies vendored into the repository for full control and offline building. This can be achieved by disallowing all git and registry sources to ensure that every dependency is added into your source control rather than via an external source.
+check
commandThe check command is the primary subcommand of cargo-deny as it is what actually runs through all of the crates in your project and checks them against your configuration.
+<which>
The check(s) to perform. By default, all checks will be performed, unless one or more checks are specified here.
+See checks for the list of available checks.
+-A, --allow <ALLOW>
Set lint allowed
+--audit-compatible-output
To ease transition from cargo-audit to cargo-deny, this flag will tell cargo-deny to output the exact same output as cargo-audit would, to stdout
instead of stderr
, just as with cargo-audit.
Note that this flag only applies when the output format is JSON, and note that since cargo-deny supports multiple advisory databases, instead of a single JSON object, there will be 1 for each unique advisory database.
+-c, --config <CONFIG>
Path to the config to use
+Defaults to <cwd>/deny.toml
if not specified
-d, --disable-fetch
Disable fetching of the advisory database
+When running the advisories
check, the configured advisory database will be fetched and opened. If this flag is passed, the database won't be fetched, but an error will occur if it doesn't already exist locally.
This option is also set if the --offline
flag is used in the global options.
--exclude-dev
If set to true
, all dev-dependencies
, even one for workspace crates, are not included in the crate graph used for any of the checks.
-D, --deny <DENY>
Set lint denied
+--feature-depth <FEATURE_DEPTH>
Specifies the depth at which feature edges are added in inclusion graphs
+-g, --graph <GRAPH>
Path to graph_output root directory
+If set, a dotviz graph will be created for whenever multiple versions of the same crate are detected.
+Each file will be created at <dir>/graph_output/<crate_name>.dot
. <dir>/graph_output/*
is deleted and recreated each run.
--hide-inclusion-graph
Hides the inclusion graph when printing out info for a crate
+By default, if a diagnostic message pertains to a specific crate, cargo-deny will append an inverse dependency graph to the diagnostic to show you how that crate was pulled into your project.
+some diagnostic message
+
+the-crate
+├── a-crate
+└── b-crate
+ └── c-crate
+
+-s, --show-stats
Show stats for all the checks, regardless of the log-level
+-W, --warn <WARN>
Set lint warnings
+As of 0.14.1, the exit code for the check command is a bitset of the checks that were executed and had 1 or more errors.
+A script or program can use the following values to determine exactly which check(s) failed.
+advisories
- 0x1
bans
- 0x2
licenses
- 0x4
sources
- 0x8
The subcommands share some common options that can be used before the subcommand.
+--manifest-path
The path to a Cargo.toml
file which is used as the context for operations.
--all-features
(single crate or workspace)Enables all features when determining which crates to consider. Works for both single crates and workspaces.
+--no-default-features
(single crate only)Disables the default
feature for a crate when determining which crates to consider.
--features
(single crate only)Space-separated list of features to enable when determining which crates to consider.
+--workspace
Forces all workspace crates to be used as roots in the crate graph that we operate on, unless they are excluded by other means. By default, if you specify a virtual manifest, all crates in the workspace will be used as roots. However, if you specify a normal package manifest somewhere inside a workspace, only that crate will be used as a graph root, and only other workspaces crates it depends on will be included in the graph. If you want to specify a sub-crate in a workspace, but still include all other crates in the workspace, you can use this flag.
+--exclude-dev
If set to true
, all dev-dependencies
, even one for workspace crates, are not included in the crate graph used for any of the checks.
--exclude
Exclude the specified package(s) from the crate graph. Unlike other cargo subcommands, it doesn't have to be used in conjunction with the --workspace
flag. This flag may be specified multiple times.
This uses a similar (though slightly more strict) Package ID specification to other cargo subcommands.
+Packages can also be excluded in your configuration files, specifying this on the command line will append the package ID to the list that may exist in your configuration.
+-L, --log-level
The log level for messages, only log messages at or above the level will be emitted.
+Possible values:
+off
- No output will be emittederror
warn
(default)info
debug
trace
--format
The format of the output of both log and diagnostic messages.
+Possible values:
+human
(default) - Output for the pesky humansjson
- Each log message/diagnostic is outputted as a single line JSON object--color
Whether coloring is applied to human-formatted output, using it on JSON output has no effect.
+Possible values:
+auto
(default) - Coloring is applied if the output stream is a TTYalways
- Coloring is always appliednever
- No coloring is applied for any output-t, --target
One or more platforms to filter crates with. If a dependency is target specific, it will be ignored if it does not match at least 1 of the specified targets. This overrides the top-level targets = []
configuration value.
--exclude-unpublished
If set, exclude unpublished workspace members from graph roots.
+Workspace members are considered unpublished if they they are explicitly marked with publish = false
. Note that the excluded workspace members are still used for the initial dependency resolution by cargo, which might affect the exact version of used dependencies.
--allow-git-index
If set, the crates.io git index is initialized for use in fetching crate information, otherwise it is enabled only if using a cargo < 1.70.0 without the sparse protocol enabled
+--locked
Asserts that the exact same dependencies and versions are used as when the existing Cargo.lock file was originally generated. Cargo will exit with an error when either of the following scenarios arises:
+--offline
Prevents Cargo and cargo-deny
from accessing the network for any reason. Without this flag, Cargo will stop with an error if it needs to access the network and the network is not available. With this flag, Cargo will attempt to proceed without the network if possible.
Beware that this may result in different dependency resolution than online mode. Cargo will restrict itself to crates that are downloaded locally, even if there might be a newer version as indicated in the local copy of the index. See the cargo-fetch(1) command to download dependencies before going offline.
+cargo-deny
will also not fetch advisory databases with this option, meaning that any new or updated advisories since the last time the database(s) were fetched won't be known and thus won't be checked against the dependency graph.
--frozen
Equivalent to specifying both --locked
and --offline
.
cargo-deny can be used either as a command line tool or as a Rust crate. Let's focus on the command line tool capabilities first.
+Precompiled binaries are provided for major platforms on a best-effort basis. Visit the releases page to download the appropriate version for your platform.
+cargo-deny is available in the Arch Linux extra repository, you can install it via pacman as shown below:
+pacman -S cargo-deny
+
+cargo-deny can also be installed from source.
+cargo-deny is written in Rust and therefore needs to be compiled with Cargo. If you haven't already installed Rust, please go ahead and install it now.
+cargo-deny depends on some crates that use C code, so you will also need to have a C toolchain available on your machine, such as gcc, clang, or msvc.
+Installing cargo-deny is relatively easy if you already have Rust and Cargo installed. You just have to type this snippet in your terminal:
+cargo install --locked cargo-deny
+
+This will fetch the source code for the latest release from Crates.io and compile it. You will have to add Cargo's bin
directory to your PATH
if you have not done so already.
Run cargo deny help
in your terminal to verify if it works. Congratulations, you have installed cargo-deny!
The git version contains all the latest bug-fixes and features, that will be released in the next version on Crates.io, if you can't wait until the next release. You can build the git version yourself.
+cargo install --locked --git https://github.com/EmbarkStudios/cargo-deny cargo-deny
+
+Run cargo deny help
in your terminal to verify if it works. Congratulations, you have installed cargo-deny!
We now have a Github Action for running cargo-deny on your Github repositories, check it out here.
+If you don't want to use the action, you can manually download (or install) cargo-deny as described above, but here's an example script that you can copy to get you started.
+#!/bin/bash
+set -eu
+
+NAME="cargo-deny"
+VS="0.8.5"
+DIR="/tmp/$NAME"
+
+mkdir $DIR
+
+# Download the tarball
+curl -L -o $DIR/archive.tar.gz https://github.com/EmbarkStudios/$NAME/releases/download/$VS/$NAME-$VS-x86_64-unknown-linux-musl.tar.gz
+
+# Unpack the tarball into the temp directory
+tar -xzvf $DIR/archive.tar.gz --strip-components=1 -C $DIR
+
+# Run cargo deny check in our current directory
+$DIR/$NAME --context . -L debug check bans licenses advisories
+
+
+ cargo-deny's configuration is a little bit complicated, so we provide the init
command to create a configuration file from a template for you to give you a starting point for configuring how you want cargo-deny to lint your project.
The init
command is used like this:
cargo deny init
+
+The init
command can take a path as an argument to use as path of the config instead of the default which is <cwd>/deny.toml
.
cargo deny init path/to/config.toml
+
+A deny.toml
file will be created in the current working directory that is a direct copy of this template.
# This template contains all of the possible sections and their default values
+
+# Note that all fields that take a lint level have these possible values:
+# * deny - An error will be produced and the check will fail
+# * warn - A warning will be produced, but the check will not fail
+# * allow - No warning or error will be produced, though in some cases a note
+# will be
+
+# The values provided in this template are the default values that will be used
+# when any section or field is not specified in your own configuration
+
+# Root options
+
+# The graph table configures how the dependency graph is constructed and thus
+# which crates the checks are performed against
+[graph]
+# If 1 or more target triples (and optionally, target_features) are specified,
+# only the specified targets will be checked when running `cargo deny check`.
+# This means, if a particular package is only ever used as a target specific
+# dependency, such as, for example, the `nix` crate only being used via the
+# `target_family = "unix"` configuration, that only having windows targets in
+# this list would mean the nix crate, as well as any of its exclusive
+# dependencies not shared by any other crates, would be ignored, as the target
+# list here is effectively saying which targets you are building for.
+targets = [
+ # The triple can be any string, but only the target triples built in to
+ # rustc (as of 1.40) can be checked against actual config expressions
+ #"x86_64-unknown-linux-musl",
+ # You can also specify which target_features you promise are enabled for a
+ # particular target. target_features are currently not validated against
+ # the actual valid features supported by the target architecture.
+ #{ triple = "wasm32-unknown-unknown", features = ["atomics"] },
+]
+# When creating the dependency graph used as the source of truth when checks are
+# executed, this field can be used to prune crates from the graph, removing them
+# from the view of cargo-deny. This is an extremely heavy hammer, as if a crate
+# is pruned from the graph, all of its dependencies will also be pruned unless
+# they are connected to another crate in the graph that hasn't been pruned,
+# so it should be used with care. The identifiers are [Package ID Specifications]
+# (https://doc.rust-lang.org/cargo/reference/pkgid-spec.html)
+#exclude = []
+# If true, metadata will be collected with `--all-features`. Note that this can't
+# be toggled off if true, if you want to conditionally enable `--all-features` it
+# is recommended to pass `--all-features` on the cmd line instead
+all-features = false
+# If true, metadata will be collected with `--no-default-features`. The same
+# caveat with `all-features` applies
+no-default-features = false
+# If set, these feature will be enabled when collecting metadata. If `--features`
+# is specified on the cmd line they will take precedence over this option.
+#features = []
+
+# The output table provides options for how/if diagnostics are outputted
+[output]
+# When outputting inclusion graphs in diagnostics that include features, this
+# option can be used to specify the depth at which feature edges will be added.
+# This option is included since the graphs can be quite large and the addition
+# of features from the crate(s) to all of the graph roots can be far too verbose.
+# This option can be overridden via `--feature-depth` on the cmd line
+feature-depth = 1
+
+# This section is considered when running `cargo deny check advisories`
+# More documentation for the advisories section can be found here:
+# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html
+[advisories]
+# The path where the advisory databases are cloned/fetched into
+#db-path = "$CARGO_HOME/advisory-dbs"
+# The url(s) of the advisory databases to use
+#db-urls = ["https://github.com/rustsec/advisory-db"]
+# A list of advisory IDs to ignore. Note that ignored advisories will still
+# output a note when they are encountered.
+ignore = [
+ #"RUSTSEC-0000-0000",
+ #{ id = "RUSTSEC-0000-0000", reason = "you can specify a reason the advisory is ignored" },
+ #"a-crate-that-is-yanked@0.1.1", # you can also ignore yanked crate versions if you wish
+ #{ crate = "a-crate-that-is-yanked@0.1.1", reason = "you can specify why you are ignoring the yanked crate" },
+]
+# If this is true, then cargo deny will use the git executable to fetch advisory database.
+# If this is false, then it uses a built-in git library.
+# Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support.
+# See Git Authentication for more information about setting up git authentication.
+#git-fetch-with-cli = true
+
+# This section is considered when running `cargo deny check licenses`
+# More documentation for the licenses section can be found here:
+# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html
+[licenses]
+# List of explicitly allowed licenses
+# See https://spdx.org/licenses/ for list of possible licenses
+# [possible values: any SPDX 3.11 short identifier (+ optional exception)].
+allow = [
+ #"MIT",
+ #"Apache-2.0",
+ #"Apache-2.0 WITH LLVM-exception",
+]
+# The confidence threshold for detecting a license from license text.
+# The higher the value, the more closely the license text must be to the
+# canonical license text of a valid SPDX license file.
+# [possible values: any between 0.0 and 1.0].
+confidence-threshold = 0.8
+# Allow 1 or more licenses on a per-crate basis, so that particular licenses
+# aren't accepted for every possible crate as with the normal allow list
+exceptions = [
+ # Each entry is the crate and version constraint, and its specific allow
+ # list
+ #{ allow = ["Zlib"], crate = "adler32" },
+]
+
+# Some crates don't have (easily) machine readable licensing information,
+# adding a clarification entry for it allows you to manually specify the
+# licensing information
+#[[licenses.clarify]]
+# The package spec the clarification applies to
+#crate = "ring"
+# The SPDX expression for the license requirements of the crate
+#expression = "MIT AND ISC AND OpenSSL"
+# One or more files in the crate's source used as the "source of truth" for
+# the license expression. If the contents match, the clarification will be used
+# when running the license check, otherwise the clarification will be ignored
+# and the crate will be checked normally, which may produce warnings or errors
+# depending on the rest of your configuration
+#license-files = [
+# Each entry is a crate relative path, and the (opaque) hash of its contents
+#{ path = "LICENSE", hash = 0xbd0eed23 }
+#]
+
+[licenses.private]
+# If true, ignores workspace crates that aren't published, or are only
+# published to private registries.
+# To see how to mark a crate as unpublished (to the official registry),
+# visit https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field.
+ignore = false
+# One or more private registries that you might publish crates to, if a crate
+# is only published to private registries, and ignore is true, the crate will
+# not have its license(s) checked
+registries = [
+ #"https://sekretz.com/registry
+]
+
+# This section is considered when running `cargo deny check bans`.
+# More documentation about the 'bans' section can be found here:
+# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html
+[bans]
+# Lint level for when multiple versions of the same crate are detected
+multiple-versions = "warn"
+# Lint level for when a crate version requirement is `*`
+wildcards = "allow"
+# The graph highlighting used when creating dotgraphs for crates
+# with multiple versions
+# * lowest-version - The path to the lowest versioned duplicate is highlighted
+# * simplest-path - The path to the version with the fewest edges is highlighted
+# * all - Both lowest-version and simplest-path are used
+highlight = "all"
+# The default lint level for `default` features for crates that are members of
+# the workspace that is being checked. This can be overridden by allowing/denying
+# `default` on a crate-by-crate basis if desired.
+workspace-default-features = "allow"
+# The default lint level for `default` features for external crates that are not
+# members of the workspace. This can be overridden by allowing/denying `default`
+# on a crate-by-crate basis if desired.
+external-default-features = "allow"
+# List of crates that are allowed. Use with care!
+allow = [
+ #"ansi_term@0.11.0",
+ #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason it is allowed" },
+]
+# List of crates to deny
+deny = [
+ #"ansi_term@0.11.0",
+ #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason it is banned" },
+ # Wrapper crates can optionally be specified to allow the crate when it
+ # is a direct dependency of the otherwise banned crate
+ #{ crate = "ansi_term@0.11.0", wrappers = ["this-crate-directly-depends-on-ansi_term"] },
+]
+
+# List of features to allow/deny
+# Each entry the name of a crate and a version range. If version is
+# not specified, all versions will be matched.
+#[[bans.features]]
+#crate = "reqwest"
+# Features to not allow
+#deny = ["json"]
+# Features to allow
+#allow = [
+# "rustls",
+# "__rustls",
+# "__tls",
+# "hyper-rustls",
+# "rustls",
+# "rustls-pemfile",
+# "rustls-tls-webpki-roots",
+# "tokio-rustls",
+# "webpki-roots",
+#]
+# If true, the allowed features must exactly match the enabled feature set. If
+# this is set there is no point setting `deny`
+#exact = true
+
+# Certain crates/versions that will be skipped when doing duplicate detection.
+skip = [
+ #"ansi_term@0.11.0",
+ #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason why it can't be updated/removed" },
+]
+# Similarly to `skip` allows you to skip certain crates during duplicate
+# detection. Unlike skip, it also includes the entire tree of transitive
+# dependencies starting at the specified crate, up to a certain depth, which is
+# by default infinite.
+skip-tree = [
+ #"ansi_term@0.11.0", # will be skipped along with _all_ of its direct and transitive dependencies
+ #{ crate = "ansi_term@0.11.0", depth = 20 },
+]
+
+# This section is considered when running `cargo deny check sources`.
+# More documentation about the 'sources' section can be found here:
+# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html
+[sources]
+# Lint level for what to happen when a crate from a crate registry that is not
+# in the allow list is encountered
+unknown-registry = "warn"
+# Lint level for what to happen when a crate from a git repository that is not
+# in the allow list is encountered
+unknown-git = "warn"
+# List of URLs for allowed crate registries. Defaults to the crates.io index
+# if not specified. If it is specified but empty, no registries are allowed.
+allow-registry = ["https://github.com/rust-lang/crates.io-index"]
+# List of URLs for allowed Git repositories
+allow-git = []
+
+[sources.allow-org]
+# github.com organizations to allow git sources for
+github = []
+# gitlab.com organizations to allow git sources for
+gitlab = []
+# bitbucket.org organizations to allow git sources for
+bitbucket = []
+
+
+ list
commandSimilarly to cargo-license, list
prints out the license information for each crate.
-c, --config <CONFIG>
Path to the config to use
+Defaults to <cwd>/deny.toml
if not specified
-f, --format
The format of the output
+human
(default) - Simple format where each crate or license is its own linejson
tsv
--color
Colors:
+-l, --layout
The layout of the output. Does not apply to the tsv
format.
license
(default) - Each license acts as the key, and the values are all of the crates that use that licensecrate
- Each crate is a key, and the values are the list of licenses it uses.-t, --threshold
The confidence threshold required for assigning a license identifier to a license text file. See the license configuration for more information.
+layout = license, format = human
(default)layout = crate, format = human
layout = license, format = json
layout = license, format = tsv
cargo-deny is a cargo plugin that lets you lint your project's dependency graph to ensure all your dependencies conform to your expectations and requirements.
+Installs cargo-deny, initializes your project with a default configuration, then runs all of the checks against your project.
+cargo install --locked cargo-deny && cargo deny init && cargo deny check
+
+cargo-deny is intended to be used as a Command Line Tool, see the link for the available commands and options.
+cargo-deny supports several classes of checks, see Checks for the available checks and their configuration options.
+cargo-deny is primarily meant to be used as a cargo plugin, but a majority of its functionality is within a library whose docs you may view on docs.rs
+For GitHub projects, one can run cargo-deny automatically as part of continuous integration using a GitHub Action:
+name: CI
+on: [push, pull_request]
+jobs:
+ cargo-deny:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: EmbarkStudios/cargo-deny-action@v1
+
+For more information, see cargo-deny-action
repository.