microsandbox_network/secrets/
config.rs1pub use microsandbox_types::{
10 HostPattern, MAX_SECRET_PLACEHOLDER_BYTES, SecretConfigError, SecretEntry, SecretInjection,
11 SecretSource, SecretsConfig, ViolationAction,
12};
13
14pub(crate) trait SecretsConfigExt {
21 fn has_plain_http_candidates(&self) -> bool;
26
27 fn has_host_scoped_secrets(&self) -> bool;
33}
34
35impl SecretsConfigExt for SecretsConfig {
36 fn has_plain_http_candidates(&self) -> bool {
37 self.secrets.iter().any(|secret| {
38 !secret.require_tls_identity
39 && (secret.injection.headers
40 || secret.injection.basic_auth
41 || secret.injection.query_params
42 || secret.injection.body)
43 })
44 }
45
46 fn has_host_scoped_secrets(&self) -> bool {
47 self.secrets
48 .iter()
49 .any(|secret| secret.allowed_hosts.iter().any(|h| *h != HostPattern::Any))
50 }
51}
52
53#[cfg(test)]
58mod tests {
59 use super::*;
60
61 fn secret(require_tls_identity: bool, hosts: Vec<HostPattern>) -> SecretEntry {
62 SecretEntry {
63 env_var: "API_KEY".into(),
64 value: zeroize::Zeroizing::new("secret".into()),
65 source: None,
66 placeholder: "$MSB_API_KEY".into(),
67 allowed_hosts: hosts,
68 injection: SecretInjection::default(),
69 on_violation: None,
70 require_tls_identity,
71 }
72 }
73
74 #[test]
75 fn plain_http_candidates_require_tls_opt_out() {
76 let tls_only = SecretsConfig {
77 secrets: vec![secret(true, vec![HostPattern::Any])],
78 on_violation: ViolationAction::default(),
79 };
80 assert!(!tls_only.has_plain_http_candidates());
81
82 let plain = SecretsConfig {
83 secrets: vec![secret(false, vec![HostPattern::Any])],
84 on_violation: ViolationAction::default(),
85 };
86 assert!(plain.has_plain_http_candidates());
87 }
88
89 #[test]
90 fn host_scoped_detects_non_any_pattern() {
91 let any = SecretsConfig {
92 secrets: vec![secret(true, vec![HostPattern::Any])],
93 on_violation: ViolationAction::default(),
94 };
95 assert!(!any.has_host_scoped_secrets());
96
97 let scoped = SecretsConfig {
98 secrets: vec![secret(
99 true,
100 vec![HostPattern::Exact("api.example.com".into())],
101 )],
102 on_violation: ViolationAction::default(),
103 };
104 assert!(scoped.has_host_scoped_secrets());
105 }
106}