Skip to main content

Crate bashkit

Crate bashkit 

Source
Expand description

Bashkit - Awesomely fast virtual sandbox with bash and file system

Virtual bash interpreter for AI agents, CI/CD pipelines, and code sandboxes. Written in Rust.

Homepage: bashkit.sh

§Features

  • POSIX compliant - Substantial IEEE 1003.1-2024 Shell Command Language compliance
  • Sandboxed, in-process execution - No real filesystem access by default
  • Virtual filesystem - InMemoryFs, OverlayFs, MountableFs, NamespaceFs
  • 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 - Virtual git operations on the VFS (git feature)
  • Experimental: Python - Embedded Python via Monty (python feature)
  • Experimental: SQLite - Embedded SQLite-compatible engine via Turso (sqlite feature)

§Built-in Commands (164)

CategoryCommands
Coreecho, printf, cat, nl, read, mapfile, readarray, log
Navigationcd, pwd, ls, find, tree, pushd, popd, dirs
Flow controltrue, false, exit, return, break, continue, test, [, assert
Variablesexport, set, unset, local, shift, source, ., eval, readonly, times, declare, typeset, let, dotenv, envsubst
Shellbash, sh (virtual re-invocation), exec, :, trap, caller, getopts, shopt, command, type, which, hash, alias, unalias, compgen, fc, help
Text processinggrep, rg, sed, awk, jq and yq (with jq feature), head, tail, sort, uniq, cut, tr, wc, paste, column, diff, comm, strings, tac, rev, seq, expr, fold, expand, unexpand, join, split, iconv, shuf, template
File operationsmkdir, mktemp, mkfifo, rm, cp, mv, touch, chmod, chown, ln, rmdir, realpath, readlink, truncate, glob, patch
File inspectionfile, stat, less
Archivestar, gzip, gunzip, bzip2, bunzip2, bzcat, zip, unzip
Byte toolsod, xxd, hexdump, base64
Checksumsmd5sum, sha1sum, sha256sum, verify
Utilitiessleep, date, basename, dirname, timeout, wait, watch, yes, kill, clear, numfmt, retry, parallel
Diskdf, du
Pipelinexargs, tee
System infowhoami, hostname, uname, id, env, printenv, history
Structured datajson, csv, tomlq, semver
Networkcurl, wget, http (requires NetworkAllowlist)
Arithmeticbc
Experimentalpython, python3 (requires python feature), git (requires git feature), ts, typescript, node, deno, bun (requires typescript feature), ssh, scp, sftp (requires ssh feature), sqlite, sqlite3 (requires sqlite feature)

§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");

§LLM Tool Integration

Use BashTool when the host needs schemas, Markdown help, a compact system prompt, and validated single-use executions.

use bashkit::{BashTool, Tool};

let tool = BashTool::builder()
    .username("agent")
    .hostname("sandbox")
    .build();

let output = tool
    .execution(serde_json::json!({
        "commands": "echo hello from bashkit",
        "timeout_ms": 1000
    }))?
    .execute()
    .await?;

assert_eq!(output.result["stdout"], "hello from bashkit\n");
assert!(tool.help().contains("## Parameters"));

§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 several filesystem implementations:

  • InMemoryFs: Simple in-memory filesystem (default)
  • OverlayFs: Copy-on-write overlay for layered storage
  • MountableFs: Mount multiple filesystems at different paths
  • NamespaceFs: Compose a static tree from rebased filesystem mounts

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

HTTP is disabled by default: the http_client feature must be compiled in and an allowlist must be configured via BashBuilder::network; otherwise curl/wget cannot reach the network at all.

Embedding hosts can replace the built-in connectivity with their own — e.g. to route all sandbox traffic through an egress gateway — by injecting an HttpTransport via BashBuilder::http_transport. Policy (allowlist, SSRF precheck, hooks, signing, size caps) stays in bashkit and runs before the transport is called.

See NetworkAllowlist for allowlist configuration options.

§Experimental: Git Support

Enable the git feature for virtual git operations. All git data lives in the virtual filesystem.

[dependencies]
bashkit = { version = "0.16.0", features = ["git"] }
use bashkit::{Bash, GitConfig};

let mut bash = Bash::builder()
    .git(GitConfig::new()
        .author("Deploy Bot", "deploy@example.com"))
    .build();

bash.exec("git init").await?;
bash.exec("echo 'hello' > file.txt").await?;
bash.exec("git add file.txt").await?;
bash.exec("git commit -m 'initial'").await?;
bash.exec("git log").await?;

Supported: init, config, add, commit, status, log, branch, checkout, diff, reset, remote, clone/push/pull/fetch (virtual mode).

See GitConfig for configuration options.

§Experimental: Python Support

Enable the python feature to embed the Monty Python interpreter (pure Rust, Python 3.12). Python pathlib.Path operations are bridged to the virtual filesystem.

[dependencies]
bashkit = { version = "0.16.0", features = ["python"] }
use bashkit::Bash;

let mut bash = Bash::builder().python().build();

// Inline code
bash.exec("python3 -c \"print(2 ** 10)\"").await?;

// VFS bridging — files shared between bash and Python
bash.exec("echo 'data' > /tmp/shared.txt").await?;
bash.exec(r#"python3 -c "
from pathlib import Path
print(Path('/tmp/shared.txt').read_text().strip())
""#).await?;

Stdlib modules: math, pathlib, os (getenv/environ), sys, typing. Security note: re is disabled due to regex backtracking DoS risk. Limitations: no open() (use pathlib.Path), no network, no classes, no third-party imports.

See PythonLimits for resource limit configuration.

See the python_guide module docs (requires python feature).

§Examples

See the examples/ directory for complete working examples:

  • basic.rs - Getting started with Bashkit
  • custom_fs.rs - Using different filesystem implementations
  • custom_filesystem_impl.rs - Implementing the FileSystem trait
  • resource_limits.rs - Setting execution limits
  • 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
  • python_scripts.rs - Embedded Python with VFS bridging
  • python_external_functions.rs - Python callbacks into host functions
  • namespace_sandbox.rs - Static read-only/read-write build namespace
  • namespace_rebase.rs - Source-root rebasing with a nested writable override

§Guides

§Resources

§Ecosystem

Bashkit is part of the Everruns ecosystem.

Re-exports§

pub use analysis::AnalyzedCommand;
pub use analysis::AnalyzedRedirect;
pub use analysis::CommandContext;
pub use analysis::RedirectMode;
pub use analysis::ScriptAnalysis;
pub use tool::BashToolBuilder as ToolBuilder;
pub use tool::BashTool;
pub use tool::BashToolBuilder;
pub use tool::Tool;
pub use tool::ToolError;
pub use tool::ToolExecution;
pub use tool::ToolImage;
pub use tool::ToolOutput;
pub use tool::ToolOutputChunk;
pub use tool::ToolOutputMetadata;
pub use tool::ToolRequest;
pub use tool::ToolResponse;
pub use tool::ToolService;
pub use tool::ToolStatus;
pub use tool::VERSION;
pub use trace::TraceCallback;
pub use trace::TraceCollector;
pub use trace::TraceEvent;
pub use trace::TraceEventDetails;
pub use trace::TraceEventKind;
pub use trace::TraceMode;
pub use scripted_tool::AsyncToolCallback;
pub use scripted_tool::CallbackKind;
pub use scripted_tool::DiscoverTool;
pub use scripted_tool::DiscoveryMode;
pub use scripted_tool::ScriptedCommandInvocation;
pub use scripted_tool::ScriptedCommandKind;
pub use scripted_tool::ScriptedExecutionTrace;
pub use scripted_tool::ScriptedTool;
pub use scripted_tool::ScriptedToolBuilder;
pub use scripted_tool::ScriptingToolSet;
pub use scripted_tool::ScriptingToolSetBuilder;
pub use scripted_tool::ToolArgs;
pub use scripted_tool::ToolCallback;
pub use scripted_tool::ToolDef;
pub use scripted_tool::ToolDefExtension;
pub use scripted_tool::ToolDefExtensionBuilder;
pub use scripted_tool::ToolDefInvocationTrace;
pub use logging::LogConfig;
pub use clap;

Modules§

analysis
Static, pre-execution introspection of a script. Static, pre-execution introspection of a script.
clap_builtins_guide
Public guide for clap-backed custom builtins.
compatibility_scorecard
Bash compatibility scorecard.
credential_injection_guide
Guide for transparent credential injection in outbound HTTP requests.
custom_builtins_guide
Guide for creating custom builtins to extend Bashkit.
hooks
Interceptor hooks for the execution pipeline.
hooks_guide
Interceptor hooks guide for Bashkit.
interop
Native-extension interop contracts.
jq_guide
jq builtin: supported filters, flags, and variables.
live_mounts_guide
Guide for live mount/unmount on a running Bash instance.
logging
Logging utilities module
logging_guide
Logging guide for Bashkit.
namespace_filesystems_guide
Guide to composing static filesystem namespaces.
parser
Parser module - exposed for fuzzing and testing Parser module for Bashkit
python_guide
Guide for embedded Python via the Monty interpreter.
script_analysis_guide
Guide for analyzing a script before running it.
scripted_tool
Scripted tool: compose ToolDef+callback pairs into a single Tool via bash scripts. Requires the scripted_tool feature. Scripted tool
sqlite_guide
Guide for the embedded SQLite builtin (Turso).
ssh_guide
Guide for SSH/SCP/SFTP remote operations.
threat_model
Security threat model guide.
tool
Tool contract for LLM integration. Requires the bash_tool feature (enabled by default). Tool contract and BashTool implementation.
trace
Structured execution trace events. Structured execution trace events.
typescript_guide
Guide for embedded TypeScript execution via the ZapCode interpreter.
yq_guide
yq builtin: YAML/JSON conversion around the shared jq evaluator.

Structs§

Bash
Main entry point for Bashkit.
BashBuilder
BashkitContext
Mutable execution context for ClapBuiltin implementations.
BotAuthConfig
Configuration for Web Bot Authentication.
BotAuthPublicKey
Derived Ed25519 public key and JWK Thumbprint for key directory serving.
BuiltinContext
Execution context for builtin commands.
BuiltinRegistry
Host-owned, mutable registry of builtin commands.
CapabilityCleanupReport
Safe, bounded summary of execution-capability cleanup.
CapabilityDelta
What differs between a snapshot’s environment and the live one.
CapabilityFingerprint
Environment that produced a commit.
CommitObject
The root object of a snapshot: what state, derived from which parents.
CommitOptions
How a commit is built: its place in the history, and what to leave out.
DirEntry
An entry in a directory listing.
ExecOptions
Per-call options for Bash::exec_with_options.
ExecResult
Result of executing a bash script.
ExecutionBudget
Non-resettable aggregate budget shared by every descendant of one request.
ExecutionBudgetLease
RAII lease for bytes held in a live/intermediate request buffer.
ExecutionCapability
Cloneable access handle tied to exactly one Bash::exec*() call.
ExecutionCounters
Execution counters for tracking resource usage
ExecutionExtensions
Typed values bound to one execution when passed through crate::ExecOptions.
ExecutionHandle
Drives one process-local execution across event-backed builtin calls.
ExecutionLimits
Resource limits for script execution
ExecutionProfile
A coherent, validated policy bundle.
ExecutionProfileBuilder
Builder for a named profile plus explicit policy-family overrides.
ExecutionProfileError
Invalid or unsupported profile configuration.
FsLimits
Filesystem resource limits.
FsUsage
Current filesystem usage statistics.
GitClient
Git client for virtual operations.
GitConfig
Git configuration for Bashkit.
HistoryEntry
A single command history entry.
HostCallId
Identifier for one suspended host-call request.
HostCallRequest
An event-backed builtin invocation waiting for a host result.
HostMount
Where a real host directory ended up in the VFS.
HostMounts
The real host directories mounted into a Bash instance.
HttpClient
HTTP client with allowlist-based access control.
HttpLimits
Per-request HTTP resource limits selected independently from URL policy.
HttpResponse
Re-exported network response type for custom HTTP transport implementations. HTTP response
HttpTransportRequest
Outbound HTTP request handed to an HttpTransport.
InMemoryFs
In-memory filesystem implementation.
MemoryBudget
Tracks approximate memory usage for budget enforcement.
MemoryLimits
Memory limits for a Bash instance.
Metadata
File or directory metadata.
MontyException
Public representation of a Monty exception.
MountableFs
Filesystem with Unix-style mount points.
NamespaceFs
One visible path tree composed from arbitrary FileSystem instances.
NamespaceFsBuilder
Builder for a static NamespaceFs.
NetworkAllowlist
Network allowlist configuration for controlling HTTP access.
ObjectId
Content address of a snapshot object: SHA-256 of [kind][payload].
OverlayFs
Copy-on-write overlay filesystem.
PackedCommit
A commit plus the objects the store does not already have.
PosixFs
POSIX-compatible filesystem wrapper.
PythonExternalFns
External function configuration for the Python builtin.
PythonLimits
Resource limits for the embedded Python (Monty) interpreter.
ReadOnlyFs
Denies all filesystem mutations while delegating read operations.
RealFs
Real filesystem backend scoped to a root directory.
RuntimeLimits
Core resource limits shared by embedded language-VM runtimes.
SearchCapabilities
Describes what a search provider supports.
SearchMatch
A single match from a search.
SearchQuery
Parameters for a search query.
SearchResults
Results from a search query.
SessionLimits
Session-level resource limits that persist across exec() calls.
ShellState
A snapshot of shell state (variables, env, cwd, options).
ShellStateView
Lightweight inspection view of shell state.
Snapshot
A serializable snapshot of a Bash interpreter’s state.
SnapshotDiff
What changed between two commits.
SnapshotGraph
Read-only operations over a snapshot object graph.
SnapshotOptions
Controls which interpreter state is captured in snapshot bytes.
Sqlite
The sqlite / sqlite3 builtin command.
SqliteLimits
Resource limits for the embedded sqlite engine.
SshAllowlist
SSH host allowlist configuration.
SshClient
SSH client with allowlist-based access control.
SshConfig
SSH configuration for Bashkit.
SshOutput
Output from a remote command execution.
SshTarget
Connection target for an SSH operation.
StreamData
Owned data carried by a shell byte stream.
ToolCall
Immutable data supplied to the approval/policy hook.
ToolCallRequest
Per-exec* registry context carried through crate::ExecutionExtensions.
ToolImpl
Complete tool: definition + sync/async exec functions.
ToolRegistry
ToolRegistryBuilder
TrustedHostKey
A trusted SSH host key entry, mapping a host pattern to a public key.
TypeScriptConfig
Configuration for the TypeScript builtin.
TypeScriptExtension
Extension that registers embedded TypeScript/JavaScript builtins.
TypeScriptExternalFns
External function configuration for the TypeScript builtin.
TypeScriptLimits
Resource limits for the embedded TypeScript (ZapCode) interpreter.
VfsEntry
One filesystem entry inside a VfsSnapshot.
VfsSnapshot
A snapshot of the virtual filesystem state.

Enums§

BotAuthError
Errors from bot-auth operations.
CheckoutPolicy
How strictly a checkout enforces the capability fingerprint.
ControlFlow
Control flow signals from commands like break, continue, return
Credential
A credential to inject into outbound HTTP requests.
Error
Bashkit error types.
ExcType
Python exception types supported by the interpreter.
ExecutionBudgetExceeded
The aggregate request resource that exhausted the shared budget.
ExecutionCapabilityError
Deterministic error returned by a handle used outside its execution.
ExecutionEvent
Observable state transition from a process-local execution.
ExecutionProfileName
Closed set of supported execution-profile baselines.
ExtFunctionResult
Return value or exception from an external function.
FileType
Type of a filesystem entry.
FsLimitExceeded
Error returned when a filesystem limit is exceeded.
HttpMethod
Re-exported request method type for custom HTTP transport implementations. HTTP request method
HttpTransportError
Typed failure returned by an HttpTransport.
LimitExceeded
Error returned when a resource limit is exceeded
MontyObject
An owned Python value exchanged between Monty and its host.
NamespaceAccess
Access granted to a filesystem mounted in a NamespaceFs.
ProfileNetworkPolicy
Network policy carried by an execution profile.
RealFsMode
Access mode for the real filesystem backend.
SqliteBackend
Choice of IO backend.
ToolCallDecision
Result of the registry’s approval/policy hook.
ToolCallSurface
Runtime surface that initiated a registry call.
VfsEntryKind
Type and payload of a VfsEntry.
ZapcodeValue

Traits§

Builtin
Trait for implementing builtin commands.
ClapBuiltin
Trait for custom builtins that parse arguments with clap.
CommandResolver
Resolve a command name to a builtin at dispatch time.
Extension
A bundle of shell capabilities registered together.
FileSystem
Async virtual filesystem trait.
FileSystemExt
Optional filesystem extensions for resource tracking and special file types.
FsBackend
Low-level filesystem backend trait.
HttpTransport
Pluggable transport for all outbound HTTP made by sandboxed scripts.
ObjectSource
Read access to a content-addressed object store.
SearchCapable
Optional trait for filesystems that support indexed search.
SearchProvider
Provides content and filename search within a filesystem scope.
SshHandler
Trait for custom SSH transport implementations.

Functions§

derive_bot_auth_public_key
Derive the Ed25519 public key and JWK Thumbprint from a base64url seed.
normalize_path
Normalize a virtual filesystem path by resolving . and .. components.
verify_filesystem_requirements
Verify that a filesystem implementation meets minimum requirements for Bashkit.

Type Aliases§

AsyncToolExec
Asynchronous execution function for a tool.
CommitId
The ObjectId of a commit object — the value a host stores per message.
LazyLoader
Lazy file content loader type.
OutputCallback
Callback for streaming output chunks as they are produced.
PythonExternalFnHandler
Async handler for external Python function calls.
Result
Result type alias using Bashkit’s Error.
SyncToolExec
Synchronous execution function for a tool.
TypeScriptExternalFnHandler
Async handler for external TypeScript function calls.

Attribute Macros§

async_trait