DEV Community

Cover image for Where Cloudflare OS Ends and SSH Begins
soy
soy

Posted on • Originally published at media.patentllm.org

Where Cloudflare OS Ends and SSH Begins

On August 5, 2026, Cloudflare open-sourced what it calls "Cloudflare OS" — an AI agent workspace built on Workers, Durable Objects, and a capability-based security model called Gatekeepers. Despite the name, it is not an operating system. It is a sandboxed environment where non-technical users can ask AI agents to build small applications ("Gadgets"), connect them to external services through controlled interfaces, and share the results as copyable templates ("Blueprints").

This post is not a review. It is an architectural comparison. I run a production stack that solves overlapping problems using different primitives — SQLite FTS5, Cloudflare Tunnel, vLLM, Tailscale SSH — and I want to examine what Cloudflare OS actually adds, what it trades away, and where the boundary sits between people who need it and people who don't.

What Cloudflare OS solves

The product's real thesis lives in one component: the Gatekeeper.

Gadgets, Blueprints, Durable Objects, real-time multiplayer — these are useful, but they are not new. The new idea is: when an AI agent acts on your behalf, it should never hold ambient access to anything. Each agent gets introduced to specific resources, one at a time, through a Gatekeeper that logs every action and can simulate outcomes before committing them.

This is a direct response to --dangerously-skip-permissions. When Claude Code asks "Allow this tool call?" and you click "always allow" because you're tired of clicking, you have just handed your agent the keys to your filesystem, your environment variables, and your SSH credentials. Cloudflare OS says: don't hand over the keys. Put a proxy in between.

Everything else — the Gadget sandbox, the Blueprint sharing, the Cap'n Web RPC that Gadget clients and servers are required to speak — is infrastructure built to make the Gatekeeper model practical. Without sandboxing, Gadgets could bypass Gatekeepers. Without Blueprints, every user would need an engineer to set up their Gadgets. The security layer is the product. The rest is scaffolding.

My stack, mapped to a grid

I maintain several production services on personal infrastructure: a US patent corpus indexed with SQLite FTS5, a semantic search over Japanese statute law covering 241,879 articles across 8,928 laws, a route-optimization PWA for recycling logistics, and a local LLM inference server running Nemotron-9B on an RTX 5090 via vLLM.

Across these projects, I use three delivery methods and four interaction layers. The grid:

                  A: Code handoff        B: Tunnel / URL         C: Tailscale SSH
                  (localhost execution)  (remote access)         (direct VPS ops)
───────────────────────────────────────────────────────────────────────────────────
① Human + code    Distilled HTML/WASM    HoureiLLM search UI     Edit FastAPI on VPS
  (Python/HTML)   handed to recipient    PatentLLM search UI     via vim, deploy with
                  to run locally         Recycle Paperless PWA   systemctl restart

② AI touches      —                      —                       Claude Code edits
  local data                                                     code and DB on VPS
  (agent writes
   and executes)

③ AI agent        —                      Nemotron CLI →          —
  (text in/out,                          vLLM on port 8000
   no data write)                        (streaming, async)

④ External svc    —                      Notion MCP              —
  (MCP / API)                            Google Drive MCP
                                         Clasp → GAS
Enter fullscreen mode Exit fullscreen mode

A few things to notice:

Column A is the densest. Most of what I ship to others is distilled code — HTML, WASM, sometimes a SQLite dump — that the recipient runs on localhost. No server, no account, no dependency on my infrastructure. I use Claude to compress the codebase to its essential parts before handoff. This is a human-curated alternative to Blueprints, and it is more selective: I choose what to include and what to strip. Blueprints copy the entire Gadget.

Column B is the most diverse. Tunnel-exposed services span all four rows: static search UIs with no AI involved (row ①), the Nemotron CLI streaming responses from vLLM (row ③), and MCP-connected services operating on third-party data (row ④). Cloudflare Tunnel is the unifying access layer, but each service behind it is independent.

Column C exists. I can SSH into any VPS, read any config file, run any command. This is the escape hatch. When an abstraction breaks — and they all break eventually — I can drop below it.

Cloudflare OS on the same grid

Now overlay Cloudflare OS onto the same framework:

                  A: Blueprint share     B: Workers URL          C: (does not exist)
───────────────────────────────────────────────────────────────────────────────────
① Human + code    Publish Blueprint,     Access Gadget via       ×
                  recipient forks        browser

② AI touches      AI builds Gadget →     AI reads/writes the     ×
  data            shared as Blueprint    Gadget's Durable
                                         Object state
                                         Gatekeeper mediates
                                         external access

③ AI agent        —                      Code Mode task          ×
  (text only)                            execution

④ External svc    —                      Gatekeeper →            ×
                                         GitHub / Google /
                                         Slack / Notion
Enter fullscreen mode Exit fullscreen mode

Column C is gone. This is the most consequential architectural difference. There is no SSH equivalent. You cannot drop into a shell inside a running Gadget to inspect state, patch code, or debug a failed operation. The abstraction is the only interface.

A necessary precision: this limitation applies to the execution unit, not the host. Cloudflare OS is not locked to Cloudflare's edge — it can run on your own servers on top of workerd, the open-source Workers runtime, and there you can SSH into the box. But you cannot reach into a specific Gadget's runtime the way you can attach to a running container or read a process's open file descriptors. The Gadget boundary is opaque by design — that opacity is what makes the security model work.

Column B absorbs everything. All four rows collapse into a single access pattern: Workers URL. Search UIs, AI agents, MCP integrations, Gadget interactions — everything is a Workers request routed through the same platform. My stack keeps these as independent services with independent failure modes. Cloudflare OS trades that independence for unified management.

Column A changes meaning. My code handoff involves human judgment about what to include — a distillation step where Claude helps compress a codebase to its portable essentials. Cloudflare OS Blueprints are full Gadget copies with no selective packaging. The recipient can fork and modify, but the sender cannot curate what ships. As of this writing the documentation describes no versioning, tagging, or changelog mechanism for Blueprints, and no .gitignore equivalent — a Blueprint is a copy of the code, not a release.

Who decides which row to use?

This is an underexplored question. In my stack, I make the routing decision: this task needs FTS5 search (row ①), that task needs Nemotron inference (row ③), this other task needs MCP to update Notion (row ④). I know what each layer does and doesn't do.

In Cloudflare OS, that decision moves toward the agent. The harness is explicitly a Code Mode agent — it "performs tasks by writing and immediately executing snippets of code" — and it can request an introduction to a resource rather than being handed one up front. The user says "update the project status in our GitHub repo," and the work of getting from that sentence to an authorized, scoped, logged write against a specific repository happens inside the platform.

This is the right model for organizations where users do not know (and should not need to know) what row they are on. A sales rep updating a CRM dashboard does not care whether the operation is a Durable Object write or an API call through a Gatekeeper. They care that it works and that it does not break anything.

It is the wrong model for someone who needs to know exactly what is happening at each layer. When the Nemotron CLI sends a request to vLLM on port 8000, I can tcpdump the traffic. When a Gadget calls a Gatekeeper, the Gatekeeper logs the action — that part is well covered — but the step before it, where the agent decided to write this snippet of code and traverse that Gatekeeper, is a model decision. Logs tell you what happened. They do not tell you what the model almost did instead.

The honest weakness in my stack

It would be easy to stop here and declare that the SSH-accessible, git-versioned, manually-routed stack is strictly superior. It is not.

My Claude Code session can read .env files containing API keys. It can run sudo systemctl restart on production services. It can push directly to main without a PR. When I use claude -p in a script, it inherits my shell's full permissions. There is no Gatekeeper between the agent and my infrastructure.

This is fine for a single developer operating on their own VPS. It is not fine the moment someone else's data or infrastructure is in scope. If I hand a colleague a Claude Code session pointed at a shared repository, they inherit my permissions — or worse, the agent does.

GitHub's org-level permissions protect repositories, but they do not protect what happens inside a Claude Code session that has cloned a repo. The agent can read secrets from the local environment, make network calls, modify files outside the repo. GitHub guards the gate to the repo; nothing guards what happens after the clone.

This is exactly the gap Cloudflare OS's Gatekeeper fills. It does not protect the repo — it protects the session. Every action the agent takes inside the session is mediated, logged, and (for side effects) queued for approval. The Gatekeeper is not guarding a resource at rest; it is guarding an agent in motion.

How Anthropic solves this internally

Anthropic published a case study documenting how its internal teams use Claude Code. The architecture is instructive, and notably ordinary.

Their collaboration infrastructure is GitHub repositories plus shared context files. CLAUDE.md sits at the project root and gets read by Claude on every session — the Infrastructure and Security Engineering teams both lean on this. Specialized sub-agents handle decomposed work: Growth Marketing's ad pipeline uses two of them to generate hundreds of ad variations. Non-technical teams use Claude Code directly — Legal built a phone tree that routes people to the right attorney, and Data Science builds JavaScript visualizations without knowing JavaScript.

(The case study documents CLAUDE.md and sub-agents. Skills — folders that package scripts, assets, and instructions into a toolkit Claude can load on demand — are a separate mechanism in the product line and are not described in that particular write-up. I mention them because they are the natural place team knowledge accumulates, not because Anthropic's case study attributes anything to them.)

There is no Cloudflare OS equivalent in this stack. No Gadget sandbox, no Gatekeeper, no Blueprint sharing. The security boundary is GitHub's org permissions plus each engineer's judgment about what to allow in a Claude Code session.

This works at Anthropic because the workforce is unusually well calibrated to what an agent is doing on their behalf. The open question is whether that model transfers to an organization where most users cannot evaluate what an agent is about to do with their permissions.

When you need Gatekeepers

The decision framework is simpler than the architecture suggests. You need Cloudflare OS's model when:

The agent's permissions reach someone else's assets. A solo developer on their own VPS can accept the risk of ambient permissions. The moment the agent can modify a shared database, send an email on behalf of a team, or write to a customer-facing system, the blast radius of a mistake extends beyond the person who issued the instruction.

The person issuing instructions cannot evaluate the agent's plan. A developer who reads the tool-call log and understands DELETE FROM orders WHERE status = 'draft' can catch a mistake before it executes. A sales rep who asked the agent to "clean up old drafts" cannot. The Gatekeeper's simulate-then-approve flow bridges this gap — the user sees the outcome of the action before it commits, without needing to read the code.

The action is irreversible toward an external system. Sending 3,000 campaign emails, posting to a public API, executing a financial transaction. These are not git revert situations. An approval queue is the only practical safeguard when the agent operates on systems that have no undo button.

If none of these conditions apply — if you are a developer, working on your own infrastructure, with full understanding of what your tools do — then the 3×4 grid with SSH at the bottom is more capable, more transparent, and more maintainable than any sandboxed platform. The escape hatch is not a crutch. It is the reason the system stays debuggable as complexity grows.

Cloudflare OS is not the wrong answer. It is the answer to a different question — one that most solo developers and small technical teams are not asking yet, but that every growing organization will eventually face.


I build local-first AI tools on SQLite, vLLM and Cloudflare Tunnel. Related work: PatentLLM (US patent search on FTS5), HoureiLLM (semantic search over 241,879 articles of Japanese statute law), and a small async CLI for Nemotron-9B that replaces most of what agent frameworks do. Descriptions of Cloudflare OS in this post reflect the repository documentation as of 2026-08-16.

Top comments (0)