Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/Cargo.toml
atlas 44984e0d36 move install_crypto_provider to swarm-secret-client
The rustls provider install is process setup every swarm binary runs, and
swarm-secret-client depends on no other swarm crate, so a binary that only
needs the provider and the store no longer links the queue client.

- swarm-secret-client/src/lib.rs, Cargo.toml: the function, its test, a
  `//!` line on why it lives there, and the rustls dependency; rustls
  `ring` as a dev-dependency feature, so the test builds both providers as
  the binaries do and fails if the install is dropped.
- swarm-queue-client/src/lib.rs, Cargo.toml: function and test removed;
  `connect()` calls the secret client's; rustls dropped (no other use),
  swarm-secret-client added.
- swarm-metrics-auth/Cargo.toml: drop swarm-queue-client, whose only use
  was the provider; the binary no longer links async-nats.
- swarm-logs-auth, swarm-logs, swarm-metrics, swarm-ci-metrics Cargo.toml:
  the dep comment no longer names the provider (they keep the dep for
  agent_token / the OIDC mint).
- Cargo.toml: the rustls comment names the provider's new home.
- 14 call sites (hive-agent, hive-c0re, hive-subagent-mcp x2,
  swarm-builder, swarm-ci-metrics, swarm-claude-login, swarm-controller,
  swarm-logs-auth, swarm-logs, swarm-metrics-auth, swarm-metrics,
  swarm-nats-auth, swarm-review-classifier): one-line path change.
- Cargo.lock: the dependency edges above.
2026-10-18 03:18:43 +02:00

278 lines
10 KiB
TOML

[workspace]
resolver = "3"
members = [
"hive-agent",
"hive-agent-mcp",
"hive-agent-sock",
"hive-core-agent-sock",
"hive-bash-mcp",
"hive-c0re",
"hive-screen-mcp",
"hive-forge",
"hive-forge-notify",
"hive-host-sock",
"hive-jobq",
"hive-jobq-metrics",
"hive-jobq-wire",
"hive-log",
"hive-matrix-mcp",
"hive-metric",
"hive-priv",
"hive-priv-sock",
"hive-runtime",
"hive-sh4re",
"hive-sock-client",
"hive-subagent-mcp",
"hive-types",
"hivectl",
"swarm-agent-verify",
"swarm-authelia-bridge",
"swarm-builder",
"swarm-ci-metrics",
"swarm-claude-login",
"swarm-authelia-bridge-sock",
"swarm-controller",
"swarm-controller-api",
"swarm-matrix-client",
"swarm-matrix-ctl",
"swarm-nats-auth",
"swarm-queue-client",
"swarm-review-classifier",
"swarm-logs",
"swarm-metrics",
"swarm-logs-auth",
"swarm-metrics-auth",
"swarm-secret-client",
"swarmctl",
]
[workspace.package]
edition = "2024"
version = "0.1.0"
[workspace.lints.clippy]
# Pedantic is a hard error (locally + in CI): we want pedantic lints
# gated, so a toolchain bump that adds a new one reds the build until the
# code is updated rather than sliding in unnoticed. Priority -1 keeps the
# specific allows below winning over the group.
pedantic = { level = "deny", priority = -1 }
# Tolerated stylistic pedantic lints (noisy, not actionable).
missing_errors_doc = "allow"
missing_panics_doc = "allow"
module_name_repetitions = "allow"
[workspace.lints.rustdoc]
# Doc-link rot has no other discoverer: clippy does not read intra-doc
# links, `cargo test` does not, and nothing else builds docs. A `[`Foo`]`
# pointing at a renamed, moved or deleted item renders as plain text and
# misleads the next reader — worse than no link, since it names something
# and so sends them looking.
#
# Here rather than in `RUSTDOCFLAGS` on the CI check, so a plain local
# `cargo doc` fails the same way CI does. A gate you only meet in CI is a
# gate you meet too late.
broken_intra_doc_links = "deny"
private_intra_doc_links = "deny"
invalid_html_tags = "deny"
redundant_explicit_links = "deny"
bare_urls = "deny"
unescaped_backticks = "deny"
[workspace.dependencies]
anyhow = "1"
libc = "0.2"
axum = { version = "0.8", features = ["ws"] }
backon = "1"
base64 = "0.22"
chrono = { version = "0.4", default-features = false, features = [
"clock",
"serde",
"std",
] }
clap = { version = "4", features = ["derive"] }
clap_complete = "4"
enumflags2 = { version = "0.7.12", features = ["serde"] }
# The OS CSPRNG, for the one thing in this tree that generates a secret rather
# than receiving one (`swarm-controller::agent_identity`). `getrandom` rather
# than `rand`: the whole need is "fill these bytes from the kernel", and `rand`
# would add `rand_core` + `rand_chacha` to do it through a userspace generator
# this has no use for.
getrandom = "0.3"
indicatif = "0.18"
hive-sh4re = { path = "hive-sh4re" }
hive-agent-sock = { path = "hive-agent-sock" }
hive-jobq = { path = "hive-jobq" }
hive-jobq-metrics = { path = "hive-jobq-metrics" }
hive-jobq-wire = { path = "hive-jobq-wire" }
hive-log = { path = "hive-log" }
hive-core-agent-sock = { path = "hive-core-agent-sock" }
hive-claude = "0.1.4"
hive-host-sock = { path = "hive-host-sock" }
hive-priv-sock = { path = "hive-priv-sock" }
hive-runtime = { path = "hive-runtime" }
hive-sock-client = { path = "hive-sock-client" }
hive-types = { path = "hive-types" }
swarm-agent-verify = { path = "swarm-agent-verify" }
swarm-authelia-bridge-sock = { path = "swarm-authelia-bridge-sock" }
swarm-controller-api = { path = "swarm-controller-api" }
swarm-matrix-client = { path = "swarm-matrix-client" }
swarm-queue-client = { path = "swarm-queue-client" }
swarm-secret-client = { path = "swarm-secret-client" }
thiserror = "2"
vaultrs = "0.8"
# vaultrs's transport crates. Direct dependencies because one endpoint is
# defined here rather than by it; both versions must stay the ones vaultrs
# resolves, since its `exec_with_empty` takes *its* `Endpoint` trait.
rustify = "0.7"
rustify_derive = "0.5"
tower-http = { version = "0.7", features = ["fs"] }
uuid = { version = "1", features = ["v4"] }
rmcp = { version = "2", default-features = false, features = [
"server",
"macros",
"transport-io",
"transport-streamable-http-server",
] }
rusqlite = { version = "0.37" }
schemars = "1.0"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
similar = "2"
# `derive`-only: `Kind`'s segment strings via `#[strum(serialize = "...")]`
# instead of a hand-written match, so the derive macro is the single source
# of truth (see `swarm-secret-client::path::Kind`).
strum = { version = "0.28.0", features = ["derive"] }
tokio = { version = "1", features = [
"fs",
"io-util",
"macros",
"net",
"process",
"rt-multi-thread",
"signal",
"sync",
"time",
] }
tokio-stream = { version = "0.1", features = ["sync"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
# The journald sink `hive-log` installs when the process runs under a
# systemd unit. Tokio-maintained; its whole dependency set is `libc` +
# `tracing-core` + `tracing-subscriber`, since it speaks the native journal
# protocol over a `UnixDatagram` and links no C journal library.
tracing-journald = "0.3.2"
# `fs::fstat` — the safe wrapper `hive-log` compares a descriptor's device
# and inode numbers against `$JOURNAL_STREAM` with. Already in the lock as
# a transitive dependency; direct here so that comparison needs no
# hand-written `unsafe libc::fstat` call. Only the `fs` API module is asked
# for: rustix gates each one behind its own feature.
rustix = { version = "1.1.4", default-features = false, features = [
"std",
"fs",
] }
reqwest = { version = "0.13", default-features = false, features = [
# RFC 7662 introspection posts an urlencoded body; without this,
# `.form()` does not exist and the alternative is percent-encoding a
# credential by hand.
"form",
"json",
"rustls",
] }
hyper = { version = "1", features = ["client", "http1"] }
hyper-util = { version = "0.1", features = ["tokio"] }
# OTEL SDK, shared by every crate that pushes metrics (hive-c0re, hive-metric,
# swarm-controller). The blocking OTLP client is deliberate everywhere it's
# used: the metrics SDK's `PeriodicReader` drives its export from a
# background thread with no Tokio reactor, where the async client panics.
# `default-features = false` on the OTLP crate drops its own diagnostics
# ("internal-logs") unless a member opts back in — hive-c0re does, via
# `{ workspace = true, features = ["internal-logs"] }`.
opentelemetry = "0.32"
opentelemetry_sdk = { version = "0.32", features = ["metrics"] }
opentelemetry-otlp = { version = "0.32", default-features = false, features = [
"metrics",
"http-json",
"reqwest-blocking-client",
"reqwest-rustls",
] }
# The trait an OTLP exporter's HTTP transport is built on
# (`opentelemetry_otlp::WithHttpConfig::with_http_client`) — pulled in
# directly (not just transitively via `opentelemetry-otlp` above) by
# `swarm-controller`'s own `otel_http_client` module, which implements the
# trait itself rather than using the crate's own blanket `reqwest`/
# `reqwest-blocking` impls (this workspace's implementation needs to mint
# a fresh bearer token per request, which no blanket impl can do). No
# extra cargo features requested here for exactly that reason — the
# blanket impls live behind `reqwest`/`reqwest-blocking` features this
# workspace never turns on for this crate.
opentelemetry-http = "0.32"
# `async-trait`: `opentelemetry_http::HttpClient` predates stable
# `async fn` in traits and is still expressed with this macro upstream —
# implementing the trait (rather than only consuming the crate's own
# blanket impls) means writing `#[async_trait::async_trait]` on the impl
# block to match its expansion.
async-trait = "0.1"
# `bytes`/`http`: the payload and request/response types
# `opentelemetry_http::HttpClient::send_bytes` is expressed in terms of —
# needed to implement the trait, not just call something that already
# does.
bytes = "1"
http = "1"
http-body-util = "0.1"
# ⚠️ 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",
] }
url = "2"
time = { version = "0.3", default-features = false, features = [
"formatting",
"parsing",
] }
petgraph = { version = "0.8", default-features = false, features = ["std"] }
matrix-sdk = { version = "0.18", default-features = false, features = [
"sqlite",
"markdown",
"e2e-encryption",
] }
futures-util = "0.3"
hmac = "0.13"
sha2 = "0.11"
# Constant-time comparison of a presented secret against the stored one
# (`swarm-agent-verify`). Already in the tree through the TLS stack.
subtle = "2.6"
# The NATS protocol client, for the swarm queue's auth-callout responder.
# `default-features = false` because the default set is broad - jetstream, kv,
# object-store, websockets, service - and a callout responder speaks none of
# them. What is named is the whole requirement: the server generation we
# deploy, nkey auth, and a TLS backend.
async-nats = { version = "0.50", default-features = false, features = [
"server_2_14",
"nkeys",
"ring",
] }
# Named only to install the process-wide provider (`swarm-secret-client`'s
# `install_crypto_provider`). `aws-lc-rs` is the provider reqwest already
# falls back to, so installing it leaves every HTTPS client unchanged.
rustls = { version = "0.23", default-features = false, features = [
"aws-lc-rs",
"std",
] }
data-encoding = "2"
# The nkey *format* - ed25519 + base32 + CRC16. The primitives are already in
# the tree; the format is not, and hand-rolling a key format on an auth path
# is how you get a CRC bug nobody reviews.
nkeys = "0.4"
# A TEST ORACLE, not a runtime dependency - see swarm-nats-auth's respond.rs.
nats-jwt = "0.3"
utoipa = { version = "5", features = ["axum_extras", "chrono"] }
utoipa-axum = "0.2"
# Reads an agent certificate's validity window, so `swarm-controller` can
# re-issue it at half its life. `der` and `spki` are already in the tree
# through `pkcs8`.
x509-cert = { version = "0.2", default-features = false, features = ["pem"] }