<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Weston Carnes</title>
    <description>The latest articles on DEV Community by Weston Carnes (@weston_carnes_d580b505e0c).</description>
    <link>https://dev.to/weston_carnes_d580b505e0c</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4048649%2Fc92f4e1d-7fd9-4fbb-a25e-d51a9a06f6b7.png</url>
      <title>DEV Community: Weston Carnes</title>
      <link>https://dev.to/weston_carnes_d580b505e0c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/weston_carnes_d580b505e0c"/>
    <language>en</language>
    <item>
      <title>How to safely run AI-generated code — a practical sandboxing checklist</title>
      <dc:creator>Weston Carnes</dc:creator>
      <pubDate>Wed, 29 Jul 2026 03:31:14 +0000</pubDate>
      <link>https://dev.to/weston_carnes_d580b505e0c/how-to-safely-run-ai-generated-code-a-practical-sandboxing-checklist-19hf</link>
      <guid>https://dev.to/weston_carnes_d580b505e0c/how-to-safely-run-ai-generated-code-a-practical-sandboxing-checklist-19hf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cross-post. Original: &lt;strong&gt;&lt;a href="https://www.stellarbytecapital.com/blog/how-to-run-ai-generated-code-safely/" rel="noopener noreferrer"&gt;stellarbytecapital.com/blog/how-to-run-ai-generated-code-safely&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you're building an AI agent, sooner or later it will write code and you'll have to &lt;em&gt;run&lt;/em&gt; that code. The moment you do, you're executing something no human reviewed against your infrastructure. This is a practical checklist for doing that safely — the controls we use in production, in the order they matter.&lt;/p&gt;

&lt;p&gt;The short version: &lt;strong&gt;treat every piece of AI-generated code as hostile, and design so that even a full compromise of the runtime buys the attacker nothing.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  First, the threat model
&lt;/h2&gt;

&lt;p&gt;Before controls, be honest about what can go wrong when you run untrusted code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It reads or exfiltrates data belonging to other users on the same host.&lt;/li&gt;
&lt;li&gt;It reaches out to the network to leak data or pull a payload.&lt;/li&gt;
&lt;li&gt;It leaves state behind — temp files, mutated env, background threads — that corrupts the &lt;em&gt;next&lt;/em&gt; run.&lt;/li&gt;
&lt;li&gt;It exhausts CPU, memory, or disk and takes down the shared service.&lt;/li&gt;
&lt;li&gt;It escapes the sandbox entirely via a kernel or runtime bug.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;"The model probably won't do that" is not a control. Design for the case where it does.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core pattern: one disposable sandbox per execution
&lt;/h2&gt;

&lt;p&gt;The single highest-leverage decision: &lt;strong&gt;run every execution in its own fresh sandbox, and destroy it after the run. Never reuse.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reuse is where most bugs and attacks live — leaked file descriptors, leftover temp files, mutated globals, a background thread from the last run. If nothing is ever reused, that entire class of problems disappears. To keep it fast, keep a &lt;em&gt;warm pool&lt;/em&gt; of ready sandboxes and backfill each one as it's consumed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The checklist
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Isolation boundary&lt;/strong&gt; — use a real boundary, not a language-level "safe eval." A container is the baseline; a microVM (&lt;code&gt;gVisor&lt;/code&gt;, &lt;code&gt;Firecracker&lt;/code&gt;) is stronger against kernel escapes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network egress: default-deny&lt;/strong&gt; — no outbound network by default. An escaped agent that can't reach the internet has nowhere to send data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filesystem: read-only + ephemeral&lt;/strong&gt; — mount inputs read-only; give a scratch space that dies with the sandbox.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource limits&lt;/strong&gt; — cap CPU, memory, PIDs, and wall-clock time per execution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-user quotas&lt;/strong&gt; — cap executions per user per window; stops abuse and runaway loops.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Least privilege&lt;/strong&gt; — non-root, dropped capabilities, no Docker socket, no host devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets stay out&lt;/strong&gt; — never mount API keys into a sandbox running generated code; proxy authenticated calls through a trusted layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit everything&lt;/strong&gt; — emit an event for every lifecycle step and every network call.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Reusing a long-lived interpreter to save startup time — you trade milliseconds for a permanent state-leak surface.&lt;/li&gt;
&lt;li&gt;Allowing full network egress "because the task might need it." Default-deny, then allowlist.&lt;/li&gt;
&lt;li&gt;Trusting the model to stay in scope. Sandbox behavior, don't prompt for it.&lt;/li&gt;
&lt;li&gt;Running as root inside the container because it was easier during development.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Container or microVM?
&lt;/h2&gt;

&lt;p&gt;For most internal tools, a hardened one-shot container with default-deny egress is a reasonable baseline. If you're multi-tenant or running adversarial code, step up to &lt;code&gt;gVisor&lt;/code&gt; or &lt;code&gt;Firecracker&lt;/code&gt; — stronger isolation, still cheap with a warm pool.&lt;/p&gt;

&lt;p&gt;The point is the &lt;em&gt;combination&lt;/em&gt;: disposable sandboxes, no egress, read-only filesystem, capped resources, quotas, least privilege, no secrets, full auditing.&lt;/p&gt;




&lt;p&gt;We're &lt;strong&gt;Xingyao Byte&lt;/strong&gt; — building secure AI-execution layers, quant trading systems, and payment platforms. Remote, async-first → &lt;strong&gt;&lt;a href="https://www.stellarbytecapital.com/" rel="noopener noreferrer"&gt;stellarbytecapital.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>devops</category>
      <category>docker</category>
    </item>
    <item>
      <title>gVisor vs Firecracker vs Docker for AI code sandboxes</title>
      <dc:creator>Weston Carnes</dc:creator>
      <pubDate>Wed, 29 Jul 2026 03:27:56 +0000</pubDate>
      <link>https://dev.to/weston_carnes_d580b505e0c/gvisor-vs-firecracker-vs-docker-for-ai-code-sandboxes-4m2d</link>
      <guid>https://dev.to/weston_carnes_d580b505e0c/gvisor-vs-firecracker-vs-docker-for-ai-code-sandboxes-4m2d</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is a cross-post. Original on our site: &lt;strong&gt;&lt;a href="https://www.stellarbytecapital.com/blog/gvisor-firecracker-docker-ai-sandbox/" rel="noopener noreferrer"&gt;stellarbytecapital.com/blog/gvisor-firecracker-docker-ai-sandbox&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once you've decided to run AI-generated code in a sandbox, the next question is &lt;em&gt;which sandbox&lt;/em&gt;. The three names you'll keep hitting are Docker, gVisor, and Firecracker. They're not competing products so much as three different strengths of boundary — and picking the wrong one either leaves you exposed or costs you performance you didn't need to spend.&lt;/p&gt;

&lt;p&gt;Here's how they actually differ, and how to choose.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one thing that separates them: where the boundary is
&lt;/h2&gt;

&lt;p&gt;All three isolate code, but at different layers — and that layer determines how hard the boundary is to break:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker (runc)&lt;/strong&gt; — standard containers. Isolation comes from Linux namespaces, cgroups, and seccomp. The container &lt;em&gt;shares the host kernel&lt;/em&gt;. Fast and universal, but a kernel exploit crosses the boundary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gVisor (runsc)&lt;/strong&gt; — a user-space kernel from Google. It intercepts the container's syscalls and services them in a sandboxed process instead of passing them straight to the host kernel. That's a second wall between the code and the real kernel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firecracker&lt;/strong&gt; — a microVM built on KVM hardware virtualization. Each sandbox is a real (tiny) virtual machine with its own guest kernel, booting in ~125ms. This is the strongest boundary of the three — it's what AWS Lambda and Fargate use to isolate tenants.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparison at a glance
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Docker (runc)&lt;/th&gt;
&lt;th&gt;gVisor (runsc)&lt;/th&gt;
&lt;th&gt;Firecracker&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Boundary&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Shared host kernel&lt;/td&gt;
&lt;td&gt;User-space kernel intercepts syscalls&lt;/td&gt;
&lt;td&gt;Hardware-virtualized microVM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Escape resistance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Weakest&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;Strongest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Startup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fastest (tens of ms)&lt;/td&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;~125ms boot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Runtime overhead&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Near-zero&lt;/td&gt;
&lt;td&gt;Syscall-heavy workloads pay a cost&lt;/td&gt;
&lt;td&gt;Low, plus a small memory floor per VM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compatibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Some syscalls unimplemented&lt;/td&gt;
&lt;td&gt;Full (real kernel in guest)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lowest&lt;/td&gt;
&lt;td&gt;Low (drop-in runtime)&lt;/td&gt;
&lt;td&gt;Higher (VM lifecycle, images)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Used by&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~Everyone&lt;/td&gt;
&lt;td&gt;Google Cloud Run, GKE Sandbox&lt;/td&gt;
&lt;td&gt;AWS Lambda, Fargate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Docker: the baseline, not the answer for untrusted code
&lt;/h2&gt;

&lt;p&gt;A hardened one-shot Docker container — non-root, dropped capabilities, seccomp on, read-only filesystem, no network by default — is a perfectly reasonable sandbox for &lt;em&gt;internal&lt;/em&gt; tools where the blast radius is contained. It's the fastest and simplest option.&lt;/p&gt;

&lt;p&gt;Its weakness is structural: the container shares the host kernel. One kernel vulnerability, and "isolated" code is on the host. If you're running genuinely untrusted or multi-tenant code, Docker alone is a bet on the kernel being flawless.&lt;/p&gt;

&lt;h2&gt;
  
  
  gVisor: a second kernel wall, at a compatibility cost
&lt;/h2&gt;

&lt;p&gt;gVisor slots in as a container runtime (&lt;code&gt;runsc&lt;/code&gt;), so it's close to a drop-in upgrade. Instead of your code's syscalls hitting the host kernel directly, they hit gVisor's user-space kernel first. An attacker now has to break gVisor &lt;em&gt;and&lt;/em&gt; the host kernel.&lt;/p&gt;

&lt;p&gt;The tradeoffs: gVisor doesn't implement every syscall, so some workloads break, and syscall-heavy programs pay a performance tax. For sandboxed Python doing data analysis or API calls, it's usually fine. For exotic low-level code, test compatibility first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Firecracker: real isolation, real VM lifecycle
&lt;/h2&gt;

&lt;p&gt;Firecracker gives each execution its own microVM with a separate guest kernel. Because the boundary is hardware virtualization, it's the strongest of the three — an escape has to break out of a VM, not just a namespace. It boots in ~125ms and strips the device model down to almost nothing.&lt;/p&gt;

&lt;p&gt;The cost is operational: you're managing VMs, guest images, and a memory floor per instance. If you're multi-tenant, handling other people's data or money, or running adversarial code, that cost buys you isolation you can actually defend.&lt;/p&gt;

&lt;h2&gt;
  
  
  So which should you use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Internal tool, your own code/data&lt;/strong&gt; → hardened one-shot Docker. Fast, simple, good enough.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Untrusted code, moderate risk&lt;/strong&gt; → gVisor. A big jump in isolation for little operational change; just verify syscall compatibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-tenant, real money/data, adversarial input&lt;/strong&gt; → Firecracker (or Kata Containers). Pay the VM tax; you'll want the hardware boundary.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The isolation tech is one decision. The policies around it — disposable per-run, default-deny egress, read-only mounts, quotas — matter just as much, whichever runtime you pick.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;We're &lt;strong&gt;Xingyao Byte&lt;/strong&gt; — building secure AI-execution layers, quant trading systems, and payment platforms. Remote, async-first. More at &lt;strong&gt;&lt;a href="https://www.stellarbytecapital.com/" rel="noopener noreferrer"&gt;stellarbytecapital.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>security</category>
      <category>ai</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
