Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
17a88be
feat: implement initial HTTP server with health check endpoint
googleboy-byte May 20, 2026
f0ff273
feat: implement YAML-based language configuration loading. next: vali…
googleboy-byte May 20, 2026
8121771
feat: implement validation logic for filenames, compiler flags, and r…
googleboy-byte May 20, 2026
c74bb1b
feat: implement code execution runner with test case validation and u…
googleboy-byte May 20, 2026
edc909c
POST /run working with py3, whitespace mismatch detection
googleboy-byte May 20, 2026
b84fd40
add nsjail 3.4 as submodule
googleboy-byte May 20, 2026
1218990
implement NsJail sandbox execution with configurable runtime argument…
googleboy-byte May 20, 2026
7899bef
update docs with progress
googleboy-byte May 20, 2026
cd7ca7a
implement build step with configurable flags. add C++ language suppor…
googleboy-byte May 21, 2026
aeb18cb
plug-and-play language extensibility verified (bash - interpreted, ru…
googleboy-byte May 21, 2026
fcd2d0f
add JSON tags to resource limits and implement per-request limit over…
googleboy-byte May 21, 2026
0e3dc83
add /readyz endpoint to monitor nsjail and language runtime availabil…
googleboy-byte May 21, 2026
4248131
update /readyz API docs
googleboy-byte May 21, 2026
82bb82c
implement internal stats tracking. replace readyz handler with health…
googleboy-byte May 21, 2026
97a0fc9
add handler and resolver tests. enforce minimum test count. export st…
googleboy-byte May 21, 2026
865e94e
replace raw docker build with makefile and load script
googleboy-byte May 21, 2026
ba881e2
update README.md
googleboy-byte May 21, 2026
6d0cbec
integrate hey for load testing and document benchmarks (without queue…
googleboy-byte May 21, 2026
fca085a
add bounded concurrency queue using configurable job limit
googleboy-byte May 21, 2026
5689232
docker-compose.yml for one-command dev setup
googleboy-byte May 21, 2026
d383fbf
add security hardening with tests including request validation, outpu…
googleboy-byte May 21, 2026
bbe8d61
add flag allowlisting for execution commands with validation and test…
googleboy-byte May 21, 2026
2606ac4
chore: initialize and update submodules before docker build in Makefile
googleboy-byte May 22, 2026
861fcff
add fresh-setup and test scripts. tested on fresh ubuntu 26.04
googleboy-byte May 22, 2026
414668a
add server readiness check and network isolation security test to ver…
googleboy-byte May 22, 2026
8b91386
fix partial limit overrides to only apply non-zero fields, preserving…
googleboy-byte May 22, 2026
c80d60b
drain stdout/stderr to io.Discard after LimitReader cap to prevent ou…
googleboy-byte May 22, 2026
519aba2
configurable queue timeout, returns 503 queue_timeout when semaphore …
googleboy-byte May 22, 2026
369a7bf
cache /readyz probe results for 30s, reduces probe overhead from 153m…
googleboy-byte May 22, 2026
d2764c4
update concurrency, resource management, health check optimizations, …
googleboy-byte May 22, 2026
22fb810
structured JSON request logging with request_id, language, status, du…
googleboy-byte May 22, 2026
2d081fc
docs: rewrite architecture documentation to provide detailed request …
googleboy-byte May 22, 2026
2cecc12
add Java 17 support with configurable source and artifact filename co…
googleboy-byte May 22, 2026
45d18f0
add support for C and JavaScript to languages.yaml plus integration t…
googleboy-byte May 22, 2026
7d6b7ba
add support for Verilog language using Icarus Verilog
googleboy-byte May 22, 2026
523260e
increase request body limit to 512KiB (since limit of 256KiB is on so…
googleboy-byte May 23, 2026
8fbe4e6
memory tracking and memory_exceeded detection
googleboy-byte May 23, 2026
5d98625
update fresh setup and test scripts
googleboy-byte May 23, 2026
da89ed9
update benchmarks before PR. reran load test
googleboy-byte May 23, 2026
b5e1488
Update CPU description in benchmarks documentation
googleboy-byte May 23, 2026
2391623
docs: add project postmortem, AI usage logs, and architectural decisi…
googleboy-byte May 23, 2026
6a4cb3a
cap per-request limit overrides at language defaults to prevent DoS v…
googleboy-byte May 24, 2026
0d1e673
add queue_size atomic counter to stats and expose via /info endpoint …
googleboy-byte May 24, 2026
6edd595
move rlimit_as to optional config in .yaml to abide by stage 2 "no co…
googleboy-byte May 27, 2026
cb6bb3d
enable Zig language support by increasing virtual memory reservation …
googleboy-byte May 28, 2026
98c2bec
feat: add docker compose helper targets to Makefile and update contai…
googleboy-byte May 28, 2026
5f70028
feat: add support for TypeScript, Dart, and Fortran languages
googleboy-byte Jun 12, 2026
96bbb38
feat: add payload testing infrastructure, update TypeScript build con…
googleboy-byte Jun 12, 2026
624e780
feat: add load testing documentation and artifacts for performance be…
googleboy-byte Jun 12, 2026
6f0b8e8
chore: add extensive load testing results and update languages config…
googleboy-byte Jun 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*.so
*.dylib

payloads/*
# Test binary, built with `go test -c`
*.test

Expand All @@ -30,3 +31,7 @@ go.work.sum
# Editor/IDE
# .idea/
# .vscode/

# Load test reports
**/report-*.json

3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "external/nsjail"]
path = external/nsjail
url = https://github.com/google/nsjail
113 changes: 79 additions & 34 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,39 +1,84 @@
# syntax=docker/dockerfile:1.7

ARG GO_VERSION=1.23
ARG DEBIAN_VERSION=bookworm
ARG NSJAIL_VERSION=3.4

# ---- Build nsjail from source ----
FROM debian:${DEBIAN_VERSION}-slim AS nsjail-builder
ARG NSJAIL_VERSION
RUN apt-get update && apt-get install -y --no-install-recommends \
autoconf bison ca-certificates flex g++ gcc git libnl-route-3-dev \
libprotobuf-dev libtool make pkg-config protobuf-compiler \
&& rm -rf /var/lib/apt/lists/*
RUN git clone --depth 1 --branch ${NSJAIL_VERSION} https://github.com/google/nsjail.git /src/nsjail \
&& make -C /src/nsjail \
&& install -m 0755 /src/nsjail/nsjail /usr/local/bin/nsjail

# ---- Builder / dev image (Go + linters + nsjail) ----
FROM golang:${GO_VERSION}-${DEBIAN_VERSION} AS builder
RUN apt-get update && apt-get install -y --no-install-recommends \
libnl-route-3-200 libprotobuf32 \
&& rm -rf /var/lib/apt/lists/*
COPY --from=nsjail-builder /usr/local/bin/nsjail /usr/local/bin/nsjail
RUN go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
WORKDIR /src
COPY go.mod ./
FROM golang:1.23-bookworm AS builder

WORKDIR /build

COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/goboxd ./cmd/goboxd
RUN go build -ldflags "-X main.version=0.1.0 -X main.commit=$(git rev-parse --short HEAD)" -o goboxd ./cmd/goboxd

FROM debian:bookworm-slim AS nsjail-builder

# ---- Runtime image ----
FROM debian:${DEBIAN_VERSION}-slim AS runtime
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates libnl-route-3-200 libprotobuf32 \
RUN apt-get update && apt-get install -y \
bison \
flex \
g++ \
gcc \
git \
libcap-dev \
libnl-route-3-dev \
libprotobuf-dev \
make \
pkg-config \
protobuf-compiler \
&& rm -rf /var/lib/apt/lists/*
COPY --from=nsjail-builder /usr/local/bin/nsjail /usr/local/bin/nsjail
COPY --from=builder /out/goboxd /usr/local/bin/goboxd

COPY external/nsjail /nsjail-src
WORKDIR /nsjail-src
RUN make -j$(nproc)

FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y \
bash \
curl \
g++ \
gcc \
gfortran \
iverilog \
libcap2 \
libnl-route-3-200 \
libprotobuf32 \
nodejs \
npm \
openjdk-17-jdk-headless \
python3 \
unzip \
wget \
xz-utils \
# Bonus languages (commented out for Stage 2)
golang-go \
kotlin \
lua5.4 \
mono-devel \
ocaml \
ruby \
rustc \
&& rm -rf /var/lib/apt/lists/*

# Install Swift and Zig (commented out for Stage 2)
RUN wget -q https://download.swift.org/swift-6.0.2-release/debian12/swift-6.0.2-RELEASE/swift-6.0.2-RELEASE-debian12.tar.gz \
&& tar -xzf swift-6.0.2-RELEASE-debian12.tar.gz -C /usr/local --strip-components=2 \
&& rm swift-6.0.2-RELEASE-debian12.tar.gz
RUN wget -q https://ziglang.org/download/0.13.0/zig-linux-x86_64-0.13.0.tar.xz \
&& tar -xJf zig-linux-x86_64-0.13.0.tar.xz -C /usr/local \
&& ln -sf /usr/local/zig-linux-x86_64-0.13.0/zig /usr/local/bin/zig \
&& rm zig-linux-x86_64-0.13.0.tar.xz

# Install Dart SDK and TypeScript
RUN wget -q https://storage.googleapis.com/dart-archive/channels/stable/release/3.4.4/sdk/dartsdk-linux-x64-release.zip \
&& unzip -q dartsdk-linux-x64-release.zip -d /usr/local \
&& ln -sf /usr/local/dart-sdk/bin/dart /usr/local/bin/dart \
&& ln -sf /usr/local/dart-sdk/bin/dart /usr/bin/dart \
&& rm dartsdk-linux-x64-release.zip \
&& npm install -g typescript @types/node \
&& ln -sf /usr/local/bin/tsc /usr/bin/tsc

COPY --from=nsjail-builder /nsjail-src/nsjail /usr/sbin/nsjail
COPY --from=builder /build/goboxd /usr/local/bin/goboxd
COPY languages.yaml /etc/goboxd/languages.yaml

EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/goboxd"]

CMD ["/usr/local/bin/goboxd", "-port", "8080", "-config", "/etc/goboxd/languages.yaml"]
73 changes: 65 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,19 +1,76 @@
.PHONY: build run test integration lint
# goboxd Makefile

COMPOSE ?= docker compose
TOOLS := $(COMPOSE) --profile tools run --rm tools
BINARY=goboxd
IMAGE=goboxd:latest
SERVER_URL=http://localhost:8080
VERSION=0.1.0
COMMIT=$(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
LDFLAGS=-ldflags "-X main.version=$(VERSION) -X main.commit=$(COMMIT)"

.PHONY: build run test integration corpus payloads load secure lint clean compose compose-down

compose:
@echo "Bringing up services with Docker Compose..."
docker compose up -d --build
@echo "Server is starting at $(SERVER_URL)"

compose-down:
@echo "Shutting down services..."
docker compose down

secure:
@echo "Running security verification tests..."
@chmod +x tests/secure/verify.sh
@bash tests/secure/verify.sh $(SERVER_URL)

build:
$(COMPOSE) build goboxd
@echo "Building $(BINARY) $(VERSION) ($(COMMIT))..."
go build $(LDFLAGS) -o $(BINARY) ./cmd/goboxd/main.go

run:
$(COMPOSE) up goboxd
@echo "Bringing up Docker container $(IMAGE)..."
git submodule update --init --recursive
-docker kill $(BINARY) 2>/dev/null || true
-docker rm $(BINARY) 2>/dev/null || true
docker build -t $(IMAGE) .
docker run -d --privileged --cpus=2 --memory=2g --cgroupns=host --name $(BINARY) -p 8080:8080 $(IMAGE)
@echo "Server is starting at $(SERVER_URL)"

test:
$(TOOLS) go test ./...
@echo "Running unit tests..."
go test -v ./tests/unit/...

integration:
$(TOOLS) go test -tags=integration ./tests/...
@echo "Running integration tests..."
@curl -s -o /dev/null --connect-timeout 2 $(SERVER_URL)/healthz || (echo "Error: Server is not running at $(SERVER_URL). Run 'make run' first." && exit 1)
bash tests/integration/run_all.sh $(SERVER_URL)

corpus:
bash tests/corpus/run_corpus.sh $(SERVER_URL)

payloads:
@chmod +x tests/corpus/run_payloads.sh
bash tests/corpus/run_payloads.sh $(SERVER_URL)

load:
@curl -s -o /dev/null --connect-timeout 2 $(SERVER_URL)/healthz || (echo "Error: Server is not running. Run 'make run' first." && exit 1)
@if ! command -v hey >/dev/null 2>&1; then \
echo "hey not found. Install with: go install github.com/rakyll/hey@latest"; \
exit 1; \
fi
bash tests/load/load.sh $(SERVER_URL)

lint:
$(TOOLS) golangci-lint run ./...
@echo "Linting code..."
go vet ./...
@if command -v staticcheck >/dev/null 2>&1; then \
staticcheck ./...; \
else \
echo "staticcheck not found, skipping (go vet passed)"; \
fi

clean:
@echo "Cleaning up..."
rm -f $(BINARY)
-docker kill $(BINARY) 2>/dev/null || true
-docker rm $(BINARY) 2>/dev/null || true
75 changes: 17 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,70 +1,29 @@
<div align="center">

# goboxd

**A Go HTTP service for executing untrusted code in isolated sandboxes.**

[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](LICENSE)
[![Go](https://img.shields.io/badge/Go-1.23-00ADD8.svg?logo=go&logoColor=white)](https://go.dev)
[![Docker](https://img.shields.io/badge/Docker-Required-2496ED.svg?logo=docker&logoColor=white)](https://www.docker.com)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/thesouldev/goboxd/pulls)

</div>

---

## Overview

goboxd is an HTTP service written in Go that compiles and runs untrusted code inside isolated sandboxes and returns the result. Optional test cases can be supplied to assert behaviour against expected output. It is built for safe execution of code across many languages, with strict isolation, bounded concurrency, and a plug and play language registry.

## Features

- Plug and play language registry driven by YAML
- Process isolation using Linux namespaces and cgroups
- Bounded concurrency with request queuing
- Fully containerised for local development and deployment
- Per request resource limits for time, memory, and processes
- Liveness and readiness probes for orchestration
This is a sandbox daemon written in go. It is used to run untrusted code in a sandbox.

## Getting started
## Run

### Prerequisites

- Docker with Compose v2

No Go toolchain or system dependencies are required on the host. Everything runs in containers.

### Installation

```sh
git clone https://github.com/thesouldev/goboxd.git
cd goboxd
make build
```

### Usage

```sh
make run # start the service on :8080
make test # run unit tests
make integration # run end to end tests
make lint # run static analysis
make run # builds image, starts container on port 8080
make test # runs unit tests
make integration # end-to-end tests, requires running container
make secure # runs automated security verification suite
make lint # runs static analysis
```

## Project structure
## Docs

```
.
├── cmd/goboxd/ binary entry point
├── internal/ private application packages
├── docs/ api, languages, security, benchmarks, architecture
└── tests/ integration tests
docs/api.md - HTTP contract
docs/languages.md - supported languages and YAML schema
docs/testing.md - test coverage index
docs/architecture.md - system architecture
docs/benchmarks.md - benchmarks
docs/security.md - security considerations
docs/test_logs.md - test logs
```

## Contributing

Contributions are welcome. Open an issue to discuss substantial changes before sending a pull request.

## License
## Framework

This project is distributed under the GNU General Public License v3.0. See [LICENSE](LICENSE) for the full text.
HTTP routing uses chi, stays close to net/http, making handlers trivial to test with httptest and avoiding framework lock-in.
Loading