AI Sandbox Guide: Code Isolation, Runtime Selection, and Cost Benchmarks

AI sandboxes limit agent code access boundaries through isolation, but credentials, networking, and lifecycle management still require application-layer oversight.
AI sandboxes provide an isolated environment for agent code execution, limiting what it can touch—the host, other users' data, credentials, and external services. The article covers isolation principles, runtime selection, security boundaries, and cost estimation: Docker shares the host kernel via namespaces and cgroups, gVisor intercepts syscalls in user space, and Firecracker offers the strongest isolation with an independent guest kernel. However, isolation only limits impact scope; credential management, egress control, and output validation remain application-layer responsibilities. Sandboxes bill by runtime including idle time, so lifecycle management and cleanup can affect total cost far more than hourly rate differences.
Title
AI Sandbox Guide: Code Isolation, Runtime Selection, and Cost Benchmarks
Meta Description
A deep dive into AI sandbox isolation principles and runtime selection: comparing the security boundaries of Docker, gVisor, and Firecracker, with a Lizard SDK code execution example and cost benchmarks to help developers choose the right AI code execution solution.
Article Content
AI agents are moving from conversation to execution—writing code, installing dependencies, running tests, starting services. But running model-generated code directly on your server is like handing the keys to a stranger. The AI sandbox exists precisely to solve this problem: it provides an isolated environment where agents can execute code while limiting what they can touch—the host machine, other users' data, credentials, and external services.
This article is based on the AI sandbox technical guide released by the Lizard team, offering an actionable reference framework covering isolation principles, runtime selection, security boundaries, and cost estimation.

What Is an AI Sandbox
In agent applications, the model proposes action suggestions, and the application decides where and how to execute them. The sandbox is the "computer" provided for actions that require code execution. The model might write a Python script, edit a code repository, or launch a web application—all of these operations happen inside the sandbox.
The design requirements for a sandbox go far beyond "give each user a folder." A practical sandbox runtime needs to provide: process isolation, file isolation, CPU and memory limits, and a way for the application to abort tasks at any time. Credential management, network access, and persistent storage each require their own rules.
A typical example: when an agent needs to analyze a user-uploaded CSV file, it should only get that file and enough compute resources to process it. It has no reason to read the web server's environment variables or another customer's uploaded files.
Sandbox Execution Flow
A complete sandbox request typically follows this path:
- The backend receives the task and asks the model to generate code or tool calls
- The backend creates a sandbox and copies the files needed for the task into it
- The sandbox executes the code, and the backend collects stdout, stderr, files, and exit codes
- The backend validates the results, then decides whether to show them to the user or pass them to other services
- The backend saves the necessary output and stops the sandbox
The most error-prone part of this flow is secret management. Model provider API Keys and sandbox management keys must remain in the backend and must never be passed into the sandbox. If generated code gains access to a management key, it can provision more resources under your account.
Programming sessions typically need the same sandbox to stay alive across multiple turns, while one-off computations can create a fresh sandbox for each task. Before introducing sandbox reuse, first determine how long state should be retained and which user it belongs to.
Isolation Boundaries: Docker vs. gVisor vs. Firecracker
When choosing a sandbox runtime, the core question is where the isolation boundary lies. Three mainstream approaches represent different security models:
| Approach | Isolation Boundary | What to Focus On |
|---|---|---|
| Standard Docker containers | Linux namespaces and resource controls separate processes; containers share the host kernel | Capability configuration, privileged mode, host mounts, daemon access, host patches |
| gVisor | A user-space application kernel handles syscalls, reducing direct exposure to the host kernel | Syscall compatibility and workload performance |
| Firecracker microVM | A VM with its own guest kernel, hardware virtualization via KVM | Guest and host patches, network policies, mounted data, lifecycle control |
Docker suits workloads with a known trust level and a strictly reviewed host configuration. Its security depends on how you run it—exposing the Docker socket or broadly mounting host directories completely changes what the workload can control.
gVisor adds a user-space kernel boundary at the cost of syscall compatibility trade-offs. Firecracker uses a small virtual machine monitor and a restricted device model to provide stronger isolation. Neither approach replaces protecting secrets and restricting access to sensitive services.
One detail worth noting: Lizard Sandboxes use Firecracker by default, but legacy volumes or snapshots—and fallback scenarios after a Firecracker startup failure—may use a container runtime. If your application requires a microVM specifically, check getInfo().runtime to confirm the actual runtime type.
Linux namespaces and container isolation: The two major Linux kernel mechanisms Docker relies on are namespaces and cgroups. Namespaces govern "what you can see"—the PID namespace makes processes inside the container see only their own process tree, the mount namespace isolates filesystem mount points, the network namespace isolates network interfaces, and the user namespace can map root inside the container to an unprivileged user on the host. Cgroups govern "how much you can use"—limiting CPU quotas, memory ceilings, and I/O bandwidth. The key point is that these mechanisms are all provided uniformly by the host kernel, and when a process inside the container issues a syscall, it is ultimately still handled by that same host kernel. Therefore, if the kernel itself has a vulnerability, or if the container is granted extra capabilities like --privileged or --cap-add, the isolation boundary can be breached. This is the fundamental reason gVisor and Firecracker exist: the former intercepts syscalls with a user-space implementation, while the latter uses hardware virtualization to give the guest its own kernel.
Syscall compatibility: gVisor works by reimplementing an "application kernel" in user space to respond to syscalls issued by the container, rather than letting them enter the host kernel directly. While this provides stronger isolation, it also means not all syscalls can be fully and correctly emulated. Linux has hundreds of syscalls with varying semantics, and obscure calls, newly introduced calls, and programs that depend on specific kernel behaviors may behave abnormally or suffer performance degradation under gVisor. Typical affected scenarios in practice include: high-performance I/O that heavily relies on io_uring, some ptrace debugging features, and certain container runtimes that require fine-grained kernel features. Therefore, when selecting a runtime, you should not rely solely on "gVisor is more secure"—instead, run your real workload through it, observe whether any syscalls are rejected and whether latency is acceptable, and then decide whether the isolation strength is worth the compatibility cost.
What Isolation Can and Cannot Protect
A sandbox limits the impact scope of code execution, but the application itself still needs to decide which actions users or agents may perform.
Credentials and Network Access
Anything copied into the sandbox becomes visible to the workload with whatever permissions you grant. Do not copy entire .env files, SSH directories, or cloud service credentials. If a task needs to call an external API, give it a short-lived, narrowly scoped credential, or proxy each request through a backend tool and validate them one by one.
Isolation does not mean the network is locked down. If code can read secrets and make external requests, it may send those secrets elsewhere. You need to choose a solution and configuration that meets your outbound network requirements, and do not assume a network allowlist is guaranteed to exist.
Least-privilege credentials: Credentials given to a sandbox should satisfy three constraints—as narrow a scope as possible, as short a lifetime as possible, and individually revocable. Specific practices include: not using long-lived account-level or project-level API Keys, but instead issuing a temporary token for the task that only allows access to specific resources; in cloud environments, preferring STS or short-term session credentials over permanent Access Keys; and passing secrets through injected environment variables or ephemeral mounts rather than writing them into files that will be persisted. A more thorough approach is to not hand credentials to the sandbox at all—let the sandbox send external requests back to the backend, which holds the credentials, makes the calls on its behalf, and validates each request's legitimacy. In this way, even if the code inside the sandbox is hijacked by malicious code, it cannot directly steal the credentials because it never sees them in the first place.
Egress control: Controlling outbound traffic is a key part of preventing data exfiltration, but its effectiveness depends on the implementation layer. Application-layer allowlists (such as only allowing access to specific domains) rely on DNS resolution and proxy configuration and are easy to bypass; network-layer firewalls or security group rules intercept at a lower level and are harder to circumvent. Note that many sandbox solutions do not restrict outbound traffic by default—code can connect directly to any external address. Therefore, if a task involves sensitive data, you should configure explicit egress rules at the sandbox infrastructure level, permitting only the endpoints the task requires, and remain vigilant about DNS queries, non-standard ports, and direct IP connections.
User and Stored Files
Every sandbox should be bound to an authenticated user or task. Check ownership every time code is executed, a file is downloaded, or a session is reopened. A guessed sandbox ID should not grant any access.
Persistent files also need per-user isolation. Even if every execution uses a fresh virtual machine, if a writable workspace is reused across different customers, data can still leak.
Timeout Limits and Returned Output
Execution timeouts and sandbox lifetimes are two independent control points. A client-side timeout only stops waiting; it does not stop the remote process. Server-side expiration policies and cleanup mechanisms are what handle different failure scenarios.
Returned files and text should be treated as untrusted input. Validate JSON against the structure your application expects, escape text when rendering, and avoid deploying generated HTML on the same domain as your account dashboard.
For agent workflows that skip interactive approval, these controls must be in place before the first command executes.
Hands-On: Running a Python Task in a Sandbox
The Lizard example uses Node.js as the backend controller to run Python inside a sandbox. Below is a minimal runnable example that performs a fixed computation to verify the execution path without calling an LLM.
It requires Node.js 22 or higher, a Lizard project, and an API Key. Set LIZARD_API_KEY and LIZARD_PROJECT_ID in the backend environment; neither should appear in browser code.
The core logic is as follows: create sandbox → check runtime to confirm Firecracker → write the Python script → execute as the specified user → validate exit code and output size → parse and validate the JSON structure → clean up the sandbox in a finally block.
On October 17, 2026, the Lizard team actually ran this script using the codex template and Node.js 22.23.2: it created a Small Firecracker sandbox from the base template, ran Python as user, output { total: 25 }, and exited with code 0 after cleanup. The API Key was always read in the backend controller's environment and was never passed into the sandbox that executed the Python.
There are several notable design decisions in the example: executing Python with an argument array avoids shell interpolation; a 30-second command timeout limits client wait time; a two-minute sandbox lifetime is a separate expiration control; and the finally block ensures cleanup is requested even if output validation fails.
To turn this example into an agent tool, simply replace the fixed script with model-returned code and define a result schema for the task. Authorization, resource limits, and output validation stay in the backend. A successful exit code does not prove the answer is correct.
Typical Use Cases
Data analysis: Process user-uploaded files, run Python, and return charts or small JSON results. Limit file size and execution time, and retain only the output the user needs.
Coding agents: Check out a task-specific copy of the code repository, edit files, and run tests. Review diffs and test results before a separate process merges or deploys the changes.
App builders: Install dependencies, start a development server, and provide a private preview. The preview environment needs to remain isolated from your dashboard domain and authentication system.
Browser agents: When a task requires UI interaction, use a runtime with a browser and desktop environment. Any logged-in session should be treated as a credential that grants access to that account.
Cost Structure and Estimation
The starting point for AI sandbox cost calculation is total runtime—including idle time between commands. Then add storage, model calls, and other service fees.
Lizard's public pricing (as of October 17, 2026) is billed by the second, and sandbox runtime including idle time is all billed. Small (2 vCPU / 4 GB) is $0.0162 per hour, Medium (4 vCPU / 8 GB) is $0.0324 per hour, and Large (8 vCPU / 16 GB) is $0.0648 per hour. The Pro subscription is $19/month, includes $19 of usage credits, and bills overage on demand. Persistent volumes are $0.14/GB/month.
An intuitive calculation: 1,000 Small tasks, each running for 5 minutes, cost 1,000 × (5/60) × $0.0162 = $1.35. That number itself looks very low, but if each sandbox runs an extra hour after the task ends before it is cleaned up, the extra cost reaches $16.20—12 times normal usage.
This comparison reveals an underappreciated fact: explicit lifecycle management and reliable cleanup mechanisms can have a far greater impact on cost than small differences in hourly rates.
Selection Checklist
Before settling on a sandbox solution, test it with real user tasks. A simple shell command does not reflect the behavior of a repository build or a browser session. Record startup time, dependency installation time, total task time, failure count, and total runtime seconds, and pay attention to both medians and slowest requests.
The following questions can serve as a selection framework:
- What isolates code and files between different customers?
- Which secrets and external services can generated code reach?
- Does the runtime support the languages, packages, and browser tools the task requires?
- What happens when the controller crashes or the connection drops?
- Which files persist after shutdown, and how are they backed up?
- After adding idle time, storage, and model calls, what is the cost of the full workload?
It is recommended to start with a single task, an ephemeral sandbox, and a validated small result. After measuring how this flow actually performs, gradually introduce persistence or longer sessions as your application requires.
One-line Summary
AI sandboxes limit the access boundaries of agent code through isolation, but credentials, networking, and lifecycle management still require application-layer oversight.
Paragraph Summary
AI sandboxes provide an isolated environment for agents to execute code, with the core goal of limiting what they can touch—the host machine, other users' data, credentials, and external services. The article lays out a complete framework from isolation principles to runtime selection, security boundaries, and cost estimation: Docker relies on namespaces and cgroups sharing the host kernel, gVisor intercepts syscalls with a user-space kernel, and Firecracker provides the strongest isolation with an independent guest kernel; but isolation itself only limits the scope of impact, while credential management, egress control, and output validation still need to be implemented at the application layer. On cost, sandboxes are billed by runtime (including idle time), and explicit lifecycle management and cleanup mechanisms can affect total cost far more than differences in hourly rates. Selection should be based on testing with real user tasks, focusing on startup time, failure rates, and full workload cost.
Related articles

Chain of Thought Isn't Just for AI: How Humans Can Use CoT to Improve Thinking Quality
Chain of Thought isn't just a prompt trick for large models. Starting from a Hacker News discussion, this article analyzes why CoT works for human thinking too, breaks down actionable ways to transfer it, and highlights the key differences between human CoT and machine CoT.
Cloudflare Teams Up with OpenAI: Closi…
Cloudflare Teams Up with OpenAI: Closing the Loop from Vulnerability Discovery to Defense with AI
Cloudflare uses OpenAI Daybreak to investigate security vulnerabilities and generate reviewable remediation plans, while developers use Codex to boost coding efficiency and quality.

Orca Multi-Agent Orchestration in Practice: A Guide to Parallel Collaboration with Claude and Codex
Orca is Stable AI's free open-source agent workbench supporting 34 agents like Claude Code and Codex in parallel. Learn its Git worktree isolation, multi-model orchestration, and mobile management.