Code Interpreter
The Code Interpreter (codeapi) runs IntelliAsk's Run Code feature in hardened sandboxes. Its architecture (six services + bundled Redis), how the app authenticates with a signed JWT, the language-runtime package tree, and the full CODEAPI_* reference in config/.env.
The Code Interpreter — codeapi — powers IntelliAsk's Run Code feature. It runs user code in hardened sandboxes, brokers tool calls, gates all sandbox network egress through an allow-listed proxy, and stores generated files in an S3-compatible bucket (the bundled Garage service by default).
Full reference lives in Services
This page is just what you need to run codeapi in the stack. For the complete per-service environment surface, architecture, and security model, see Services → Code Interpreter.
Architecture
codeapi is six services plus a dedicated redis, all defined in
config/codeapi.compose.yml. They share the stack network and reuse the bundled
garage (S3) service.
| Service | Port | Role |
|---|---|---|
codeapi-api | 3112 | Public entry point — the IntelliAsk app sends /v1/* requests here. |
codeapi-service-worker | 3113 (health) | Pulls jobs from Redis, drives the sandbox, signs execution manifests. |
codeapi-sandbox-runner | 2000 | Runs untrusted user code. Privileged. |
codeapi-egress-gateway | 3190 | Allow-listed outbound proxy; the sandbox may only reach the network through here. |
codeapi-tool-call-server | 3033 | Brokers tool calls back to the caller. |
codeapi-file-server | 3000 | S3/object I/O, backed by the bundled Garage. |
redis | 6379 | Cache/queue backend shared by the codeapi services. |
Privileged sandbox + host requirements
codeapi-sandbox-runner runs privileged because it executes untrusted code,
isolating via unshare --mount + NsJail user namespaces (KVM_ENABLED=false, no
libkrun MicroVM). This path needs host cgroup v2 (unified hierarchy). Keep the
service on the internal network only — never publish its port.
How the app talks to codeapi
The IntelliAsk app (the intelliask service) reaches the API at
http://codeapi-api:3112/v1 and authenticates with a short-lived Ed25519 JWT it
mints per request. There is no reverse proxy and no X-API-Key in this path.
The signing key is a pair: the IntelliAsk app holds the private half
(CODEAPI_JWT_PRIVATE_KEY_BASE64) and codeapi-api verifies with the public half
(CODEAPI_JWT_PUBLIC_KEY). Both are auto-provisioned.
Prerequisite: the language-runtime package tree
Build the package tree before first use
The sandbox loads its runtimes from a prebuilt package tree bind-mounted
read-only at /host-packages (from ${STORAGE_ROOT}/code-interpreter-packages on
the host). An empty tree makes every run fail with runtime is unknown.
Populate it before first use — provisioning only creates the empty directory.
Configuration
Every codeapi variable lives in config/.env and is read by the containers under the
same name — see
Services → Code Interpreter → Configuration
for the full per-service reference. The defaults are production-ready and the sandbox
is hardened by default (CODEAPI_HARDENED_SANDBOX_MODE=true). The only secrets
are auto-provisioned during intelliask provision — leave them blank on a fresh
install and never edit one half of a pair by hand:
| Secret | Used by |
|---|---|
CODEAPI_JWT_PRIVATE_KEY_BASE64 ⇄ CODEAPI_JWT_PUBLIC_KEY | App signs request JWTs / codeapi-api verifies them. |
CODEAPI_EXECUTION_MANIFEST_PRIVATE_KEY ⇄ SANDBOX_EXECUTION_MANIFEST_PUBLIC_KEY | service-worker signs execution manifests / sandbox-runner verifies them. |
CODEAPI_INTERNAL_SERVICE_TOKEN | Service-to-service auth between the codeapi components. |
CODEAPI_EGRESS_GRANT_SECRET | HMAC secret for signed egress grants. |
Resource limits
Each service has its own CODEAPI_*_CPUS / CODEAPI_*_MEMORY ceiling in
config/.env. The sandbox-runner is the heavy one — it launches user code — so
its defaults are the largest:
| Service | CPUs | Memory |
|---|---|---|
codeapi-api | CODEAPI_API_CPUS (1.0) | CODEAPI_API_MEMORY (1024m) |
codeapi-service-worker | CODEAPI_WORKER_CPUS (1.0) | CODEAPI_WORKER_MEMORY (1024m) |
codeapi-sandbox-runner | CODEAPI_SANDBOX_CPUS (2.0) | CODEAPI_SANDBOX_MEMORY (3072m) |
codeapi-file-server | CODEAPI_FILE_CPUS (0.5) | CODEAPI_FILE_MEMORY (512m) |
codeapi-tool-call-server | CODEAPI_TOOLCALL_CPUS (0.3) | CODEAPI_TOOLCALL_MEMORY (384m) |
codeapi-egress-gateway | CODEAPI_EGRESS_CPUS (0.3) | CODEAPI_EGRESS_MEMORY (384m) |
codeapi needs a bigger host than LCI
These ceilings sum to well over the 4 GiB / 2 vCPU reference host. The sandbox in particular runs untrusted, memory-hungry code — size the VM accordingly (give the sandbox its own headroom).
Applying changes
After editing any CODEAPI_* value, recreate the affected service(s):
Updating the Code Interpreter
codeapi ships as six images, each with its own CODEAPI_*_IMAGE variable, so you
can update the whole code interpreter or a single service independently:
To roll back, restore the previous tag(s) and re-run the update. Use immutable tags so rollbacks stay unambiguous.
Last updated on