90 lines
2.7 KiB
Rust
90 lines
2.7 KiB
Rust
//! Sandbox policy types and parsing.
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use std::path::PathBuf;
|
|
|
|
/// Sandbox strictness mode.
|
|
///
|
|
/// Using an enum instead of a raw string ensures that invalid values (e.g. typos
|
|
/// like "strcit") cause a deserialization error rather than silently falling
|
|
/// through to a less-strict mode (fail-closed).
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
|
|
#[serde(rename_all = "lowercase")]
|
|
pub enum SandboxMode {
|
|
Strict,
|
|
#[default]
|
|
Compat,
|
|
Permissive,
|
|
}
|
|
|
|
/// Windows Restricted Token sandbox policy.
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
#[serde(tag = "type", rename_all = "kebab-case")]
|
|
pub enum SandboxPolicy {
|
|
/// Read-only access to the entire file-system.
|
|
ReadOnly,
|
|
|
|
/// Read-only + write access to workspace directories.
|
|
WorkspaceWrite {
|
|
/// Additional writable folders beyond cwd and TMPDIR.
|
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
|
writable_roots: Vec<PathBuf>,
|
|
|
|
/// Allow outbound network access. Defaults to false.
|
|
#[serde(default)]
|
|
network_access: bool,
|
|
|
|
/// Sandbox strictness mode — controls which system paths are writable.
|
|
/// - "strict": only workspace + TEMP/TMP (no APPDATA)
|
|
/// - "compat": workspace + TEMP/TMP + APPDATA/LOCALAPPDATA
|
|
/// - "permissive": all user-writable paths
|
|
/// Defaults to "compat" when absent.
|
|
#[serde(default)]
|
|
sandbox_mode: SandboxMode,
|
|
},
|
|
}
|
|
|
|
impl Default for SandboxPolicy {
|
|
fn default() -> Self {
|
|
SandboxPolicy::ReadOnly
|
|
}
|
|
}
|
|
|
|
impl SandboxPolicy {
|
|
pub fn new_read_only_policy() -> Self {
|
|
SandboxPolicy::ReadOnly
|
|
}
|
|
|
|
pub fn new_workspace_write_policy() -> Self {
|
|
SandboxPolicy::WorkspaceWrite {
|
|
writable_roots: Vec::new(),
|
|
network_access: false,
|
|
sandbox_mode: SandboxMode::Compat,
|
|
}
|
|
}
|
|
|
|
pub fn has_full_network_access(&self) -> bool {
|
|
match self {
|
|
SandboxPolicy::ReadOnly => false,
|
|
SandboxPolicy::WorkspaceWrite { network_access, .. } => *network_access,
|
|
}
|
|
}
|
|
|
|
/// Returns the sandbox strictness mode.
|
|
pub fn sandbox_mode(&self) -> &SandboxMode {
|
|
match self {
|
|
SandboxPolicy::ReadOnly => &SandboxMode::Strict,
|
|
SandboxPolicy::WorkspaceWrite { sandbox_mode, .. } => sandbox_mode,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Parse a policy from a string (preset name or JSON).
|
|
pub fn parse_policy(value: &str) -> anyhow::Result<SandboxPolicy> {
|
|
match value {
|
|
"read-only" => Ok(SandboxPolicy::new_read_only_policy()),
|
|
"workspace-write" => Ok(SandboxPolicy::new_workspace_write_policy()),
|
|
other => Ok(serde_json::from_str(other)?),
|
|
}
|
|
}
|