So you want to run untrusted code?

Congrats, you just purchased a brand new domain name for your enterprising SaaS startup. Overnight you came up with the brilliant idea to start a company that runs other people’s code as a business. I applaud you on your originality. The only problem is… how are you going to do it securely?

Fortunately for you, I've spent a little bit of time (read: a few hours) over the last couple of days reading about how other people run other other people’s code . Let’s see what your options are in 2025.

Outline

Virtual Machines

Ah yes, good ol’ virtual machines. A tried-and-true method. The stable work horse of running code securely. They’re slow to start, resource intensive, but pretty darn secure — sort of like a Tank class in your favorite game.

Containers

This is a really popular way to run other people’s code. The focus of my reading was not on this due to it’s ubiquity. Running containers securely seems like mostly a solved problem. Probably analagous to a standard DPS class — faster than a tank, less resource intensive, pretty secure, not especially skilled in any one area. Moving on…

V8 Isolates

Now we’re getting into some interesting territory. V8 is Google’s JavaScript and Wasm engine. My understanding is that every Chrome tab runs in its own isolate. Isolates have also become a popular way to run untrusted code, particularly because they have a much lower overhead than virtual machine and start faster (~5 ms cold start).

Isolate represents an isolated instance of the V8 engine. V8 isolates have completely separate states.

To force continuing the character-class metaphor, isolates are kind of like a Mage class — their ability to raise a billion low-health skeletons to to fight is pretty impressive.

Deno Deploy

Deno Deploy runs “serverless” JavaScript for its customers. It uses isolates to run its deployments. Deno Deploy runs each isolate in it’s own process for added security. It also runs the isolates with Deno (not surprsising given the name).

Cloudflare Workers

Cloudflare Workers also runs “serverless” code for its customers. They support more languages than just JavaScript. Cloudflare has also open sourced it’s server runtime, workerd. Workers also use isolates, sometimes in separate processes. Cloudflare only runs isolates in the same processe because each process requires more resources and they want to keep costs low for customers. They’ll run an isolate in its own process when it looks suss. They also run every worker on every node. How’s that for distributed computing?

Sometimes, though, we do decide to schedule a worker in its own private process. We do this if it uses certain features that we feel need an extra layer of isolation.

Defense-in-Depth

Something that both Deno Deploy and Cloudflare Workers make mention of is the concept “defense-in-depth”. Defense-in-depth means having multiple layers of security against would-be attackers. In practice, this means not just using isolates, but also using namespaces, cgroups, and seccomp (the last of which I had never heard of before).

Deno

Deno is a JavaScript/TypeScript runtime. Deno by itself has some cool security features. By default it disables file system access, network connectivity, and more. We already mentioned Deno above, but there is one more product that uses Deno that is worth mentioning.

Val Town

Val Town is a “collaborative website to write and deploy TypeScript”. Val Town has had a interesting evolution, from briefly using Node.js with it’s vm/vm2 modules, to using just Deno, to using Node+Deno. As of February 2024, Val Town runs customer’s code in Deno as a subprocesses of a Node server using node-deno-vm, a Node→Deno virtual machine module.

microVMs

Alas, we’ve come full circle. Everthing that is old is new again, and so VMs have resurfaced. microVMs are virtual machines that are purpose-built for running workloads securely with a smaller footprint than a traditional VM. Their cold boot time is in the range of 200–300 ms. I believe the term “microVM” was coined by AWS, the creators of Firecracker.

Firecracker was created by AWS for use with AWS Lambda and Fargate. Firecracker microVMs use the “Linux Kernel-based Virtual Machine” (KVM… no, not that KVM). I’m not very familar with KVM, nor QEMU, which Firecracker is compared to. microVMs are like a Rogue class — they’re small but pack a punch.

Firecracker is also used by cool new companies like…

Fly.io

Fly.io’s excellent blog is where I first read about Firecracker. Honestly, just go read these two posts from them on how they’re using it. The first link is a much better version of this article.

WebAssembly (Wasm)

Running Wasm in the cloud is a thing. I’ve never done it and don’t know much about it. Smarter people than me have written about it.

Summary

So you came here expecting some insightful synopsis or a spicy hot-take? Well, based on my extreme expertise (read again: hours of reading /s), I would suggest one of two approaches, depending on your scenario:

I know, shocking conclusions I came to, eh? Thanks for making it this far. You’ve earned a screenshot of @mrkurt1 replying to a Hacker News post about V8 isolates, with a response from @kentonv2:

and a fancy product comparison table:

Method Processes Other Security Language
Deno Deploy Isolates + Deno Always separate Hypervisor resource monitoring (WatchDog), namespaces, seccomp, cgroups Rust 🦀
Cloudflare Workers Isolates Sometimes separate "cordons" (multiple runtime instances), namespaces, seccomp, no network access (only Unix sockets) C++?
Val Town Deno Subprocesses + VM Deno VM wrapper, cgroups? TypeScript/Rust?
Fly.io Firecracker …it’s a VM ? Rust
wasmCloud Wasm ¯\_(ツ)_/¯

Resources