cheeseburger 0.1.0

The Safe Script Execution Environment.
Documentation
# 🍔 Cheeseburger

The Safe Script Execution Environment.

[![Crates.io](https://img.shields.io/crates/v/cheeseburger.svg)](https://crates.io/crates/cheeseburger)
[![Documentation](https://docs.rs/cheeseburger/badge.svg)](https://docs.rs/cheeseburger)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Overview

Cheeseburger is a secure script execution library for Rust that lets you run system commands with fine-grained control. I
t provides a sandboxed environment that limits what commands can run and what files they can access.

**Key Features:**
- Command allowlisting
- Working directory confinement
- Path protection with glob patterns
- Command-specific protection overrides
- Comprehensive execution results

## Installation

Add Cheeseburger to your `Cargo.toml`:

```toml
[dependencies]
cheeseburger = "0.1.0"
```

or run:

```shell
cargo add cheeseburger
```

## Quick Start

```rust
use cheeseburger::ScriptExecutor;

fn main() {
    // create a script executor a.k.a burger flipper with constraints
    let executor = BurgerFlipper::new(
        // list of allowed commands
        vec!["ls".to_string(), "echo".to_string()],
        // pwd that commands are confined to
        "/path/to/sandbox",
        // global protection patterns that apply to all commands
        vec!["**/secret*".to_string(), "**/.env".to_string()],
    );
    
    // execute a simple command
    match executor.execute("echo Hello world") {
        Ok(result) => {
            println!("Command output: {}", result.stdout);
            println!("Exit code: {}", result.exit_code);
        },
        Err(err) => {
            eprintln!("Error: {}", err);
        }
    }
}
```

## Features

### Command Allowlisting

Cheeseburger only executes commands that are explicitly allowed:

```rust
let executor = BurgerFlipper::new(
    vec!["ls".to_string(), "cat".to_string(), "echo".to_string()],
    working_dir,
    global_protected_patterns,
);
```

Attempts to run any command not in this list will result in a `CommandNotAllowed` error.

### Working Directory Confinement

Commands can only access files within the specified working directory:

```rust
// this will fail with PathOutsideWorkingDir error
executor.execute("cat /etc/passwd");
```

### Protected Files and Directories

Define global protection patterns that apply to all commands:

```rust
let global_protected = vec![
    "**/secret*".to_string(),     // protect anything with "secret" in the name
    "**/protected/**".to_string(), // protect the "protected" directory and its contents
    "**/.env".to_string(),        // protect .env files
];
```

### Command-Specific Protection Rules

Set different protection rules for specific commands:

```rust
executor.add_command_protection(
    "echo".to_string(),
    // cmd-specific protections (in addition to global)
    vec!["**/important/**".to_string()], 
    // cmd-specific overrides (exceptions to global protection)
    vec!["**/public_secrets.txt".to_string()], 
);
```

### Command Namespace Support

Run commands within namespaces like `fs`:

```rust
executor.execute("fs ls -la");
```

## Security Considerations

Cheeseburger is designed with security in mind, but has some limitations:

- It does not provide full containerization or process isolation
- It does not restrict memory usage, CPU, or other system resources
- It does not handle signals or provide timeout mechanisms
- It validates paths but does not prevent symlink attacks by default

Higher-security environment features will be added in later releases.

## Advanced Usage

### Environment Variables

The `ScriptEnvironment` extension provides environment variable support:

```rust
let mut env = ScriptEnvironment::new(executor);

// set environment variables
env.set_env("PROJECT_DIR", "/tmp/sandbox/project");
env.set_env("LOG_LEVEL", "debug");

// execute scripts with environment variables
env.execute("echo Working in ${PROJECT_DIR} with log level ${LOG_LEVEL}");
```

### Batch Execution

Run multiple commands in sequence:

```rust
let batch = [
    "mkdir -p ${PROJECT_DIR}",
    "touch ${PROJECT_DIR}/file.txt",
    "echo 'Hello world' > ${PROJECT_DIR}/file.txt",
    "cat ${PROJECT_DIR}/file.txt",
];

env.execute_batch(&batch);
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the MIT License - see the LICENSE file for details.