systemprompt_config/bootstrap/secrets/
resolve.rs1use systemprompt_manifest::profile::{SecretsConfig, SecretsSource, VaultSecretsConfig};
19
20use super::SecretsBootstrapError;
21
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub enum ResolvedSource<'a> {
24 SubprocessEnv,
25 Vault(&'a VaultSecretsConfig),
26 DeploymentHostEnv,
27 LocalEnvWithFileFallback(&'a str),
28 File(&'a str),
29}
30
31pub fn resolve_source(
32 config: Option<&SecretsConfig>,
33 is_subprocess: bool,
34 is_deployment_host: bool,
35 has_valid_pepper_in_env: bool,
36) -> Result<ResolvedSource<'_>, SecretsBootstrapError> {
37 if is_subprocess && has_valid_pepper_in_env {
38 return Ok(ResolvedSource::SubprocessEnv);
39 }
40
41 let Some(config) = config else {
42 return if is_deployment_host && has_valid_pepper_in_env {
43 Ok(ResolvedSource::DeploymentHostEnv)
44 } else {
45 Err(SecretsBootstrapError::NoSecretsConfigured)
46 };
47 };
48
49 match config.source {
50 SecretsSource::Vault => config
51 .vault
52 .as_ref()
53 .map(ResolvedSource::Vault)
54 .ok_or(SecretsBootstrapError::VaultBlockMissing),
55 SecretsSource::Env if is_deployment_host => Ok(ResolvedSource::DeploymentHostEnv),
56 SecretsSource::File if is_deployment_host && has_valid_pepper_in_env => {
57 Ok(ResolvedSource::DeploymentHostEnv)
58 },
59 SecretsSource::Env => Ok(ResolvedSource::LocalEnvWithFileFallback(configured_path(
60 config,
61 )?)),
62 SecretsSource::File => Ok(ResolvedSource::File(configured_path(config)?)),
63 }
64}
65
66fn configured_path(config: &SecretsConfig) -> Result<&str, SecretsBootstrapError> {
67 config
68 .secrets_path()
69 .map_err(SecretsBootstrapError::SecretsConfigInvalid)
70}