Safeguard
Security Guides•

How do Rust crates declare licenses in Cargo.toml?

Cargo uses a license field with SPDX expressions or a license-file path for custom terms. Learn what OR, AND and WITH mean when you audit crates.

Safeguard Security Team
3 min read

A Rust crate declares its license with the license field, an SPDX 2.3 expression such as MIT OR Apache-2.0, or with license-file, a path to a custom license text. crates.io requires one of the two. OR means you choose, AND means you must satisfy both, and WITH adds a named exception.

The two fields

The Cargo reference says the license field is interpreted by crates.io as an SPDX 2.3 expression, with names drawn from the SPDX list. The older slash separator, as in MIT/Apache-2.0, still works but is deprecated.

The license-file field points to a file relative to Cargo.toml. Use it for a nonstandard license. Cargo always includes that file when packaging, even if include or exclude rules would otherwise drop it.

Reading the operators

ExpressionMeaningRecord this
MIT OR Apache-2.0Pick oneThe one you rely on
LGPL-2.1-only AND MIT AND BSD-2-ClauseMeet all threeObligations of each
GPL-2.0-or-later WITH Bison-exception-2.2GPL plus a special exceptionThe exception text applies
Only license-file setCustom termsManual review

The dual MIT OR Apache-2.0 pattern is very common in the Rust ecosystem, which makes crate audits easier than in some other ecosystems. It still deserves a recorded choice, because Apache-2.0 brings a patent grant and notice rules that MIT does not.

A short audit routine

  1. List every crate in Cargo.lock, including transitive ones.
  2. Read the license value for the exact version in the lockfile.
  3. Parse expressions rather than matching strings, so AND and OR are handled correctly.
  4. Route license-file crates and unrecognized identifiers to manual review.
  5. Check again when the lockfile changes, since a new version can change terms.

Statically linked means shipped

Rust links dependencies into the binary you ship. If you distribute that binary, the notice and source obligations of every linked crate can apply. If you only run it on your own servers, the picture is different. See internal use versus distribution for how that line works.

One more habit helps with Rust: check build scripts and bundled native code. A crate that wraps a C library can carry that library's license inside its source tree, separate from the crate's own field. When a crate bundles code, read its license files as well as its manifest.

Safeguard scans dependencies and builds SBOMs from lockfiles, and you can run a free scan to see your inventory.

Quick check

What if a crate has no license field?

crates.io requires license or license-file, so a published crate should have one. If metadata is missing locally, treat the license as unknown and read the repository.

Is MIT/Apache-2.0 the same as MIT OR Apache-2.0?

The slash form is a deprecated older spelling that tools generally treat as OR. Prefer parsing the modern form.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.