PARAS MADAN
All writing

Latest in AI

Self-Hosting Cloudflare Kitesurf: Access, Cost and Compatibility Checks

An open-source agent browser is useful, but its public endpoint and Chromium differences need attention before you connect an agent.

Cloudflare open-sourced Kitesurf on November 13, allowing developers to run its agent-focused browser locally or deploy it to their own Workers account. Before connecting an agent, check two things: who can reach the engine and whether it can complete your actual workflow. Neither follows automatically from a successful deployment.

The announcement describes a browser built on Workers rather than a Chromium container, with Chrome DevTools Protocol support for clients such as Puppeteer. The engine remains under active development. Open source gives you another deployment choice, not a promise of Chrome compatibility.

Choose managed Kitesurf or your own engine

There are two different operating arrangements. Cloudflare's Browser Run documentation describes managed Kitesurf as free during beta, subject to account limits. The open-source engine deployed in your own account requires a Workers Paid plan because it uses Dynamic Workers. Do not apply the managed beta's price description to your own deployment.

The distinction also explains a confusing local-development error. Browser Run's Kitesurf quick action needs a remote browser binding during wrangler dev. Running the open-source repository locally is a separate path. Changing a managed binding is not the same thing as starting your own engine.

For an initial evaluation, choose one path and label it clearly in your test results. Otherwise you can end up comparing local development against a managed service and attributing the difference to the browser engine.

Protect the endpoint before deployment

The repository's deployment warning is direct: the engine has no authentication of its own. Someone who can reach it can control browser sessions, make outbound requests through your account and consume paid resources. An obscure URL is not an access policy.

The repository also notes that ordinary workers.dev URLs are public by default. Deploying first and adding protection afterward leaves a gap. Follow Cloudflare's workers.dev access configuration to arrange protection before exposing the engine, including any version URLs you enable.

My suggested acceptance check is simple: test from a signed-out session before you connect real accounts or sensitive workflows. Confirm that an unauthenticated client cannot open the engine, then confirm that the intended authorized client can connect. Repeat this for every hostname you plan to distribute, rather than assuming protection on one route covers another.

I have not deployed or penetration-tested Kitesurf. These are deployment checks to perform in your own authorized environment, not a security certification.

Give automated clients their own Access credentials

A human browser session and a background CDP client authenticate differently. The repository documents a Service Auth policy and an Access service token for Puppeteer, with CF-Access-Client-Id and CF-Access-Client-Secret headers on its WebSocket connection.

Use the service-token documentation to manage that machine credential. Keep the secret outside prompts, source files and screenshots. If a connection fails, check the hostname, policy and credential handling before removing authentication to make the error disappear.

Treat the agent's access as the ability to operate the browser, not merely to read its status page. Limit who receives the credential and have a way to revoke it when an integration is retired.

Test task completion, not just a screenshot

Cloudflare currently advises using Chromium instead for video, WebGL and long-running authenticated sessions that need persistent state. It also distinguishes standards-test coverage from compatibility with an individual website. A successful screenshot of your landing page says little about whether your agent can finish a multi-step task.

For a useful comparison, select three representative jobs on pages you own or are authorized to automate. For example, extract a known product field, navigate a client-rendered search result and fill a staging form without submitting a real transaction. Define the expected result before running either engine.

Record task completion, missing fields, rendering errors and elapsed time separately. If Kitesurf extracts the right information but produces a different screenshot, decide whether visual fidelity matters to that job. If the agent loses required session state, cheaper execution is irrelevant because the task did not finish.

Keep Chromium as a fallback until your own task set supports a narrower choice. The operational advantage of another browser engine comes from assigning suitable work to it, not from routing every existing automation through a new endpoint.

I’m Paras. I work at the intersection of AI, engineering and distribution.

I help technical teams turn infrastructure decisions and product launches into clear stories developers can use.

Book a 30-minute call