Expand description
BashKit - Sandboxed bash interpreter for multi-tenant environments
BashKit provides a fully sandboxed bash interpreter with a virtual filesystem, making it safe to execute untrusted scripts in multi-tenant environments like AI agents, CI/CD pipelines, and code sandboxes.
§Features
- Virtual Filesystem: All file operations happen in memory by default
- Resource Limits: Control command count, loop iterations, and function depth
- Sandboxed Identity: Customizable username/hostname for
whoami,hostname, etc. - Custom Builtins: Extend with domain-specific commands (psql, kubectl, etc.)
- 30+ Built-in Commands:
echo,cat,grep,sed,awk,jq, and more - Full Bash Syntax: Variables, pipelines, redirects, loops, functions, arrays
§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");§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 builtinscompatibility_guide- Full bash compatibility reference
Modules§
- compatibility_
guide - Comprehensive reference for supported bash features.
- custom_
builtins_ guide - Guide for creating custom builtins to extend BashKit.
- parser
- Parser module - exposed for fuzzing and testing Parser module for BashKit
Structs§
- Bash
- Main entry point for BashKit.
- Bash
Builder - Builder for customized Bash configuration.
- 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
- InMemory
Fs - In-memory filesystem implementation.
- Metadata
- File or directory metadata.
- Mountable
Fs - Filesystem with Unix-style mount points.
- Network
Allowlist - Network allowlist configuration.
- 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.
- 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.