use systemprompt_models::profile::{SecretsConfig, SecretsSource, VaultSecretsConfig};
use super::SecretsBootstrapError;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ResolvedSource<'a> {
SubprocessEnv,
Vault(&'a VaultSecretsConfig),
DeploymentHostEnv,
LocalEnvWithFileFallback(&'a str),
File(&'a str),
}
pub fn resolve_source(
config: Option<&SecretsConfig>,
is_subprocess: bool,
is_deployment_host: bool,
has_valid_pepper_in_env: bool,
) -> Result<ResolvedSource<'_>, SecretsBootstrapError> {
if is_subprocess && has_valid_pepper_in_env {
return Ok(ResolvedSource::SubprocessEnv);
}
let Some(config) = config else {
return if is_deployment_host && has_valid_pepper_in_env {
Ok(ResolvedSource::DeploymentHostEnv)
} else {
Err(SecretsBootstrapError::NoSecretsConfigured)
};
};
match config.source {
SecretsSource::Vault => config
.vault
.as_ref()
.map(ResolvedSource::Vault)
.ok_or(SecretsBootstrapError::VaultBlockMissing),
SecretsSource::Env if is_deployment_host => Ok(ResolvedSource::DeploymentHostEnv),
SecretsSource::File if is_deployment_host && has_valid_pepper_in_env => {
Ok(ResolvedSource::DeploymentHostEnv)
},
SecretsSource::Env => Ok(ResolvedSource::LocalEnvWithFileFallback(configured_path(
config,
)?)),
SecretsSource::File => Ok(ResolvedSource::File(configured_path(config)?)),
}
}
fn configured_path(config: &SecretsConfig) -> Result<&str, SecretsBootstrapError> {
config
.secrets_path()
.map_err(|e| SecretsBootstrapError::SecretsConfigInvalid {
message: e.to_string(),
})
}