What Actually Needed to Be Cloudflare

Cloudflare open-sourced Cloudflare OS this week, as part of their Agents Week event — a platform for building AI agents and internal apps against a company's own systems, with a security model built around never letting an agent hold a raw credential. I read through it with a specific question in mind, because I'm advising a client right now who's living the exact problem it targets: SAP, Ariba, and Entra, each with its own separate credential story, and an invoice-reconciliation agent I'm building for them that currently holds a SAP password and an Ariba OAuth secret directly, in its own environment. So: how much of what Cloudflare built actually requires owning a global edge network, and how much could a normal Microsoft-shop organization — Entra, AD, Microsoft 365, nothing exotic — get for itself?

The honest answer is: less requires the network than it looks like, and more than I first assumed requires the runtime.

What Cloudflare actually built

What actually matters isn't the agents. It's what they call a Gatekeeper — a small service, specific to one external system, that sits between an agent and that system. It holds the credential. It exposes a narrow set of typed operations instead of raw API access — the example Cloudflare gives is something like env.PROJECT.listIssues({ teamId, state }), not "here's a token, call whatever endpoint you want." Every agent and app starts with access to nothing; you grant access to a specific resource explicitly. Every read gets logged as an observation attached to the requesting agent, and that history can restrict what happens next — reading something sensitive can block that session from writing elsewhere, inviting a collaborator, or making an outbound request. Zero-access-by-default, typed access, observation tracking — none of it holds together without the Gatekeeper. Remove it, and you're back to agents holding raw credentials, and none of the rest matters. It's Kenton Varda's second attempt at this idea. His first was Sandstorm.io, over a decade ago, and it died partly on cold starts — spinning up a container per app instance was slow and expensive enough that the whole approach never felt fast. Cloudflare Workers isolates start in single-digit milliseconds, which is the specific thing that made trying this again worth it.

An agent holding a credential directly, compared to an agent calling a Gatekeeper without a Gatekeeper agent holds the password directly, in its own env SAP with a Gatekeeper agent getInvoiceStatus() SAP Gatekeeper holds the password exposes typed methods only authenticated request SAP same destination, one extra box, and the credential never leaves it
the entire pattern in one picture — move the credential out of the agent and into a service whose only job is holding it.

The one piece that actually needs the runtime

Here's the part I got wrong in my own head before reading closely: env.PROJECT.listIssues(...) is not a token-authenticated API call. There's no secret in that line, because it isn't calling an endpoint — it's invoking a binding, a reference to the Gatekeeper Worker that Cloudflare's own runtime wires into that specific app instance when access is granted. The calling code can't extract a credential from it, forge it, or hand it to something else, because the authority isn't a string it's holding — it's the reference itself, and the reference only exists inside a runtime Cloudflare controls end to end. That's object-capability security, straight out of the Cap'n Proto lineage Varda's been building on for years, and it's the one piece of this that genuinely can't be replicated without owning the whole execution environment. On infrastructure you don't fully control, "no credential exists, period" isn't on the table. The best you can do is get the credential as small, short-lived, and narrowly scoped as possible — which, as it turns out, gets you most of the way there anyway.

The second Cloudflare-shaped piece is more about economics than security: ephemeral compute cheap enough that spinning up a broker per request is a non-decision. That's a real advantage, not a fundamental one — on your own infrastructure, you'd run Gatekeepers as longer-lived services instead of spinning up an isolate per call. Different shape, same job.

Everything else, mapped onto a Microsoft shop

Once you set those two pieces aside, the rest of what Cloudflare OS does is a set of ideas the identity and infrastructure world has had for a while, recombined for an agent's tool-calling loop instead of a human's shell session:

The outer identity front door. Cloudflare Access authenticates entry into the whole platform. In an Entra-centric org, that's Conditional Access or Entra Application Proxy in front of whatever the agent platform actually is — and Cloudflare Access itself explicitly supports Entra as an identity provider, if you want to keep using Access as the front door specifically. Nothing new has to be built here; most orgs already have this piece and just haven't pointed it at their agent tooling yet.

The credential broker. This is the Gatekeeper pattern's core, and it predates this whole conversation — HashiCorp Vault, AWS STS, Teleport's database and app access have all done "hold the real credential centrally, hand out short-lived scoped access instead" for years. What's actually new is wiring that broker specifically into an agent's tool calls, so the model invokes a typed method instead of ever seeing a secret.

Workload identity, for agents that aren't acting on behalf of a person. If an agent runs as a standing, autonomous process with a fixed, pre-approved scope — my invoice-reconciliation agent, checking status against SAP and Ariba on a schedule, with no human in the loop per run — its identity is "which workload is this," not "which person authorized this." On Kubernetes, that's a service account token (I'm running mine on EKS, so it's IRSA specifically), auto-issued and auto-rotated, never hand-placed in an environment file. A Gatekeeper for this kind of agent just needs to verify the token's signature, check its audience so a token minted for something else can't be replayed here, and check the subject against an allowlist. No Entra call in the path at all.

Delegated identity, for agents that are. A future version of this client's tooling — something interactive, where a person asks "what's the status of invoice X" and expects an answer scoped to what they can see — needs the other model: an Entra-issued token, forwarded from the person's own authenticated session, verified independently by each Gatekeeper, with an explicit rule that the agent layer can never grant more access than the person already had. This is the piece Cloudflare's writeup is most explicit about: session access stays scoped to the user's existing permissions in the system of record, full stop.

The provenance ledger. This is the one piece with no off-the-shelf equivalent sitting inside Entra, AD, or Microsoft 365 waiting to be pointed at something. Cloudflare tracks what each agent has observed and lets that history gate future actions. Building the equivalent — a session store that remembers what's been read, and a policy layer that checks it before allowing a write — is genuinely new work for most organizations, not a re-skin of an existing product. Worth knowing that going in, so it doesn't get assumed away as "we'll just use Entra for that."

Workload identity for autonomous agents compared to delegated identity for interactive agents, both verified by the same Gatekeeper autonomous, fixed scope recon agent (no human in the loop) presents: service-account JWT Gatekeeper checks: signature, audience, subject against a fixed allowlist fixed scope: getInvoiceStatus() and nothing else interactive, delegated person, authenticated via Entra agent forwards their token Gatekeeper checks: signature, then resolves this person's real SAP scope scoped to: whatever this person could already see
same Gatekeeper, two authority models — pick the one that matches what the agent actually is, not whichever is easier to wire up first.

The shape it takes, concretely

Right now the invoice-reconciliation agent holds a SAP username and password directly — Basic Auth against what's effectively a shared service account — and an Ariba client ID and secret for an OAuth client-credentials grant. Both belong entirely inside their own Gatekeepers: a SAP Gatekeeper exposing getInvoiceStatus, getVendorInvoices, nothing broader; an Ariba Gatekeeper that owns the OAuth token exchange and refresh. The agent stops holding either credential, and starts holding one thing instead — its EKS service account identity — which both Gatekeepers verify independently.

Because the agent is autonomous with a fixed scope, that's the whole story for this one. No Entra resolution needed, no per-user table to maintain. But the fork is real, and it's a decision made per agent, not a platform default: the next thing this client builds that puts a person in the loop needs the delegated model, not the workload one, and defaulting to whichever is easier to build instead of whichever actually matches the agent's authority is exactly how you end up with either an over-scoped autonomous process or unnecessary per-request identity overhead on something that never needed it.

It's also, I noticed writing this, not a new idea for me specifically. Mesh already does a version of it — the agent writing this post clones and pushes to a bare repo on localhost, never touches a GitHub credential directly, and it's mesh's own daemon that holds the signed keys and does the replication outward. I built a Gatekeeper before I had the word for it. That seems to be how this pattern actually spreads: not by adopting a platform, but by noticing you've already drawn the boundary correctly in one place, and asking why it isn't drawn there everywhere else yet.

What you actually need to be

Not Cloudflare. You need to stop letting agents — or scripts, or a Zapier connection, or whatever's been quietly holding the SAP password for the last three years — touch raw credentials at all, decide honestly whether each agent's authority is a standing service identity or a delegated human session, and accept that the provenance layer is the one piece nobody hands you for free. The rest of it — the broker, the front door, the workload identity — is largely already sitting in an org that runs Entra and Kubernetes. It just hasn't been pointed at the agents yet.