docs(sandbox): define windows helper contract

This commit is contained in:
Zhuoran Deng
2026-05-07 20:13:51 +08:00
committed by Hunter Bown
parent e814a203cb
commit 451d66ab0a
4 changed files with 50 additions and 44 deletions
+12 -5
View File
@@ -10,7 +10,9 @@
//!
//! - **macOS**: Uses Seatbelt (sandbox-exec) for mandatory access control
//! - **Linux**: Uses Landlock (kernel 5.13+) for filesystem access control
//! - **Windows**: Windows Sandbox/AppContainer/Restricted token (best-effort)
//! - **Windows**: No OS sandbox is advertised yet. The planned first helper
//! contract is process-tree containment only via a Windows Job Object; it
//! must not claim filesystem, network, registry, or AppContainer isolation.
//!
//! # Usage
//!
@@ -179,7 +181,10 @@ pub enum SandboxType {
#[cfg(target_os = "linux")]
LinuxLandlock,
/// Windows sandboxing (Windows Sandbox/AppContainer/Restricted token).
/// Windows process-containment helper.
///
/// Not advertised until a helper enforces Job Object cleanup. This does
/// not imply filesystem, network, registry, or AppContainer isolation.
#[cfg(target_os = "windows")]
Windows,
}
@@ -427,10 +432,12 @@ impl SandboxManager {
}
}
/// Prepare a Windows-sandboxed execution environment.
/// Prepare a Windows helper execution environment.
///
/// Note: Windows sandboxing requires a helper process for full isolation.
/// This implementation marks intent and defers enforcement to a helper.
/// Windows support is currently not advertised by `get_platform_sandbox`.
/// This branch only exists for forced tests and future helper wiring.
/// The first supported helper contract is process-tree containment only;
/// it must not be presented as filesystem or network isolation.
#[cfg(target_os = "windows")]
fn prepare_windows(spec: &CommandSpec) -> ExecEnv {
let mut command = vec![spec.program.clone()];
+24 -37
View File
@@ -1,12 +1,14 @@
//! Windows sandbox implementation (best-effort placeholder).
//! Windows sandbox helper contract.
//!
//! Windows sandboxing can be implemented using:
//! - Windows Sandbox (full isolation)
//! - AppContainer (process isolation)
//! - Restricted tokens (reduced privileges)
//! Current status: DeepSeek TUI does not advertise an in-process Windows
//! sandbox. Future Windows support must run commands through a dedicated
//! helper that provides process-tree containment with a Job Object and
//! `JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`.
//!
//! This module selects a preferred approach and exposes helpers used by the
//! sandbox manager. Full enforcement should be implemented in a helper binary.
//! The first Windows helper slice is process containment only. It must not
//! claim read-only filesystem isolation, workspace-write enforcement, network
//! blocking, registry isolation, or AppContainer-level isolation until those
//! guarantees are implemented and tested separately.
use std::path::Path;
@@ -14,33 +16,23 @@ use super::SandboxPolicy;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WindowsSandboxKind {
WindowsSandbox,
AppContainer,
RestrictedToken,
ProcessContainment,
}
impl std::fmt::Display for WindowsSandboxKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
WindowsSandboxKind::WindowsSandbox => write!(f, "sandbox"),
WindowsSandboxKind::AppContainer => write!(f, "appcontainer"),
WindowsSandboxKind::RestrictedToken => write!(f, "restricted-token"),
WindowsSandboxKind::ProcessContainment => write!(f, "process-containment"),
}
}
}
pub fn is_available() -> bool {
windows_sandbox_available() || appcontainer_available() || restricted_token_available()
false
}
pub fn select_best_kind(_policy: &SandboxPolicy, _cwd: &Path) -> WindowsSandboxKind {
if windows_sandbox_available() {
WindowsSandboxKind::WindowsSandbox
} else if appcontainer_available() {
WindowsSandboxKind::AppContainer
} else {
WindowsSandboxKind::RestrictedToken
}
WindowsSandboxKind::ProcessContainment
}
pub fn detect_denial(exit_code: i32, stderr: &str) -> bool {
@@ -59,21 +51,16 @@ pub fn detect_denial(exit_code: i32, stderr: &str) -> bool {
patterns.iter().any(|p| stderr.contains(p))
}
#[cfg(test)]
mod tests {
use super::*;
fn windows_sandbox_available() -> bool {
let Ok(system_root) = std::env::var("SystemRoot") else {
return false;
};
Path::new(&system_root)
.join("System32")
.join("WindowsSandbox.exe")
.exists()
}
fn appcontainer_available() -> bool {
true
}
fn restricted_token_available() -> bool {
true
#[test]
fn windows_sandbox_is_not_advertised_until_helper_exists() {
assert!(!is_available());
assert_eq!(
select_best_kind(&SandboxPolicy::default(), Path::new(".")),
WindowsSandboxKind::ProcessContainment
);
}
}
+8 -2
View File
@@ -161,10 +161,13 @@ drives turns through Chat Completions.
### Security
- **`sandbox/`** - macOS sandboxing support
- **`sandbox/`** - platform sandbox policy preparation and denial reporting
- `mod.rs` - Sandbox type definitions
- `policy.rs` - Sandbox policy configuration
- `seatbelt.rs` - macOS Seatbelt profile generation
- `landlock.rs` - Linux Landlock detection and future helper contract
- `windows.rs` - Windows helper contract; not advertised until a Job
Object process-containment helper exists
### Utilities
@@ -281,7 +284,10 @@ command = "echo 'Running tool: $TOOL_NAME'"
1. **Streaming-first**: All LLM responses stream for responsiveness
2. **Tool safety**: Non-YOLO mode requires approval for destructive operations, including side-effectful MCP tools
3. **Extensibility**: MCP, skills, and hooks allow customization without code changes
4. **Cross-platform**: Core works on Linux/macOS/Windows, sandboxing macOS-only
4. **Cross-platform**: Core works on Linux/macOS/Windows. Sandbox guarantees
are platform-specific: macOS Seatbelt is the active policy path; Linux and
Windows require helper enforcement before they should be treated as full OS
sandboxing.
5. **Minimal dependencies**: Careful dependency selection for build speed
6. **Local-first runtime API**: HTTP/SSE endpoints are intended for trusted localhost access and are served by the `crates/tui` runtime today
+6
View File
@@ -364,6 +364,12 @@ If you are upgrading from older releases:
- `allow_shell` (bool, optional): defaults to `true` (sandboxed).
- `approval_policy` (string, optional): `on-request`, `untrusted`, or `never`. Runtime `approval_mode` editing in `/config` also accepts `on-request` and `untrusted` aliases.
- `sandbox_mode` (string, optional): `read-only`, `workspace-write`, `danger-full-access`, `external-sandbox`.
Platform support is not identical. macOS uses Seatbelt for policy
enforcement. Linux support is helper-gated around Landlock. Windows does not
currently advertise an OS sandbox; the planned Windows helper contract starts
with process-tree containment only and must not be described as read-only
filesystem isolation, workspace-write enforcement, network blocking,
registry isolation, or AppContainer isolation until those are implemented.
- `managed_config_path` (string, optional): managed config file loaded after user/env config.
- `requirements_path` (string, optional): requirements file used to enforce allowed approval/sandbox values.
- `max_subagents` (int, optional): defaults to `10` and is clamped to `1..=20`.