The [licenses]
section
Contains all of the configuration for cargo deny check license
.
Example
[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 }
]
SPDX Identifiers
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",
]
The 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.
The 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 allowed
The allow
field (optional)
The licenses that are explicitly allowed.
Note on GNU licenses
- GPL
- AGPL
- LGPL
- GFDL
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"]
The 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.
Additional exceptions configuration file
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" },
]
The allow
field
This 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"] },
]
The 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
)
The 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 },
]
The expression
field
The SPDX license expression you are specifying as the license requirements for the crate.
The license-files
field
Contains one or more files that will be checked to ensure the license expression still applies to a version of the crate.
The path
field
The crate relative path to a file to be used as a source of truth.
The hash
field
An 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.
The 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.
The ignore
field
If 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 }
The registries
field
A 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"] }
The ignore-sources
field
A 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"]
The 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 inlicense.allow
but which is not used in any crate.allow
- Unused licenses in thelicenses.allow
list are ignored.deny
- An unused license in thelicenses.allow
list triggers an error, and cause the license check to fail.