Expand description
BashKit - Sandboxed bash interpreter for multi-tenant environments
Sandboxed 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
- 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
§Built-in Commands (66)
| Category | Commands |
|---|---|
| Core | echo, printf, cat, read |
| Navigation | cd, pwd, ls, find |
| Flow control | true, false, exit, return, break, continue, test, [ |
| Variables | export, set, unset, local, shift, source, . |
| Text processing | grep, sed, awk, jq, head, tail, sort, uniq, cut, tr, wc |
| File operations | mkdir, rm, cp, mv, touch, chmod, rmdir |
| File inspection | file, stat, less |
| Archives | tar, gzip, gunzip |
| Utilities | sleep, date, basename, dirname, timeout, wait, xargs, tee |
| System info | whoami, hostname, uname, id, env, printenv, history |
| Network | curl, wget (requires NetworkAllowlist) |
§Shell Features
-
Variables and parameter expansion (
$VAR,${VAR:-default},${#VAR}) -
Command substitution (
$(cmd)) -
Arithmetic expansion (
$((1 + 2))) -
Pipelines and redirections (
|,>,>>,<,<<<,2>&1) -
Control flow (
if/elif/else,for,while,case) -
Functions (POSIX and bash-style)
-
Arrays (
arr=(a b c),${arr[@]},${#arr[@]}) -
Glob expansion (
*,?) -
Here documents (
<<EOF) -
compatibility_scorecard- Full compatibility status
§Quick Start
use bashkit::Bash;
let mut bash = Bash::new();
let result = bash.exec("echo 'Hello, World!'").await?;
assert_eq!(result.stdout, "Hello, World!\n");
assert_eq!(result.exit_code, 0);§Basic Usage
§Simple Commands
use bashkit::Bash;
let mut bash = Bash::new();
// Echo with variables
let result = bash.exec("NAME=World; echo \"Hello, $NAME!\"").await?;
assert_eq!(result.stdout, "Hello, World!\n");
// Pipelines
let result = bash.exec("echo -e 'apple\\nbanana\\ncherry' | grep a").await?;
assert_eq!(result.stdout, "apple\nbanana\n");
// Arithmetic
let result = bash.exec("echo $((2 + 2 * 3))").await?;
assert_eq!(result.stdout, "8\n");§Control Flow
use bashkit::Bash;
let mut bash = Bash::new();
// For loops
let result = bash.exec("for i in 1 2 3; do echo $i; done").await?;
assert_eq!(result.stdout, "1\n2\n3\n");
// If statements
let result = bash.exec("if [ 5 -gt 3 ]; then echo bigger; fi").await?;
assert_eq!(result.stdout, "bigger\n");
// Functions
let result = bash.exec("greet() { echo \"Hello, $1!\"; }; greet World").await?;
assert_eq!(result.stdout, "Hello, World!\n");§File Operations
All file operations happen in the virtual filesystem:
use bashkit::Bash;
let mut bash = Bash::new();
// Create and read files
bash.exec("echo 'Hello' > /tmp/test.txt").await?;
bash.exec("echo 'World' >> /tmp/test.txt").await?;
let result = bash.exec("cat /tmp/test.txt").await?;
assert_eq!(result.stdout, "Hello\nWorld\n");
// Directory operations
bash.exec("mkdir -p /data/nested/dir").await?;
bash.exec("echo 'content' > /data/nested/dir/file.txt").await?;§Configuration with Builder
Use Bash::builder() for advanced configuration:
use bashkit::{Bash, ExecutionLimits};
let mut bash = Bash::builder()
.env("API_KEY", "secret123")
.username("deploy")
.hostname("prod-server")
.limits(ExecutionLimits::new().max_commands(100))
.build();
let result = bash.exec("whoami && hostname").await?;
assert_eq!(result.stdout, "deploy\nprod-server\n");§Custom Builtins
Register custom commands to extend BashKit with domain-specific functionality:
use bashkit::{Bash, Builtin, BuiltinContext, ExecResult, async_trait};
struct Greet;
#[async_trait]
impl Builtin for Greet {
async fn execute(&self, ctx: BuiltinContext<'_>) -> bashkit::Result<ExecResult> {
let name = ctx.args.first().map(|s| s.as_str()).unwrap_or("World");
Ok(ExecResult::ok(format!("Hello, {}!\n", name)))
}
}
let mut bash = Bash::builder()
.builtin("greet", Box::new(Greet))
.build();
let result = bash.exec("greet Alice").await?;
assert_eq!(result.stdout, "Hello, Alice!\n");Custom builtins have access to:
- Command arguments (
ctx.args) - Environment variables (
ctx.env) - Shell variables (
ctx.variables) - Virtual filesystem (
ctx.fs) - Pipeline stdin (
ctx.stdin)
See BashBuilder::builtin for more details.
§Virtual Filesystem
BashKit provides three filesystem implementations:
InMemoryFs: Simple in-memory filesystem (default)OverlayFs: Copy-on-write overlay for layered storageMountableFs: Mount multiple filesystems at different paths
See the fs module documentation for details and examples.
§Direct Filesystem Access
Access the filesystem directly via Bash::fs():
use bashkit::{Bash, FileSystem};
use std::path::Path;
let mut bash = Bash::new();
let fs = bash.fs();
// Pre-populate files before running scripts
fs.mkdir(Path::new("/config"), false).await?;
fs.write_file(Path::new("/config/app.conf"), b"debug=true").await?;
// Run a script that reads the config
let result = bash.exec("cat /config/app.conf").await?;
assert_eq!(result.stdout, "debug=true");
// Read script output directly
bash.exec("echo 'result' > /output.txt").await?;
let output = fs.read_file(Path::new("/output.txt")).await?;
assert_eq!(output, b"result\n");§HTTP Access (curl/wget)
Enable the http_client feature and configure an allowlist for network access:
use bashkit::{Bash, NetworkAllowlist};
let mut bash = Bash::builder()
.network(NetworkAllowlist::new()
.allow("https://httpbin.org"))
.build();
// curl and wget now work for allowed URLs
let result = bash.exec("curl -s https://httpbin.org/get").await?;
assert!(result.stdout.contains("httpbin.org"));Security features:
- URL allowlist enforcement (no access without explicit configuration)
- 10MB response size limit (prevents memory exhaustion)
- 30 second timeout (prevents hanging)
- No automatic redirects (prevents allowlist bypass)
- Zip bomb protection for compressed responses
See NetworkAllowlist for allowlist configuration options.
§Examples
See the examples/ directory for complete working examples:
basic.rs- Getting started with BashKitcustom_fs.rs- Using different filesystem implementationscustom_filesystem_impl.rs- Implementing theFileSystemtraitresource_limits.rs- Setting execution limitssandbox_identity.rs- Customizing username/hostnametext_processing.rs- Using grep, sed, awk, and jqagent_tool.rs- LLM agent integration
§Guides
custom_builtins_guide- Creating custom builtins
§Resources
threat_model- Security threats and mitigations
§Ecosystem
BashKit is part of the Everruns ecosystem.
Re-exports§
pub use tool::BashTool;pub use tool::BashToolBuilder;pub use tool::Tool;pub use tool::ToolRequest;pub use tool::ToolResponse;pub use tool::ToolStatus;pub use tool::VERSION;
Modules§
- compatibility_
scorecard - Bash compatibility scorecard.
- custom_
builtins_ guide - Guide for creating custom builtins to extend BashKit.
- parser
- Parser module - exposed for fuzzing and testing Parser module for BashKit
- threat_
model - Security threat model guide.
- tool
- Tool contract for LLM integration Tool trait and BashTool implementation
Structs§
- Bash
- Main entry point for BashKit.
- Bash
Builder - Builtin
Context - Execution context for builtin commands.
- DirEntry
- An entry in a directory listing.
- Exec
Result - Result of executing a bash script.
- Execution
Counters - Execution counters for tracking resource usage
- Execution
Limits - Resource limits for script execution
- FsLimits
- Filesystem resource limits.
- FsUsage
- Current filesystem usage statistics.
- InMemory
Fs - In-memory filesystem implementation.
- Metadata
- File or directory metadata.
- Mountable
Fs - Filesystem with Unix-style mount points.
- Network
Allowlist - Network allowlist configuration for controlling HTTP access.
- Overlay
Fs - Copy-on-write overlay filesystem.
Enums§
- Control
Flow - Control flow signals from commands like break, continue, return
- Error
- BashKit error types.
- File
Type - Type of a filesystem entry.
- FsLimit
Exceeded - Error returned when a filesystem limit is exceeded.
- Limit
Exceeded - Error returned when a resource limit is exceeded
Traits§
- Builtin
- Trait for implementing builtin commands.
- File
System - Async virtual filesystem trait.
Type Aliases§
- Result
- Result type alias using BashKit’s Error.