Sandboxing for untrusted commands on Kubernetes.
An HTTP server that fans commands out to a pool of resident, resource-bounded worker containers in your Kubernetes cluster. Each command runs in its own worker, which resets to a clean slate between commands โ no state bleed, ever.
Run a server, run a worker, dispatch a command. The worker stays resident and resets between commands.
# Terminal 1 โ the server (the only ingress) SHIITAKE_AUTH_TOKEN=dev-token SHIITAKE_CAPTURE_ROOT=/tmp/capture \ cargo run --bin shiitake-server # Terminal 2 โ one worker, joining the pool SHIITAKE_WORKER_ID=worker-0 SHIITAKE_CAPTURE_ROOT=/tmp/capture \ cargo run --bin shiitake-worker # Terminal 3 โ dispatch a command, get a handle back curl -s -H "Authorization: Bearer dev-token" \ -X POST localhost:8080/api/v1/exec \ -d '{"command": "echo hello from a sandboxed worker"}'
One server is the only ingress. It hands each command to a worker over an authenticated WebSocket โ in the same pod or another one; the worker runs it, streams output to disk, reports the result, then resets its sandbox before the next command.
Shiitake is generic โ it knows nothing about your application. A few things it's particularly good at:
Every command runs in its own resource-bounded worker container โ it can't see or touch another command's process, files, or output. The worker resets to a clean slate between commands (and recycles a fresh container if it can't), so nothing carries over to the next caller.
Skip giving your workload Kubernetes permissions to spawn a Job or Pod per task. A fixed pool
of workers is already running and waiting โ you just POST a command and get a
handle back. No RBAC to create pods, no per-task scheduling latency.
Memory limits are enforced at the container level, so an allocation bomb only kills its own
worker โ the server and every other worker keep running. The kill is detected from the
kubelet's container status and reported as oom_container, never silently lost.
The worker redirects stdout/stderr straight into capture files via inherited fds โ the kernel
writes to disk, so neither process buffers output in memory. Read it back over HTTP with
Range support, and watch output size as a metric instead of truncating it.
Shiitake is better because of the people who pitch in from outside the team โ thank you for every issue, review, and pull request.