use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Envelope {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub scopes: Vec<String>,
#[serde(default)]
pub network: NetworkPolicy,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub filesystem: Vec<FilesystemRule>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub subprocess: Vec<SubprocessRule>,
#[serde(default)]
pub safety: Safety,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub sensitive_invocations: Vec<SensitivePredicate>,
#[serde(default)]
pub data_classification: DataClassification,
}
impl Default for Envelope {
fn default() -> Self {
Self {
scopes: Vec::new(),
network: NetworkPolicy::None,
filesystem: Vec::new(),
subprocess: Vec::new(),
safety: Safety::ReadOnly,
sensitive_invocations: Vec::new(),
data_classification: DataClassification::Public,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(tag = "mode", rename_all = "snake_case")]
pub enum NetworkPolicy {
#[default]
None,
AllowList {
rules: Vec<NetworkRule>,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct NetworkRule {
pub host: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub port: Option<u16>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub scheme: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct FilesystemRule {
pub path: String,
pub mode: FilesystemMode,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum FilesystemMode {
Read,
Write,
Delete,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SubprocessRule {
pub argv_pattern: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub env_allow: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cwd: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Default)]
#[serde(rename_all = "kebab-case")]
pub enum Safety {
#[default]
ReadOnly,
Mutating,
Destructive,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(rename_all = "snake_case")]
pub enum DataClassification {
#[default]
Public,
Pii,
Secret,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SensitivePredicate {
pub jsonpath: String,
pub matcher: SensitiveMatcher,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", content = "value", rename_all = "snake_case")]
pub enum SensitiveMatcher {
Exists,
Equals(serde_json::Value),
Regex(String),
Gt(f64),
Lt(f64),
}