use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct IpcSecurityConfig {
#[serde(default)]
pub peer_identity: PeerIdentityConfig,
#[serde(default)]
pub authorization: AuthorizationConfig,
#[serde(default)]
pub replay_protection: ReplayProtectionConfig,
#[serde(default)]
pub request_size_limit: RequestSizeLimitConfig,
#[serde(default)]
pub rate_limit: RateLimitConfig,
#[serde(default)]
pub idempotency: IdempotencyConfig,
#[serde(default)]
pub allowlist: AllowlistConfig,
}
impl Default for IpcSecurityConfig {
fn default() -> Self {
Self {
peer_identity: PeerIdentityConfig::default(),
authorization: AuthorizationConfig::default(),
replay_protection: ReplayProtectionConfig::default(),
request_size_limit: RequestSizeLimitConfig::default(),
rate_limit: RateLimitConfig::default(),
idempotency: IdempotencyConfig::default(),
allowlist: AllowlistConfig::default(),
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct PeerIdentityConfig {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_true")]
pub require_uid_match: bool,
#[serde(default)]
pub allowed_gids: Vec<u32>,
#[serde(default)]
pub allowed_pids: Vec<u32>,
}
impl Default for PeerIdentityConfig {
fn default() -> Self {
Self {
enabled: true,
require_uid_match: true,
allowed_gids: Vec::new(),
allowed_pids: Vec::new(),
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct AuthorizationConfig {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_high_risk_commands")]
pub high_risk_commands: Vec<String>,
#[serde(default = "default_root_only")]
pub allowed_uids: Vec<u32>,
}
impl Default for AuthorizationConfig {
fn default() -> Self {
Self {
enabled: true,
high_risk_commands: default_high_risk_commands(),
allowed_uids: default_root_only(),
}
}
}
fn default_high_risk_commands() -> Vec<String> {
vec![
"command.restart_child".into(),
"command.pause_child".into(),
"command.resume_child".into(),
"command.quarantine_child".into(),
"command.remove_child".into(),
"command.add_child".into(),
"command.shutdown_tree".into(),
]
}
fn default_root_only() -> Vec<u32> {
vec![0]
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct ReplayProtectionConfig {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_1024")]
pub window_size: usize,
#[serde(default = "default_60")]
pub ttl_seconds: u64,
}
impl Default for ReplayProtectionConfig {
fn default() -> Self {
Self {
enabled: true,
window_size: 1024,
ttl_seconds: 60,
}
}
}
fn default_1024() -> usize {
1024
}
fn default_60() -> u64 {
60
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct RequestSizeLimitConfig {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_65536")]
pub max_bytes: usize,
}
impl Default for RequestSizeLimitConfig {
fn default() -> Self {
Self {
enabled: true,
max_bytes: 65536,
}
}
}
fn default_65536() -> usize {
65536
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct RateLimitConfig {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_100_0")]
pub refill_rate: f64,
#[serde(default = "default_20")]
pub burst_capacity: u32,
}
impl Default for RateLimitConfig {
fn default() -> Self {
Self {
enabled: true,
refill_rate: 100.0,
burst_capacity: 20,
}
}
}
fn default_100_0() -> f64 {
100.0
}
fn default_20() -> u32 {
20
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct IdempotencyConfig {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_60")]
pub result_cache_ttl_seconds: u64,
#[serde(default = "default_1024")]
pub max_cached_results: usize,
}
impl Default for IdempotencyConfig {
fn default() -> Self {
Self {
enabled: true,
result_cache_ttl_seconds: 60,
max_cached_results: 1024,
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct AllowlistConfig {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default)]
pub allowed_paths: Vec<String>,
}
impl Default for AllowlistConfig {
fn default() -> Self {
Self {
enabled: true,
allowed_paths: Vec::new(),
}
}
}
fn default_true() -> bool {
true
}