From 251a8e086e7b256595281865ac26f3f779f98475 Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Thu, 25 Jun 2026 17:34:11 -0400 Subject: [PATCH 1/2] Set rustls crypto provider explicitly Signed-off-by: Zhiwei Liang --- Cargo.lock | 1 + crates/trigger/Cargo.toml | 1 + crates/trigger/src/cli.rs | 1 + crates/trigger/src/crypto.rs | 15 +++++++++++++++ crates/trigger/src/lib.rs | 1 + src/bin/spin.rs | 1 + 6 files changed, 20 insertions(+) create mode 100644 crates/trigger/src/crypto.rs diff --git a/Cargo.lock b/Cargo.lock index 30894eb174..893deb6a4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9756,6 +9756,7 @@ dependencies = [ "ctrlc", "futures", "heck 0.5.0", + "rustls 0.23.37", "sanitize-filename", "serde", "serde_json", diff --git a/crates/trigger/Cargo.toml b/crates/trigger/Cargo.toml index 9b405b5e6d..c180be0b7b 100644 --- a/crates/trigger/Cargo.toml +++ b/crates/trigger/Cargo.toml @@ -18,6 +18,7 @@ experimental-wasm-features = [] [dependencies] anyhow = { workspace = true } +rustls = { workspace = true } clap = { workspace = true, features = ["derive", "env", "wrap_help"] } ctrlc = { workspace = true } futures = { workspace = true } diff --git a/crates/trigger/src/cli.rs b/crates/trigger/src/cli.rs index 6c7836be1f..1e91989dd7 100644 --- a/crates/trigger/src/cli.rs +++ b/crates/trigger/src/cli.rs @@ -185,6 +185,7 @@ pub struct NoCliArgs; impl, B: RuntimeFactorsBuilder> FactorsTriggerCommand { /// Create a new TriggerExecutorBuilder from this TriggerExecutorCommand. pub async fn run(self) -> Result<()> { + crate::crypto::install_default_crypto_provider(); // Handle --help-args-only if self.help_args_only { Self::command() diff --git a/crates/trigger/src/crypto.rs b/crates/trigger/src/crypto.rs new file mode 100644 index 0000000000..b9b283ebba --- /dev/null +++ b/crates/trigger/src/crypto.rs @@ -0,0 +1,15 @@ +use std::sync::Once; + +static INSTALL_DEFAULT_CRYPTO_PROVIDER: Once = Once::new(); + +/// Install Spin's process-wide rustls crypto provider. +/// +/// This is idempotent for Spin's own duplicate calls from `main` and the trigger, +/// but fails loudly if something else installed a rustls provider first. +pub fn install_default_crypto_provider() { + INSTALL_DEFAULT_CRYPTO_PROVIDER.call_once(|| { + rustls::crypto::ring::default_provider() + .install_default() + .expect("failed to install rustls ring crypto provider"); + }); +} diff --git a/crates/trigger/src/lib.rs b/crates/trigger/src/lib.rs index ed3c6291e0..3c6e8cc6ac 100644 --- a/crates/trigger/src/lib.rs +++ b/crates/trigger/src/lib.rs @@ -1,4 +1,5 @@ pub mod cli; +pub mod crypto; pub mod loader; use heck::ToTitleCase; diff --git a/src/bin/spin.rs b/src/bin/spin.rs index ec8dc8aefe..1b6a4bc616 100644 --- a/src/bin/spin.rs +++ b/src/bin/spin.rs @@ -2,6 +2,7 @@ use spin_cli::subprocess::ExitStatusError; #[tokio::main] async fn main() { + spin_trigger::crypto::install_default_crypto_provider(); if let Err(err) = spin_cli::run().await { let code = match err.downcast_ref::() { // If we encounter an `ExitStatusError` it means a subprocess has already From 425eac170f41075642a8ebbaccb2eb495c16a17c Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Tue, 30 Jun 2026 19:45:05 -0400 Subject: [PATCH 2/2] Moving `install_default_crypto_provider` to dedicated crate Signed-off-by: Zhiwei Liang --- Cargo.lock | 10 +++++++++- Cargo.toml | 1 + crates/tls/Cargo.toml | 15 +++++++++++++++ crates/{trigger/src/crypto.rs => tls/src/lib.rs} | 0 crates/trigger/Cargo.toml | 2 +- crates/trigger/src/cli.rs | 2 +- crates/trigger/src/lib.rs | 1 - src/bin/spin.rs | 2 +- 8 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 crates/tls/Cargo.toml rename crates/{trigger/src/crypto.rs => tls/src/lib.rs} (100%) diff --git a/Cargo.lock b/Cargo.lock index 893deb6a4b..a721982c57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8777,6 +8777,7 @@ dependencies = [ "spin-runtime-factors", "spin-telemetry", "spin-templates", + "spin-tls", "spin-trigger", "spin-trigger-http", "spin-trigger-redis", @@ -9747,6 +9748,13 @@ dependencies = [ "walkdir", ] +[[package]] +name = "spin-tls" +version = "4.1.0-pre0" +dependencies = [ + "rustls 0.23.37", +] + [[package]] name = "spin-trigger" version = "4.1.0-pre0" @@ -9756,7 +9764,6 @@ dependencies = [ "ctrlc", "futures", "heck 0.5.0", - "rustls 0.23.37", "sanitize-filename", "serde", "serde_json", @@ -9771,6 +9778,7 @@ dependencies = [ "spin-factors", "spin-factors-executor", "spin-telemetry", + "spin-tls", "spin-world", "tempfile", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 1a2eb8b932..8c8bc05a98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,6 +74,7 @@ spin-telemetry = { path = "crates/telemetry", features = [ "tracing-log-compat", ] } spin-templates = { path = "crates/templates" } +spin-tls = { path = "crates/tls" } spin-trigger = { path = "crates/trigger" } spin-trigger-http = { path = "crates/trigger-http" } spin-trigger-redis = { path = "crates/trigger-redis" } diff --git a/crates/tls/Cargo.toml b/crates/tls/Cargo.toml new file mode 100644 index 0000000000..83e913d690 --- /dev/null +++ b/crates/tls/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "spin-tls" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +rust-version.workspace = true + +[dependencies] +rustls = { workspace = true } + +[lints] +workspace = true diff --git a/crates/trigger/src/crypto.rs b/crates/tls/src/lib.rs similarity index 100% rename from crates/trigger/src/crypto.rs rename to crates/tls/src/lib.rs diff --git a/crates/trigger/Cargo.toml b/crates/trigger/Cargo.toml index c180be0b7b..7098bbc8d3 100644 --- a/crates/trigger/Cargo.toml +++ b/crates/trigger/Cargo.toml @@ -18,7 +18,6 @@ experimental-wasm-features = [] [dependencies] anyhow = { workspace = true } -rustls = { workspace = true } clap = { workspace = true, features = ["derive", "env", "wrap_help"] } ctrlc = { workspace = true } futures = { workspace = true } @@ -37,6 +36,7 @@ spin-factor-wasi = { path = "../factor-wasi" } spin-factors = { path = "../factors" } spin-factors-executor = { path = "../factors-executor" } spin-telemetry = { path = "../telemetry" } +spin-tls = { path = "../tls" } spin-world = { path = "../world" } tokio = { workspace = true, features = ["fs", "rt"] } tracing = { workspace = true } diff --git a/crates/trigger/src/cli.rs b/crates/trigger/src/cli.rs index 1e91989dd7..eb698b269e 100644 --- a/crates/trigger/src/cli.rs +++ b/crates/trigger/src/cli.rs @@ -185,7 +185,7 @@ pub struct NoCliArgs; impl, B: RuntimeFactorsBuilder> FactorsTriggerCommand { /// Create a new TriggerExecutorBuilder from this TriggerExecutorCommand. pub async fn run(self) -> Result<()> { - crate::crypto::install_default_crypto_provider(); + spin_tls::install_default_crypto_provider(); // Handle --help-args-only if self.help_args_only { Self::command() diff --git a/crates/trigger/src/lib.rs b/crates/trigger/src/lib.rs index 3c6e8cc6ac..ed3c6291e0 100644 --- a/crates/trigger/src/lib.rs +++ b/crates/trigger/src/lib.rs @@ -1,5 +1,4 @@ pub mod cli; -pub mod crypto; pub mod loader; use heck::ToTitleCase; diff --git a/src/bin/spin.rs b/src/bin/spin.rs index 1b6a4bc616..95bffef59f 100644 --- a/src/bin/spin.rs +++ b/src/bin/spin.rs @@ -2,7 +2,7 @@ use spin_cli::subprocess::ExitStatusError; #[tokio::main] async fn main() { - spin_trigger::crypto::install_default_crypto_provider(); + spin_tls::install_default_crypto_provider(); if let Err(err) = spin_cli::run().await { let code = match err.downcast_ref::() { // If we encounter an `ExitStatusError` it means a subprocess has already