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.
This commit is contained in:
parent
d9c586ef94
commit
44984e0d36
25 changed files with 64 additions and 47 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
|
@ -4984,7 +4984,6 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"serde",
|
"serde",
|
||||||
"subtle",
|
"subtle",
|
||||||
"swarm-queue-client",
|
|
||||||
"swarm-secret-client",
|
"swarm-secret-client",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
|
@ -5026,10 +5025,10 @@ dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"hive-sh4re",
|
"hive-sh4re",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rustls",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"strum",
|
"strum",
|
||||||
|
"swarm-secret-client",
|
||||||
"thiserror 2.0.18",
|
"thiserror 2.0.18",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
|
@ -5066,6 +5065,7 @@ dependencies = [
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rustify",
|
"rustify",
|
||||||
"rustify_derive",
|
"rustify_derive",
|
||||||
|
"rustls",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"strum",
|
"strum",
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ async-nats = { version = "0.50", default-features = false, features = [
|
||||||
"nkeys",
|
"nkeys",
|
||||||
"ring",
|
"ring",
|
||||||
] }
|
] }
|
||||||
# Named only to install the process-wide provider (`swarm-queue-client`'s
|
# Named only to install the process-wide provider (`swarm-secret-client`'s
|
||||||
# `install_crypto_provider`). `aws-lc-rs` is the provider reqwest already
|
# `install_crypto_provider`). `aws-lc-rs` is the provider reqwest already
|
||||||
# falls back to, so installing it leaves every HTTPS client unchanged.
|
# falls back to, so installing it leaves every HTTPS client unchanged.
|
||||||
rustls = { version = "0.23", default-features = false, features = [
|
rustls = { version = "0.23", default-features = false, features = [
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ struct Cli {
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
hive_log::init();
|
hive_log::init();
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
|
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
serve_main::<AgentSurface>(&cli.socket, cli.poll_ms).await
|
serve_main::<AgentSurface>(&cli.socket, cli.poll_ms).await
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ enum Cmd {
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
hive_log::init();
|
hive_log::init();
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
|
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
match cli.cmd {
|
match cli.cmd {
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ impl Reader {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
let agent = target.agent.clone();
|
let agent = target.agent.clone();
|
||||||
let client = Arc::new(OnceLock::new());
|
let client = Arc::new(OnceLock::new());
|
||||||
tokio::spawn(connect_until_up(Arc::new(target), Arc::clone(&client)));
|
tokio::spawn(connect_until_up(Arc::new(target), Arc::clone(&client)));
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ impl Publisher {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
url = %target.url,
|
url = %target.url,
|
||||||
stream = %subagent_term::stream_name(&target.agent),
|
stream = %subagent_term::stream_name(&target.agent),
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ const MAX_SLOT_WAIT: Duration = REPLY_DEADLINE
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
hive_log::init();
|
hive_log::init();
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
let var = |name: &str| {
|
let var = |name: &str| {
|
||||||
let full = format!("{PREFIX}_{name}");
|
let full = format!("{PREFIX}_{name}");
|
||||||
std::env::var(&full).with_context(|| format!("{full} is unset"))
|
std::env::var(&full).with_context(|| format!("{full} is unset"))
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ hive-log.workspace = true
|
||||||
reqwest.workspace = true
|
reqwest.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
# The OIDC client-credentials mint, and the rustls provider.
|
# The OIDC client-credentials mint.
|
||||||
swarm-queue-client.workspace = true
|
swarm-queue-client.workspace = true
|
||||||
# The forge token and client secret paths, and the store login.
|
# The forge token and client secret paths, and the store login.
|
||||||
swarm-secret-client.workspace = true
|
swarm-secret-client.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ struct Config {
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
hive_log::init();
|
hive_log::init();
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
let var = |name: &str| {
|
let var = |name: &str| {
|
||||||
let full = format!("{PREFIX}_{name}");
|
let full = format!("{PREFIX}_{name}");
|
||||||
std::env::var(&full).with_context(|| format!("{full} is unset"))
|
std::env::var(&full).with_context(|| format!("{full} is unset"))
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ impl login::CredentialSink for AgentLeaf {
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
hive_log::init();
|
hive_log::init();
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
let var = |name: &str| {
|
let var = |name: &str| {
|
||||||
let full = format!("{PREFIX}_{name}");
|
let full = format!("{PREFIX}_{name}");
|
||||||
std::env::var(&full).with_context(|| format!("{full} is unset"))
|
std::env::var(&full).with_context(|| format!("{full} is unset"))
|
||||||
|
|
|
||||||
|
|
@ -3475,7 +3475,7 @@ async fn start_forge(
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
hive_log::init();
|
hive_log::init();
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
|
|
||||||
let path = socket_path();
|
let path = socket_path();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ clap.workspace = true
|
||||||
# The verdict cache's key: a digest of the bearer, never the bearer.
|
# The verdict cache's key: a digest of the bearer, never the bearer.
|
||||||
sha2.workspace = true
|
sha2.workspace = true
|
||||||
swarm-agent-verify.workspace = true
|
swarm-agent-verify.workspace = true
|
||||||
# The agent-token spelling, and the rustls provider the store client needs.
|
# The agent-token spelling.
|
||||||
swarm-queue-client.workspace = true
|
swarm-queue-client.workspace = true
|
||||||
swarm-secret-client.workspace = true
|
swarm-secret-client.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ async fn handle(
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
tracing_subscriber::fmt()
|
tracing_subscriber::fmt()
|
||||||
.with_env_filter(
|
.with_env_filter(
|
||||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@ path = "src/main.rs"
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
clap.workspace = true
|
clap.workspace = true
|
||||||
clap-markdown = "0.1"
|
clap-markdown = "0.1"
|
||||||
# The agent-token spelling the gateway's responder parses, and the rustls
|
# The agent-token spelling the gateway's responder parses.
|
||||||
# provider the store client needs.
|
|
||||||
swarm-queue-client.workspace = true
|
swarm-queue-client.workspace = true
|
||||||
# The read of this agent's own queue secret.
|
# The read of this agent's own queue secret.
|
||||||
swarm-secret-client.workspace = true
|
swarm-secret-client.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ fn main() -> Result<()> {
|
||||||
// keep working on a machine that has no log store wired up at
|
// keep working on a machine that has no log store wired up at
|
||||||
// all — `markdown-docs` in particular runs in a nix check, where
|
// all — `markdown-docs` in particular runs in a nix check, where
|
||||||
// no credential exists and none should.
|
// no credential exists and none should.
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
let cfg = auth::Config::from_env()?;
|
let cfg = auth::Config::from_env()?;
|
||||||
let stdout = std::io::stdout();
|
let stdout = std::io::stdout();
|
||||||
query::run(&cfg, &logsql, limit, format, &mut stdout.lock())
|
query::run(&cfg, &logsql, limit, format, &mut stdout.lock())
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ clap.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
# Comparing the presented bearer with the stored one.
|
# Comparing the presented bearer with the stored one.
|
||||||
subtle.workspace = true
|
subtle.workspace = true
|
||||||
# Only for the rustls provider the store client needs.
|
|
||||||
swarm-queue-client.workspace = true
|
|
||||||
swarm-secret-client.workspace = true
|
swarm-secret-client.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ async fn handle(State(responder): State<Arc<Responder<Store>>>, headers: HeaderM
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
tracing_subscriber::fmt()
|
tracing_subscriber::fmt()
|
||||||
.with_env_filter(
|
.with_env_filter(
|
||||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@ path = "src/main.rs"
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
clap.workspace = true
|
clap.workspace = true
|
||||||
clap-markdown = "0.1"
|
clap-markdown = "0.1"
|
||||||
# The agent-token spelling the gateway's responder parses, and the rustls
|
# The agent-token spelling the gateway's responder parses.
|
||||||
# provider the store client needs.
|
|
||||||
swarm-queue-client.workspace = true
|
swarm-queue-client.workspace = true
|
||||||
# The read of this agent's own queue secret.
|
# The read of this agent's own queue secret.
|
||||||
swarm-secret-client.workspace = true
|
swarm-secret-client.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ fn main() -> Result<()> {
|
||||||
};
|
};
|
||||||
// Config read only for a store verb: `markdown-docs` runs in a nix check,
|
// Config read only for a store verb: `markdown-docs` runs in a nix check,
|
||||||
// where no credential exists.
|
// where no credential exists.
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
let cfg = auth::Config::from_env()?;
|
let cfg = auth::Config::from_env()?;
|
||||||
let stdout = std::io::stdout();
|
let stdout = std::io::stdout();
|
||||||
query::run(&cfg, &request, &mut stdout.lock())
|
query::run(&cfg, &request, &mut stdout.lock())
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ struct Args {
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
tracing_subscriber::fmt()
|
tracing_subscriber::fmt()
|
||||||
.with_env_filter(
|
.with_env_filter(
|
||||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||||
|
|
|
||||||
|
|
@ -82,10 +82,11 @@ hive-sh4re = { workspace = true, optional = true }
|
||||||
# feature's comment above), and `cargo check -p swarm-queue-client` alone
|
# feature's comment above), and `cargo check -p swarm-queue-client` alone
|
||||||
# must not depend on what else is in the build.
|
# must not depend on what else is in the build.
|
||||||
reqwest = { workspace = true, features = ["blocking"] }
|
reqwest = { workspace = true, features = ["blocking"] }
|
||||||
rustls.workspace = true
|
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
strum.workspace = true
|
strum.workspace = true
|
||||||
|
# The rustls provider `connect` installs.
|
||||||
|
swarm-secret-client.workspace = true
|
||||||
# A library, so its errors are a matchable enum rather than an opaque
|
# A library, so its errors are a matchable enum rather than an opaque
|
||||||
# `anyhow::Error`. The binaries that consume this keep anyhow; `?` converts.
|
# `anyhow::Error`. The binaries that consume this keep anyhow; `?` converts.
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -941,18 +941,6 @@ pub fn max_payload(client: &async_nats::Client) -> usize {
|
||||||
client.server_info().max_payload
|
client.server_info().max_payload
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Install `aws-lc-rs` as the process-wide rustls crypto provider. Call it
|
|
||||||
/// first thing in `main` of every binary that dials the queue.
|
|
||||||
///
|
|
||||||
/// rustls is built with both `ring` and `aws-lc-rs`; without an installed
|
|
||||||
/// default, the first TLS handshake panics (async-nats builds its config with
|
|
||||||
/// `ClientConfig::builder()`) and the client never connects. `aws-lc-rs`
|
|
||||||
/// because it is what reqwest uses when nothing is installed.
|
|
||||||
pub fn install_crypto_provider() {
|
|
||||||
// `Err` only means a provider is already installed, which is all this needs.
|
|
||||||
let _already_installed = rustls::crypto::aws_lc_rs::default_provider().install_default();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Connect to the swarm queue, presenting a token on each connection attempt
|
/// Connect to the swarm queue, presenting a token on each connection attempt
|
||||||
/// and minting a fresh one only when the cached one is near expiry. Reply
|
/// and minting a fresh one only when the cached one is near expiry. Reply
|
||||||
/// inboxes are under [`client_inbox_prefix`] of `cfg.client_id`.
|
/// inboxes are under [`client_inbox_prefix`] of `cfg.client_id`.
|
||||||
|
|
@ -962,7 +950,7 @@ pub fn install_crypto_provider() {
|
||||||
/// token expires, the controller keeps serving, its status data quietly stops
|
/// token expires, the controller keeps serving, its status data quietly stops
|
||||||
/// updating, and nothing says so until someone reads a dashboard.
|
/// updating, and nothing says so until someone reads a dashboard.
|
||||||
pub async fn connect(cfg: QueueConfig) -> Result<async_nats::Client, Error> {
|
pub async fn connect(cfg: QueueConfig) -> Result<async_nats::Client, Error> {
|
||||||
install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
// Trusts `cfg.ca_file` when set (the swarm's own CA, when the token
|
// Trusts `cfg.ca_file` when set (the swarm's own CA, when the token
|
||||||
// endpoint is signed by it) — see `build_http_client`. A timeout too,
|
// endpoint is signed by it) — see `build_http_client`. A timeout too,
|
||||||
// because this client runs INSIDE the auth callback: a token endpoint
|
// because this client runs INSIDE the auth callback: a token endpoint
|
||||||
|
|
@ -1134,14 +1122,6 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn a_tls_client_config_builds_once_the_provider_is_installed() {
|
|
||||||
install_crypto_provider();
|
|
||||||
let _config = rustls::ClientConfig::builder()
|
|
||||||
.with_root_certificates(rustls::RootCertStore::empty())
|
|
||||||
.with_no_client_auth();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn a_debug_print_of_a_config_does_not_carry_a_held_secret() {
|
async fn a_debug_print_of_a_config_does_not_carry_a_held_secret() {
|
||||||
let cfg = QueueConfig {
|
let cfg = QueueConfig {
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
async fn serve() -> Result<()> {
|
async fn serve() -> Result<()> {
|
||||||
hive_log::init();
|
hive_log::init();
|
||||||
swarm_queue_client::install_crypto_provider();
|
swarm_secret_client::install_crypto_provider();
|
||||||
let var = |name: &str| {
|
let var = |name: &str| {
|
||||||
let full = format!("{PREFIX}_{name}");
|
let full = format!("{PREFIX}_{name}");
|
||||||
std::env::var(&full).with_context(|| format!("{full} is unset"))
|
std::env::var(&full).with_context(|| format!("{full} is unset"))
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ reqwest.workspace = true
|
||||||
# implement — see `client::WriteAclPolicy`.
|
# implement — see `client::WriteAclPolicy`.
|
||||||
rustify.workspace = true
|
rustify.workspace = true
|
||||||
rustify_derive.workspace = true
|
rustify_derive.workspace = true
|
||||||
|
# `install_crypto_provider`, which the store client (reqwest, via vaultrs)
|
||||||
|
# needs before its first TLS handshake.
|
||||||
|
rustls.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
# `read_versioned` decodes the data half of the response vaultrs hands back as
|
# `read_versioned` decodes the data half of the response vaultrs hands back as
|
||||||
# a `serde_json::Value`.
|
# a `serde_json::Value`.
|
||||||
|
|
@ -22,3 +25,9 @@ vaultrs.workspace = true
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
|
# `ring` as well, as every binary that links async-nats builds it: with one
|
||||||
|
# provider compiled in rustls picks it without an install, so the provider
|
||||||
|
# test would pass with `install_crypto_provider` doing nothing.
|
||||||
|
[dev-dependencies]
|
||||||
|
rustls = { workspace = true, features = ["ring"] }
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,10 @@
|
||||||
//!
|
//!
|
||||||
//! [`mtls`] is the one module about reaching the store rather than about a
|
//! [`mtls`] is the one module about reaching the store rather than about a
|
||||||
//! value inside it, and its doc explains why that is not circular.
|
//! value inside it, and its doc explains why that is not circular.
|
||||||
|
//!
|
||||||
|
//! [`install_crypto_provider`] is process setup, not an agreement. It lives
|
||||||
|
//! here because this crate depends on no other swarm crate, so a binary that
|
||||||
|
//! needs only the provider and the store links nothing else.
|
||||||
|
|
||||||
pub mod acp;
|
pub mod acp;
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
|
|
@ -105,3 +109,30 @@ impl From<vaultrs::error::ClientError> for Error {
|
||||||
Self::Vault(Box::new(e))
|
Self::Vault(Box::new(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Install `aws-lc-rs` as the process-wide rustls crypto provider. Call it
|
||||||
|
/// first thing in `main` of every binary that dials the queue or reaches the
|
||||||
|
/// secret store over TLS.
|
||||||
|
///
|
||||||
|
/// rustls is built with both `ring` and `aws-lc-rs`; without an installed
|
||||||
|
/// default, the first TLS handshake panics. On the queue side async-nats
|
||||||
|
/// builds its config with `ClientConfig::builder()`, so the client never
|
||||||
|
/// connects. On the store side the client is reqwest, via vaultrs.
|
||||||
|
/// `aws-lc-rs` because it is what reqwest uses when nothing is installed.
|
||||||
|
pub fn install_crypto_provider() {
|
||||||
|
// `Err` only means a provider is already installed, which is all this needs.
|
||||||
|
let _already_installed = rustls::crypto::aws_lc_rs::default_provider().install_default();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_tls_client_config_builds_once_the_provider_is_installed() {
|
||||||
|
install_crypto_provider();
|
||||||
|
let _config = rustls::ClientConfig::builder()
|
||||||
|
.with_root_certificates(rustls::RootCertStore::empty())
|
||||||
|
.with_no_client_auth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue