# Where should code nobody reviewed run?

> Where does code written by a model or a customer run, so it can't reach your credentials, your network or the next user's files? A sandbox is for code nobody on your team reviewed: code a model writes at runtime, or code a customer uploads. Reviewed code, even an agent's, runs in a normal Lambda, Worker or Fargate task. Unreviewed code must never run where your credentials live: a Lambda carries its role and environment variables, and its /tmp survives into the next invocation. Give each session its own walls (a container on Cloudflare Sandbox by default; a microVM on Lambda MicroVMs when the code must stay in Australia, reach a private VPC, use a bigger machine or keep its processes for hours) and put nothing secret inside: its traffic leaves through a proxy that adds the credentials, to the destinations it needs and no others.

- A concept by Nicolas Dao (Cloudless Labs, Sydney): the decision before the tool
- Area: [Security, access and residency](https://cloudlesslabs.com/concepts/areas/security/index.md)
- Last reviewed: 9 November 2026, by Nicolas Dao
- Web page: https://cloudlesslabs.com/concepts/sandboxing/

## What you'll be able to decide

Whether a piece of code needs a sandbox at all; when a container per session is enough and when it takes a microVM in your own AWS account; and why the sandbox must hold nothing secret, whatever its walls.

## In short

### The options

- **A. No sandbox: the code is reviewed:** Your team wrote it or reviewed it, even if an agent typed it, and it shipped through the tests. A Lambda, a Worker or a Fargate task does the job. Tools: [AWS Lambda](https://cloudlesslabs.com/stack/aws-lambda/index.md) (My default), [Cloudflare Workers](https://cloudlesslabs.com/stack/cloudflare-workers/index.md) (My default), [Fargate scheduled tasks](https://cloudlesslabs.com/stack/aws-fargate-scheduled-tasks/index.md) (Use when it fits).
- **B. A container per session:** Each session gets its own container, started and driven from a Worker, with a ready-made toolkit and billed on active CPU. My default for short bursts of code. Tools: [Cloudflare Sandbox](https://cloudlesslabs.com/stack/cloudflare-sandbox/index.md) (Use when it fits).
- **C. A microVM per session:** Each session gets its own Firecracker VM inside your AWS account: in Sydney, next to a private VPC, up to 16 vCPU, suspended with its memory intact. I'm watching it. Tools: [Lambda MicroVMs](https://cloudlesslabs.com/stack/aws-lambda-microvms/index.md) (Watching).
- **D. Nothing secret inside:** Whatever the walls, the sandbox holds no keys. Its traffic leaves through a proxy that adds the credentials per destination, and only to the destinations it needs. Tools: [Cloudflare Workers](https://cloudlesslabs.com/stack/cloudflare-workers/index.md) (My default).

### The rule of thumb

Code nobody reviewed must never run where your credentials live. Never put secrets inside the sandbox. From [Cloudflare Sandbox](https://cloudlesslabs.com/stack/cloudflare-sandbox/index.md).

### How the answer changes with scale

- **Only your team's code, reviewed, even when an agent wrote it:** No sandbox. A Lambda, a Worker or a Fargate task does the job.
- **Code nobody reviewed, in short bursts, in a product on Workers:** Cloudflare Sandbox: a container per session, nothing secret inside, destroyed when the user leaves.
- **The code or its data must stay in Australia, reach a private VPC, use more than 4 vCPU or 12 GiB, or keep its processes through sessions of hours:** Lambda MicroVMs in your AWS account in Sydney. It's on my watch list: I haven't run it in production.
- **One enterprise tenant needs Australia, and nobody else does:** Both: Sandbox for everyone else, MicroVMs for that tenant, if the tenant pays for the second runtime.

## The problem, in plain words

More and more products run code that nobody on the team has read. A model writes Python to answer a user's question; a customer uploads a script; a platform lets each client write its own rules. That code does exactly what it says, and nobody checked what it says. A model writes it from what the user typed and what it read along the way, and an email or a web page can carry instructions to the model.

So the question isn't whether the code is malicious. It's what the code could reach if it were. Run it inside your API's Lambda and it runs with that function's role and environment variables, next to whatever the last invocation left in `/tmp`. Everything the function can reach, the code can reach: your database, your keys, the previous user's file.

Three decisions follow, in this order. Does this code need a sandbox at all? If it does, what kind of walls? And what's left inside the walls for the code to take?

## The picture

The same idea three ways: reviewed code, unreviewed code in the wrong place, and unreviewed code in a sandbox with nothing in it.

**Diagram:** Three lanes. Code an agent wrote and the team reviewed runs in a normal Lambda, with no sandbox. Python a model wrote at runtime, run inside the API's own Lambda, can reach the function's role, its environment variables and what the last invocation left in /tmp. The same Python in a sandbox of its own holds no secrets: its traffic leaves through a proxy that adds the key for the destinations it may call, and the session is destroyed when the user leaves.

- **Reviewed code, no sandbox:** An agent writes the endpoint → The team reviews it, the tests pass → A normal Lambda, with its role. The line is the review, not who typed the code.
- **Code nobody reviewed, in the API's Lambda:** The model writes Python → It runs in the API's Lambda → [The function's role / Its environment variables / /tmp from the last invocation]. Everything the function can reach, the code can reach.
- **A sandbox per session, nothing secret inside:** The model writes Python → Its own container or microVM → A proxy adds the key, for allowed destinations only → Session destroyed. The walls keep the code in. The empty room leaves it nothing to take.

## The options

**No sandbox: the code is reviewed.** Who wrote the code? If it's your team, reviewed, you don't need a sandbox. An agent typing it doesn't change that: code that Claude Code writes on a laptop, that a person reviews and the tests pass before it ships, is your code. A [Lambda](https://cloudlesslabs.com/stack/aws-lambda/index.md), a [Worker](https://cloudlesslabs.com/stack/cloudflare-workers/index.md) or a [Fargate task](https://cloudlesslabs.com/stack/aws-fargate-scheduled-tasks/index.md) does the job. The line is the review, not the author. Code a model writes at runtime, which nobody sees before it runs, is on the other side of that line, however good the model.

**Don't harden a Lambda instead.** It's the tempting shortcut: trim the role, clear the variables, wipe `/tmp`. But a normal Lambda runs with its function's role and environment variables, and its `/tmp` survives into the next invocation; hardening it into a sandbox is a project in itself. Use a sandbox built for the job.

**A container per session.** [Cloudflare Sandbox](https://cloudlesslabs.com/stack/cloudflare-sandbox/index.md) gives each session its own container, driven from a Worker through an SDK: run commands, Python and JavaScript, read and write files, open a terminal, back the workspace up and restore it. It went GA in April 2026 and bills active CPU, so an agent waiting on a model costs almost nothing. Sizes go from 1/16 vCPU and 256 MiB up to 4 vCPU, 12 GiB and 20 GB of disk. Its limits are where the next option starts: containers offer only the `eu`, `us` and `fedramp` jurisdictions, so it can't be pinned to Australia; it has no direct route into a private VPC; and it's only partly in Pulumi (the image goes through wrangler, and a small custom provider takes about 3–5 days). It's "Use when it fits", and my default for this job. In one week of October, three more agent sandboxes launched. The category is crowded and young; Cloudflare Sandbox stays my pick.

**A microVM per session.** [Lambda MicroVMs](https://cloudlesslabs.com/stack/aws-lambda-microvms/index.md) launched in June 2026, and they've been in Sydney since 19 August 2026. Each session gets its own Firecracker VM inside your AWS account, reaching the public internet or your VPC through a network connector, from 1 vCPU and 2 GB up to 16 vCPU, 32 GB and 32 GB of disk. A session idle for a while suspends with its memory intact and resumes on the next request with its processes running, for up to 8 hours in all. The price of all that: there's no exec SDK, so you build the server inside yourself, it's Arm64 only, and the baseline is billed every second it runs. It's in Pulumi officially. I'm watching it rather than using it: I haven't run it in production.

**Nothing secret inside.** This isn't a fourth place to run code. It's what makes the other two worth having. The walls decide what the code can touch on the machine; the network decides what it can reach beyond it, and untrusted code can still try to reach your APIs or leak secrets through the network. Never put secrets inside the sandbox. On Cloudflare Sandbox, route its traffic through an outbound Worker, the egress proxy that injects credentials per destination so the code never sees them, and allow only the destinations it needs. It's the same move as [the LLM streaming proxy](https://cloudlesslabs.com/stack/guides/llm-proxy/index.md): a Worker holds the key, and the untrusted side never gets it. On Lambda MicroVMs, watch the snapshot: every MicroVM starts from the same one, so anything generated at initialisation (random IDs, open connections, temporary credentials) is cloned into every copy. Generate unique values and open connections after resume, and connect the VPC only to what the code needs.

## A concrete scenario

A Sydney company sells a reporting product on Workers. A user uploads a spreadsheet and asks which region's sales dropped; the model writes Python, runs it on the file and returns a chart. The Python also calls one outside service, an exchange-rate API with a paid key.

| | As first built | What the code could reach | The fix |
|---|---|---|---|
| Where the Python runs | Inside the API's own function | Its role and its environment variables | A Cloudflare Sandbox container per session |
| The uploaded file | In `/tmp`, which survives into the next invocation | The last user's spreadsheet | Only in that session's container, destroyed when the user leaves |
| The exchange-rate key | An environment variable the code can read | The key itself, to print or send anywhere | Outside the sandbox: the outbound Worker adds it for that one destination |
| The rest of the network | Open | Any address on the internet | Refused: only the destinations it needs |

Every session gets a timeout and is destroyed when the user leaves; if the user comes back, the workspace is restored from a backup. On the guide's worked case, 50,000 sessions a month of five minutes each (20 seconds of CPU) come to about $141, plus $5, on Sandbox, against about $525 on MicroVMs. That isn't the reason to pick it, but it doesn't argue against it either.

**In year two,** a large Australian client signs, and its contract keeps its data in Australia. A Cloudflare container can't be pinned there, so that tenant's sessions run on Lambda MicroVMs in Sydney, and everyone else stays on Sandbox. Two runtimes are two things to build and maintain, so the second one is worth it only if the tenant pays for it. And since MicroVMs are on my watch list, I'd tell the client that, and test them on their workload before promising anything.

## The trade-offs

| | No sandbox (reviewed code) | A container per session | A microVM per session |
|---|---|---|---|
| Fits | Code your team reviewed, whoever typed it | Short bursts of code nobody reviewed, in a product on Workers | Code nobody reviewed that must stay in Australia, reach a VPC, use a bigger machine or keep its processes for hours |
| What the code can touch | Everything the function can: its role, its variables, its `/tmp` | Its own container | Its own Firecracker VM |
| Where it runs | Wherever the app runs | Cloudflare's network: can't be pinned to Australia | Your AWS account, Sydney included |
| Biggest machine | The service's own limits | 4 vCPU, 12 GiB, 20 GB of disk | 16 vCPU, 32 GB, 32 GB of disk |
| What survives a pause | No sessions to keep | Files, through backup and restore | Memory, disk and running processes, up to 8 hours in all |
| Billing | The service's own | Active CPU, plus the memory and disk you provision while it runs | A baseline every second it runs, busy or idle |
| Nothing secret inside | Not needed: the code is yours | An outbound Worker adds the credentials per destination | Nothing created at initialisation; connect only what the code needs |
| In Pulumi | As the rest of the app | Partly: the image goes through wrangler | Official, in `@pulumi/aws` |
| My verdict | Lambda and Workers: my default | Use when it fits: my default for this job | Watching |
| What goes wrong | Unreviewed code slips into the same runtime | A session left running keeps costing | A key created at startup, cloned into every copy |

## The rule of thumb

**Ask who wrote the code before you ask where it runs.** If your team reviewed it, no sandbox. If nobody did, it must never run where your credentials live: one sandbox per session, a container on Cloudflare Sandbox by default, a microVM on Lambda MicroVMs when the code or its data must stay in Australia, reach a private VPC, use more than 4 vCPU or keep its processes through long sessions. Then put nothing secret inside: whatever the code calls, a proxy outside adds the key, and only for the destinations it needs.

## When the answer changes with scale

- **Only reviewed code:** no sandbox, at any size. A Lambda, a Worker or a Fargate task does the job.
- **Short bursts of code nobody reviewed, in a product on Workers:** Cloudflare Sandbox. The toolkit is already built, and for that pattern it's about 3.7 times cheaper than MicroVMs.
- **Australia, a private VPC, more than 4 vCPU or 12 GiB, or sessions of hours:** Lambda MicroVMs, in your account in Sydney. It's Watching: I haven't run it in production.
- **One tenant needs Australia:** both, Sandbox for everyone else and MicroVMs for that tenant, if the tenant pays for the second runtime. Not both in one product without a reason: two runtimes to build and maintain.
- **Untrusted files and binaries:** Lambda MicroVMs. Opening them deserves a full VM's isolation, inside the AWS account with the rest of the security tooling.
- **Government work under IRAP:** check with the client before choosing. Cloudflare's Australian assessment lists Workers, R2 and Durable Objects, not Containers (not confirmed), and MicroVMs aren't confirmed either: new AWS services take time to join the assessed list.

## Before you run a stranger's code

- **One session per user, destroyed when they leave.** Give every session a timeout and destroy it when the user leaves; restore the workspace from a backup if they come back. That way one user's files never reach the next.
- **Nothing secret in the image, the snapshot or the environment.** On MicroVMs, generate unique values and open connections after resume, never at initialisation.
- **Allow only the destinations the code needs,** and let a proxy outside the sandbox add the credentials for each.
- **Don't suspend a short session.** On MicroVMs, one suspend and resume of a 3 GB snapshot costs more than the session's compute: stop it when the session ends.
- **Build for arm64** if it's MicroVMs, and check that every native dependency has an arm64 build.

## Questions that change the answer

- Who wrote the code that will run? If it's your team, reviewed, you don't need a sandbox.
- If that code ran where your app runs, what could it reach: a role, environment variables, the last user's files?
- Must the code or the data stay in Australia, or reach a private VPC? Then it's Lambda MicroVMs.
- How long is a session, and must its running processes survive a pause? Seconds to minutes points to Sandbox, hours with a running dev server to MicroVMs.
- Which destinations does the code really need to call? Allow those, and nothing else.

Doesn't cover:

- Sandboxing the coding agent on your own machine: that's the [Claude Code](https://cloudlesslabs.com/stack/claude-code/index.md) entry (headless jobs in a dev container or VM, with /sandbox on) and the [Codex](https://cloudlesslabs.com/stack/openai-codex/index.md) entry (its workspace-write sandbox).
- What a model may do through its tools, and which actions wait for a person: that's [MCP servers](https://cloudlesslabs.com/stack/mcp-servers/index.md) and [How much freedom should an AI step get?](https://cloudlesslabs.com/concepts/ai-autonomy/index.md).

## Check your call

- **A team's coding agent writes a new API endpoint. A developer reviews the pull request, the tests pass, and it ships to Lambda.** No sandbox. The code is reviewed, so the agent that typed it doesn't matter: a normal Lambda does the job.
- **A SaaS product on Workers lets users ask questions about the spreadsheet they upload. The model writes Python, runs it on the file and returns a chart. Nothing has to stay in Australia.** Cloudflare Sandbox: a container per session, nothing secret inside, outbound traffic only to the destinations the code needs, and the session destroyed when the user leaves.
- **A startup wants to run that same Python inside its existing API Lambda, with the function's IAM role trimmed down.** Don't. The code still runs with the function's role and environment variables, and /tmp survives into the next invocation, so this user's file can still be there when the next user's code runs. Hardening a Lambda into a sandbox is a project in itself: use Cloudflare Sandbox or Lambda MicroVMs.
- **An IoT platform lets each client write its own alert rules, which run on that client's sensor data in the platform's private Postgres. The contracts keep the data in Australia.** Lambda MicroVMs in Sydney, with a network connector into the VPC: a Cloudflare container can't be pinned to Australia and has no direct route into a private VPC. It's on my watch list, so say so to the client and test it on their workload before promising it.
- **A security product opens suspicious documents and binaries that customers upload.** Lambda MicroVMs: untrusted files deserve a full VM's isolation, inside the AWS account with the rest of the security tooling.

## The technology on this site

- [Cloudflare Sandbox or Lambda MicroVMs?](https://cloudlesslabs.com/stack/guides/sandbox-or-microvms/index.md): the decision guide
- [The LLM streaming proxy](https://cloudlesslabs.com/stack/guides/llm-proxy/index.md): the decision guide
- [AI that runs the code it writes](https://cloudlesslabs.com/stack/use-cases/ai-code/index.md): the use case

## Thoughts on it

- [Stop building software. Build the software factory that builds it.](https://cloudlesslabs.com/thoughts/software-factory-philosophy/index.md), 11 November 2026: A software factory is the environment you build for your coding agents. For me, it's the new software development lifecycle, automated and constrained, from the moment a request arrives until its business outcome is met. Here's how Matt Pocock, Lauren Tan and StrongDM define it, and how I'm building mine.

## Related

- [Where may the data go?](https://cloudlesslabs.com/concepts/data-residency/index.md): read next
- [How much freedom should an AI step get?](https://cloudlesslabs.com/concepts/ai-autonomy/index.md): read next
- [Pay for the work, or pay to be ready?](https://cloudlesslabs.com/concepts/pay-to-be-ready/index.md): read next
- [One AWS account, or many?](https://cloudlesslabs.com/concepts/accounts-as-walls/index.md): the decision after it
- [Security, access and residency](https://cloudlesslabs.com/concepts/areas/security/index.md): the area, and the technology for each answer
- [Every concept](https://cloudlesslabs.com/concepts/index.md)
- [Map of every Markdown file on cloudlesslabs.com, with what each one answers](https://ask.cloudlesslabs.com)
