IndexSIG-00

WRK-02Record

CodeFlow

Gamified backend-dev learning platform. I built the Kubernetes/gVisor sandbox that runs student code safely, and the in-browser IDE on top of it.

Status
Pre-launch — repository private; hardened execution path built but not yet the default
Updated
Stack
FastAPIKubernetesgVisorNext.js 15Monaco EditorPostgreSQL

What it is

CodeFlow teaches backend and API development as a lesson loop: build a small FastAPI endpoint, watch a bot sabotage one line, predict the symptom, explain the break, get graded. It is a team project — roughly six or seven collaborators — and my slice is the part that has to run other people’s code. I built the sandboxed workspace infrastructure, the browser IDE on top of it, the async job pipeline that keeps untrusted execution off the request path, and a pre-launch security audit across all of it. I also led the frontend migration from a Vite SPA to Next.js 15.

How it works

Workspace pods run under gVisor’s runsc userspace kernel rather than a bare container boundary, in a namespace separate from the control plane: no service-account token, no network path to Postgres, no shared filesystem. A WorkspaceOrchestrator seam selects between a mock implementation and the real Kubernetes one from a single environment variable, so the rest of the team could build against workspaces locally without a cluster. The browser side pairs Monaco with xterm over a WebSocket bridge to the pod’s exec stream. Both the interactive workspace and the grading pipelines are enqueue-and-poll — the backend never executes untrusted code inline inside an HTTP handler.

Notable decisions

The isolation runtime is one field on the pod spec, so moving to a stronger microVM boundary later is a config change rather than an application rewrite. The separation between control plane and execution plane is enforced by manifests — Pod Security Admission, default-deny NetworkPolicy, ResourceQuota, least-privilege RBAC — and documented as a review checklist rather than tribal knowledge.

Current state

Pre-launch, and the audit I wrote says the honest thing: the hardening is real in code and matches the documented threat model, but as of that audit it was not yet the default running path — the orchestrator still defaulted to the mock implementation and the Kubernetes path had not been validated against a live cluster. The follow-up commit moved the last synchronous execution endpoint to enqueue-and-poll and added a fail-fast production config guard. Standing up and validating the real cluster path end to end is still open.