Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Code Runner: An Ephemeral Cloud Sandbox for Untrusted Python Execution

Abstract

This document describes the design and operation of Code Runner, a minimal, on-demand code execution sandbox built on Amazon Web Services (AWS). The system accepts arbitrary Python programs submitted as compressed archives, executes them within resource-constrained, network-isolated virtual machines, and returns captured output to the caller via a REST API. Critically, compute instances are provisioned at the moment of execution and autonomously terminated upon completion, eliminating idle resource consumption entirely. Infrastructure is expressed as code using Terraform, and all sandbox constraints — including CPU, memory, process count, execution time, and network egress — are governed by a single declarative configuration file.

Motivation

Remote code execution services typically fall into one of two categories: always-on runtimes that maintain warm instances to reduce latency (e.g., AWS Lambda, containerised runners), or batch-oriented pipelines that schedule work against a pre-existing fleet. Both models incur costs during periods of inactivity and introduce non-trivial operational surface area.

For workloads where execution frequency is low and unpredictable, neither approach is economical. Moreover, executing untrusted third-party code carries inherent security risks: without strong isolation boundaries, a malicious or poorly-written program may exhaust host resources, exfiltrate data, or interfere with co-located workloads.

Code Runner addresses these concerns through three design principles:

  1. Ephemeral compute. Each execution is assigned a dedicated EC2 instance that is launched on demand and terminates itself upon completion. No instance persists between runs.
  2. Defense in depth. Resource limits are enforced at the operating-system level via systemd cgroup controls (CPU quota, memory ceiling, process cap), supplemented by a hard execution timeout and a watchdog timer that destroys the instance unconditionally after a configurable lifetime.
  3. Minimal attack surface. Instances operate with no inbound network access. Outbound egress is restricted by default to HTTPS (required for S3 communication), with all traffic to AWS services routed through a VPC Gateway Endpoint that never traverses the public internet.

System Architecture

┌──────────┐    POST /run (zip)    ┌─────────────┐   launch   ┌──────────────┐
│          │ ───────────────────▶  │  API Server │ ─────────▶ │  EC2 Runner  │
│  Client  │                       │  (FastAPI)  │            │  (ephemeral) │
│          │  GET /run/{id}        └─────────────┘            └──────┬───────┘
│          │ ◀──────────────────────────────────────────────── S3 ◀──┘
└──────────┘              output.txt + status.json

The API server is the sole persistent component. Execution state is mediated entirely through S3: the server writes the user's code archive and an initial status document to S3 before launching the instance, and the instance writes its output and final status to S3 before terminating. The client polls the API, which proxies S3 reads, until a terminal status is observed.

Requirements

Operator (deployment host)

Requirement Version
AWS CLI, configured with appropriate IAM credentials ≥ 2.x
Terraform ≥ 1.6
Python (API server) ≥ 3.10

Python dependencies (API server)

Install via pip install -r api/requirements.txt:

Package Purpose
fastapi HTTP API framework
uvicorn[standard] ASGI server
boto3 AWS SDK (S3 reads/writes, EC2 launch)
pyyaml Parses sandbox.yaml configuration
python-multipart Enables multipart file upload in FastAPI

Code submission format

  • The submission must be a valid .zip archive.
  • main.py must be present at the archive root and serves as the sole entry point.
  • An optional requirements.txt at the archive root will be passed to pip install before execution.
  • The total archive size must not exceed the configured storage.max_upload_mb limit (default: 50 MB).

Configuration

All sandbox parameters are centralised in sandbox.yaml at the repository root. Changes to EC2 or network settings require re-running ./scripts/deploy.sh; changes to execution limits take effect on the next API server restart.

Key Default Description
ec2.instance_type t3.micro AWS EC2 instance size
ec2.region us-east-1 Deployment region
execution.timeout_seconds 60 Hard process kill timeout
execution.python_version 3.11 Python interpreter version
resources.max_memory_mb 256 Memory ceiling (systemd MemoryMax)
resources.max_cpu_percent 80 CPU quota (systemd CPUQuota)
resources.max_processes 64 Process cap (systemd TasksMax)
storage.max_upload_mb 50 Maximum accepted archive size
network.allow_outbound_internet false Permit unrestricted egress
shutdown.shutdown_after_run true Auto-terminate instance after run
shutdown.max_lifetime_minutes 10 Watchdog lifetime ceiling

Usage

1. Deploy infrastructure

chmod +x scripts/deploy.sh
./scripts/deploy.sh

2. Start the API server

cd api
pip install -r requirements.txt
uvicorn main:app --port 8000

3. Submit a run

zip code.zip main.py
curl -X POST http://localhost:8000/run \
     -F "file=@code.zip"

4. Poll for results

EC2 instance boot and code installation typically takes 30–90 seconds.

curl http://localhost:8000/run/abc-123

Possible terminal status values: success, error, timeout.

5. Teardown

cd terraform && terraform destroy

About

An ephemeral cloud sandbox for untrusted python execution.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages