greentic_component_runtime/
policy.rs1use std::collections::HashMap;
2use std::sync::{Arc, Mutex};
3
4use greentic_component_store::ComponentStore;
5use greentic_component_store::VerificationPolicy;
6
7#[derive(Debug, Clone)]
8pub struct HostPolicy {
9 pub allow_http_fetch: bool,
10 pub allow_telemetry: bool,
11 pub allow_state_read: bool,
12 pub allow_state_write: bool,
13 pub allow_state_delete: bool,
14 pub state_store: Arc<Mutex<HashMap<String, Vec<u8>>>>,
15}
16
17impl Default for HostPolicy {
18 fn default() -> Self {
19 Self {
20 allow_http_fetch: false,
21 allow_telemetry: true,
22 allow_state_read: false,
23 allow_state_write: false,
24 allow_state_delete: false,
25 state_store: Arc::new(Mutex::new(HashMap::new())),
26 }
27 }
28}
29
30#[derive(Debug, Clone)]
31pub struct LoadPolicy {
32 pub store: Arc<ComponentStore>,
33 pub verification: VerificationPolicy,
34 pub host: HostPolicy,
35}
36
37impl LoadPolicy {
38 pub fn new(store: Arc<ComponentStore>) -> Self {
39 Self {
40 store,
41 verification: VerificationPolicy::default(),
42 host: HostPolicy::default(),
43 }
44 }
45
46 pub fn with_verification(mut self, policy: VerificationPolicy) -> Self {
47 self.verification = policy;
48 self
49 }
50
51 pub fn with_host_policy(mut self, host: HostPolicy) -> Self {
52 self.host = host;
53 self
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 use greentic_component_store::{DigestPolicy, SignaturePolicy};
61
62 #[test]
63 fn default_host_policy_denies_mutating_or_network_features() {
64 let policy = HostPolicy::default();
65 assert!(!policy.allow_http_fetch);
66 assert!(!policy.allow_state_read);
67 assert!(!policy.allow_state_write);
68 assert!(!policy.allow_state_delete);
69 assert!(policy.allow_telemetry);
70 assert!(policy.state_store.lock().expect("lock").is_empty());
71 }
72
73 #[test]
74 fn load_policy_builder_preserves_store_and_overrides_fields() {
75 let cache_dir = std::env::temp_dir().join(format!(
76 "greentic-component-runtime-policy-{}",
77 std::process::id()
78 ));
79 std::fs::create_dir_all(&cache_dir).expect("cache dir");
80 let store = Arc::new(ComponentStore::new(&cache_dir).expect("store"));
81 let verification = VerificationPolicy {
82 digest: Some(DigestPolicy::sha256(Some("abcd".into()), true)),
83 signature: Some(SignaturePolicy::Disabled),
84 };
85 let host = HostPolicy {
86 allow_http_fetch: true,
87 ..HostPolicy::default()
88 };
89
90 let policy = LoadPolicy::new(store.clone())
91 .with_verification(verification.clone())
92 .with_host_policy(host.clone());
93
94 assert!(Arc::ptr_eq(&policy.store, &store));
95 assert_eq!(policy.verification.digest.unwrap().expected(), Some("abcd"));
96 assert!(matches!(
97 policy.verification.signature,
98 Some(SignaturePolicy::Disabled)
99 ));
100 assert!(policy.host.allow_http_fetch);
101 assert_eq!(policy.host.allow_telemetry, host.allow_telemetry);
102 }
103}