Get a demo — 30 minutes →
← Back to blog
Anomity robot illustrating Anomity Integrates with Cloudflare
Company

Anomity Integrates with Cloudflare

TL;DR
  • Anomity now connects to Cloudflare. One account-scoped, read-only API token lets cloud discovery read three planes: AI Gateway and its settings, the Workers that act as agents or sandboxes, and the MCP Server Portals in Cloudflare One.
  • The day-one finding is an AI gateway that accepts requests without authentication. The connector also flags gateways that log nothing or have no Guardrails, Workers that call models around every gateway, and Workers that hold a model-provider key by name.
  • The MCP portal join is the finding only Anomity can make: remote MCP servers configured on managed devices that no portal publishes, with device counts and the AI tools that reach them, plus portal servers that are not on the Anomity MCP allowlist.
  • It reads settings and metadata only. Anomity never fetches a prompt or response body from gateway logs and never downloads Worker source code, and the Global API Key is refused at connect time.
  • The edges are stated plainly: the AI Gateway reads are verified, the Workers binding and Cloudflare One shapes follow Cloudflare's documentation, and any field Anomity cannot find is reported as Not checked, never as a finding and never as clean.
  • Cloudflare governs the gateway and the portal. Anomity tells you whether those controls are switched on, which agents route around them, and which laptops never touch them.

Anomity now integrates with Cloudflare. Connect a Cloudflare account with one read-only API token and Anomity reads three things that live there: the AI Gateways your teams route model traffic through, the Workers that act as agents or sandboxes, and the MCP Server Portals in Cloudflare One that publish internal tools to AI clients. It then joins the portals to the MCP servers actually configured on your managed devices. The integration is available today from the discovery connectors page in the Anomity console.

This post covers what the connector reads, what it flags, how it authenticates, and where its edges are, because we would rather name them than leave you to find them.

Why Cloudflare, and why now

Cloudflare is no longer only the thing in front of an application. It offers a full stack for building agents: an agent written with Cloudflare's Agents SDK runs as a Durable Object, executes code in a Sandbox or a container, calls models through AI Gateway, and reaches internal tools through an MCP Server Portal. None of that sits on a laptop, in an identity provider, or in an AWS, Azure or Google Cloud account.

That made it a blind spot for every other collector. The Endpoint Sensor sees agents and MCP servers on managed devices, the Browser Sensor sees AI web services in the browser, and cloud discovery already reads the hyperscaler AI platforms, from AWS Bedrock to Azure AI Foundry and Google Cloud Vertex AI. An agent deployed on Cloudflare showed up in none of them.

An AI gateway is also a control point, and a control point is only as good as its settings. A gateway that accepts requests without authentication is a model endpoint anyone can call, and where provider keys are stored on it, anyone can spend against your vendor accounts. We covered the general case in securing LLM gateways and proxies. This connector checks it on the gateways you actually run.

What the connector reads

Three planes, one token. Every call is a read.

PlaneWhat Anomity readsWhat it records
Inference: AI GatewayEvery gateway and its settings, plus log metadata (model, provider, timestamp, last use) as aggregatesOne row per gateway, with its posture: authentication, logging, Guardrails, DLP profile, whether callers may bring their own provider keys, and whether requests carry user identity
Build: WorkersWorker names and their bindings, never source codeOne row per Worker with an AI-relevant binding, inferred as an agent or a sandbox
Access: Cloudflare OneMCP Server Portals and the servers behind them, and Access applications that are agent-ready through Managed OAuthOne row per portal, per portal server and per agent-ready app. Read only when the account has Cloudflare One

Two things are never read. Anomity never fetches a prompt or response body from AI Gateway logs, and it never downloads Worker source. Tests in the product hold both rules: no request for a log body or for script content is ever made.

Agents are inferred, and the row says so

Cloudflare has no 'list my agents' API, so Anomity infers agents from bindings. A Durable Object whose class name follows the Agents SDK convention, a container or Sandbox class, a Worker Loader for Dynamic Workers, a Browser Rendering binding or a Workers AI binding makes a Worker part of the AI inventory. A Worker with none of these is not a row. A Durable Object next to a Workers AI binding is probably an agent and possibly a chat widget, and the note on the row says the class name cannot tell the two apart.

Whether a Worker's inference goes through a gateway is decided from evidence too: a binding that names a gateway, or a variable carrying the ID of a gateway in the same account. Without that, a Workers AI binding is treated as direct inference.

The MCP portal join

MCP Server Portals let a platform team publish a curated set of MCP servers to people through Cloudflare One. Anomity's Endpoint Sensor knows which agent config on which laptop actually reaches which MCP server, and the Anomity MCP allowlist records what the security team approved. Side by side, the three produce two findings no single product can:

  • Portal server not on the allowlist. A server published through a portal that no Anomity MCP approval covers. The platform team has sanctioned something the security team has not.
  • Laptop server outside every portal. A remote MCP server configured on managed devices that no portal in the account publishes, so the portal's tool-level controls, logging and identity checks do not apply to it. It is raised once, on the account row, listing each server with its device count and the AI tools whose configs reach it.

URLs are normalised before they are compared, so the same server written with a different case, a trailing slash or a query string counts once. Only remote servers take part: a local stdio server never goes through a portal and is inventoried elsewhere in Anomity. One finding per account is deliberate. The remediation, publishing those servers through a portal or blocking them, is one conversation and one ticket, whether it lands in Jira or a Slack channel. It is the inventory problem we described in how to build an MCP server registry, with Cloudflare's portal as the registry.

What it flags

Cloudflare posture runs through Anomity's cloud AI posture policy type, with a seeded template, Cloudflare AI Gateway and agent posture. Each check can be switched on or off per policy. On by default:

  • Unauthenticated gateway. The gateway accepts requests without authentication, so anyone who learns its URL can send prompts through it. This is the day-one finding.
  • Logging off. The gateway records no requests, so there is nothing to investigate after the fact.
  • No Guardrails, or Guardrails that flag but do not block. A Guardrails configuration that only flags a category detects it and lets the request through anyway.
  • No user identity on requests. Requests carry no identity from Cloudflare Access, so there is no answer to who sent a given prompt. Checked only when the account has Cloudflare One to supply identity.
  • Inference that bypasses the gateway. A Worker calls Workers AI directly with no gateway in the path, so none of the logging, Guardrails, DLP or rate limits configured on your gateways apply to it.
  • Provider key held in a Worker. A Worker holds a secret whose name is a model-provider API key and references no gateway, so it most likely calls the vendor directly. The name is the evidence, the value is never read, and the finding says so. The wider problem is the subject of our guide to secrets management for AI agents.
  • The two halves of the MCP portal join, described above.

Three more checks ship switched off, because each fires on the ordinary state of a healthy account: no DLP profile on a gateway, bring-your-own-key not disabled, and Dynamic Worker loaders, which run model-written code and are reported as presence rather than a verdict. Turn them on where they match your policy. Findings route to the SIEM, Slack or Jira like every other Anomity finding.

How it authenticates: one read-only token

  1. In Cloudflare, create an account-scoped API token. The Read all resources template grants every read permission and no write in one click. For least privilege, create a custom token with four reads instead: AI Gateway Read, Workers Scripts Read, Access: Apps and Policies Read, and Account Settings Read.
  2. Scope the token's account resources to the one account you are connecting.
  3. In Anomity, add the Cloudflare connector with the token and your account ID.
  4. Test, then sync. The test verifies the token, reads the account and lists one page of gateways, so a token scoped to a different account fails at connect time with a message that says which check failed.

Anomity refuses the Global API Key at connect time. It carries every permission on the account, and nothing here needs it. The token is stored encrypted, and revoking Anomity's access is deleting the token in Cloudflare.

Current limits

The connector is connectable today. Its current limits are at the edges, and we would rather list them:

  • Some reads are verified, some are documented. The AI Gateway list, the gateway log metadata and the bring-your-own-key setting are verified. The Workers binding shapes and the Cloudflare One portal paths follow Cloudflare's documented behaviour, but no live account has confirmed them yet.
  • A field Anomity cannot find is 'Not checked', never a finding and never a clean result. A gateway that returns none of the posture fields produces no findings and a set of 'Not checked' notes, so a silent gap cannot read as a well-configured gateway.
  • A plane the account does not have is an answer, not a gap. No Cloudflare One means a 'Not available' note and the identity check is withdrawn. A token missing a permission for a plane that does exist is a coverage gap, and it is raised.
  • Some things are decided in code. Sandbox egress and exposed ports, and what a Dynamic Worker may reach, are set in the parent Worker's source. Anomity does not read customer source, so those rows carry a 'Not checked' note instead of a guess.
  • Large accounts are bounded. A sync reads up to 500 Workers and up to 200 gateways and portals. Anything past that is noted on the account row.

How Anomity and Cloudflare fit together

AI Gateway and MCP Server Portals are real controls, and Anomity does not replace them or sit in their request path. It reads whether they are switched on, finds the Workers and keys that route around them, and joins them to the endpoint. There, the Endpoint Sensor inventories agents, MCPs, extensions, plugins, skills, secrets, hooks, CLIs and local LLM runtimes, and the Browser Sensor covers AI web services and the accounts used in them. On agents that expose a hook, Anomity decides allow, deny or log before a tool call runs.

Cloudflare now sits beside the other AI platforms cloud discovery reads, from the OpenAI API platform and the Anthropic Console to the hyperscalers and code platforms such as GitLab, and its findings can stream to a SIEM such as Datadog Cloud SIEM like every other finding. Anomity collects metadata only, redacts secret values on the endpoint, and is SOC 2 Type II attested. To see it against your own Cloudflare account and fleet, book a 30-minute demo.

Frequently asked questions

What does the Anomity Cloudflare integration do?

It connects one Cloudflare account to Anomity's cloud discovery with a read-only API token and reads three planes: AI Gateway (every gateway, its settings and aggregate log metadata), Workers (names and bindings, from which agents and sandboxes are inferred) and, where the account has Cloudflare One, MCP Server Portals and Access applications that are agent-ready through Managed OAuth. Anomity then joins the portals to the MCP servers configured on managed devices and raises findings through its cloud AI posture policy type.

Does Anomity read my prompts, responses or Worker code?

No. From AI Gateway logs Anomity reads metadata only, such as model, provider and timestamp, as aggregates. It never requests a log's request or response body, and it never downloads Worker source code, only Worker names and bindings. Both rules are enforced by tests in the product. When a Worker holds a secret whose name looks like a provider API key, Anomity reads the name and never the value.

How does Anomity find agents on Cloudflare if there is no agent list?

It infers them from Worker bindings, and says so on each row. A Durable Object whose class name follows the Agents SDK convention, a container or Sandbox class, a Worker Loader for Dynamic Workers, a Browser Rendering binding or a Workers AI binding makes a Worker part of the AI inventory. A Worker with none of these is not recorded. Where a binding could mean an agent or something simpler, such as a chat widget, the row says the evidence cannot tell them apart.

What is the MCP portal join?

It compares three lists only Anomity holds together: the MCP servers published through your Cloudflare MCP Server Portals, the remote MCP servers actually configured in AI tools on managed devices, and your Anomity MCP allowlist. Portal servers no allowlist entry covers are flagged on their rows. Remote servers on laptops that no portal publishes are raised once on the account row, naming each server, its device count and the AI tools that reach it, so the remediation is one conversation and one ticket.

What permissions does the Cloudflare API token need?

Four reads: AI Gateway Read, Workers Scripts Read, Access: Apps and Policies Read, and Account Settings Read, with the token's account resources scoped to the one account you connect. Cloudflare's Read all resources template also works in one click: it grants every read permission and no write, which is broader than needed but cannot change anything. The Global API Key is refused at connect time.

What if my account does not use Cloudflare One?

Then the portal plane is simply not there, and Anomity records that as a 'Not available' note rather than a coverage gap. The check for user identity on gateway requests is withdrawn too, since without Access there is nothing to supply that identity. A token that lacks permission for a plane the account does have is different: that is a real coverage gap, and Anomity raises it.

Has every Cloudflare read been verified on a live account?

Not yet. Some of what it reads has not yet been seen on a live account. The AI Gateway list, log metadata and the bring-your-own-key setting are verified. The Workers binding shapes and the Cloudflare One portal paths follow Cloudflare's documented behaviour. Every field Anomity cannot find is reported as 'Not checked', so an unverified shape can produce a note but never a false finding or a false clean result.

Does Anomity replace Cloudflare AI Gateway or MCP Server Portals?

No. They are the controls, and Anomity does not sit in the request path. Anomity reads whether those controls are configured, finds the Workers and laptops that route around them, and covers the endpoint, where the Endpoint Sensor inventories agents, MCPs, extensions, skills, hooks, secrets and local runtimes, and where Anomity can allow, deny or log a tool call at the agent hook before it runs.

Ask AI about Anomity
ChatGPT Claude Perplexity Google AI Grok