From f097f000d8d53ca3b5caa089a3082960ffbb833f Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Fri, 3 Apr 2026 14:02:08 -0300 Subject: [PATCH] Fix: nested runtime panic in AuthConfig::from_env() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: AuthConfig::from_env() was creating a new tokio runtime with Runtime::new() inside an existing runtime during initialization. Impact: Botserver crashed with "Cannot start a runtime from within a runtime" panic right after CORS layer initialization. Fix: Use new_current_thread() + std::thread::spawn pattern (same as get_database_url_sync fix) to create an isolated thread for async operations. Files: src/security/auth_api/config.rs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/security/auth_api/config.rs | 49 +++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/src/security/auth_api/config.rs b/src/security/auth_api/config.rs index 8c433256..88937737 100644 --- a/src/security/auth_api/config.rs +++ b/src/security/auth_api/config.rs @@ -1,3 +1,5 @@ +use anyhow::anyhow; + #[derive(Debug, Clone)] pub struct AuthConfig { pub require_auth: bool, @@ -54,26 +56,33 @@ impl AuthConfig { if let Ok(secret) = std::env::var("VAULT_TOKEN") { if !secret.is_empty() { - let rt = tokio::runtime::Runtime::new().ok(); - if let Some(rt) = rt { - let sm = crate::core::shared::utils::get_secrets_manager_sync(); - if let Some(sm) = sm { - if let Ok(secrets) = - rt.block_on(sm.get_secret(crate::core::secrets::SecretPaths::JWT)) - { - if let Some(s) = secrets.get("secret") { - config.jwt_secret = Some(s.clone()); - } - if let Some(r) = secrets.get("require_auth") { - config.require_auth = r == "true" || r == "1"; - } - if let Some(p) = secrets.get("anonymous_paths") { - config.allow_anonymous_paths = p - .split(',') - .map(|s| s.trim().to_string()) - .filter(|s| !s.is_empty()) - .collect(); - } + let sm = crate::core::shared::utils::get_secrets_manager_sync(); + if let Some(sm) = sm { + let sm_clone = sm.clone(); + let (tx, rx) = std::sync::mpsc::channel(); + std::thread::spawn(move || { + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build(); + let result = match rt { + Ok(rt) => rt.block_on(sm_clone.get_secret(crate::core::secrets::SecretPaths::JWT)), + Err(e) => Err(anyhow::anyhow!("Failed to create runtime: {}", e)), + }; + let _ = tx.send(result); + }); + if let Ok(Ok(secrets)) = rx.recv() { + if let Some(s) = secrets.get("secret") { + config.jwt_secret = Some(s.clone()); + } + if let Some(r) = secrets.get("require_auth") { + config.require_auth = r == "true" || r == "1"; + } + if let Some(p) = secrets.get("anonymous_paths") { + config.allow_anonymous_paths = p + .split(',') + .map(|s| s.trim().to_string()) + .filter(|s| !s.is_empty()) + .collect(); } } }