1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# Supply-chain gate (RFC-035 §5.5, roadmap decision D3).
#
# `RUSTSEC-2026-0194`/`-0195` sat in `quick-xml` for two months, reachable
# through `calamine`, before this project noticed -- the consumer's own
# `cargo audit` gate caught it first. This file is what makes the next one
# visible on the day it lands instead of two months later. Reproduce
# locally with `cargo deny check`; see `.github/CONTRIBUTING.md`.
[]
# Collect metadata with every feature enabled, so the gate covers the full
# surface a consumer could actually compile, not just the default build.
= true
= false
[]
= 1
# ---------------------------------------------------------------------------
# advisories -- deny. This is the section that would have caught the
# quick-xml chain the day it was published instead of two months later.
#
# RFC-035 Handoff 03 §2 dev-dependency decision: BLOCK.
#
# A compromised dev dependency runs on maintainer machines and in CI with
# repository credentials in scope; "dev-only" is a smaller blast radius,
# not a zero one. The one dev-only advisory in the tree as of this writing
# -- RUSTSEC-2026-0204, crossbeam-epoch via criterion -> rayon -> rayon-core
# -> crossbeam-deque -- turned out to cost nothing to fix: a single
# non-breaking lockfile update (`cargo update -p crossbeam-epoch`, 0.9.18 ->
# 0.9.20; no Cargo.toml edit, no conflict). Blocking was free here, so the
# `ignore` list below is empty. If a future dev-only advisory is NOT this
# cheap, the decision still stands: a reasoned, expiry-dated `ignore` entry
# is the correct escape hatch (RFC-035 §5.7), not loosening this section.
# ---------------------------------------------------------------------------
[]
= []
# ---------------------------------------------------------------------------
# licenses -- allowlist consistent with Apache-2.0 distribution. Every
# entry is a permissive license (MIT/Apache-2.0-family, BSD-3-Clause,
# Unicode-3.0, Zlib) with no copyleft or field-of-use restriction. No
# per-crate exceptions: if a future dependency needs one, that is a
# decision to make deliberately, not a default to fall into.
# ---------------------------------------------------------------------------
[]
= [
"MIT",
"Apache-2.0",
"BSD-3-Clause",
"Unicode-3.0",
"Zlib",
]
= 0.8
= []
[]
= false
# ---------------------------------------------------------------------------
# bans
# ---------------------------------------------------------------------------
[]
# Denied rather than warned: a version split is a maintenance question that
# deserves an answer, not a note nobody reads. RFC-035 §5.5 ("deny
# duplicate versions where practical").
#
# Coverage caveat, so a reader doesn't assume this is exhaustive: cargo-deny's
# `multiple-versions-include-dev` defaults to false, so a duplicate reachable
# only through a dev-dependency path is not reported. As of this writing the
# tree has exactly such a case -- `zip` 7.2.0 (dev-only, via
# `rust_xlsxwriter`) alongside `zip` 8.6.0 (via `calamine`) -- and it is
# silent here. This is deliberate, not an oversight: `rust_xlsxwriter` pins
# 7.2, `calamine` pins 8.6, we control neither, and a duplicate that ships in
# no artefact a consumer receives is a hygiene signal, not a security one --
# unlike an advisory, which stays denied regardless of dev/normal status.
# Enabling `multiple-versions-include-dev` would fail permanently on this
# unfixable split, and the only way back to green would be a skip entry,
# which is the "allowlist to fit" pattern this file exists to avoid.
= "deny"
= "allow"
= "all"
= "allow"
= "allow"
= []
= false
# What turns NF-015 ("the library must not access the network") from a
# documentation claim into a build-time property. Every entry is a crate
# whose entire purpose is opening a network connection -- HTTP client or
# server, raw sockets, an async network reactor, DNS resolution, SMTP.
# None has any legitimate reason to appear here, direct or transitive:
# sheets-diff parses bytes the caller already holds. A failure here is a
# genuine "how did this get pulled in" question, not a false positive to
# allowlist away.
= [
{ = "reqwest", = "HTTP client -- NF-015: no network access" },
{ = "hyper", = "HTTP client/server -- NF-015: no network access" },
{ = "ureq", = "HTTP client -- NF-015: no network access" },
{ = "curl", = "HTTP client (libcurl binding) -- NF-015: no network access" },
{ = "curl-sys", = "libcurl FFI -- NF-015: no network access" },
{ = "isahc", = "HTTP client -- NF-015: no network access" },
{ = "surf", = "HTTP client -- NF-015: no network access" },
{ = "h2", = "HTTP/2 implementation -- NF-015: no network access" },
{ = "tonic", = "gRPC over HTTP/2 -- NF-015: no network access" },
{ = "tokio", = "async runtime with a network-capable reactor -- NF-015: no network access" },
{ = "async-std", = "async runtime with a network-capable reactor -- NF-015: no network access" },
{ = "smol", = "async runtime with a network-capable reactor -- NF-015: no network access" },
{ = "mio", = "cross-platform network/IO reactor underlying most async-net crates -- NF-015: no network access" },
{ = "socket2", = "raw socket access -- NF-015: no network access" },
{ = "trust-dns-resolver", = "DNS resolution is network access -- NF-015: no network access" },
{ = "hickory-resolver", = "DNS resolution is network access (trust-dns' successor name) -- NF-015: no network access" },
{ = "lettre", = "SMTP client -- NF-015: no network access" },
]
= []
= []
# ---------------------------------------------------------------------------
# sources -- crates.io only (RFC-035 §5.5). Denied, not warned: a git or
# unknown-registry dependency bypasses crates.io's namespace and yank
# protections entirely, which is a bigger supply-chain hole than any single
# banned crate.
# ---------------------------------------------------------------------------
[]
= "deny"
= "deny"
= ["https://github.com/rust-lang/crates.io-index"]
= []
[]
= []
= []
= []