Skip to main content
isol8 provides a unified execution engine accessible through three interfaces: a CLI for local development, a TypeScript Library for application integration, and an HTTP API for remote services.

Execution Lifecycle

Every execution request follows a strict pipeline to ensure security and isolation.

Pipeline Overview

In ephemeral mode, simple requests can skip file injection and execute inline (for example python -c, node -e, bun -e, bash -c) when no stdin, files, outputPaths, or package installs are requested. The agent runtime always uses file injection and passes the code as a prompt to the pi coding agent.

Execution Modes

isol8 supports two execution modes, determined by your use case.
ModeBehaviorBest For
Ephemeral (Default)Creates a fresh container for every request. State is lost after execution.stateless tasks, untrusted code, parallel workloads
PersistentReuses a single container across multiple requests. Files and state are preserved.interactive sessions, multi-step workflows, notebooks

Selecting a Mode

Use the --persistent flag to enable persistent mode.
# Ephemeral (Default)
isol8 run script.py

# Persistent (Keeps container alive)
isol8 run --persistent script.py
In CLI persistent mode, the container is tied to the CLI process. To reuse a persistent container across multiple CLI commands, you would need to use the API or Library.

Inputs & Outputs

You can pass code, environment variables, and files into the sandbox.

1. Source Code

The core of every request.
Pass a file path, an inline string, or pipe from stdin.
# File
isol8 run script.py

# Inline
isol8 run -e "print('Hello')" --runtime python

# Stdin
echo "print('Piped')" | isol8 run --runtime python

1.1 Remote Code URLs

isol8 can fetch source code from a URL before execution.
code and codeUrl are mutually exclusive. Provide only one per request.
Remote URL execution is controlled by:
  • request fields: codeUrl, codeHash, allowInsecureCodeUrl
  • CLI flags: --url, --github, --gist, --hash, --allow-insecure-code-url
  • config policy: remoteCode.* in isol8.config.json
# Direct URL
isol8 run --url https://raw.githubusercontent.com/user/repo/main/script.py --runtime python

# GitHub shorthand
isol8 run --github user/repo/main/script.py --runtime python

# Gist shorthand
isol8 run --gist abcd1234/example.js --runtime node

# Integrity verification
isol8 run --url https://example.com/script.py --hash <sha256> --runtime python
URL fetching is disabled by default. Enable and tune remoteCode policy in config first. For full policy fields and security guidance, see Remote code URLs.

2. Environment Variables

Inject configuration or secrets.
Security Note: Environment variables are visible to the running process. For sensitive data, use the “Secrets” feature to ensure values are masked in logs and output.
The CLI only supports Secrets via --secret. These are injected as environment variables but their values are masked in stdout/stderr.
isol8 run script.py --secret API_KEY=sk_12345

3. Files

Inject files before execution and retrieve them after.
The CLI supports file injection for the agent runtime via --files <dir>, which recursively copies a local directory into /sandbox. For other runtimes, use the Library or API for generic file injection (files) or retrieval (outputPaths). All runtimes support --out to capture stdout to a file.
# Capture stdout to file
isol8 run script.py --out result.txt

# Inject project files for agent runtime
isol8 run -e "add tests" --runtime agent \
  --files ./my-project \
  --net filtered --allow "api.anthropic.com" \
  --secret "ANTHROPIC_API_KEY=sk-..."

Streaming Output

Real-time output is essential for long-running tasks or LLM code generation.
Streaming is enabled by default. Use --no-stream to wait for completion.
# Streams output as it appears
isol8 run long_task.py

# Waits until finished, then prints all output
isol8 run long_task.py --no-stream
When using RemoteIsol8, executeStream() automatically selects the best available transport: WebSocket (/execute/ws) with automatic SSE (/execute/stream) fallback. See the WebSocket endpoint reference for protocol details.

StreamEvent reference

Each value yielded by executeStream is a StreamEvent:
FieldTypeDescription
type"stdout" | "stderr" | "exit" | "error"Event kind. exit carries the process exit code as a string in data.
datastringPayload: output text for stdout/stderr, exit code string for exit, error message for error.
phase"setup" | "code"Which stage produced the event. "setup" = from a setupScript; "code" = from the main code/command. Always set by isol8.
Use phase to distinguish setupScript output from main code output when both are present:
for await (const event of engine.executeStream({
  runtime: "bash",
  setupScript: "git clone https://$GITHUB_TOKEN@github.com/my-org/repo.git /sandbox/repo",
  code: "ls /sandbox/repo",
})) {
  if (event.phase === "setup") {
    process.stderr.write(`[setup] ${event.data}`);
  } else if (event.type === "stdout") {
    process.stdout.write(event.data);
  }
}
If a setupScript exits non-zero, executeStream yields an error event then an exit event (both with phase: "setup") and stops — no phase: "code" events follow. See Setup scripts for full details.

Resource Limits & Safety

isol8 enforces strict limits to contain untrusted code.
ParameterCLI FlagLibrary OptionDefaultDescription
Timeout--timeouttimeoutMs30sHard execution time limit.
Memory--memorymemoryLimit512mRAM limit for the container.
CPU--cpucpuLimit1.0CPU shares (1.0 = 1 core).
Network--netnetworknonenone, host, or filtered.
Output--max-outputmaxOutputSize1MBMax stdout/stderr size before truncation.

Output Truncation

If a script produces excessive output, isol8 truncates it to prevent memory issues.
  • result.truncated will be true.
  • The output will end with a truncation message.

Secret Masking

If you provide secrets (via CLI --secret or Library config), isol8 scans stdout and stderr and replaces occurrences of secret values with ***.
# Input
isol8 run -e "print('my-secret-value')" --secret KEY=my-secret-value

# Output
***

Troubleshooting

The code ran longer than timeoutMs.
  • Fix: Increase limit via --timeout or optimize the code.
  • Note: Infinite loops are a common cause.
The script printed more data than maxOutputSize allowed.
  • Fix: Reduce logging or increase the limit via --max-output.
Remember that the code runs in an isolated container.
  • It cannot see files on your host machine unless you explicitly inject them (Library/API).
  • CLI users should pipe data via stdin or use inline strings for simple inputs.

FAQ

Use request.timeoutMs when you want a per-execution timeout. Use options.timeoutMs as a baseline engine default for a client/session.
Use codeUrl for pinned remote artifacts (for example immutable GitHub raw URLs). Keep code for direct inline or generated source. Never set both in one request.
CLI runs are process-scoped. For durable cross-call state, use a stable sessionId through the API or RemoteIsol8.

Option mapping

Exact option mapping across CLI, config, API, and library.

Runtime reference

Runtime-specific behavior, extensions, and package semantics.

Setup scripts

Run shell commands before execution — streaming output, phase events, and early-exit on failure.

Remote code URLs

URL-based source fetching policy and integrity controls.

Troubleshooting

Symptom-based fixes for execution and session issues.