Architecture
How the Code Interpreter's six microservices, Redis, and Garage fit together, how a single execution job flows through them, and the ports each service exposes.
The Code Interpreter is not a single container — it is six cooperating microservices plus a Redis cache/queue and a Garage (S3) object store. Splitting the work this way keeps the component that runs untrusted code (the sandbox-runner) small, privileged, and tightly isolated, while everything else stays unprivileged.
The services
| Service | Container | Port | Role |
|---|---|---|---|
| api | codeapi-api | 3112 | Public entry point. Accepts HTTP requests from IntelliAsk, verifies the Ed25519 JWT, and enqueues jobs. |
| service-worker | codeapi-service-worker | 3113 (health) | Pulls jobs from Redis, signs the execution manifest, drives the sandbox, and collects results. |
| file-server | codeapi-file-server | 3000 | S3-compatible object I/O — stores job input files and generated outputs in Garage. |
| tool-call-server | codeapi-tool-call-server | 3033 | Brokers tool/function calls between sandboxed code and external systems; manages sessions. |
| egress-gateway | codeapi-egress-gateway | 3190 | Forward proxy for all sandbox outbound traffic. Allow-lists destinations and signs egress grants. |
| sandbox-runner | codeapi-sandbox-runner | 2000 | Privileged. Executes untrusted code in an NsJail sandbox with mounted language runtimes. |
| Redis | redis | 6379 | Job queue, cache, tool-call sessions, and the egress grant ledger. |
| Garage | garage | 3900 | S3-compatible object store backing the file-server. |
The sandbox-runner is privileged
Only the sandbox-runner runs privileged (it needs to create namespaces and cgroups for NsJail). Every other service is unprivileged. This is the whole point of the split: the blast radius of untrusted code is confined to one small, purpose-built container that holds no secrets (see the Security model).
How a job flows
- The app calls the api with a signed Ed25519 JWT. The api verifies the issuer, audience, and algorithm before doing anything else.
- The job is enqueued in Redis. The service-worker dequeues it.
- The worker signs an execution manifest with its Ed25519 private key and posts the job to the sandbox-runner.
- The sandbox-runner verifies the manifest, scrubs forbidden environment
variables, and runs the code inside an NsJail sandbox with the language runtime
mounted read-only from
/pkgs. - Outbound traffic is proxied through the egress-gateway — the sandbox has no direct network. Tool calls go to the tool-call-server; file I/O to the file-server, which persists to Garage (S3).
- Results flow back to the worker, then the api, then the app.
Isolation modes
The sandbox-runner supports two isolation backends, selected by KVM_ENABLED:
| Mode | KVM_ENABLED | How it works | Used where |
|---|---|---|---|
| Direct NsJail | false (default) | Linux namespaces + cgroups v2 + seccomp via NsJail. No hardware virtualization required. | The default; required on hosts without /dev/kvm (e.g. the Nomad Rocky Linux clients). |
| libkrun microVM | true | Each job runs in a lightweight KVM microVM (LAUNCHER_VCPUS, LAUNCHER_RAM_MIB). | Hosts that expose /dev/kvm. |
cgroup v2 is required for the no-KVM path
The direct NsJail path needs a cgroup v2 unified hierarchy on the host.
intelliask doctor checks for this. On Rocky Linux 8 it is enabled with the
kernel argument systemd.unified_cgroup_hierarchy=1.
Language runtimes
Language runtimes (Python, Node.js, etc.) and their packages are built into a
package tree and mounted read-only into every sandbox at
SANDBOX_PACKAGES_DIRECTORY (default /pkgs). Browser automation jobs additionally
use a Chromium build under PLAYWRIGHT_BROWSERS_PATH.
Because the tree is read-only and shared, a job cannot modify the runtimes seen by other jobs. See Configuration for the sandbox mount and limit settings.
Ports summary
| Port | Service | Exposed to |
|---|---|---|
3112 | api | The IntelliAsk app (the only externally-reached port) |
3113 | service-worker | Health checks only |
3000 | file-server | Internal services + sandbox (via egress-gateway) |
3033 | tool-call-server | api + egress-gateway |
3190 | egress-gateway | The sandbox's only outbound route |
2000 | sandbox-runner | service-worker (/api/v2) |
6379 | Redis | All services |
3900 | Garage | file-server |
Last updated on