Make sandbox isolation behavior explicit and inspectable

This adds a small runtime sandbox policy/status layer, threads
sandbox options through the bash tool, and exposes `/sandbox`
status reporting in the CLI. Linux namespace/network isolation
is best-effort and intentionally reported as requested vs active
so the feature does not overclaim guarantees on unsupported
hosts or nested container environments.

Constraint: No new dependencies for isolation support
Constraint: Must keep filesystem restriction claims honest unless hard mount isolation succeeds
Rejected: External sandbox/container wrapper | too heavy for this workspace and request
Rejected: Inline bash-only changes without shared status model | weaker testability and poorer CLI visibility
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Treat this as observable best-effort isolation, not a hard security boundary, unless stronger mount enforcement is added later
Tested: cargo fmt --all; cargo clippy --workspace --all-targets --all-features -- -D warnings; cargo test --workspace
Not-tested: Manual `/sandbox` REPL run on a real nested-container host
This commit is contained in:
Yeachan-Heo
2026-04-01 01:14:38 +00:00
parent d6341d54c1
commit 2d09bf9961
9 changed files with 720 additions and 22 deletions

View File

@@ -5,6 +5,8 @@ pub enum PermissionMode {
ReadOnly,
WorkspaceWrite,
DangerFullAccess,
Prompt,
Allow,
}
impl PermissionMode {
@@ -14,6 +16,8 @@ impl PermissionMode {
Self::ReadOnly => "read-only",
Self::WorkspaceWrite => "workspace-write",
Self::DangerFullAccess => "danger-full-access",
Self::Prompt => "prompt",
Self::Allow => "allow",
}
}
}
@@ -90,7 +94,7 @@ impl PermissionPolicy {
) -> PermissionOutcome {
let current_mode = self.active_mode();
let required_mode = self.required_mode_for(tool_name);
if current_mode >= required_mode {
if current_mode == PermissionMode::Allow || current_mode >= required_mode {
return PermissionOutcome::Allow;
}
@@ -101,8 +105,9 @@ impl PermissionPolicy {
required_mode,
};
if current_mode == PermissionMode::WorkspaceWrite
&& required_mode == PermissionMode::DangerFullAccess
if current_mode == PermissionMode::Prompt
|| (current_mode == PermissionMode::WorkspaceWrite
&& required_mode == PermissionMode::DangerFullAccess)
{
return match prompter.as_mut() {
Some(prompter) => match prompter.decide(&request) {