<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Kiri Blog</title><description>The Kiri blog: long-form, hands-on posts on AI, security and containers, from agent sandboxes to supply-chain attacks to how runtimes really work, with real numbers and code you can run.</description><link>https://runkiri.com/blog/</link><language>en</language><atom:link href="https://runkiri.com/blog/rss.xml" rel="self" type="application/rss+xml"/><item><title>Why is everyone suddenly putting AI agents in a box?</title><link>https://runkiri.com/blog/posts/agent-sandboxes-intro/</link><guid isPermaLink="true">https://runkiri.com/blog/posts/agent-sandboxes-intro/</guid><description>AI tools used to suggest code. Now they run it. What an agent sandbox is, and why every team running agents needs one.</description><pubDate>Tue, 27 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A year ago, AI coding tools suggested code. You read it and decided whether to run it.&lt;/p&gt;
&lt;p&gt;Now they run it. They install packages, execute tests, call APIs and open pull requests, while reading text from strangers: README files, GitHub issues, web pages. Usually with the same access as the engineer who started them.&lt;/p&gt;
&lt;h2 id=&quot;what-is-an-agent-sandbox&quot;&gt;What is an agent sandbox?&lt;/h2&gt;
&lt;div class=&quot;definition&quot;&gt;&lt;span class=&quot;label&quot;&gt;Agent sandbox&lt;/span&gt;&lt;p&gt;A boundary around an AI agent that controls what it can read, run and reach.&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Inside the boundary, the agent can work freely: edit the project, run the tests, install what it needs. Outside it are the things it should never touch on its own: your SSH keys, your cloud credentials, other repositories, and most of the internet.&lt;/p&gt;
&lt;h2 id=&quot;what-changed&quot;&gt;What changed&lt;/h2&gt;
&lt;div class=&quot;compare&quot;&gt;&lt;div&gt;&lt;span class=&quot;label&quot;&gt;Before&lt;/span&gt;&lt;strong&gt;AI suggests code.&lt;/strong&gt; It writes, and a person decides what executes.&lt;/div&gt;&lt;div class=&quot;now&quot;&gt;&lt;span class=&quot;label&quot;&gt;Now&lt;/span&gt;&lt;strong&gt;AI runs the code.&lt;/strong&gt; A sandbox decides what it can read, run and reach.&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;That shift is why agent sandboxes have gone from a niche security topic to something every team running agents needs to understand. A permission prompt on every command doesn’t scale: after the fortieth one, nobody reads them.&lt;/p&gt;
&lt;h2 id=&quot;what-this-series-covers&quot;&gt;What this series covers&lt;/h2&gt;
&lt;p&gt;Starting Friday, two short parts a week. Each one stands on its own, with three diagrams:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What an agent can reach without a sandbox, and how one poisoned README leaks your keys&lt;/li&gt;
&lt;li&gt;Why git worktrees aren’t isolation&lt;/li&gt;
&lt;li&gt;Containers, gVisor and microVMs, and what actually separates them&lt;/li&gt;
&lt;li&gt;The network wall, secrets, many agents at once, and a reference architecture to finish&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No vendor pitches. Just how it works. If there’s something you want covered, tell us and we’ll fold it in.&lt;/p&gt;
&lt;aside class=&quot;series-box&quot;&gt;&lt;p class=&quot;label&quot;&gt;Series · Agent sandboxes, in diagrams&lt;/p&gt;&lt;p class=&quot;series-t&quot;&gt;11 parts, 27 October – 3 December&lt;/p&gt;&lt;ol class=&quot;parts&quot;&gt;&lt;li class=&quot;here&quot;&gt;&lt;span class=&quot;n&quot;&gt;Intro&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;Why is everyone suddenly putting AI agents in a box?&lt;/span&gt;&lt;span class=&quot;d&quot;&gt;27 Oct&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;What your AI agent can reach without a sandbox&lt;/span&gt;&lt;span class=&quot;d&quot;&gt;30 Oct&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;Git worktrees don’t isolate your AI agents&lt;/span&gt;&lt;span class=&quot;d&quot;&gt;3 Nov&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;How strong is your AI agent’s sandbox?&lt;/span&gt;&lt;span class=&quot;d&quot;&gt;6 Nov&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;Your laptop already has a sandbox for AI agents&lt;/span&gt;&lt;span class=&quot;d&quot;&gt;9 Nov&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;05&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;How to stop AI agents leaking your data&lt;/span&gt;&lt;span class=&quot;d&quot;&gt;12 Nov&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;06&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;Keep API keys out of your AI agent’s reach&lt;/span&gt;&lt;span class=&quot;d&quot;&gt;17 Nov&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;07&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;Running many AI agents at once, without collisions&lt;/span&gt;&lt;span class=&quot;d&quot;&gt;20 Nov&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;Throwaway sandboxes: why AI agents should start fresh&lt;/span&gt;&lt;span class=&quot;d&quot;&gt;24 Nov&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;09&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;How cloud sandboxes for AI agents work&lt;/span&gt;&lt;span class=&quot;d&quot;&gt;30 Nov&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;A reference architecture for sandboxing AI agents&lt;/span&gt;&lt;span class=&quot;d&quot;&gt;3 Dec&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/aside&gt;</content:encoded><dc:creator>Precious Okwu</dc:creator><category>AI</category><category>Security</category><category>Containers</category></item><item><title>Review the Dockerfile your agent wrote</title><link>https://runkiri.com/blog/posts/agent-written-dockerfiles/</link><guid isPermaLink="true">https://runkiri.com/blog/posts/agent-written-dockerfiles/</guid><description>Agent-written Dockerfiles build, run and often ship your keys. Six things to check in review, what to change, and how to make the agent get them right first time.</description><pubDate>Tue, 27 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ask a coding agent to containerise an app and you get a Dockerfile in seconds. It builds. It runs. In review, it’s easy to skim: it’s eight lines, and the app works.&lt;/p&gt;
&lt;p&gt;The trouble is where models learned to write Dockerfiles: tutorials and quick-start READMEs, written to get something running, not to ship. The same few shortcuts turn up again and again.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://runkiri.com/blog/_astro/d1.gGh1CN5n_1phl9R.webp&quot; srcset=&quot;/blog/_astro/d1.gGh1CN5n_18Ttub.webp 720w, /blog/_astro/d1.gGh1CN5n_1SW5xL.webp 1080w&quot; alt=&quot;Six things to check first, in a Dockerfile as an agent wrote it. 1: FROM node:latest moves under you. 2: COPY . . copies .env and .git too. 3: ENV OPENAI_API_KEY is saved in the image forever. 4: RUN curl piped to sh runs whatever it gets. 5: RUN npm install ignores the lockfile. 6: CMD with no USER runs as root.&quot; sizes=&quot;(max-width: 760px) 100vw, 720px&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;2160&quot; height=&quot;2160&quot;&gt;&lt;/figure&gt;
&lt;h2 id=&quot;the-six-checks&quot;&gt;The six checks&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1. Is the base image pinned?&lt;/strong&gt; &lt;code&gt;node:latest&lt;/code&gt; today is a different image next month. Pin a version and its digest: &lt;code&gt;FROM node:22-slim@sha256:…&lt;/code&gt;. &lt;code&gt;docker buildx imagetools inspect node:22-slim&lt;/code&gt; prints the digest. Dependabot or Renovate can keep it current, through pull requests you review.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. What does &lt;code&gt;COPY&lt;/code&gt; copy?&lt;/strong&gt; &lt;code&gt;COPY . .&lt;/code&gt; takes everything in the folder, including &lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;.git&lt;/code&gt; and whatever the agent left lying around. Copy named paths, and add a &lt;code&gt;.dockerignore&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;.env*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;.git&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;node_modules&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;*.pem&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;3. Are there secrets in &lt;code&gt;ENV&lt;/code&gt; or &lt;code&gt;ARG&lt;/code&gt;?&lt;/strong&gt; Both are saved in the image. Anyone who can pull it can read them with &lt;code&gt;docker history&lt;/code&gt; or &lt;code&gt;docker inspect&lt;/code&gt;, even if a later step “removes” them. Pass runtime secrets when the container starts (&lt;code&gt;--env-file&lt;/code&gt;, or your platform’s secrets). For build-time secrets, use a secret mount, which never lands in a layer:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;dockerfile&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;RUN&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; --mount=type=secret,id=npm_token \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;    NPM_TOKEN=$(cat /run/secrets/npm_token) npm ci&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;4. Is anything piped to a shell?&lt;/strong&gt; &lt;code&gt;curl … | sh&lt;/code&gt; runs whatever that URL serves on the day you build. Install from a package manager, or download a pinned version and check its checksum.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. Does the install use the lockfile?&lt;/strong&gt; &lt;code&gt;npm install&lt;/code&gt; can resolve newer versions than the ones you tested. &lt;code&gt;npm ci&lt;/code&gt; installs exactly what &lt;code&gt;package-lock.json&lt;/code&gt; says, and &lt;code&gt;--ignore-scripts&lt;/code&gt; stops install scripts, a favourite place to hide malware. For Python, &lt;code&gt;pip install --require-hashes -r requirements.txt&lt;/code&gt; does the same job.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. Who does it run as?&lt;/strong&gt; With no &lt;code&gt;USER&lt;/code&gt; line, the app runs as root inside the container. Add &lt;code&gt;USER&lt;/code&gt; with a non-root user, or start from an image that already has one.&lt;/p&gt;
&lt;h2 id=&quot;after-review&quot;&gt;After review&lt;/h2&gt;
&lt;p&gt;Put together, the fixes usually mean two stages: one that builds with all the tools it needs, and a small final image that has only the app. No shell, no package manager, nothing for an attacker to work with.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://runkiri.com/blog/_astro/d2.C2n_9bb8_ZLMIUs.webp&quot; srcset=&quot;/blog/_astro/d2.C2n_9bb8_Z1Hw15f.webp 720w, /blog/_astro/d2.C2n_9bb8_Zi7Ywy.webp 1080w&quot; alt=&quot;The same app after review: a build stage from a pinned node:22-slim digest that copies only package.json, package-lock.json and src and runs npm ci with ignore-scripts; and a run stage from a pinned distroless Node.js image that copies the app and runs as nonroot. Outside the file: secrets come in at run time, nothing is piped to a shell, and a .dockerignore drops .env and .git.&quot; sizes=&quot;(max-width: 760px) 100vw, 720px&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;2160&quot; height=&quot;2160&quot;&gt;&lt;/figure&gt;
&lt;p&gt;You don’t have to build minimal base images yourself. &lt;a href=&quot;https://github.com/GoogleContainerTools/distroless&quot;&gt;Distroless&lt;/a&gt;, Chainguard and &lt;a href=&quot;https://www.helpnetsecurity.com/2025/12/22/free-open-docker-hardened-images/&quot;&gt;Docker Hardened Images&lt;/a&gt; (free and open source since December 2025) all ship images without a shell or package manager, with a software bill of materials, and with non-root variants.&lt;/p&gt;
&lt;h2 id=&quot;make-the-agent-get-it-right&quot;&gt;Make the agent get it right&lt;/h2&gt;
&lt;p&gt;Reviewing the same six things on every pull request gets old. Two cheaper fixes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tell the agent.&lt;/strong&gt; Add the six rules to your &lt;code&gt;AGENTS.md&lt;/code&gt; or &lt;code&gt;CLAUDE.md&lt;/code&gt;, the file the agent reads in every session. It will follow them far more often than it guesses them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Check it in CI.&lt;/strong&gt; &lt;a href=&quot;https://github.com/hadolint/hadolint&quot;&gt;hadolint&lt;/a&gt; flags most of these in the Dockerfile itself, &lt;code&gt;latest&lt;/code&gt; tags and missing pins included. Trivy or Grype then scans the built image for known vulnerabilities. A failing check catches what a tired reviewer won’t.&lt;/li&gt;
&lt;/ul&gt;
&lt;aside class=&quot;series-box&quot;&gt;&lt;p class=&quot;label&quot;&gt;Series · Containers for AI&lt;/p&gt;&lt;p class=&quot;series-t&quot;&gt;3 short parts&lt;/p&gt;&lt;ol class=&quot;parts&quot;&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;&lt;a href=&quot;https://runkiri.com/blog/posts/containers-gpus/&quot;&gt;How a container gets a GPU&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;&lt;a href=&quot;https://runkiri.com/blog/posts/mcp-servers-in-containers/&quot;&gt;Run your MCP servers in a box&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;here&quot;&gt;&lt;span class=&quot;n&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;Review the Dockerfile your agent wrote&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/aside&gt;</content:encoded><dc:creator>Precious Okwu</dc:creator><category>Containers</category><category>Security</category><category>AI</category></item><item><title>A file in your Downloads folder can hijack your coding agent</title><link>https://runkiri.com/blog/posts/agents-md-downloads-attack/</link><guid isPermaLink="true">https://runkiri.com/blog/posts/agents-md-downloads-attack/</guid><description>A planted AGENTS.md told a coding agent to install a malicious npm package. How the attack works, why no patch fixes it, and what to change today.</description><pubDate>Tue, 27 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last week, a coding agent on a developer’s laptop tried to install a known-malicious npm package. Nobody typed the command. A text file did.&lt;/p&gt;
&lt;p&gt;The file was called &lt;code&gt;AGENTS.md&lt;/code&gt;, and it was sitting in the developer’s Downloads folder. Forever Security, who caught it, &lt;a href=&quot;https://www.helpnetsecurity.com/2026/10/26/ai-coding-agents-malware-openai-codex/&quot;&gt;published the details on 22 October&lt;/a&gt;. There was no bug and no exploit. The agent did exactly what it was built to do.&lt;/p&gt;
&lt;h2 id=&quot;what-happened&quot;&gt;What happened&lt;/h2&gt;
&lt;p&gt;Coding agents such as Codex and Claude Code read an instruction file from the folder they start in: &lt;code&gt;AGENTS.md&lt;/code&gt;, or &lt;code&gt;CLAUDE.md&lt;/code&gt; for Claude Code. It is how a project tells the agent its conventions: how to run the tests, which package manager to use. The agent treats it as guidance from you.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;A file lands in Downloads.&lt;/strong&gt; Forever could not tell how this one got there. In their tests, an ordinary web page saved a file named &lt;code&gt;AGENTS.md&lt;/code&gt; into &lt;code&gt;~/Downloads&lt;/code&gt; with no prompt in Chrome, Edge or Firefox. Brave asked first.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A developer starts an agent in Downloads.&lt;/strong&gt; This is more common than it sounds: you download something, open a terminal there, and ask the agent to look at it. Forever counted more than 1,300 Claude Code sessions started from Downloads across its customers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The agent reads the file as instructions.&lt;/strong&gt; It was dressed up as engineering notes. One section told the agent to add a server to its own configuration and install a package called &lt;code&gt;function-color&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The agent runs &lt;code&gt;npm install function-color&lt;/code&gt;.&lt;/strong&gt; That package is linked to a malware campaign Forever calls MALFEX. The install would have run with the developer’s shell, files and credentials.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Forever blocked the install before any code ran. npm has since replaced the package with a security placeholder.&lt;/p&gt;
&lt;h2 id=&quot;how-well-it-works&quot;&gt;How well it works&lt;/h2&gt;
&lt;p&gt;Forever then tried it on purpose, with harmless payloads.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Codex&lt;/strong&gt; followed the planted instructions in about 90% of attempts. Their payload opened the calculator.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Code&lt;/strong&gt;, given a malicious &lt;code&gt;CLAUDE.md&lt;/code&gt;, sent its API traffic to a server the researchers controlled in roughly half of their runs. That exposed the login token and let the fake server send back its own tool calls. Reports differ on the details here, so treat this number as rougher than the Codex one.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Neither vendor had commented in the coverage we found.&lt;/p&gt;
&lt;h2 id=&quot;why-there-is-nothing-to-patch&quot;&gt;Why there is nothing to patch&lt;/h2&gt;
&lt;p&gt;Reading instruction files is a feature. So is running shell commands. The weakness is the combination: an agent that &lt;strong&gt;trusts any file in its working folder&lt;/strong&gt; and &lt;strong&gt;acts with your full permissions&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The same pattern shows up anywhere an agent reads text a stranger wrote: a README in a cloned repo, a GitHub issue, a web page it fetches. Downloads is just the easiest place to drop the text, because browsers write there for you.&lt;/p&gt;
&lt;aside class=&quot;callout-box&quot;&gt;&lt;p class=&quot;callout-t&quot;&gt;The short version&lt;/p&gt;&lt;p&gt;An agent with your shell and your credentials is only as safe as the files it reads. You can’t vet every file, so limit what the agent can do when it reads a bad one.&lt;/p&gt;&lt;/aside&gt;
&lt;h2 id=&quot;what-to-change-today&quot;&gt;What to change today&lt;/h2&gt;
&lt;p&gt;These take minutes and work with any coding agent.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Start agents in a project, never in Downloads or your home folder.&lt;/strong&gt; Open the terminal at the root of the repository you mean to work on. If you need the agent to look at a download, move the file into a project first.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Answer “no” to folder trust prompts you didn’t expect.&lt;/strong&gt; Some agents ask whether you trust the files in a new folder before loading them. That question is the defence against this attack. Don’t approve it for Downloads, Desktop or your home folder.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Read unfamiliar instruction files before the agent does.&lt;/strong&gt; In a repo you just cloned, open &lt;code&gt;AGENTS.md&lt;/code&gt;, &lt;code&gt;CLAUDE.md&lt;/code&gt; and similar files and look for anything that installs packages, adds servers or changes settings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keep approval prompts and the sandbox on.&lt;/strong&gt; Modes that skip every confirmation remove the last point where you would have seen &lt;code&gt;npm install function-color&lt;/code&gt; go by. If your agent has a sandbox, turn it on: Claude Code has &lt;code&gt;/sandbox&lt;/code&gt;, and Codex runs commands in a sandbox unless you switch it off.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stop install scripts by default.&lt;/strong&gt; Many malicious packages run their payload from an install script. This turns them off for npm on your machine:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; config&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; ignore-scripts&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some packages genuinely need their scripts. Run those installs on purpose, in a project you trust.&lt;/p&gt;
&lt;h2 id=&quot;check-whether-you-were-hit&quot;&gt;Check whether you were hit&lt;/h2&gt;
&lt;p&gt;Look for stray instruction files in the places agents shouldn’t start:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;find&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; ~/Downloads&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; ~/Desktop&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; ~&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; -maxdepth&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt; \(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; -name&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; AGENTS.md&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; -o&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; -name&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; CLAUDE.md&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt; \)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Look for the package in projects you work on (change &lt;code&gt;~/code&lt;/code&gt; to where yours live):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;grep&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; -rl&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; --include=package-lock.json&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; function-color&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; ~/code&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The planted file told the agent to add a server to its own configuration, so check that list for anything you don’t recognise: &lt;code&gt;~/.codex/config.toml&lt;/code&gt; for Codex, and &lt;code&gt;~/.claude.json&lt;/code&gt; or a project’s &lt;code&gt;.mcp.json&lt;/code&gt; for Claude Code. Also check that &lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt; and &lt;code&gt;OPENAI_BASE_URL&lt;/code&gt; are unset, or point where you expect, both in your shell and in the agent’s settings.&lt;/p&gt;
&lt;p&gt;If anything turns up, assume the agent’s credentials were exposed. Log out of the agent and log back in, and rotate any tokens that machine could reach: npm, GitHub, cloud keys.&lt;/p&gt;
&lt;h2 id=&quot;the-longer-fix&quot;&gt;The longer fix&lt;/h2&gt;
&lt;p&gt;The tips above depend on people remembering them. The durable fix is a boundary the agent can’t talk its way out of: a sandbox that decides which files it sees, which addresses it can reach, which credentials it holds and what it can push. With that in place, a bad instruction file becomes a failed command instead of a stolen token.&lt;/p&gt;
&lt;p&gt;That is what our series on agent sandboxes is about. &lt;a href=&quot;https://runkiri.com/blog/posts/agent-sandboxes-intro/&quot;&gt;Part 1&lt;/a&gt; explains what a sandbox is and why every team running agents now needs one.&lt;/p&gt;
&lt;p&gt;Sources: &lt;a href=&quot;https://www.helpnetsecurity.com/2026/10/26/ai-coding-agents-malware-openai-codex/&quot;&gt;Help Net Security&lt;/a&gt;, &lt;a href=&quot;https://thehackernews.com/2026/10/malicious-file-in-downloads-folder.html&quot;&gt;The Hacker News&lt;/a&gt;, &lt;a href=&quot;https://runtimewire.com/article/forever-security-ai-agent-downloads-folder-instructions&quot;&gt;RuntimeWire&lt;/a&gt;.&lt;/p&gt;</content:encoded><dc:creator>Precious Okwu</dc:creator><category>Security</category><category>AI</category></item><item><title>How a container gets a GPU</title><link>https://runkiri.com/blog/posts/containers-gpus/</link><guid isPermaLink="true">https://runkiri.com/blog/posts/containers-gpus/</guid><description>Containers were built for CPUs. Here is how one reaches a GPU, why the driver never lives in the image, and what changes when several containers share one card.</description><pubDate>Tue, 27 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Almost every AI workload you run in a container wants a GPU: serving a model with vLLM, fine-tuning with PyTorch, running llama.cpp. But a container is just a process with a fenced-off view of the machine, and nothing about that view includes a graphics card. So how does the card get in?&lt;/p&gt;
&lt;h2 id=&quot;two-halves-of-a-driver&quot;&gt;Two halves of a driver&lt;/h2&gt;
&lt;p&gt;A GPU driver comes in two halves. One half lives in the host’s kernel. The other is a user-space library, &lt;code&gt;libcuda.so&lt;/code&gt;, that programs load to talk to it. The two must come from the same driver release.&lt;/p&gt;
&lt;p&gt;That rules out putting the driver in the image. The image can’t know which driver the host runs. So the work is split:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The image brings CUDA&lt;/strong&gt;: the toolkit libraries your framework was built against, such as cuBLAS and cuDNN.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The host brings the driver.&lt;/strong&gt; When the container starts, the NVIDIA Container Toolkit adds the device files (&lt;code&gt;/dev/nvidia*&lt;/code&gt;) and mounts the host’s copy of &lt;code&gt;libcuda.so&lt;/code&gt; into it.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;img src=&quot;https://runkiri.com/blog/_astro/d1.COagkgn1_Z4EAmk.webp&quot; srcset=&quot;/blog/_astro/d1.COagkgn1_1pYimw.webp 720w, /blog/_astro/d1.COagkgn1_p091z.webp 1080w&quot; alt=&quot;How a container gets a GPU. Inside the container, from the image: your app and the CUDA libraries. Plugged in at start by the NVIDIA Container Toolkit: the /dev/nvidia device files and libcuda.so from the host. Both lead to the host kernel and NVIDIA driver, shared by every container, then to the GPU.&quot; sizes=&quot;(max-width: 760px) 100vw, 720px&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;2160&quot; height=&quot;2160&quot;&gt;&lt;/figure&gt;
&lt;p&gt;You ask for this with one flag:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; --rm&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; --gpus&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; all&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; nvidia/cuda:12.6.3-base-ubuntu24.04&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; nvidia-smi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If that prints your card, the plumbing works. Newer setups describe the same devices and files in a &lt;a href=&quot;https://github.com/cncf-tags/container-device-interface&quot;&gt;CDI&lt;/a&gt; spec, a small file that Docker, Podman and containerd can all read, so the runtime doesn’t need NVIDIA-specific code.&lt;/p&gt;
&lt;h2 id=&quot;the-version-rule&quot;&gt;The version rule&lt;/h2&gt;
&lt;p&gt;Because the driver comes from the host, the host sets the ceiling. An image built for a newer CUDA than the host driver supports fails at start-up, usually with “CUDA driver version is insufficient”. &lt;code&gt;nvidia-smi&lt;/code&gt; on the host shows the highest CUDA version its driver supports. Pick images at or below it.&lt;/p&gt;
&lt;p&gt;This is why the same image can work on your workstation and fail on a cloud node: different machines, different drivers.&lt;/p&gt;
&lt;h2 id=&quot;the-part-that-runs-as-root&quot;&gt;The part that runs as root&lt;/h2&gt;
&lt;p&gt;The toolkit is the piece that reaches into the host to wire each container up, so it runs with the host’s privileges. Its bugs are container escapes. In July 2025, Wiz disclosed &lt;a href=&quot;https://www.wiz.io/blog/nvidia-ai-vulnerability-cve-2025-23266-nvidiascape&quot;&gt;NVIDIAScape (CVE-2025-23266)&lt;/a&gt;: an image could set one environment variable and get the toolkit’s start-up hook to load the attacker’s library, as root, on the host. Version 1.17.8 fixed it.&lt;/p&gt;
&lt;p&gt;Two habits follow. Keep the toolkit and GPU Operator updated like you would the kernel. And don’t run images you don’t trust on a GPU host that other people’s workloads share.&lt;/p&gt;
&lt;h2 id=&quot;sharing-one-card&quot;&gt;Sharing one card&lt;/h2&gt;
&lt;p&gt;GPUs are expensive, so teams pack several containers onto one. There are three ways to do it, and they differ in one thing that matters: whether the tenants can see each other.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://runkiri.com/blog/_astro/d2.DUt_KVet_11KeHp.webp&quot; srcset=&quot;/blog/_astro/d2.DUt_KVet_Z1tW4LD.webp 720w, /blog/_astro/d2.DUt_KVet_1vpY6j.webp 1080w&quot; alt=&quot;Three ways to share one GPU. Time-slicing: apps take turns; memory shared; no isolation. MPS: apps run together through one server; memory shared; partial isolation. MIG: the GPU is cut into hardware slices with separate memory; hardware isolation.&quot; sizes=&quot;(max-width: 760px) 100vw, 720px&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;2160&quot; height=&quot;2160&quot;&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Time-slicing&lt;/strong&gt; gives each container the whole card in turns. Easy, but memory is shared and nothing keeps one tenant out of another’s work.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MPS&lt;/strong&gt; runs several processes on the card at once through one server. Better use of the GPU, still shared memory.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MIG&lt;/strong&gt; splits a data-centre card (A100, H100 and newer) into hardware slices, each with its own memory. It is the only one of the three you should treat as a boundary.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On Kubernetes, the device plugin hands out whole GPUs (&lt;code&gt;nvidia.com/gpu: 1&lt;/code&gt;). &lt;a href=&quot;https://kubernetes.io/blog/2025/09/01/kubernetes-v1-34-dra-updates/&quot;&gt;Dynamic Resource Allocation&lt;/a&gt;, stable since Kubernetes 1.34, lets a pod ask for a GPU by its properties instead, such as memory or model. That is the path to sharing schemes like MIG without hand-labelling nodes.&lt;/p&gt;
&lt;h2 id=&quot;and-on-a-mac&quot;&gt;And on a Mac?&lt;/h2&gt;
&lt;p&gt;There’s no NVIDIA card, and the Linux VM that every Mac container runtime uses can’t see the Apple GPU through Metal. Podman’s libkrun backend gets part of the way: it passes Vulkan compute through to the host GPU, which llama.cpp can use. One user measured it at &lt;a href=&quot;https://github.com/ggml-org/llama.cpp/discussions/12985&quot;&gt;about 40% slower&lt;/a&gt; than running natively, but well ahead of CPU-only. Most Mac tooling for local models runs the model on the host instead and keeps containers for everything around it.&lt;/p&gt;
&lt;aside class=&quot;series-box&quot;&gt;&lt;p class=&quot;label&quot;&gt;Series · Containers for AI&lt;/p&gt;&lt;p class=&quot;series-t&quot;&gt;3 short parts&lt;/p&gt;&lt;ol class=&quot;parts&quot;&gt;&lt;li class=&quot;here&quot;&gt;&lt;span class=&quot;n&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;How a container gets a GPU&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;&lt;a href=&quot;https://runkiri.com/blog/posts/mcp-servers-in-containers/&quot;&gt;Run your MCP servers in a box&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;&lt;a href=&quot;https://runkiri.com/blog/posts/agent-written-dockerfiles/&quot;&gt;Review the Dockerfile your agent wrote&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/aside&gt;</content:encoded><dc:creator>Precious Okwu</dc:creator><category>Containers</category><category>AI</category></item><item><title>Run your MCP servers in a box</title><link>https://runkiri.com/blog/posts/mcp-servers-in-containers/</link><guid isPermaLink="true">https://runkiri.com/blog/posts/mcp-servers-in-containers/</guid><description>An MCP server is a program that runs as you, with your keys and your network. How to put each one in a container, and what that does and doesn&apos;t protect.</description><pubDate>Tue, 27 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;MCP servers are how coding agents get tools: GitHub, a database, a browser, your files. Adding one is a line in a config file, usually something like &lt;code&gt;npx some-mcp-server&lt;/code&gt;. That line starts a program on your machine, as you.&lt;/p&gt;
&lt;h2 id=&quot;what-that-program-can-reach&quot;&gt;What that program can reach&lt;/h2&gt;
&lt;p&gt;An MCP server started with &lt;code&gt;npx&lt;/code&gt; or &lt;code&gt;uvx&lt;/code&gt; runs with your user’s permissions. It can read your SSH keys and cloud credentials, see every environment variable the agent was started with, read any file you can, and connect anywhere on the internet. It needs none of that to list your GitHub issues.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://runkiri.com/blog/_astro/d1.DT0yVMAg_Z27cY9p.webp&quot; srcset=&quot;/blog/_astro/d1.DT0yVMAg_Z25a0aS.webp 720w, /blog/_astro/d1.DT0yVMAg_Z1CxeKv.webp 1080w&quot; alt=&quot;What an MCP server can reach. Run with npx, it runs as you and can reach your SSH keys, AWS credentials, every environment variable, every file you own and the whole internet. The same server in a container gets one token, one read-only folder and one allowed host, with no home folder and no other secrets.&quot; sizes=&quot;(max-width: 760px) 100vw, 720px&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;2160&quot; height=&quot;2160&quot;&gt;&lt;/figure&gt;
&lt;p&gt;This has already gone wrong. In September 2025, a popular npm package called &lt;code&gt;postmark-mcp&lt;/code&gt;, which let agents send email, shipped an update that quietly blind-copied every message to an outside address. Researchers at Koi Security spotted it, and the package was pulled from npm. A flaw in &lt;code&gt;mcp-remote&lt;/code&gt;, a widely used helper, let a malicious server run commands on the developer’s machine (&lt;a href=&quot;https://labs.cloudsecurityalliance.org/agentic/agentic-mcp-security-best-practices-v1/&quot;&gt;CVE-2025-6514&lt;/a&gt;, rated 9.6). Dozens more MCP vulnerabilities were reported in the first half of 2026.&lt;/p&gt;
&lt;h2 id=&quot;boxing-one-server-by-hand&quot;&gt;Boxing one server by hand&lt;/h2&gt;
&lt;p&gt;Most MCP clients only need a command that speaks MCP over standard input and output. &lt;code&gt;docker run -i&lt;/code&gt; is such a command. Here is GitHub’s official server in Claude Code’s &lt;code&gt;.mcp.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7EE787&quot;&gt;  &amp;quot;mcpServers&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7EE787&quot;&gt;    &amp;quot;github&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7EE787&quot;&gt;      &amp;quot;command&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&amp;quot;docker&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7EE787&quot;&gt;      &amp;quot;args&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;        &amp;quot;run&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&amp;quot;-i&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&amp;quot;--rm&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;        &amp;quot;--read-only&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&amp;quot;--cap-drop=ALL&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;        &amp;quot;--security-opt&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&amp;quot;no-new-privileges&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;        &amp;quot;--memory&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&amp;quot;512m&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;        &amp;quot;-e&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&amp;quot;GITHUB_PERSONAL_ACCESS_TOKEN&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;        &amp;quot;ghcr.io/github/github-mcp-server&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;      ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7EE787&quot;&gt;      &amp;quot;env&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#7EE787&quot;&gt;&amp;quot;GITHUB_PERSONAL_ACCESS_TOKEN&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&amp;quot;${GITHUB_TOKEN}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What each part buys you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;-i --rm&lt;/code&gt;&lt;/strong&gt;: talk over stdin and stdout, and throw the container away when the session ends.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No &lt;code&gt;-v&lt;/code&gt; mounts&lt;/strong&gt;: the server can’t see your home folder. If it needs files, mount one folder, read-only: &lt;code&gt;-v &amp;quot;$PWD/docs:/docs:ro&amp;quot;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;-e&lt;/code&gt; with one name&lt;/strong&gt;: the container gets that one token, not your whole environment.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--read-only --cap-drop=ALL --security-opt no-new-privileges&lt;/code&gt;&lt;/strong&gt;: it can’t modify its own image or gain privileges.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--network none&lt;/code&gt;&lt;/strong&gt; for servers that work only on local files, such as a filesystem or SQLite server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pin the image by digest (&lt;code&gt;ghcr.io/github/github-mcp-server@sha256:…&lt;/code&gt;), so an update reaches you only when you choose it. That alone would have stopped a &lt;code&gt;postmark-mcp&lt;/code&gt;-style update.&lt;/p&gt;
&lt;h2 id=&quot;many-servers-a-gateway&quot;&gt;Many servers: a gateway&lt;/h2&gt;
&lt;p&gt;Once you have five servers, five blocks of &lt;code&gt;docker run&lt;/code&gt; flags get unwieldy. A gateway is one MCP server that fronts all the others. Your client connects to it once. It starts each real server in its own container when a tool is first called, hands each one only its own secret, and logs every call.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://runkiri.com/blog/_astro/d2.C8d8qHTq_Z2nKg7H.webp&quot; srcset=&quot;/blog/_astro/d2.C8d8qHTq_Z1gEAG8.webp 720w, /blog/_astro/d2.C8d8qHTq_Z1T5vIN.webp 1080w&quot; alt=&quot;One gateway, many small boxes. An AI client such as Claude Code, Codex or Cursor connects to an MCP gateway that starts servers, adds each secret and logs every call. Below it, three containers: github with GITHUB_TOKEN and access to api.github.com; postgres with DB_URL and access to db:5432 only; browser with no secrets and web access but no LAN.&quot; sizes=&quot;(max-width: 760px) 100vw, 720px&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;2160&quot; height=&quot;2160&quot;&gt;&lt;/figure&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.docker.com/ai/mcp-catalog-and-toolkit/mcp-gateway/&quot;&gt;Docker’s MCP Gateway&lt;/a&gt; works this way: secrets are set with &lt;code&gt;docker mcp secret set&lt;/code&gt; and injected only into the container that needs them. The log matters as much as the isolation. When an agent does something odd, you can see which tool it called, with what.&lt;/p&gt;
&lt;h2 id=&quot;what-the-box-doesnt-fix&quot;&gt;What the box doesn’t fix&lt;/h2&gt;
&lt;p&gt;A container limits what a server can reach. It doesn’t limit what the server is allowed to do with the access you gave it. A GitHub token that can delete repositories still can, from inside a container. So:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Give each server the smallest token that works&lt;/strong&gt;: a fine-grained, read-only token for a server that only reads issues.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Treat tool output as untrusted text.&lt;/strong&gt; A server that fetches web pages or issues can hand your agent instructions written by a stranger. That is a prompt-injection problem, and no container solves it on its own.&lt;/li&gt;
&lt;/ul&gt;
&lt;aside class=&quot;series-box&quot;&gt;&lt;p class=&quot;label&quot;&gt;Series · Containers for AI&lt;/p&gt;&lt;p class=&quot;series-t&quot;&gt;3 short parts&lt;/p&gt;&lt;ol class=&quot;parts&quot;&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;&lt;a href=&quot;https://runkiri.com/blog/posts/containers-gpus/&quot;&gt;How a container gets a GPU&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;here&quot;&gt;&lt;span class=&quot;n&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;Run your MCP servers in a box&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;n&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;t&quot;&gt;&lt;a href=&quot;https://runkiri.com/blog/posts/agent-written-dockerfiles/&quot;&gt;Review the Dockerfile your agent wrote&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/aside&gt;</content:encoded><dc:creator>Precious Okwu</dc:creator><category>AI</category><category>Security</category><category>Containers</category></item><item><title>Security roundup: 19–25 October 2026</title><link>https://runkiri.com/blog/posts/security-roundup-2026-10-19/</link><guid isPermaLink="true">https://runkiri.com/blog/posts/security-roundup-2026-10-19/</guid><description>LiteLLM poisoned on PyPI, exploited Arista, BeyondTrust and Ivanti bugs, Node.js and Brotli fixes, and an attack aimed at AI coding agents. What developers should patch.</description><pubDate>Mon, 26 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last week was busy enough that some trackers started calling it “Black October”. Here is what matters if you write and ship software, most urgent first.&lt;/p&gt;
&lt;p&gt;A note on sources: much of this week’s coverage comes from vendor blogs and incident trackers rather than the affected companies. Every item links to where it was reported. Before you act on a version number or a deadline, check the vendor’s advisory or &lt;a href=&quot;https://www.cisa.gov/known-exploited-vulnerabilities-catalog&quot;&gt;CISA’s catalog&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;supply-chain-the-one-developers-should-read-first&quot;&gt;Supply chain: the one developers should read first&lt;/h2&gt;
&lt;h3 id=&quot;litellm-was-poisoned-on-pypi-and-docker-hub-21-october&quot;&gt;LiteLLM was poisoned on PyPI and Docker Hub (21 October)&lt;/h3&gt;
&lt;p&gt;Attackers published a malicious &lt;strong&gt;LiteLLM 1.107.0&lt;/strong&gt; to PyPI and Docker Hub. It carried an info-stealer aimed at cloud credentials, AI provider keys and developer secrets, and sent them to a server the attackers controlled. The bad release was on PyPI for about an hour and three quarters, from roughly 11:40 to 13:23 UTC.&lt;/p&gt;
&lt;p&gt;The GitHub tag for v1.107.0 was clean. That means the attackers got into the &lt;strong&gt;release pipeline&lt;/strong&gt;, not the source code, so reading the code on GitHub would not have shown anything wrong. As of 25 October, how they got in was still being investigated. (&lt;a href=&quot;https://aviatrix.ai/threat-research-center/litellm-release-pipeline-hacked-to-distribute-info-stealer-malware/&quot;&gt;Aviatrix&lt;/a&gt;, &lt;a href=&quot;https://shattered.io/litellm-supply-chain-attack-pypi-ovhcloud-cli-2026/&quot;&gt;Shattered&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you installed 1.107.0, or pulled that image, during that window:&lt;/strong&gt; treat every secret on that machine or CI runner as stolen. Rotate cloud credentials, AI API keys and tokens, then pin to a known-good version.&lt;/p&gt;
&lt;h3 id=&quot;the-pattern-hijacked-releases-not-lookalike-packages&quot;&gt;The pattern: hijacked releases, not lookalike packages&lt;/h3&gt;
&lt;p&gt;Two days earlier, five &lt;strong&gt;OVHcloud CLI&lt;/strong&gt; releases were reportedly swapped for builds that steal secrets (&lt;a href=&quot;https://agentbeam.com/blog/october-2026-software-supply-chain-incidents-tracker&quot;&gt;AgentBeam tracker&lt;/a&gt;). One weekly review calls the campaign the first publicly attributed large-scale supply-chain attack driven by agentic AI (&lt;a href=&quot;https://shieldworkz.com/blogs/cybersecurity-week-in-review-major-data-breaches-critical-vulnerabilities-and-supply-chain-attacks-(october-17%E2%80%9323-2026)&quot;&gt;Shieldworkz&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The common thread is that attackers take over a real maintainer account or release pipeline instead of publishing a package with a similar name. Checking the package name doesn’t help when the name is right. What helps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pin exact versions and commit lockfiles.&lt;/li&gt;
&lt;li&gt;Install in CI without lifecycle scripts where you can (&lt;code&gt;npm ci --ignore-scripts&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Keep long-lived secrets off the machines that install dependencies.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;exploited-right-now-patch-these-first&quot;&gt;Exploited right now: patch these first&lt;/h2&gt;
&lt;p&gt;These are on &lt;a href=&quot;https://www.cisa.gov/known-exploited-vulnerabilities-catalog&quot;&gt;CISA’s Known Exploited Vulnerabilities list&lt;/a&gt;, which means attackers are already using them.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Product&lt;/th&gt;
&lt;th&gt;CVE&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Arista VeloCloud Orchestrator (on-premises)&lt;/td&gt;
&lt;td&gt;CVE-2026-114625&lt;/td&gt;
&lt;td&gt;SQL injection, CVSS 9.9&lt;/td&gt;
&lt;td&gt;Disclosed 22 October and &lt;a href=&quot;https://www.cisa.gov/news-events/alerts/2026/10/23/cisa-adds-one-known-exploited-vulnerability-catalog&quot;&gt;added to the list 23 October&lt;/a&gt;. The federal deadline to patch is 26 October.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BeyondTrust Remote Support&lt;/td&gt;
&lt;td&gt;CVE-2026-102764&lt;/td&gt;
&lt;td&gt;Zero-day&lt;/td&gt;
&lt;td&gt;Flagged as the most urgent item of the week (&lt;a href=&quot;https://techjacksolutions.com/security/briefing/weekly-security-intelligence-briefing-week-of-2026-10-19/&quot;&gt;briefing&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ivanti Connect Secure&lt;/td&gt;
&lt;td&gt;CVE-2026-104935&lt;/td&gt;
&lt;td&gt;Authentication bypass&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.cisa.gov/news-events/alerts/2026/10/13/cisa-adds-two-known-exploited-vulnerabilities-catalog&quot;&gt;Added 13 October&lt;/a&gt; and still being exploited&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;critical-bugs-to-patch&quot;&gt;Critical bugs to patch&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Node.js&lt;/strong&gt; (&lt;a href=&quot;https://nodejs.org/en/blog/vulnerability/october-2026-security-releases&quot;&gt;advisory, 21 October&lt;/a&gt;): security releases for 22.x, 24.x and 26.x fix two bugs:
&lt;ul&gt;
&lt;li&gt;DNS resolution silently cut short hostnames that contain a NUL byte;&lt;/li&gt;
&lt;li&gt;the HTTP Agent reused connections when it shouldn’t have.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Brotli decoder&lt;/strong&gt; (CVE-2026-111497): an out-of-bounds write in versions 1.0.3 to 1.2.0. It was first disclosed for Node.js as “Node2Shell” and has since reached Python packages. Check what bundles a Brotli decoder in your dependency tree, not just your direct imports. (&lt;a href=&quot;https://github.com/kakapez/agents-radar/issues/1681&quot;&gt;HN digest&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitLab&lt;/strong&gt;: a vulnerability rated CVSS 10.0 (&lt;a href=&quot;https://shieldworkz.com/blogs/cybersecurity-week-in-review-major-data-breaches-critical-vulnerabilities-and-supply-chain-attacks-(october-17%E2%80%9323-2026)&quot;&gt;Shieldworkz&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PHP&lt;/strong&gt;: two critical remote code execution flaws (same source).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dell&lt;/strong&gt;: five flaws in Dell System Update, one of which lets an unauthenticated remote attacker run code as root (&lt;a href=&quot;https://www.esecurityplanet.com/weekly-roundup/active-exploits-ai-failures-and-data-leaks-define-the-week/&quot;&gt;eSecurityPlanet&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Certificates&lt;/strong&gt;: a compromised certificate authority was reported, and an eMudhra certificate key-generation flaw was discussed on Hacker News.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;ai-coding-agents-are-now-a-target&quot;&gt;AI coding agents are now a target&lt;/h2&gt;
&lt;p&gt;A malicious instruction file sitting in a developer’s Downloads folder tried to make their AI coding agent install a known-malicious npm package (&lt;a href=&quot;https://github.com/kakapez/agents-radar/issues/1681&quot;&gt;HN digest&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;No exploit was needed. The attack only needs an agent that reads files it was never meant to trust and then runs commands with the developer’s permissions. It is the clearest real-world case so far for running coding agents in a sandbox, with limits on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;which files the agent can read and write;&lt;/li&gt;
&lt;li&gt;which network addresses it can reach;&lt;/li&gt;
&lt;li&gt;which credentials it can see.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Many agent tools ship such a sandbox, often turned off by default (&lt;a href=&quot;https://codersera.com/blog/how-to-sandbox-ai-coding-agents-2026/&quot;&gt;guide&lt;/a&gt;).&lt;/p&gt;
&lt;h2 id=&quot;ransomware-and-breaches&quot;&gt;Ransomware and breaches&lt;/h2&gt;
&lt;p&gt;Most of these are claims posted on ransomware groups’ leak sites and have not been confirmed by the victims.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Qilin&lt;/strong&gt; listed:
&lt;ul&gt;
&lt;li&gt;the US law firm White &amp;amp; Case on 25 October (&lt;a href=&quot;https://www.hookphish.com/blog/ransomware-group-qilin-hits-white-and-case/&quot;&gt;HookPhish&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;SLTN Inter Access in the Netherlands on 24 October (&lt;a href=&quot;https://www.hookphish.com/blog/ransomware-group-qilin-hits-sltn-inter-access/&quot;&gt;HookPhish&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;Aryza on 23 October (&lt;a href=&quot;https://www.hookphish.com/blog/ransomware-group-qilin-hits-aryza/&quot;&gt;HookPhish&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;N0n&lt;/strong&gt; claimed:
&lt;ul&gt;
&lt;li&gt;the health insurer Asisken Asistencia Médica, listing 139,006 client records with diagnosis codes (&lt;a href=&quot;https://www.hookphish.com/blog/ransomware-group-n0n-hits-asisken-asistencia-medica-s-a/&quot;&gt;HookPhish&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;Texcar in Dallas, with tax records that include Social Security numbers (&lt;a href=&quot;https://www.hookphish.com/blog/ransomware-group-n0n-hits-texcar-inc/&quot;&gt;HookPhish&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Earlier in October&lt;/strong&gt; (&lt;a href=&quot;https://sharkstriker.com/blog/october-2026-data-breaches/&quot;&gt;SharkStriker&lt;/a&gt;):
&lt;ul&gt;
&lt;li&gt;ransomware forced the cloud provider IDCF Frontier to shut down, affecting 495 companies and local governments;&lt;/li&gt;
&lt;li&gt;Daiwa Securities reported more than 110,000 client records exposed;&lt;/li&gt;
&lt;li&gt;Skyticket reported 14.64 million records exposed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;this-weeks-checklist&quot;&gt;This week’s checklist&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Search lockfiles, images and CI logs for &lt;code&gt;litellm==1.107.0&lt;/code&gt; and the OVHcloud CLI. If you find either, rotate every secret that machine could reach.&lt;/li&gt;
&lt;li&gt;Update Node.js on every supported line.&lt;/li&gt;
&lt;li&gt;Find and update anything that bundles a Brotli decoder between 1.0.3 and 1.2.0.&lt;/li&gt;
&lt;li&gt;If you run Arista VeloCloud Orchestrator on-premises, BeyondTrust Remote Support or Ivanti Connect Secure, patch now and look for signs of compromise.&lt;/li&gt;
&lt;li&gt;Turn on your coding agent’s sandbox, and stop it from reading folders like Downloads.&lt;/li&gt;
&lt;/ol&gt;
</content:encoded><dc:creator>Precious Okwu</dc:creator><category>Security</category><category>AI</category></item><item><title>What&apos;s hot: agent sandboxes, Claude Fable 5.1 and TypeScript in Rust</title><link>https://runkiri.com/blog/posts/whats-hot-2026-10-26/</link><guid isPermaLink="true">https://runkiri.com/blog/posts/whats-hot-2026-10-26/</guid><description>Agent sandboxes became infrastructure, Claude Fable 5.1 and Opus 5.5 cut the cost of agent loops, and Cloudflare rewrote TypeScript in Rust. What happened, and why it matters.</description><pubDate>Mon, 26 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Three things dominated developer conversation this month: sandboxes for AI agents, a new round of Claude models, and JavaScript tooling being rewritten by agents. Here is what happened, with links to where it was reported, and what we think it means.&lt;/p&gt;
&lt;h2 id=&quot;agent-sandboxes-became-infrastructure&quot;&gt;Agent sandboxes became infrastructure&lt;/h2&gt;
&lt;p&gt;Running agent code in isolation recently stopped being a niche idea. This month, money, open-source projects and standards bodies all moved at once.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Money:&lt;/strong&gt; Daytona reportedly raised a $60 million Series B at a $1 billion valuation to build cloud infrastructure for short-lived, stateful agent jobs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Open source:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;AWS released &lt;strong&gt;Strands Box&lt;/strong&gt; in developer preview (&lt;a href=&quot;https://www.helpnetsecurity.com/2026/10/12/aws-strands-box-open-source-ai-agent-sandbox/&quot;&gt;Help Net Security&lt;/a&gt;). It combines operating-system isolation with rules that look at what an agent has already done before letting it run a command or call an API. It runs on Apple-silicon Macs, with Linux support planned.&lt;/li&gt;
&lt;li&gt;Kubernetes SIG Apps has an &lt;strong&gt;Agent Sandbox&lt;/strong&gt; project that adds a &lt;code&gt;Sandbox&lt;/code&gt; resource for untrusted agent code, using gVisor or Kata Containers underneath.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Standards:&lt;/strong&gt; the Agentic AI Foundation took on Alibaba’s &lt;strong&gt;OpenSandbox&lt;/strong&gt;, alongside Anthropic’s Agent Skills, OpenAI’s Open Responses and Hugging Face’s OpenEnv (&lt;a href=&quot;https://aiagentstore.ai/ai-agent-news/this-week&quot;&gt;AI Agents News&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The platforms:&lt;/strong&gt; a ranking published on 9 October lists six hosted options: Northflank, E2B, Modal, Daytona, Together Code Sandbox and Vercel Sandbox (&lt;a href=&quot;https://northflank.com/blog/top-ai-sandbox-platforms-for-code-execution&quot;&gt;Northflank&lt;/a&gt;; see also &lt;a href=&quot;https://modal.com/resources/best-code-execution-sandboxes-ai-agents&quot;&gt;Modal&lt;/a&gt; and &lt;a href=&quot;https://cosmonic.com/ai-sandbox/choosing-an-agent-sandbox/&quot;&gt;Cosmonic&lt;/a&gt;). They split into two camps:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Firecracker microVMs&lt;/strong&gt;, where each sandbox gets its own small VM (E2B, Vercel);&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;gVisor and similar&lt;/strong&gt;, where a user-space kernel sits between the code and the real one (Modal, and Northflank depending on configuration).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On your own machine:&lt;/strong&gt; coding agents now ship sandboxes too. Claude Code’s &lt;code&gt;/sandbox&lt;/code&gt; wraps shell commands with macOS Seatbelt, or bubblewrap on Linux and WSL2. It’s off by default (&lt;a href=&quot;https://codersera.com/blog/how-to-sandbox-ai-coding-agents-2026/&quot;&gt;guide&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Why it matters.&lt;/strong&gt; The same week, a malicious instruction file in a developer’s Downloads folder tried to make their coding agent install a malicious npm package (see &lt;a href=&quot;https://runkiri.com/blog/posts/security-roundup-2026-10-19/&quot;&gt;this week’s security roundup&lt;/a&gt;). An agent with your shell and your credentials is only as safe as the files it reads. A sandbox has to limit four things: which files the agent sees, which addresses it can reach, which credentials it holds, and what it can push to git.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Our take, as people building a container runtime.&lt;/strong&gt; An agent sandbox is a container problem with harsher rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it has to start in milliseconds, because agents start thousands of them;&lt;/li&gt;
&lt;li&gt;it has to keep state between steps;&lt;/li&gt;
&lt;li&gt;it has to treat the code inside as hostile, not just buggy.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That is why the microVM approach keeps winning, and it’s the design space Kiri works in. We’ll go deep on it in a later post.&lt;/p&gt;
&lt;h2 id=&quot;claude-fable-51-and-opus-55-agent-loops-got-cheaper&quot;&gt;Claude Fable 5.1 and Opus 5.5: agent loops got cheaper&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.anthropic.com/claude/fable&quot;&gt;Claude Fable 5.1&lt;/a&gt;&lt;/strong&gt; launched on 1 September (&lt;a href=&quot;https://www.macrumors.com/2026/09/01/anthropic-claude-fable-5-1/&quot;&gt;MacRumors&lt;/a&gt;, &lt;a href=&quot;https://venturebeat.com/technology/anthropics-claude-fable-5-1-and-mythos-5-1-arrive-with-a-75-cost-reduction-for-fable-cache-reads&quot;&gt;VentureBeat&lt;/a&gt;):
&lt;ul&gt;
&lt;li&gt;a 1 million token context window and up to 128,000 output tokens;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cache reads 75% cheaper&lt;/strong&gt;, while base prices stayed the same;&lt;/li&gt;
&lt;li&gt;Anthropic says Claude Code users should see about 60% fewer cybersecurity false positives;&lt;/li&gt;
&lt;li&gt;generated text carries an invisible watermark, with a detection API in preview;&lt;/li&gt;
&lt;li&gt;a sibling model, &lt;strong&gt;Claude Mythos 5.1&lt;/strong&gt;, has lighter safeguards and is limited to vetted security and life-sciences users.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Opus 5.5&lt;/strong&gt; followed on 22 September. Reports describe it as close to Fable 5.1 on most tasks at about 40% lower cost than Opus 5 (&lt;a href=&quot;https://technews.tw/2026/09/23/anthropic-upgrades-claude-with-new-opus-5-5-model/&quot;&gt;technews.tw&lt;/a&gt;, &lt;a href=&quot;https://www.vals.ai/models/anthropic_claude-opus-5-5-range&quot;&gt;Vals AI&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Why the cache price matters most for agents.&lt;/strong&gt; An agent loop sends the same long prefix on every step: system prompt, tool definitions and the conversation so far. Only a little is new each time. Most of the input tokens in a long agent run are therefore cache reads, and that’s the part that just got 75% cheaper. One outlet estimates typical workloads cost about 25% less, and highly agentic ones up to 45% less. We haven’t measured this ourselves yet, and the real saving depends on how well your prompts are cached.&lt;/p&gt;
&lt;h2 id=&quot;javascript-typescript-in-rust-and-a-quieter-week-for-node-and-bun&quot;&gt;JavaScript: TypeScript in Rust, and a quieter week for Node and Bun&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare announced a Rust port of TypeScript&lt;/strong&gt;, described as “written by agents, for agents”, with the line “We are not forking TypeScript” (&lt;a href=&quot;https://thenewstack.io/javascript/&quot;&gt;The New Stack&lt;/a&gt;). It’s two trends at once: JS tooling moving to native code, and agents doing large rewrites.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bun 1.4.3&lt;/strong&gt; added &lt;code&gt;bun check&lt;/code&gt;, a built-in TypeScript type checker, and 1.4.4 focused on getting package installs right and fast (&lt;a href=&quot;https://en.wikipedia.org/wiki/Bun_(software)&quot;&gt;Bun&lt;/a&gt;, &lt;a href=&quot;https://jsdevspace.substack.com/p/friday-links-45-fresh-tools-frameworks&quot;&gt;JSDevSpace&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Node.js&lt;/strong&gt; shipped 26.12.0 and 24.22.0 on 14 October, then &lt;a href=&quot;https://nodejs.org/en/blog/vulnerability/october-2026-security-releases&quot;&gt;security releases on 21 October&lt;/a&gt; for 22.x, 24.x and 26.x. Update.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;also-on-hacker-news&quot;&gt;Also on Hacker News&lt;/h2&gt;
&lt;p&gt;From last week’s front-page digests (&lt;a href=&quot;https://github.com/kakapez/agents-radar/issues/1681&quot;&gt;1&lt;/a&gt;, &lt;a href=&quot;https://github.com/yaojiejia/agents-radar/issues/365&quot;&gt;2&lt;/a&gt;, &lt;a href=&quot;https://zeli.app/digest/2026-10-24&quot;&gt;3&lt;/a&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kimi K3.1 Pro&lt;/strong&gt; drew the most attention of any model release.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenShell&lt;/strong&gt;, a runtime for autonomous agents, was discussed as a way to run them in isolation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Astral&lt;/strong&gt; shipped an experimental integration between uv, its Python package manager, and ty, its type checker.&lt;/li&gt;
&lt;li&gt;A post on &lt;strong&gt;building a container runtime from scratch&lt;/strong&gt; did well. Its takeaway was that containers are just processes with kernel restrictions, which we agree with, and which is where most of the interesting work is.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Most links here are secondary coverage. Where numbers matter to you, check the vendor’s own announcement.&lt;/em&gt;&lt;/p&gt;
</content:encoded><dc:creator>Precious Okwu</dc:creator><category>AI</category><category>Containers</category></item></channel></rss>