Cloudflare open-sourced an operating system that you can only run on Cloudflare.
That sentence landed at 612 points on Hacker News on August 5, 2026, when Cloudflare launched Cloudflare OS — an open-source agent workspace with zero-access-by-default agents, a "Gatekeeper" Worker mediating every external call, and agent-built apps deployed as Dynamic Workers with per-app SQLite via Durable Object Facets. The repo is public. The starter template is a git clone away. And "self-hosting" it means deploying that starter into your own Cloudflare account.
The code is open. The only supported substrate is still one company's proprietary network. That distinction matters more than the star count.
If you care about what "open source" lets you actually control — where data sits, what runtime you can patch, how you leave — here is the question Cloudflare OS forces you to ask, answered in one table before the rest of the post earns it.
The One-Table Answer
This is the core deliverable: the same six dimensions, scored for both models.
| What you control | Cloudflare OS (open code, Cloudflare-only substrate) | Apache-2.0 PaaS on your own machines (e.g. Bex.co on Cluster API + Hetzner) |
|---|---|---|
| Code license | Repo is open source; you can read, fork, and PR. | Entire control plane is Apache-2.0. Same freedoms, broader scope — builders, routers, TLS, scheduler are all in-repo. |
| Where it runs | Only on Cloudflare's edge — Workers runtime, Durable Objects, D1/SQLite facets. No local wrangler dev equivalent that fully replicates prod. | Anywhere Kubernetes runs — your Hetzner box, an on-prem rack, another cloud's VMs. You choose the metal. |
| Data & storage locus | Per-app SQLite via Durable Object Facets, housed inside Cloudflare's storage fleet. You own the account tenancy, Cloudflare operates the disk. | Postgres/SQLite on a volume you provision, in a data center you rented, on a disk you can snapshot and move with pg_dump and no vendor API. |
| Network substrate | Cloudflare's global network — Argo, anycast, 300+ PoPs. You do not operate the L3. | WireGuard + your own ingress (Envoy/Traefik) on nodes you operate. You trade global PoP density for L3 control and no egress-vendor lock-in. |
| Runtime you can patch | You can patch the agent workspace and Gatekeeper Worker. You cannot patch workerd, Durable Objects, or the Durable Object Facets implementation — those are closed. | You can patch every layer — kubelet, containerd, buildpack runner, router — because every layer is a container image you built. |
| Exit path | Leave Cloudflare = rewrite the app off Workers semantics (Durable Objects, Facets, Workers bindings). No drop-in second substrate. | Leave a vendor = kubectl still works, containers still run, App CR still applies. Second substrate is a new MachineDeployment. |
Read it left to right for the headline: Cloudflare OS maximizes what you can change at the app layer while keeping where it physically executes single-vendor. An Apache-2.0 PaaS on your own machines maximizes where and how it executes while keeping the app abstraction deliberately boring (standard containers, standard Postgres, standard HTTPS).
That tradeoff is the whole post. The sections below substantiate each row.
What Cloudflare OS Actually Shipped on August 5
The launch was not a slide deck. Cloudflare pushed a repo and a starter that already resembles a usable product, which is part of why HN paid attention. The pieces that matter for the "what is open" question:
-
Open-sourced agent workspace. The canvas where a user chats with agents, assigns tasks, and reviews agent-built apps. Open in the literal sense: you can clone it, run it, and modify the UI and orchestration. It is the first time Cloudflare has open-sourced the workspace layer of an agent runtime rather than just an SDK or CLI.
-
Zero-access-by-default agents. Agents start with no ambient permissions. Every read of a file, every API call, every shell spawn must be explicitly granted. That is a security architecture choice, not just a UX one — the agent cannot exfiltrate what it was never given.
-
Gatekeeper Workers mediating every external call. Between the agent and the outside world sits a Worker that enforces policy: allowlist checks, rate limits, audit logging. In Cloudflare's diagram, no agent touches the internet directly; the Gatekeeper does, synchronously, with a Durable Object often holding session state. If you have operated a Zero Trust gateway before, the mental model is familiar — just implemented as an edge function you can fork.
-
Agent-built apps deployed as Dynamic Workers with per-app SQLite via Durable Object Facets. This is the most substantive architectural bet. When an agent builds an app for you (a dashboard, a handler, a small API), that app is not a static asset upload. It becomes a Dynamic Worker — a Worker minted at runtime with its own isolate — backed by a per-app SQLite database exposed through Durable Object Facets, the mid-2026 primitive that lets a single Durable Object expose multiple coordinated SQLite databases without sharding workarounds. Each app therefore gets isolated compute and isolated storage without Cloudflare provisioning a container per app.
Taken together, the architecture is coherent and Cloudflare-native in the way you would expect: everything composes from primitives Cloudflare already operates at scale (isolates, Durable Objects, SQLite at the edge, Workers bindings). That is also why the openness question is pointed rather than pedantic — those primitives are precisely the parts that are not open.
Why "Deploy to Your Cloudflare Account" Is Not Self-Hosting in the Traditional Sense
Self-hosting has had a stable informal definition for two decades: you can run the same software on a machine you physically or contractually control, without asking any single vendor for permission to keep it running tomorrow, and you can move the data with tooling you also control.
By that definition, Cloudflare OS's self-hosting story is thin, and the HN thread's skepticism was predictable. Compare the checklist that a team evaluating a self-hosted PaaS normally walks:
| Self-hosting test | Traditional meaning | Cloudflare OS meaning |
|---|---|---|
| Can I run this without a vendor account? | Yes — docker compose up or k3s on a Hetzner AX, a home lab NUC, an air-gapped rack. | No. The Workers runtime and Durable Objects do not have a production-equivalent you can run outside Cloudflare. workerd is open, but the surrounding storage/network/control plane is not. |
| Who operates the OS/kernel/hypervisor? | You (or your IaaS) — you can patch containerd, replace the CNI, rotate the host cert. | Cloudflare operates the isolate host and the object store. You operate config and bindings. |
| Can I move the data without vendor tooling? | Yes — pg_dump, rsync, S3-compatible copy with any client. | SQLite via Durable Object Facets is addressable through Cloudflare bindings and APIs; bulk export exists but is mediated by Cloudflare's data plane, not by mounting a volume. |
| What happens if the vendor raises prices or changes terms? | You keep running at your contracted hardware price (Hetzner's 2026 hikes notwithstanding, the instance you haven't rescaled stays at the old price) and migrate the PaaS layer by moving containers. | Your bill is Cloudflare's meter — Workers invocations, Durable Object GB-hours, D1/SQLite rows read. You negotiate with one price list and one terms-of-service. |
| Can I fork the runtime? | Yes — Apache-2.0 control plane, fork it and keep shipping. | You can fork the workspace and Gatekeeper; forking the Workers runtime into a second global edge is not the same operation. |
None of this makes Cloudflare OS closed source, and calling it closed would be inaccurate. The repo is open, contributions are possible, and deploying into your own account does give you meaningful tenancy isolation (your data, your bill, your audit log) versus a vendor-hosted SaaS tenancy where another customer's workload shares the same logical DB.
The category error is conflating account isolation with substrate independence. You own the account; you do not own the substrate. For many teams that distinction is immaterial — they already live on Cloudflare and prefer to — but for the segment that self-hosts because they need substrate independence (regulated data, cost-capped hardware, survival if any single vendor changes the deal), the label matters.
This is not a new tension. Vercel open-sourced Next.js while the only production substrate that fully replicates Vercel's runtime is Vercel. Supabase open-sourced its Postgres + realtime layer while the managed offering's advantage is the surrounding network, auth, and storage you do not recreate by cloning the repo. Cloudflare OS is a sharper version of the same shape — more of the system is open, but the part that makes the system global, fast, and Durable-Objects-consistent remains single-vendor.
The Other Pole: Apache-2.0 on Machines You Own
If the Cloudflare model is "open code, single substrate," the brute-force alternative is "open code and open substrate" — a PaaS whose entire control plane is Apache-2.0 and whose substrate is a Kubernetes fleet you provision into an account you already pay.
Bex.co is a concrete reference for that pole because it is explicit about the design constraint: push a git repo, get a running HTTPS service on machines you own, via a Cluster API fleet you also own. No hidden cloudflare:* or vercel:* bindings in the app contract.
What that looks like against the same six rows, made operational:
# An App CR that runs the same on Hetzner, AWS VMs, or your lab rack.
# The PaaS doesn't care where the MachineDeployment's nodes live.
apiVersion: paas.bex.co/v1
kind: App
metadata:
name: agent-workspace
spec:
git: https://github.com/acme/workspace
build: { pack: "heroku/nodejs" }
env:
- name: DATABASE_URL
value: postgres://app:secret@postgres.internal/acme
domains:
- workspace.acme.team
scale: { min: 1, max: 4 }Three properties that the table above compresses into rows but that are load-bearing in production:
-
The build, the router, and the TLS terminator are all containers you can inspect. Buildpacks run in a Job on a node you provision. TLS is
cert-manager+ Let's Encrypt in-cluster, not a vendor's certificate edge. The ingress is Envoy or Traefik you configured. Patching the router is a container image bump, not a support ticket. -
The fleet is hardware-portable by design. The same manifests that provision three
MachineDeploymentson Hetzner Cloud can provision one on Hetzner + one on an on-prem ProxmoxCluster APIprovider + one on AWS spot. The PaaS is not the machine; the machine is a replaceable node pool. Hetzner's own 2026 price moves (an April broad hike, then a June jump of 113–176% on CPX/CCX shared-vCPU lines) are exactly why node-pool portability is not theoretical trivia — you keep old instances at their old price until a rescale, but new capacity prices at the new list. Owning the fleet lets you provision the next pool somewhere cheaper without rewriting apps. -
Data moves like data, not like export jobs. A tenant Postgres is a container with a volume.
pg_dumpover WireGuard, a volume snapshot, or a WAL-replayed replica are all vendor-agnostic because Postgres itself is vendor-agnostic. Per-app SQLite on Cloudflare is elegant; per-app Postgres on your own volume is portable.
None of this is a claim that operating your own fleet is less work than owning a Cloudflare account. It is a claim that the kind of work is different — and that the residual risk you retain (you must patch nodes, you must operate storage) is the complement of the residual risk you shed (no single vendor's runtime, network, or bill is load-bearing for every app).
A Fork-and-Exit Test: Four Checks Before You Build on Either
A satisfying table is not the same as a decision. Use this checklist — applied identically to both platforms — to test which openness actually matters for your workload. Score each as yes/no; the pattern of no-answers is more useful than a single aggregate.
1. Can I run this workload with no vendor API reachable?
- Cloudflare OS: No for prod. You can develop portions locally, but the Dynamic Worker + Durable Object Facets + SQLite shape is not reproducible offline without Cloudflare's data plane.
- Apache-2.0 fleet: Yes. Air-gap the rack, keep the container images mirrored, and the
AppCR still reconciles. You lose global anycast, not the ability to serve.
2. Can I move the data off the platform with tooling I already own?
- Cloudflare OS: Partially. Cloudflare provides export APIs for D1/Durable Object storage, but the tool is Cloudflare's. You are exporting from Cloudflare, not copying between two Postgreses you control.
- Apache-2.0 fleet: Yes — standard
pg_dump/pg_restore, volume snapshots, or S3-compatible sync with any client. The egress is bandwidth you provision, not a per-row API meter.
3. Can I patch the runtime when I need to, not when the vendor ships?
- Cloudflare OS: For the workspace and Gatekeeper, yes. For the isolate runtime and Durable Objects, no — you ship a fix to Cloudflare's runtime boundary by deploying a new Worker that works around it.
- Apache-2.0 fleet: Yes at every layer, because every layer is a container image: patch
workerdif you self-host a Workers-compatible runtime, patch the builder, patch the ingress. The operational cost is real, but so is the capability.
4. What happens if the vendor doubles a price or deprecates a primitive?
- Cloudflare OS: You renegotiate or you rewrite off Durable Object Facets and Dynamic Workers. There is no second Workers-cloud that speaks the same bindings without Cloudflare. The August 2026 launch is early — that is the moment to sketch the rewrite cost, not after 50 apps depend on per-app SQLite semantics.
- Apache-2.0 fleet: You reprice only the next
MachineDeployment. Existing Hetzner instances hold their old price until a rescale; even at new prices, spot and dedicated markets compete for the next pool. The deprecation risk is distributed across open components (K8s, buildpacks, Envoy) rather than concentrated in one vendor's roadmap.
When to accept four no-answers and pick Cloudflare anyway? When the asset you are buying is Cloudflare's network itself. If your app's value proposition is "runs at 50 ms from every eyeball, with SQLite at the edge that no DIY fleet replicates at that latency without a global build-out," the substrate lock-in is the point. Many agent-built dashboards, webhook handlers, and edge auth proxies are exactly that — they have no regulated-data tail and no 12-month hardware budget to protect, and the team correctly values edge density over forkability.
When to require four yes-answers? When the workload carries data that cannot be re-exported on vendor terms, when the team needs to show an auditor a volume it can unplug, when the hosting forecast must survive two repricings in one half-year without re-architecting, or when the whole point of self-hosting was to place a margin-free fleet between the team and the billing pages that, in the first half of 2026 alone, moved at Render, Vercel, Netlify, Fly, Docker Hub, Hetzner, and OVHcloud in the same six months.
The self-hosted PaaS does not have to win that comparison on every workload to be the right platform. It only has to win it on the workloads that would have forced a rewrite anyway — and to keep losing it gracefully on the rest by letting those apps call a Cloudflare Worker or a managed SQLite endpoint from a container that still runs on hardware the team controls. A fleet that can run its own Postgres and call someone else's distributed SQLite without rewriting either app is hedged in a way that a single-substrate workspace, however open its repo, structurally cannot be.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. No per-seat meter, no single-vendor runtime under your apps, just standard containers on a Cluster API fleet you control. Star the repo on GitHub or deploy your first app today.