hive-forge: pin forgejo-api to 0.11.1 so it shares the workspace reqwest

forgejo-api 0.11.0 links reqwest 0.12 while the workspace is on 0.13, and
cargo unifies features per (crate, VERSION) — not per crate. So forgejo-api's
internal client was a *second* reqwest, built with neither the workspace's TLS
features nor the system trust store, and every https call it made to a gateway
name failed `invalid peer certificate: UnknownIssuer` while a client built in
this workspace succeeded against the same host.

Pinning to 0.11.1 puts one reqwest in the tree, which is what makes the
existing "feature unification gives forgejo-api our TLS backend" comment true
rather than aspirational — the claim is a fact about the lockfile, so the pin
is load-bearing and says so.

The reqwest feature list moves with it: `rustls-native-certs` and
`webpki-roots` were 0.13.1-era names that no longer exist, and `rustls` now
carries the platform verifier (OS trust store, honours SSL_CERT_FILE). Naming
a feature that is gone is a hard resolution error rather than a silent no-op,
so the list had to change in the same commit as the pin.

Refs #3391
This commit is contained in:
atlas 2026-08-19 12:30:50 +02:00
commit 74dfd366b4
3 changed files with 45 additions and 83 deletions

89
Cargo.lock generated
View file

@ -1312,18 +1312,18 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]] [[package]]
name = "forgejo-api" name = "forgejo-api"
version = "0.11.0" version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c51fffa047d5836a4d89179a20b21b7e41ad97e713104752169d819b83c9158" checksum = "e723c70a2a46fe0dbc2c10024218170ad9ca6ce8f98a39cee8032478ab748086"
dependencies = [ dependencies = [
"base64ct", "base64ct",
"bytes", "bytes",
"futures", "futures",
"reqwest 0.12.28", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"soft_assert", "soft_assert",
"thiserror 1.0.69", "thiserror 2.0.18",
"time", "time",
"tokio", "tokio",
"url", "url",
@ -1593,7 +1593,7 @@ dependencies = [
"hyper", "hyper",
"hyper-util", "hyper-util",
"libc", "libc",
"reqwest 0.13.1", "reqwest",
"rmcp", "rmcp",
"rusqlite", "rusqlite",
"schemars", "schemars",
@ -1619,7 +1619,7 @@ dependencies = [
"hive-sh4re", "hive-sh4re",
"hive-sock-client", "hive-sock-client",
"hive-types", "hive-types",
"reqwest 0.13.1", "reqwest",
"rmcp", "rmcp",
"serde", "serde",
"serde_json", "serde_json",
@ -1691,7 +1691,7 @@ dependencies = [
"opentelemetry_sdk", "opentelemetry_sdk",
"petgraph", "petgraph",
"problem_details", "problem_details",
"reqwest 0.13.1", "reqwest",
"rusqlite", "rusqlite",
"serde", "serde",
"serde_json", "serde_json",
@ -1736,7 +1736,7 @@ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
"forgejo-api", "forgejo-api",
"reqwest 0.13.1", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"time", "time",
@ -1751,7 +1751,7 @@ dependencies = [
"forgejo-api", "forgejo-api",
"hive-agent-sock", "hive-agent-sock",
"hive-sock-client", "hive-sock-client",
"reqwest 0.13.1", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"time", "time",
@ -1809,7 +1809,7 @@ dependencies = [
"matrix-sdk", "matrix-sdk",
"mime", "mime",
"mime_guess", "mime_guess",
"reqwest 0.13.1", "reqwest",
"rmcp", "rmcp",
"schemars", "schemars",
"serde", "serde",
@ -2060,7 +2060,6 @@ dependencies = [
"tokio", "tokio",
"tokio-rustls", "tokio-rustls",
"tower-service", "tower-service",
"webpki-roots 1.0.8",
] ]
[[package]] [[package]]
@ -2661,7 +2660,7 @@ dependencies = [
"oauth2-reqwest", "oauth2-reqwest",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"reqwest 0.13.1", "reqwest",
"ruma", "ruma",
"rustls", "rustls",
"rustls-native-certs", "rustls-native-certs",
@ -3039,7 +3038,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "234fb5c965bbce983ee5de636a7a51d6a3223da8067ea02f9ab2d2d78ac08be2" checksum = "234fb5c965bbce983ee5de636a7a51d6a3223da8067ea02f9ab2d2d78ac08be2"
dependencies = [ dependencies = [
"oauth2", "oauth2",
"reqwest 0.13.1", "reqwest",
] ]
[[package]] [[package]]
@ -3090,7 +3089,7 @@ dependencies = [
"bytes", "bytes",
"http", "http",
"opentelemetry", "opentelemetry",
"reqwest 0.13.1", "reqwest",
] ]
[[package]] [[package]]
@ -3105,7 +3104,7 @@ dependencies = [
"opentelemetry-proto", "opentelemetry-proto",
"opentelemetry_sdk", "opentelemetry_sdk",
"prost", "prost",
"reqwest 0.13.1", "reqwest",
"serde_json", "serde_json",
"thiserror 2.0.18", "thiserror 2.0.18",
] ]
@ -3708,9 +3707,9 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
[[package]] [[package]]
name = "reqwest" name = "reqwest"
version = "0.12.28" version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3"
dependencies = [ dependencies = [
"base64", "base64",
"bytes", "bytes",
@ -3734,49 +3733,6 @@ dependencies = [
"quinn", "quinn",
"rustls", "rustls",
"rustls-pki-types", "rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tokio-rustls",
"tower",
"tower-http 0.6.11",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"webpki-roots 1.0.8",
]
[[package]]
name = "reqwest"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62"
dependencies = [
"base64",
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-util",
"js-sys",
"log",
"mime_guess",
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls",
"rustls-native-certs",
"rustls-pki-types",
"rustls-platform-verifier", "rustls-platform-verifier",
"serde", "serde",
"serde_json", "serde_json",
@ -3793,7 +3749,6 @@ dependencies = [
"wasm-bindgen-futures", "wasm-bindgen-futures",
"wasm-streams", "wasm-streams",
"web-sys", "web-sys",
"webpki-roots 1.0.8",
] ]
[[package]] [[package]]
@ -4574,7 +4529,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"axum", "axum",
"reqwest 0.13.1", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"serde_norway", "serde_norway",
@ -4607,7 +4562,7 @@ dependencies = [
"hive-types", "hive-types",
"hmac 0.13.0", "hmac 0.13.0",
"problem_details", "problem_details",
"reqwest 0.13.1", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"sha2 0.11.0", "sha2 0.11.0",
@ -4632,7 +4587,7 @@ dependencies = [
"futures-util", "futures-util",
"nats-jwt", "nats-jwt",
"nkeys", "nkeys",
"reqwest 0.13.1", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"sha2 0.11.0", "sha2 0.11.0",
@ -4647,7 +4602,7 @@ name = "swarm-queue-client"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-nats", "async-nats",
"reqwest 0.13.1", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"thiserror 2.0.18", "thiserror 2.0.18",
@ -5483,9 +5438,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-streams" name = "wasm-streams"
version = "0.4.2" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb"
dependencies = [ dependencies = [
"futures-util", "futures-util",
"js-sys", "js-sys",

View file

@ -128,7 +128,14 @@ reqwest = { version = "0.13", default-features = false, features = [
hyper = { version = "1", features = ["client", "http1"] } hyper = { version = "1", features = ["client", "http1"] }
hyper-util = { version = "0.1", features = ["tokio"] } hyper-util = { version = "0.1", features = ["tokio"] }
http-body-util = "0.1" http-body-util = "0.1"
forgejo-api = { version = "0.11", default-features = false, features = [ # ⚠️ Keep at 0.11.1 or newer, and keep it on the SAME reqwest as everything
# else. 0.11.0 links reqwest 0.12 while the workspace is on 0.13, and cargo
# resolves features per (crate, VERSION): that older client got neither the
# workspace's TLS features nor the system trust store, so every https call to
# a gateway name died with `invalid peer certificate: UnknownIssuer` while
# clients built here worked (#3391). One version of reqwest in the tree is
# what keeps that class impossible rather than merely fixed.
forgejo-api = { version = "0.11.1", default-features = false, features = [
"rustls-tls", "rustls-tls",
] } ] }
url = "2" url = "2"

View file

@ -11,28 +11,28 @@ path = "src/main.rs"
[dependencies] [dependencies]
anyhow = { workspace = true } anyhow = { workspace = true }
clap = { workspace = true } clap = { workspace = true }
# `sync` = blocking client (hive-forge is a blocking CLI). TLS backend # `sync` = blocking client (hive-forge is a blocking CLI). TLS backend comes
# comes from workspace feature unification on reqwest: the # from feature unification on reqwest — which only works because forgejo-api
# `rustls-tls-native-roots` feature below applies to forgejo-api's # and this crate now resolve to the SAME reqwest version; cargo unifies
# internal client too (same compiled reqwest), so the hive-CA trust # features per (crate, version), so the claim is a fact about the lockfile,
# note keeps holding. # not about the workspace. See the pin note on `forgejo-api` in the root
# `Cargo.toml`.
forgejo-api = { workspace = true, features = ["sync"] } forgejo-api = { workspace = true, features = ["sync"] }
url.workspace = true url.workspace = true
time.workspace = true time.workspace = true
reqwest = { workspace = true, features = [ reqwest = { workspace = true, features = [
"json", "json",
# Trust the OS/system CA store (`rustls-native-certs`), plus the bundled # `rustls` carries the platform verifier, which reads the OS trust store
# Mozilla roots (`webpki-roots`), so hive-forge validates the hive # (and honours `SSL_CERT_FILE`), so hive-forge validates the hive
# gateway's self-signed leaf once the hive CA is in the agent's trust # gateway's self-signed leaf once the hive CA is in the agent's trust
# store (embedded into agent flakes via security.pki.certificateFiles) # store — embedded into agent flakes via `security.pki.certificateFiles`
# AND public CAs still validate. Cargo unifies features across the build, # — while public CAs still validate.
# so both root sources are enabled for every reqwest client; harmless (a #
# superset of roots, and on NixOS the system store already includes the # The separate `rustls-native-certs` / `webpki-roots` features this entry
# Mozilla bundle). (reqwest 0.13 renamed the 0.12 `rustls-tls` / # used to name were 0.13.1-era and no longer exist; naming a feature that
# `rustls-tls-native-roots` features to `rustls` / `rustls-native-certs`.) # is gone is a hard resolution error, not a silent no-op, so this list has
# to move with the pin.
"rustls", "rustls",
"rustls-native-certs",
"webpki-roots",
"blocking", "blocking",
"multipart", "multipart",
] } ] }