FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

codize-dev/sandbox: 💻 A sandboxed code execution engine. · GitHub

Repository files navigation

Codize Sandbox

A sandboxed code execution engine.

Codize Sandbox is the code execution engine that powers Codize in production, running arbitrary code safely inside Linux namespace jails (google/nsjail). It exposes an HTTP API to receive code, execute it in an isolated environment, and return the output.

Supported Runtimes

Runtime Identifier
Node.js node
TypeScript node-typescript
Ruby ruby
Go go
Python python
Rust rust
Bash bash

Usage

The container must run in privileged mode (required for nsjail to create Linux namespaces) with --cgroupns=host (required for nsjail to manage cgroups for resource limiting).

Docker

$ docker run \
    --privileged \
    --cgroupns=host \
    -p 8080:8080 \
    ghcr.io/codize-dev/sandbox:latest serve

Behavior can be customized via CLI flags (see CLI Flags for the full list):

$ docker run \
    --privileged \
    --cgroupns=host \
    -p 8080:8080 \
    ghcr.io/codize-dev/sandbox:latest serve --run-timeout 10 --compile-timeout 10

Docker Compose

Create a compose.yml:

services:
  sandbox:
    image: ghcr.io/codize-dev/sandbox:latest
    privileged: true
    cgroup: host
    command: ["serve", "--run-timeout", "10", "--compile-timeout", "10"]
    ports:
      - "8080:8080"
$ docker compose up

CLI Flags

Flag Default Description
--port 8080 (overridden by PORT env var) Listen port
--run-timeout 30 Run timeout in seconds
--compile-timeout 30 Compile timeout in seconds
--output-limit 1048576 (1 MiB) Maximum combined output bytes
--max-files 10 Maximum number of files per request
--max-file-size 262144 (256 KiB) Maximum file size in bytes
--max-stdin-size 1048576 (1 MiB) Maximum stdin size in bytes (post-decode when base64_encoded is true; wire bytes otherwise)
--max-body-size 5242880 (5 MiB) Maximum request body size in bytes
--max-concurrency 10 Maximum number of concurrent sandbox executions
--max-queue-size 50 Maximum number of requests waiting in the execution queue
--queue-timeout 30 Maximum time in seconds a request waits in the execution queue
--metrics false Enable the /metrics endpoint

API

GET /healthz

Returns the service health status. Intended for load balancer health checks, Docker health checks, and Kubernetes liveness probes.

Response:

{"status":"ok"}

POST /v1/run

Request:

{
  "runtime": "node",
  "files": [
    {
      "name": "index.js",
      "content": "console.log(\"Hello, World!\")"
    }
  ]
}
  • runtime (required): one of "node", "node-typescript", "ruby", "go", "python", "rust", "bash"
  • files (required): array of source files. The first file in the array is used as the entrypoint
    • name (required): file name
    • content (required): file content as plain text (default) or Base64-encoded string
    • base64_encoded (optional, default: false): when true, content is treated as a Base64-encoded string and decoded by the server
  • stdin (optional): stdin payload delivered to the run-step child process only. Compile steps never receive stdin.
    • content (required when stdin is specified): stdin bytes as plain text (default) or Base64-encoded string
    • base64_encoded (optional, default: false): when true, content is treated as a Base64-encoded string and decoded by the server

Response:

{
  "compile": null,
  "run": {
    "stdout": "SGVsbG8sIFdvcmxkIQo=",
    "stderr": "",
    "output": "SGVsbG8sIFdvcmxkIQo=",
    "exit_code": 0,
    "status": "OK",
    "signal": null,
    "duration_ms": 42
  }
}
  • compile: compilation result (same schema as run). null for interpreted runtimes (node, ruby, python, bash). When compilation fails, run is null
  • run: execution result. null when compilation fails
    • stdout / stderr / output: Base64-encoded output. output is the interleaved combination of stdout and stderr
    • exit_code: process exit code
    • status: one of "OK", "SIGNAL", "TIMEOUT", "OUTPUT_LIMIT_EXCEEDED"
    • signal: signal name if the process was killed by a signal (e.g. "SIGKILL"), null otherwise
    • duration_ms: wall-clock execution time for this step in milliseconds (integer). Measured around the nsjail process lifetime (from successful cmd.Start() to cmd.Wait() returning), so it includes nsjail's own startup/teardown overhead in addition to user code runtime. Always present regardless of status.

GET /metrics

Returns Prometheus text exposition format metrics. Only available when the --metrics flag is enabled.

Response (Content-Type: text/plain; version=0.0.4; charset=utf-8):

# HELP sandbox_concurrency_active Number of requests currently executing.
# TYPE sandbox_concurrency_active gauge
sandbox_concurrency_active 0
# HELP sandbox_queue_length Number of requests waiting in queue.
# TYPE sandbox_queue_length gauge
sandbox_queue_length 0
# HELP sandbox_concurrency_max Configured maximum concurrent executions.
# TYPE sandbox_concurrency_max gauge
sandbox_concurrency_max 10
# HELP sandbox_queue_max Configured maximum queue size.
# TYPE sandbox_queue_max gauge
sandbox_queue_max 50

How It Works

Architecture

POST /v1/run
  → Echo HTTP server (request validation, optional Base64 decoding, write files to tmpdir)
    → nsjail (execute code in a namespace-isolated environment)
      → Return response

Sandbox Isolation

Code is isolated by google/nsjail with multiple layers of defense:

  • Linux namespaces: PID, network, mount, UTS, IPC, and cgroup namespaces are all isolated. External network access is completely blocked, and loopback communication is also disabled.
  • UID/GID mapping: Sandboxed processes run as nobody (65534). Only a single UID is mapped, making setuid impossible.
  • Filesystem restrictions: Only the minimum required paths are mounted (shared libraries, device files, user code directory). Everything except the user code directory is read-only. /tmp is a 64 MiB tmpfs mounted with noexec.
  • Resource limits: Execution time is enforced by nsjail's --time_limit and --rlimit_cpu. Cgroups limit PID count, memory, and CPU usage. Rlimits constrain stack size and other per-process resources.
  • Seccomp-BPF: Dangerous syscalls (io_uring, bpf, mount, ptrace, unshare, etc.) are blocked at the kernel level. Clone calls with namespace creation flags are also blocked.
  • Output limits: The process is killed if the combined stdout and stderr exceeds the configured limit.

License

MIT

About

💻 A sandboxed code execution engine.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages


Back | FazBrowse Home | New Git URL