https://github.com/aayushadhikari7/aegis
A local-first WebAssembly sandbox runtime with capability-based security
https://github.com/aayushadhikari7/aegis
capability-based-security runtime rust sandbox security wasm wasmtime webassembly
Last synced: 6 months ago
JSON representation
A local-first WebAssembly sandbox runtime with capability-based security
- Host: GitHub
- URL: https://github.com/aayushadhikari7/aegis
- Owner: aayushadhikari7
- License: other
- Created: 2026-01-11T17:26:50.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2026-01-11T19:21:46.000Z (6 months ago)
- Last Synced: 2026-01-11T20:32:23.921Z (6 months ago)
- Topics: capability-based-security, runtime, rust, sandbox, security, wasm, wasmtime, webassembly
- Language: Rust
- Homepage: https://crates.io/crates/aegis-wasm
- Size: 128 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# Aegis
**Run untrusted WebAssembly code safely**
[](https://crates.io/crates/aegis-wasm)
[](https://docs.rs/aegis-wasm)
[](https://www.rust-lang.org/)
[](#license)
[Installation](#installation) | [CLI Usage](#cli-usage) | [Library Usage](#library-usage) | [Features](#features)
---
## What is Aegis?
Aegis is a **WebAssembly sandbox** that lets you run untrusted code without risk. The code:
- Cannot access your filesystem (unless you allow it)
- Cannot access the network (unless you allow it)
- Cannot use unlimited memory (you set the limit)
- Cannot run forever (you set the timeout)
- Cannot crash your application
**Use cases:** Plugin systems, serverless functions, game mods, user-submitted code, CI/CD isolation, safe scripting.
---
## Installation
### CLI Tool
```bash
cargo install aegis-wasm-cli
```
### As a Library
```bash
cargo add aegis-wasm
```
Or add to your `Cargo.toml`:
```toml
[dependencies]
aegis-wasm = "0.1"
```
---
## CLI Usage
### Running WebAssembly
```bash
# Run a function with arguments
aegis run module.wasm --function add -- 5 10
# Output: Result: 15
# Run the default function (_start or main)
aegis run module.wasm
# Run with resource limits
aegis run module.wasm --function process \
--memory-limit 33554432 \
--fuel-limit 1000000 \
--timeout 10
# Show execution metrics
aegis run module.wasm --function main --metrics
```
### Granting Permissions
By default, WASM code has **zero permissions**. You grant what it needs:
```bash
# Allow reading from /data directory
aegis run module.wasm --allow-read /data
# Allow reading and writing to /tmp
aegis run module.wasm --allow-write /tmp
# Allow logging output
aegis run module.wasm --allow-logging
# Allow access to system clock
aegis run module.wasm --allow-clock
# Combine permissions
aegis run module.wasm \
--allow-read /data \
--allow-write /tmp \
--allow-logging
```
### Validating Modules
Check if a WASM file is valid before running:
```bash
aegis validate module.wasm
# Output: Module is valid
aegis validate corrupt.wasm
# Output: Module is invalid: ...
```
### Inspecting Modules
See what a WASM module contains:
```bash
# Show everything
aegis inspect module.wasm --all
# Show only exports (functions you can call)
aegis inspect module.wasm --exports
# Show only imports (what the module needs)
aegis inspect module.wasm --imports
```
Example output:
```
Module: plugin.wasm
Exports (3):
add [function]: (i32, i32) -> (i32)
multiply [function]: (i32, i32) -> (i32)
memory [memory]: 1 pages
Imports (1):
env.log [function]: (i32) -> ()
```
### Output Formats
```bash
# Human-readable (default)
aegis run module.wasm --function add -- 2 3
# JSON output
aegis run module.wasm --function add --format json -- 2 3
# Compact JSON (single line)
aegis run module.wasm --function add --format json-compact -- 2 3
```
### All CLI Options
```
aegis run [OPTIONS] [-- ARGS...]
Options:
-e, --function Function to call (default: _start or main)
--memory-limit Max memory in bytes (default: 64MB)
--fuel-limit Max CPU fuel units (default: 1B)
--timeout Max execution time (default: 30s)
--allow-read Grant read access to path
--allow-write Grant read/write access to path
--allow-logging Enable logging output
--allow-clock Enable clock/time access
--metrics Show execution metrics
-f, --format Output format: human, json, json-compact
-v, --verbose Increase verbosity (-v, -vv, -vvv)
-q, --quiet Suppress non-essential output
```
---
## Library Usage
### Basic Example
```rust
use aegis_wasm::prelude::*;
use std::time::Duration;
fn main() -> Result<(), AegisError> {
// Create a sandboxed runtime
let runtime = Aegis::builder()
.with_memory_limit(64 * 1024 * 1024) // 64 MB max
.with_fuel_limit(1_000_000_000) // 1 billion instructions max
.with_timeout(Duration::from_secs(30)) // 30 second timeout
.build()?;
// Load a WASM module
let module = runtime.load_file("plugin.wasm")?;
// Create a sandbox and run code
let mut sandbox = runtime.sandbox().build()?;
sandbox.load_module(&module)?;
// Call a function
let result: i32 = sandbox.call("add", (2i32, 3i32))?;
println!("2 + 3 = {}", result);
Ok(())
}
```
### Loading WASM from Different Sources
```rust
// From a file
let module = runtime.load_file("plugin.wasm")?;
// From bytes (e.g., uploaded by user)
let wasm_bytes: Vec = receive_upload();
let module = runtime.load_bytes(&wasm_bytes)?;
// From WAT text format (useful for testing)
let module = runtime.load_wat(r#"
(module
(func (export "double") (param i32) (result i32)
local.get 0
i32.const 2
i32.mul
)
)
"#)?;
```
### Granting Capabilities
```rust
use aegis_wasm::prelude::*;
let runtime = Aegis::builder()
.with_memory_limit(64 * 1024 * 1024)
.with_fuel_limit(1_000_000_000)
// Allow reading from specific paths
.with_filesystem(FilesystemCapability::read_only(&["/data", "/config"]))
// Allow reading AND writing to specific paths
.with_filesystem(FilesystemCapability::read_write(&["/tmp/sandbox"]))
// Allow logging
.with_logging(LoggingCapability::all())
// Allow clock access
.with_clock(ClockCapability::monotonic_only())
.build()?;
```
### Registering Host Functions
Let WASM code call your Rust functions:
```rust
let mut sandbox = runtime.sandbox().build()?;
// Register a function that WASM can call
sandbox.register_func("env", "print_number", |value: i32| {
println!("WASM says: {}", value);
})?;
sandbox.register_func("env", "add_numbers", |a: i32, b: i32| -> i32 {
a + b
})?;
sandbox.load_module(&module)?;
sandbox.call_void("main")?;
```
### Getting Execution Metrics
```rust
let mut sandbox = runtime.sandbox().build()?;
sandbox.load_module(&module)?;
let result: i32 = sandbox.call("compute", (input,))?;
// Check how much resources were used
let metrics = sandbox.metrics();
println!("Execution time: {:?}", metrics.duration());
println!("Fuel consumed: {}", metrics.fuel_consumed);
println!("Peak memory: {} bytes", metrics.peak_memory);
```
### Handling Errors
```rust
use aegis_wasm::prelude::*;
match sandbox.call::<(i32,), i32>("process", (input,)) {
Ok(result) => println!("Success: {}", result),
Err(ExecutionError::OutOfFuel { consumed, limit }) => {
println!("Code used too much CPU: {} / {}", consumed, limit);
}
Err(ExecutionError::Timeout(duration)) => {
println!("Code took too long: {:?}", duration);
}
Err(ExecutionError::MemoryExceeded { used, limit }) => {
println!("Code used too much memory: {} / {}", used, limit);
}
Err(ExecutionError::Trap(info)) => {
println!("Code crashed: {}", info.message);
}
Err(e) => println!("Other error: {}", e),
}
```
### Reusing Sandboxes
```rust
let mut sandbox = runtime.sandbox().build()?;
sandbox.load_module(&module)?;
// Process multiple inputs with the same sandbox
for input in inputs {
let result: i32 = sandbox.call("process", (input,))?;
println!("Result: {}", result);
}
// Or reset and reuse
sandbox.reset();
sandbox.load_module(&another_module)?;
```
---
## Features
### Resource Limits
| Resource | What it Limits | Default |
|----------|---------------|---------|
| **Memory** | Max RAM the code can use | 64 MB |
| **Fuel** | Max CPU instructions (deterministic) | 1 billion |
| **Timeout** | Max wall-clock time | 30 seconds |
| **Stack** | Max call stack depth | 512 KB |
### Capabilities (Permissions)
| Capability | What it Allows |
|------------|---------------|
| **Filesystem** | Read/write specific directories |
| **Network** | Connect to specific hosts |
| **Logging** | Print output |
| **Clock** | Access system time |
**Principle:** Code has **zero** permissions by default. You explicitly grant what it needs.
### Supported Value Types
The CLI and library support these WASM types:
| Type | Example |
|------|---------|
| `i32` | `42`, `-17` |
| `i64` | `9999999999` |
| `f32` | `3.14` |
| `f64` | `3.141592653589793` |
---
## Security Model
```
┌─────────────────────────────────────┐
│ Untrusted WASM Code │
├─────────────────────────────────────┤
│ Capability Layer (Permissions) │ ← Can it access this resource?
├─────────────────────────────────────┤
│ Resource Limiter (Memory/CPU) │ ← Has it exceeded limits?
├─────────────────────────────────────┤
│ Wasmtime Sandbox (Memory Safety) │ ← Is the code valid?
└─────────────────────────────────────┘
```
**Guarantees:**
1. Code cannot access anything you don't explicitly allow
2. Code cannot use more resources than you allocate
3. Code cannot crash your application
4. Code cannot escape the sandbox
---
## Project Structure
| Crate | Description |
|-------|-------------|
| [`aegis-wasm`](https://crates.io/crates/aegis-wasm) | Main library - start here |
| [`aegis-wasm-cli`](https://crates.io/crates/aegis-wasm-cli) | Command-line tool |
| [`aegis-core`](https://crates.io/crates/aegis-core) | Low-level engine and sandbox |
| [`aegis-capability`](https://crates.io/crates/aegis-capability) | Permission system |
| [`aegis-resource`](https://crates.io/crates/aegis-resource) | Memory/CPU/time limits |
| [`aegis-host`](https://crates.io/crates/aegis-host) | Host function registration |
| [`aegis-observe`](https://crates.io/crates/aegis-observe) | Metrics and monitoring |
---
## Requirements
- **Rust 1.85+**
- Works on Linux, macOS, and Windows
---
## License
Dual-licensed under:
- [MIT License](LICENSE-MIT)
- [Apache License 2.0](LICENSE-APACHE)
Choose whichever you prefer.
---
## Contributing
Contributions welcome! Feel free to:
- Open issues for bugs or feature requests
- Submit pull requests
- Improve documentation
---
**[GitHub](https://github.com/aayushadhikari7/aegis)** | **[Crates.io](https://crates.io/crates/aegis-wasm)** | **[Docs](https://docs.rs/aegis-wasm)** | **[Issues](https://github.com/aayushadhikari7/aegis/issues)**