use crate::config::{SecretReference, SecretReferenceProvider};
use crate::error::DataError;
use crate::secret::SecretString;
pub async fn resolve_secret(reference: &SecretReference) -> Result<SecretString, DataError> {
match reference.provider {
SecretReferenceProvider::Env => resolve_env(reference),
SecretReferenceProvider::Vault => resolve_vault(reference).await,
SecretReferenceProvider::Kms => Err(DataError::InvalidSecretReference {
input: format!("kms://{}", reference.path),
}),
}
}
fn resolve_env(reference: &SecretReference) -> Result<SecretString, DataError> {
std::env::var(&reference.path)
.map(SecretString::new)
.map_err(|_| DataError::SecretNotFound {
reference: format!("env://{}", reference.path),
})
}
#[cfg(feature = "vault")]
async fn resolve_vault(reference: &SecretReference) -> Result<SecretString, DataError> {
let vault_addr = std::env::var("VAULT_ADDR").map_err(|_| DataError::ProviderUnavailable {
provider: "vault".to_string(),
reason: "VAULT_ADDR environment variable not set".to_string(),
})?;
let vault_token = std::env::var("VAULT_TOKEN").map_err(|_| DataError::ProviderUnavailable {
provider: "vault".to_string(),
reason: "VAULT_TOKEN environment variable not set".to_string(),
})?;
let value = crate::providers::vault::fetch_vault_kv_secret(
&vault_addr,
&vault_token,
&reference.path,
reference.field.as_deref(),
)
.await?;
Ok(SecretString::new(value))
}
#[cfg(not(feature = "vault"))]
async fn resolve_vault(_reference: &SecretReference) -> Result<SecretString, DataError> {
Err(DataError::ProviderUnavailable {
provider: "vault".to_string(),
reason: "vault feature not enabled — recompile with --features vault".to_string(),
})
}