Skip to content

Commit 283e3c6

Browse files
authored
fix(config): don't attempt secrets resolution if backend command is empty (#1167)
1 parent 98de5fa commit 283e3c6

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

lib/saluki-config/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ serde_json = { workspace = true }
1616
serde_yaml = { workspace = true }
1717
snafu = { workspace = true }
1818
tempfile = { workspace = true }
19-
tokio = { workspace = true, features = ["fs", "io-util", "process", "time"] }
19+
tokio = { workspace = true, features = ["fs", "io-util", "process", "sync", "time"] }
2020
tracing = { workspace = true }
21+
2122
[dev-dependencies]
2223
tokio = { workspace = true, features = ["macros", "rt"] }

lib/saluki-config/src/lib.rs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,20 +334,20 @@ impl ConfigurationLoader {
334334
/// Care should be taken to not return sensitive information in either the error output (standard error) of the
335335
/// backend command or the `error` field in the JSON response, as these values are logged in order to aid debugging.
336336
pub async fn with_default_secrets_resolution(mut self) -> Result<Self, ConfigurationError> {
337-
let initial_figment = build_figment_from_sources(&self.provider_sources);
337+
let configuration = build_figment_from_sources(&self.provider_sources);
338338

339339
// If no secrets backend is set, we can't resolve secrets, so just return early.
340-
if !initial_figment.contains("secret_backend_command") {
340+
if !has_valid_secret_backend_command(&configuration) {
341341
debug!("No secrets backend configured; skipping secrets resolution.");
342342
return Ok(self);
343343
}
344344

345-
let resolver_config = initial_figment.extract::<secrets::resolver::ExternalProcessResolverConfiguration>()?;
345+
let resolver_config = configuration.extract::<secrets::resolver::ExternalProcessResolverConfiguration>()?;
346346
let resolver = secrets::resolver::ExternalProcessResolver::from_configuration(resolver_config)
347347
.await
348348
.context(Secrets)?;
349349

350-
let provider = secrets::Provider::new(resolver, &initial_figment)
350+
let provider = secrets::Provider::new(resolver, &configuration)
351351
.await
352352
.context(Secrets)?;
353353

@@ -856,10 +856,53 @@ fn from_figment_error(lookup_sources: &HashSet<LookupSource>, e: figment::Error)
856856
}
857857
}
858858

859+
fn has_valid_secret_backend_command(configuration: &Figment) -> bool {
860+
configuration
861+
.find_value("secret_backend_command")
862+
.ok()
863+
.is_some_and(|v| v.as_str().filter(|s| !s.is_empty()).is_some())
864+
}
865+
859866
#[cfg(test)]
860867
mod tests {
861868
use super::*;
862869

870+
macro_rules! json_to_figment {
871+
($json:tt) => {
872+
Figment::from(Serialized::defaults(serde_json::json!($json)))
873+
};
874+
}
875+
876+
#[test]
877+
fn test_has_valid_secret_backend_command() {
878+
// When `secrets_backend_command` is not set at all, or is set to an empty string, or isn't even a string
879+
// value... then we should consider those scenarios as "secrets backend not configured".
880+
let figment = Figment::new();
881+
assert!(!has_valid_secret_backend_command(&figment));
882+
883+
let figment = json_to_figment!({
884+
"secret_backend_command": ""
885+
});
886+
assert!(!has_valid_secret_backend_command(&figment));
887+
888+
let figment = json_to_figment!({
889+
"secret_backend_command": false
890+
});
891+
assert!(!has_valid_secret_backend_command(&figment));
892+
893+
// Otherwise, whether it's a valid path or not, then we should consider things enabled, which means we'll
894+
// at least attempt secrets resolution:
895+
let figment = json_to_figment!({
896+
"secret_backend_command": "/usr/bin/foo"
897+
});
898+
assert!(has_valid_secret_backend_command(&figment));
899+
900+
let figment = json_to_figment!({
901+
"secret_backend_command": "or anything else"
902+
});
903+
assert!(has_valid_secret_backend_command(&figment));
904+
}
905+
863906
#[tokio::test]
864907
async fn test_static_configuration() {
865908
let (cfg, _) = ConfigurationLoader::for_tests(

0 commit comments

Comments
 (0)