<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0"><channel><title>Pulumi Blog: Mike Coleman</title><link>https://www.pulumi.com/blog/authors/mike-coleman/</link><description>Pulumi blog posts: Mike Coleman.</description><language>en-us</language><pubDate>Wed, 21 Oct 2026 00:00:00 +0000</pubDate><item><title>Running Pulumi Neo in a Docker Sandbox: workshop recap</title><link>https://www.pulumi.com/blog/running-pulumi-neo-in-a-docker-sandbox/</link><pubDate>Wed, 21 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/running-pulumi-neo-in-a-docker-sandbox/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/running-pulumi-neo-in-a-docker-sandbox/index.png" /&gt;
&lt;p&gt;The more an agent can do on its own, the more infrastructure work you can hand it, as long as its limits hold when it gets something wrong. In April, they didn&amp;rsquo;t hold for PocketOS. A coding agent on a routine staging task deleted the company&amp;rsquo;s production volume in 9 seconds. According to &lt;a href="https://www.theregister.com/software/2026/04/27/cursor-opus-agent-snuffs-out-startups-production-database/5224442"&gt;founder Jer Crane&amp;rsquo;s account&lt;/a&gt;, it used an API token it found in an unrelated file. Its explanation afterward: &amp;ldquo;I guessed that deleting a staging volume via the API would be scoped to staging only. I didn&amp;rsquo;t verify.&amp;rdquo; Railway recovered the data two days later.&lt;/p&gt;
&lt;p&gt;The agent had been told not to. &amp;ldquo;System prompts are advisory, not enforcing,&amp;rdquo; Crane wrote afterward. If the prompt can&amp;rsquo;t stop an agent, the limits have to sit where the agent can&amp;rsquo;t negotiate with them. That was the premise of Neo in a Docker Sandbox, the workshop Adam Gordon Bell and I ran with Mike Coleman from Docker. So we gave &lt;a href="https://www.pulumi.com/docs/ai/neo/"&gt;Pulumi Neo&lt;/a&gt; two layers. The first is a Docker Sandbox. Neo runs in its own microVM and reaches only the files and hosts we allow. The Pulumi token gets injected by a proxy on the way out, so Neo never holds the real credential. The second is Pulumi itself, which decides what Neo may change and when it has to ask. With both in place, you can let Neo work without approving every step.&lt;/p&gt;
&lt;p&gt;For why YOLO mode belongs in a sandbox at all, see &lt;a href="https://www.pulumi.com/blog/sandboxing-coding-agents-yolo-mode/"&gt;my August post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mike Coleman&lt;/strong&gt; is a Principal Solutions Architect at Docker. His running joke is that agents &amp;ldquo;want to be helpful&amp;rdquo;. It happens in his own demos:&lt;/p&gt;
&lt;div class="say flex items-start gap-3 my-6"&gt;
&lt;img class="rounded-full w-10 h-10 object-cover flex-shrink-0 m-0 mt-1" src="https://www.pulumi.com/images/team/mike-coleman.jpg" alt="Mike Coleman"&gt;
&lt;div class="flex-1"&gt;
&lt;div class="text-sm font-semibold text-gray-700 m-0 mb-1"&gt;Mike Coleman&lt;/div&gt;
&lt;div class="say-body m-0"&gt;I talk to people about agents a lot. They just really want to please you. I don&amp;rsquo;t know how many times I&amp;rsquo;ve done a demo [of] governance for MCP servers, and I&amp;rsquo;ll be like, &amp;ldquo;Can you write to my Notion page?&amp;rdquo; And there will be a policy applied to the sandbox that says it can&amp;rsquo;t. But I have a connector enabled in Claude somewhere. And it&amp;rsquo;s like, &amp;ldquo;Well, not with that MCP server, but I can use this thing over here to do it.&amp;rdquo;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Mike&amp;rsquo;s answer is to close those doors before the agent finds them:&lt;/p&gt;
&lt;div class="say flex items-start gap-3 my-6"&gt;
&lt;img class="rounded-full w-10 h-10 object-cover flex-shrink-0 m-0 mt-1" src="https://www.pulumi.com/images/team/mike-coleman.jpg" alt="Mike Coleman"&gt;
&lt;div class="flex-1"&gt;
&lt;div class="text-sm font-semibold text-gray-700 m-0 mb-1"&gt;Mike Coleman&lt;/div&gt;
&lt;div class="say-body m-0"&gt;The more you can create an environment where these alternate avenues are roadblocked, the safer you&amp;rsquo;re gonna be with agentic workflows. That&amp;rsquo;s where we&amp;rsquo;re coming at with the sandboxes: how do we take something that is as powerful as an agent, allow it to run as close to its full potential as possible, but avoid a bunch of catastrophic things.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/aTimO_kMS0c?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;h2 id="a-deleted-database-scores-the-same-as-a-failed-task"&gt;A deleted database scores the same as a failed task&lt;/h2&gt;
&lt;p&gt;Adam&amp;rsquo;s explanation of why a capable agent does this starts with how it&amp;rsquo;s trained. Agents got good at code fast. METR measures the length of software task, in human hours, that a model can finish on its own half the time, and it has doubled every few months.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="https://www.pulumi.com/blog/running-pulumi-neo-in-a-docker-sandbox/metr-time-horizon.webp" alt="Scatter plot of LLM release date against the length of software tasks each model completes 50 percent of the time, on a log scale. GPT-2 in 2019 is at a few seconds. Claude Opus 4.6 in early 2026 is near 16 hours. A dashed trend line runs straight through on the log scale."&gt;
&lt;figcaption&gt;&lt;em&gt;Source: &lt;a href="https://metr.org/time-horizons/"&gt;METR, Time Horizon 1.1&lt;/a&gt;.&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Behind that improvement is reinforcement learning on coding tasks. The model gets a task, tries it many times in a throwaway sandbox, and each attempt is scored pass or fail.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="https://www.pulumi.com/blog/running-pulumi-neo-in-a-docker-sandbox/rl-training-loop-slide.webp" alt="Trained in a sandbox. One task, fix this bug, fans out to three sandbox attempts. Tests pass scores plus one, gave up scores zero, repo destroyed scores zero, and all three feed into update weights. The environment resets after every attempt."&gt;
&lt;figcaption&gt;&lt;em&gt;Every attempt runs in a sandbox that resets afterward.&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In that sandbox, nothing it does can go worse than failing the task. There is no downside bigger than a zero, so the model never learns that some actions are worse than others.&lt;/p&gt;
&lt;div class="say flex items-start gap-3 my-6"&gt;
&lt;img class="rounded-full w-10 h-10 object-cover flex-shrink-0 m-0 mt-1" src="https://www.pulumi.com/images/team/adam-gordon-bell.jpg" alt="Adam Gordon Bell"&gt;
&lt;div class="flex-1"&gt;
&lt;div class="text-sm font-semibold text-gray-700 m-0 mb-1"&gt;Adam Gordon Bell&lt;/div&gt;
&lt;div class="say-body m-0"&gt;&lt;p&gt;In the training environment, if you solve a task, you get one point. If you don&amp;rsquo;t solve the task, you get zero. But there&amp;rsquo;s no in-between.&lt;/p&gt;
&lt;p&gt;If you destroy the entire repo, if you delete prod, that&amp;rsquo;s the same thing. You got the task or you failed the task. &lt;strong&gt;There&amp;rsquo;s no asymmetric downside.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Production is different.&lt;/p&gt;
&lt;div class="say flex items-start gap-3 my-6"&gt;
&lt;img class="rounded-full w-10 h-10 object-cover flex-shrink-0 m-0 mt-1" src="https://www.pulumi.com/images/team/adam-gordon-bell.jpg" alt="Adam Gordon Bell"&gt;
&lt;div class="flex-1"&gt;
&lt;div class="text-sm font-semibold text-gray-700 m-0 mb-1"&gt;Adam Gordon Bell&lt;/div&gt;
&lt;div class="say-body m-0"&gt;[With] existing benchmarks, no matter what you do, the worst you can get on any task is: you didn&amp;rsquo;t complete it. But in the real world, some tasks have a catastrophic downside.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Published coding-agent training runs such as &lt;a href="https://www.together.ai/blog/deepswe"&gt;DeepSWE&lt;/a&gt; and &lt;a href="https://arxiv.org/abs/2602.02361"&gt;SWE-Universe&lt;/a&gt; use that 1-or-0 reward. Adam&amp;rsquo;s answer is a matrix with reversibility on one axis and blast radius on the other.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="https://www.pulumi.com/blog/running-pulumi-neo-in-a-docker-sandbox/blast-radius-reversibility-slide.webp" alt="A grid with low and high blast radius across the top and no side effects, reversible, and irreversible down the side. No side effects is the sandbox. Reversible and low blast radius is let it cook, reversible and high is eyes open. Irreversible and low is look before you leap, irreversible and high is here be dragons."&gt;
&lt;figcaption&gt;&lt;em&gt;Training happens in the top row. Production work lives in the bottom right.&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Adam&amp;rsquo;s rule is that agents can act on their own when there are no side effects, when someone reviews the change, or when there&amp;rsquo;s an easy way to recover. The PocketOS agent was working in staging, which felt safe. The token it found let it leave staging without anyone noticing.&lt;/p&gt;
&lt;p&gt;Infrastructure as code moves production work toward those conditions. An agent&amp;rsquo;s change becomes a diff you can preview, check against policy, and review before it reaches the cloud.&lt;/p&gt;
&lt;h2 id="six-questions-before-an-agent-gets-your-cloud-account"&gt;Six questions before an agent gets your cloud account&lt;/h2&gt;
&lt;p&gt;Before an agent gets a cloud account, six questions:&lt;/p&gt;
&lt;div class="say flex items-start gap-3 my-6"&gt;
&lt;img class="rounded-full w-10 h-10 object-cover flex-shrink-0 m-0 mt-1" src="https://www.pulumi.com/images/team/engin-diri.jpg" alt="Engin Diri"&gt;
&lt;div class="flex-1"&gt;
&lt;div class="text-sm font-semibold text-gray-700 m-0 mb-1"&gt;Engin Diri&lt;/div&gt;
&lt;div class="say-body m-0"&gt;&lt;p&gt;Who is this agent acting as? What is it allowed to change? And when does it stop and ask?&lt;/p&gt;
&lt;p&gt;That last one has a history. The human-in-the-loop pattern was very, very big at the start, and everybody was like, &amp;ldquo;Hey, there should always be a human approving stuff.&amp;rdquo; Then it shifted when everything came around to the Ralph loop, loop engineering and so on. Asking was considered something which slows you down. Still, maybe very important.&lt;/p&gt;
&lt;p&gt;Where does the agent actually run? Which credentials does it hold? And what stops it when it goes wrong?&lt;/p&gt;
&lt;p&gt;Keep these questions as a loose guardrail.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;figure&gt;
&lt;img src="https://www.pulumi.com/blog/running-pulumi-neo-in-a-docker-sandbox/agent-cloud-account-six-questions.webp" alt="Six cards that ask who the agent acts as, what it may change, when it stops to ask, where it runs, which credentials it holds, and what stops it when it gets something wrong."&gt;
&lt;figcaption&gt;&lt;em&gt;Six questions before an agent gets a cloud account.&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Pulumi answers who, what, when, and what stops it. The sandbox answers where, and it splits the credentials question with Pulumi ESC (Environments, Secrets, and Configuration).&lt;/p&gt;
&lt;h2 id="pulumi-controls-that-live-outside-the-prompt"&gt;Pulumi controls that live outside the prompt&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/docs/ai/neo/pulumi-cli/"&gt;&lt;code&gt;pulumi neo&lt;/code&gt;&lt;/a&gt; runs Neo in your terminal (Essentials, Pro, and Enterprise editions). Its controls live in Pulumi:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Neo runs as you.&lt;/strong&gt; It uses your &lt;code&gt;pulumi login&lt;/code&gt; and &lt;a href="https://www.pulumi.com/docs/ai/neo/permissions/"&gt;role-based access control (RBAC)&lt;/a&gt; permissions, and its file and shell tool calls run locally, inside the sandbox.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Approval mode sets when it asks.&lt;/strong&gt; &lt;code&gt;--approval-mode manual&lt;/code&gt;, the default, asks before every tool call, &lt;code&gt;balanced&lt;/code&gt; only before &lt;code&gt;pulumi up&lt;/code&gt;, and &lt;code&gt;auto&lt;/code&gt; never.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Read-only blocks Pulumi Cloud writes only.&lt;/strong&gt; With &lt;code&gt;--permission-mode read-only&lt;/code&gt;, Neo can&amp;rsquo;t trigger writes such as &lt;code&gt;pulumi up&lt;/code&gt;, but it can still open ESC environments and reach the cloud accounts behind them. To &lt;a href="https://www.pulumi.com/docs/ai/neo/permissions/#esc-secrets-and-downstream-cloud-access"&gt;keep it out of an environment&lt;/a&gt;, don&amp;rsquo;t grant your user or role &lt;code&gt;environment:open&lt;/code&gt; on it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;protect: true&lt;/code&gt; guards against accidental deletes.&lt;/strong&gt; A deployment that would delete a &lt;a href="https://www.pulumi.com/docs/iac/concepts/resources/options/protect/"&gt;protected resource&lt;/a&gt; fails. &lt;code&gt;protect: false&lt;/code&gt;, &lt;code&gt;pulumi state unprotect&lt;/code&gt;, or &lt;code&gt;--ignore-protect&lt;/code&gt; still gets past it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pulumi Policies blocks unsafe changes.&lt;/strong&gt; Mandatory policies in a &lt;a href="https://www.pulumi.com/docs/discovery-governance/concepts/policy-as-code/policy-groups/"&gt;preventative policy group&lt;/a&gt; (Pro and Enterprise editions) run on every &lt;code&gt;pulumi preview&lt;/code&gt; and &lt;code&gt;pulumi up&lt;/code&gt;, Neo&amp;rsquo;s included, and stop a violating change before anything reaches the cloud. The workshop&amp;rsquo;s pack included &lt;code&gt;s3-no-public-acl&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pulumi ESC replaces stored cloud keys.&lt;/strong&gt; It mints short-lived AWS credentials through &lt;a href="https://www.pulumi.com/docs/esc/guides/configuring-oidc/aws/"&gt;OpenID Connect (OIDC)&lt;/a&gt; for each run. They still reach the CLI, so they limit a leak&amp;rsquo;s damage rather than prevent it.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="what-a-docker-sandbox-isolates"&gt;What a Docker Sandbox isolates&lt;/h2&gt;
&lt;p&gt;Each agent gets its own microVM, kernel, and Docker Engine. Only the workspace is mounted (plus a read-only skills store for supported agents), but SSH agent forwarding is on by default. All outbound TCP goes through a host proxy that injects proxy-managed credentials such as the Pulumi token. The &lt;code&gt;sbx&lt;/code&gt; CLI and local sandboxes are free; centralized sandbox, network, and Model Context Protocol (MCP) controls are part of Docker&amp;rsquo;s paid AI Governance.&lt;/p&gt;
&lt;h2 id="what-changed-in-docker-sandboxes-since-august"&gt;What changed in Docker Sandboxes since August&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Secrets are global and reach running sandboxes.&lt;/strong&gt; Since v0.38.0 (August 6), &lt;code&gt;sbx secret set pulumi&lt;/code&gt; covers every sandbox whose kit asks for it. Since v0.45.0 (September 21), &lt;a href="https://docs.docker.com/ai/sandboxes/configuration/credentials/"&gt;changing a global secret&lt;/a&gt; updates running sandboxes without a restart.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sandbox environment files (experimental).&lt;/strong&gt; An &lt;code&gt;sbxenv.yaml&lt;/code&gt; captures a sandbox&amp;rsquo;s agent, kits, workspace, ports, and credentials for &lt;code&gt;sbx env run&lt;/code&gt;. Mike compared it to a dev container definition. Docker now says to keep &lt;a href="https://docs.docker.com/ai/sandboxes/configuration/environment-files/"&gt;the file&lt;/a&gt; under version control but outside the mounted workspace, because it can run host commands.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloud sandboxes (experimental).&lt;/strong&gt; &lt;a href="https://docs.docker.com/ai/sandboxes/cloud/"&gt;&lt;code&gt;sbx --cloud run claude&lt;/code&gt;&lt;/a&gt; runs the sandbox in Docker&amp;rsquo;s cloud, so it keeps going after you close the laptop. It needs &lt;code&gt;sbx&lt;/code&gt; 0.45.0 or later and a pay-as-you-go Docker Agentic Platform subscription. New signups get a &lt;a href="https://www.docker.com/c/sbx-promo/"&gt;one-time $250 compute credit&lt;/a&gt;, instead of $25, through October 31, 2026.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="running-neo-inside-a-docker-sandbox"&gt;Running Neo inside a Docker Sandbox&lt;/h2&gt;
&lt;p&gt;Every script is in the &lt;a href="https://github.com/pulumi/workshops/tree/main/neo-in-a-docker-sandbox"&gt;workshop repo&lt;/a&gt;. Store the token on the host, allow &lt;code&gt;ghcr.io/dirien/&lt;/code&gt; in &lt;code&gt;kit.allowedSources&lt;/code&gt;, then start the sandbox from &lt;a href="https://github.com/dirien/infrastructure-sandbox-kit"&gt;my kit&lt;/a&gt; plus a mixin for the demo&amp;rsquo;s AWS region:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sbx secret &lt;span class="nb"&gt;set&lt;/span&gt; pulumi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sbx run --name neo-demo --kit ./01-sandbox/region-kit &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ghcr.io/dirien/infrastructure-sandbox-kit:v0.10.0 ./02-app
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Neo isn&amp;rsquo;t a built-in &lt;code&gt;sbx&lt;/code&gt; agent, so the sandbox opens a shell, where &lt;code&gt;pulumi whoami -v&lt;/code&gt; works through the injected token while the variable holds a placeholder:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$PULUMI_ACCESS_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;proxy-managed
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;From the host, the workshop&amp;rsquo;s &lt;code&gt;boundaries.sh&lt;/code&gt; checks a host the kit doesn&amp;rsquo;t allow and one it does:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sbx policy check network --sandbox neo-demo ifconfig.me
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sbx policy check network --sandbox neo-demo api.pulumi.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Under Balanced or Locked Down the first is denied, and &lt;code&gt;sbx policy log neo-demo&lt;/code&gt; shows what the proxy refused.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="https://www.pulumi.com/blog/running-pulumi-neo-in-a-docker-sandbox/sbx-egress-default-deny.webp" alt="Three cards. The hosts the kit allows, the regional AWS endpoints a mixin kit adds for this sandbox, and &amp;quot;no matching rule&amp;quot;, which is blocked at the host proxy. Below them is the mixin's YAML allow-list."&gt;
&lt;figcaption&gt;&lt;em&gt;The Open preset allows all traffic. Without organization governance, a request that matches no rule is blocked and queued for your approval (&lt;code&gt;sbx policy approval ls&lt;/code&gt;). The allow-list is an excerpt.&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Then start Neo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi neo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Inside the sandbox, I think auto approval mode is defensible for throwaway work. But allowed hosts, AWS included, still receive whatever Neo sends, and ESC&amp;rsquo;s short-lived credentials reach the CLI, so keep the Pulumi controls on. The last step, Neo trying to tear the stack down and &lt;code&gt;protect: true&lt;/code&gt; refusing, didn&amp;rsquo;t make it into the live session.&lt;/p&gt;
&lt;h2 id="where-to-start"&gt;Where to start&lt;/h2&gt;
&lt;p&gt;In an informal poll at the end of the workshop, 8 of the 11 people who voted said they don&amp;rsquo;t use a sandbox for their agents. If that&amp;rsquo;s you, start closed: pick &lt;a href="https://docs.docker.com/ai/sandboxes/governance/access-controls/local/"&gt;Locked Down&lt;/a&gt; when the first start asks for a network preset. Read the denials in the terminal dashboard (&lt;code&gt;sbx&lt;/code&gt; with no subcommand) or with &lt;code&gt;sbx policy log&lt;/code&gt;, then approve them or add rules with &lt;code&gt;sbx policy allow network &amp;lt;host&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On the Pulumi side, start Neo with &lt;a href="https://www.pulumi.com/docs/ai/neo/permissions/"&gt;balanced approval&lt;/a&gt; near production, so it works freely but asks before &lt;code&gt;pulumi up&lt;/code&gt;, and back the stack with an &lt;a href="https://www.pulumi.com/docs/esc/guides/configuring-oidc/aws/"&gt;ESC environment that uses OIDC&lt;/a&gt;.&lt;/p&gt;
&lt;div class="my-8"&gt;
&lt;article class="group relative h-full"&gt;
&lt;a href="https://www.pulumi.com/events/neo-in-a-docker-sandbox/" rel="" target="" class="card card-hover bg-white p-6 md:p-7 flex h-full flex-col no-underline"&gt;
&lt;div class="flex items-start justify-between gap-6"&gt;
&lt;div class="min-w-0"&gt;
&lt;div class="mb-4 flex flex-wrap items-center gap-2"&gt;
&lt;span class="badge badge-outline"&gt;workshop&lt;/span&gt;
&lt;span class="badge badge-ghost"&gt;virtual&lt;/span&gt;
&lt;span data-event-countdown data-event-date="2026-09-16T09:00:00-07:00" hidden&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;h3 class="m-0 heading-3 leading-snug text-service-black transition-colors group-hover:text-violet-primary"&gt;
Neo in a Docker Sandbox: Using Pulumi’s Coding Agent for All Things Infra Safely and Securely
&lt;/h3&gt;
&lt;/div&gt;
&lt;div data-event-tile data-event-date="2026-09-16T09:00:00-07:00" class="flex h-auto w-16 shrink-0 flex-col items-center overflow-hidden rounded-lg border border-gray-200 text-gray-950"&gt;
&lt;div class="flex w-full flex-col items-center px-1 py-1.5"&gt;
&lt;div data-event-tile-day class="font-mono text-xl leading-none"&gt;16&lt;/div&gt;
&lt;div data-event-tile-month class="font-mono text-[0.65rem] uppercase"&gt;Sep&lt;/div&gt;
&lt;/div&gt;
&lt;div data-event-tile-time class="w-full border-t border-gray-200 p-1 text-center font-mono text-[0.6rem] whitespace-nowrap uppercase" hidden&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class="mt-1.5 mb-0 body-base line-clamp-3 text-service-black"&gt;Join Docker and Pulumi to run Neo, Pulumi’s infrastructure coding agent, inside a Docker Sandbox and turn plain-English requests into real cloud infrastructure.&lt;/p&gt;
&lt;div class="mt-auto flex flex-col gap-4 pt-6"&gt;
&lt;div class="flex items-center gap-3"&gt;
&lt;div class="flex -space-x-2 shrink-0"&gt;
&lt;img class="size-14 rounded-full object-cover ring-2 ring-white" src="https://www.pulumi.com/images/team/adam-gordon-bell.jpg" alt="Adam Gordon Bell" loading="lazy" /&gt;
&lt;img class="size-14 rounded-full object-cover ring-2 ring-white" src="https://www.pulumi.com/images/team/engin-diri.jpg" alt="Engin Diri" loading="lazy" /&gt;
&lt;img class="size-14 rounded-full object-cover ring-2 ring-white" src="https://www.pulumi.com/images/team/mike-coleman.jpg" alt="Mike Coleman" loading="lazy" /&gt;
&lt;/div&gt;
&lt;span class="body-sm text-gray-600 line-clamp-1"&gt;with Adam Gordon Bell, Engin Diri, Mike Coleman&lt;/span&gt;
&lt;/div&gt;
&lt;div class="flex items-end justify-between gap-3"&gt;
&lt;div class="flex flex-wrap items-center gap-1.5"&gt;
&lt;span class="badge badge-secondary"&gt;Beginner&lt;/span&gt;
&lt;/div&gt;
&lt;span class="btn btn-primary btn-lg group-hover:bg-violet-800 shrink-0"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--regular" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.930341d891823cfdd478d54625fe6a3208720ef3ac597420c81d818e3555671d.svg#p-calendar-check-regular"/&gt;&lt;/svg&gt;Register&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/a&gt;
&lt;/article&gt;
&lt;/div&gt;
&lt;p&gt;If you sandbox your agents differently, tell me how in the &lt;a href="https://slack.pulumi.com/"&gt;Pulumi Community Slack&lt;/a&gt;.&lt;/p&gt;</description><author>Engin Diri</author><author>Adam Gordon Bell</author><author>Mike Coleman</author><category>ai</category><category>ai-agents</category><category>pulumi-neo</category><category>docker</category><category>security</category><category>esc</category></item></channel></rss>