active tools

sandrun

Anonymous batch job execution system with Linux namespace/seccomp sandboxing, resource limits, and WebSocket streaming

Started 2024 C++

Resources & Distribution

Package Registries

๐Ÿƒ Sandrun

Anonymous, ephemeral, sandboxed code execution service

Sandrun provides secure, isolated code execution without user accounts or data persistence. Submit code, get results, everything auto-deletes. Simple, private, secure.

โœจ Features

  • ๐Ÿ”’ Secure Sandbox - Linux namespaces, seccomp-BPF, resource limits
  • ๐ŸŽญ Anonymous - No accounts, no tracking, no logs
  • ๐Ÿ’จ Ephemeral - All data in tmpfs (RAM), auto-deletes after use
  • ๐Ÿš€ Fast - Native C++ implementation, minimal overhead
  • ๐ŸŒ Multi-language - Python, Node.js, Bash, and more
  • ๐Ÿ“ฆ Directory Upload - Submit entire projects with dependencies
  • โšก Simple API - RESTful endpoints, multipart uploads
  • ๐ŸŽฏ Resource Limits - CPU quotas, memory limits, timeouts
  • ๐Ÿ” Worker Identity - Ed25519 signatures for result verification
  • ๐Ÿ”— Pool Support - Distribute jobs across multiple workers

๐Ÿš€ Quick Start

Build and Run

# Install dependencies
sudo apt-get install libseccomp-dev libcap-dev

# Build
cmake -B build
cmake --build build

# Run server (requires root for namespaces)
sudo ./build/sandrun --port 8443

Submit a Job

# Quick Python code
curl -X POST http://localhost:8443/submit \
  -F "files=@job.tar.gz" \
  -F 'manifest={"entrypoint":"main.py","interpreter":"python3"}'

๐Ÿ—๏ธ Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     HTTP/REST     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Client    โ”‚ โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚  HTTP Server โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                          โ”‚
                                    โ”Œโ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”
                                    โ”‚ Job Queue  โ”‚
                                    โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                          โ”‚
                                    โ”Œโ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                    โ”‚ Sandbox        โ”‚
                                    โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
                                    โ”‚ โ”‚ Namespaces โ”‚ โ”‚
                                    โ”‚ โ”‚ Seccomp    โ”‚ โ”‚
                                    โ”‚ โ”‚ Cgroups    โ”‚ โ”‚
                                    โ”‚ โ”‚ tmpfs      โ”‚ โ”‚
                                    โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
                                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Security Layers

  1. Namespace Isolation - PID, network, mount, IPC, UTS
  2. Syscall Filtering - Seccomp-BPF whitelist (~60 safe syscalls)
  3. Resource Limits - Memory, CPU, processes, file descriptors
  4. Network Isolation - Complete network namespace isolation
  5. Filesystem Isolation - tmpfs only, no persistent storage
  6. Capability Dropping - All Linux capabilities dropped

๐Ÿ“ก API Reference

Endpoints

MethodEndpointDescription
GET/Server info and status
POST/submitSubmit new job
GET/status/{job_id}Get job status
GET/logs/{job_id}Get stdout/stderr
GET/outputs/{job_id}List output files
GET/download/{job_id}/{file}Download output file

Job Manifest

{
  "entrypoint": "main.py",           // Required: Entry file
  "interpreter": "python3",          // Required: Interpreter
  "args": ["--input", "data.csv"],  // Optional: Arguments
  "outputs": ["*.png", "results/"], // Optional: Output patterns
  "timeout": 300,                    // Optional: Timeout (seconds)
  "memory_mb": 512                  // Optional: Memory limit (MB)
}

Rate Limits

  • 10 CPU-seconds per minute per IP
  • 2 concurrent jobs per IP
  • 20 jobs per hour per IP
  • 512MB RAM per job
  • 5 minute maximum execution time

๐ŸŽจ Integrations

Web Frontend

Simple, elegant web interface with configurable server endpoint:

cd integrations/web-frontend
python3 -m http.server 8000
# Open http://localhost:8000

Python Client

from integrations.python_client.sandrun_client import SandrunClient

client = SandrunClient("http://localhost:8443")
result = client.run_and_wait(
    code="print('Hello, Sandrun!')",
    interpreter="python3"
)
print(result['logs']['stdout'])

Command Line

# See examples
./integrations/examples/curl_examples.sh

Trusted Pool Coordinator

NEW: Distribute jobs across multiple trusted workers for increased capacity and redundancy.

# Install dependencies
cd integrations/trusted-pool
pip install -r requirements.txt

# Generate worker keys
./build/sandrun --generate-key /etc/sandrun/worker1.pem
./build/sandrun --generate-key /etc/sandrun/worker2.pem

# Configure workers (add worker IDs to workers.json)
# See integrations/trusted-pool/workers.example.json

# Start workers on different machines
sudo ./build/sandrun --port 8443 --worker-key /etc/sandrun/worker1.pem  # Machine 1
sudo ./build/sandrun --port 8443 --worker-key /etc/sandrun/worker2.pem  # Machine 2

# Start pool coordinator
python3 integrations/trusted-pool/coordinator.py --port 9000 --workers workers.json

# Submit jobs to pool (same API as single worker)
curl -X POST http://pool-coordinator:9000/submit \
  -F "files=@project.tar.gz" \
  -F 'manifest={"entrypoint":"main.py"}'

Features:

  • Worker allowlist - Ed25519 public key authentication
  • Health checking - Automatic worker health monitoring
  • Load balancing - Jobs distributed across available workers
  • Job routing - Automatic dispatch to least-loaded worker
  • Transparent proxy - Same API as single worker

See: integrations/trusted-pool/README.md for full documentation and testing guide.

Trust Model: Workers are pre-approved and trusted. No result verification needed. Perfect for private clusters where you control all workers.

Coming Soon: Trustless pool coordinator with consensus-based verification for public/untrusted workers.

๐Ÿ”ง Configuration

Build Options

# Debug build
cmake -B build -DCMAKE_BUILD_TYPE=Debug

# Release build with optimizations
cmake -B build -DCMAKE_BUILD_TYPE=Release

# Custom port
./build/sandrun --port 9000

Resource Limits (constants.h)

constexpr size_t DEFAULT_MEMORY_LIMIT = 512 * 1024 * 1024;  // 512MB
constexpr size_t MAX_OUTPUT_SIZE = 10 * 1024 * 1024;        // 10MB
constexpr int DEFAULT_TIMEOUT_SECONDS = 300;                // 5 minutes
constexpr int MAX_PROCESSES_PER_JOB = 32;                   // Thread limit

๐Ÿ›ก๏ธ Security Considerations

Sandrun is designed for defensive security only:

  • โœ… Run untrusted code safely
  • โœ… Educational sandboxing
  • โœ… CI/CD testing
  • โœ… Code evaluation
  • โŒ NOT for cryptocurrency mining
  • โŒ NOT for network attacks
  • โŒ NOT for system exploitation

Threat Model

Sandrun protects against:

  • Code execution exploits
  • Container escapes
  • Resource exhaustion
  • Data persistence
  • Network access
  • System file access

๐Ÿ“Š Performance

  • Startup overhead: ~100ms per job
  • Memory overhead: ~10MB base + job requirements
  • Concurrent jobs: Limited by system resources
  • Throughput: ~10-50 jobs/second (depends on job complexity)

๐Ÿค Contributing

Contributions are welcome! Key principles:

  1. Simplicity - Avoid unnecessary complexity
  2. Security - Every change must maintain security guarantees
  3. Privacy - No tracking, logging, or data retention
  4. Elegance - Clean, readable, maintainable code

๐Ÿ“œ License

MIT License - See LICENSE file for details.

โš ๏ธ Disclaimer

Sandrun is provided as-is for educational and defensive security purposes. Users are responsible for compliance with applicable laws and regulations. The authors assume no liability for misuse.

๐Ÿ™ Acknowledgments

Built with:

  • Linux kernel namespaces
  • libseccomp for syscall filtering
  • Modern C++17
  • Security best practices from container runtimes

Remember: Sandrun is about providing secure, anonymous code execution. No accounts, no tracking, no persistence. Just code in, results out, then everything disappears. Simple as that.

Discussion