Independent AI intelligence Two editions daily · ET
Fervor AI

Analysis · September 25, 2026 · concept

Turnstile SpinCloudflare Turnstileagent-securityai-skillsagent-infrastructureprivacy

Cloudflare Turnstile Spin: When an Agent Installs the Security Control, Who Checks That It Works?

Spin wires Turnstile's widget and its server-side siteverify call into your codebase, and Cloudflare deliberately never sees the result. Here is the one check that decides whether you got protection or decoration.

Cloudflare says Turnstile now processes about three billion verifications on a typical weekday. Buried inside that number is a fact the company admitted on September 25 by shipping a feature to fix it: some unknown share of those verifications protect nothing at all, because the site embedded the widget and never wired up the server-side check behind it. Cloudflare calls the fix "widget recovery," and it is one of three modes in Turnstile Spin, which hands the whole installation job to an AI coding agent.

Think about what that means for a second. A bot-protection vendor built a repair mode because enough customers shipped a security control that was purely visual. And the repair tool is an agent editing your backend.

What a Turnstile token actually is

The widget is the part everyone sees and the part that does not matter. When a visitor solves the challenge, Turnstile hands the browser a token, and that token is worth exactly nothing until your server sends it to Cloudflare and gets an answer back.

The server-side validation docs are blunt about the mechanics. You POST the token plus your widget's secret key to https://challenges.cloudflare.com/turnstile/v0/siteverify. The token is valid for 300 seconds from generation, and each one can be validated exactly once: "A replayed token will be rejected." A second attempt comes back with error-codes containing timeout-or-duplicate. The response carries success, a challenge_ts timestamp, the hostname the challenge was solved on, and the action and cdata values you set.

Cloudflare's own warning on that page is the whole security model in two sentences: "Only call the Siteverify API in your backend environment. If you expose the secret key in the front-end client code to call Siteverify, attackers can bypass the security check."

So a Turnstile install has two halves. The visible half takes five minutes. The invisible half is the one that stops anything, and a site can ship with the first half working perfectly and the second half missing entirely, and look completely fine in a browser while a script posts to your signup endpoint all day long.

That is the failure Spin exists to repair, and it is also the failure an agent can introduce in a single confident commit.

What the skill actually tells the agent to do

I went and read the skill, because the interesting part of any agent-installed control is not the marketing page, it is the instructions the agent receives. Cloudflare publishes it at https://developers.cloudflare.com/turnstile/spin/prompt.md and keeps the source in the cloudflare/skills repo, so anyone can audit exactly what their agent was told.

It is better than I expected. The skill walks a twelve-step workflow: acknowledge the task, check CLI tooling, authenticate with an API token scoped to Account.Turnstile:Edit, scan the codebase to identify the framework and any existing CAPTCHA, confirm the insertion points with the user, create the widget, embed it, wire the server-side verification, and then validate the whole path with a real token.

The canonical verification pattern it prescribes checks three things, not one. Not only success === true, but also that the returned action matches the action you expected and that the hostname is one you approve. It calls siteverify with a ten-second timeout and fails closed on any error. Those two extra conditions are what separate a correct Turnstile install from one that accepts a valid token minted on somebody else's form.

The secret handling is stricter than most human-written integration guides. The skill instructs the agent not to write the Turnstile secret to disk "except as part of the user's own env / secret store," and never to run secret-bearing commands through project package managers like npx or pnpm exec, where the value can land in a shell history or a package manager's log.

And then there is the line worth circling. If the backend cannot be exercised, the skill says to skip validation and report it as pending.

The gap that no amount of skill quality closes

Cloudflare states its position clearly and correctly: Spin does not "send your application code to Cloudflare or ask Cloudflare to change it remotely," and the docs add that none of the three paths "deploy infrastructure on your behalf." Spin uses the canonical siteverify endpoint called from the backend you already have.

That is the right privacy posture. I want my security vendor reading as little of my source as possible.

It is also, word for word, a description of why Cloudflare cannot tell you whether the install worked. The company can see that a widget was created, which is how it counts more than 65,000 successful Spin widget creations since the July 2026 release. It cannot see whether a siteverify call sits behind any of them. Those two facts live in the same sentence, and every agent-installed control has the same shape: the vendor that knows what correct looks like is structurally the party least able to confirm you got it.

Which puts the burden somewhere specific. Not on Cloudflare, and not really on the agent either. The skill told the agent to validate with a real token and to report pending if it could not. The question is whether anybody read that report.

Agent sessions produce a lot of output. A line saying validation is pending, in the middle of a successful-looking run that created a widget, edited three files, and printed a green summary, is exactly the kind of line that gets scrolled past. That is the actual risk here, and it is a human attention problem wearing a security costume.

Put this into practice

Start with the check, not the install. If you already run Turnstile anywhere, you can find out in about ninety seconds whether it does anything.

Open your signup or contact form in a browser, solve the challenge, and capture the value of the cf-turnstile-response field before you submit. Submit once, which should succeed. Then replay that same token to the same endpoint. If the second request also succeeds, your backend is not calling siteverify, because Cloudflare would have returned timeout-or-duplicate and a correct handler would have rejected it. That single test separates protection from decoration, and it needs no tooling beyond your browser's dev tools and a curl command.

The harsher version: delete the widget element from the DOM entirely, post the form with no token at all, and see what happens. A correct backend fails closed on a missing token. A decorative one takes the submission.

If you are running Spin itself, three habits make the difference. Read the agent's transcript for the word "pending" before you accept the change, since that is the skill's own signal that it never proved the path end to end. Read the diff on the verification handler specifically and confirm all three conditions are there, because success === true alone will accept a token generated against a different action on a different hostname. And confirm the secret landed in your environment store rather than in a committed file, which takes one git grep against your dashboard's secret key.

If you are running widget recovery on an existing widget, Cloudflare's path retrieves and stores the secret through Wrangler 4.109 or newer without exposing it in chat or logs. Check your Wrangler version first, because an older one turns a careful flow into a secret pasted into a terminal that an agent can read.

Where this falls short

Turnstile is not a drop-in replacement for everything it migrates from. The skill's own migration guidance notes that Turnstile has no equivalent of reCAPTCHA v3's score thresholds, so if your fraud logic branches on a confidence score, a Spin migration does not port that decision, it deletes it. You will be rewriting that logic yourself. reCAPTCHA Enterprise migrations are explicitly out of scope for the automated path and get sent to separate documentation.

The Account.Turnstile:Edit token the agent needs is real account access. The skill says to confirm with the user before retrieving credentials, and that confirmation is only as good as the approval mode you are running the agent in. If you have your coding agent set to auto-approve, you have handed an account-scoped credential to a process that reads your entire repository.

The 65,000 figure is a Cloudflare dashboard count of widget creations. It says nothing about how many of those reached a working server-side check, and Cloudflare, by its own design, has no way to know.

And the honest note on my own reading: I have audited the skill text and Cloudflare's documentation, not a large sample of Spin-generated diffs across frameworks. The instructions are good. Whether a given agent follows them faithfully in a Rails app with an unusual middleware stack is a question the skill text cannot answer for you.

The part that generalizes

Spin is a preview of a pattern that is going to keep arriving. A vendor knows how its control should be installed, cannot see your code, and so ships that knowledge as a skill and lets your agent do the work. Cloudflare did this about as responsibly as the pattern allows: the instructions are public, auditable in a repo, fail closed by default, include a real end-to-end validation step, and carry explicit rules about where secrets may go.

Even done well, the verification still lands on you. So build the habit now, while the stakes are a contact form. Every agent-installed control deserves one adversarial test written by a human who assumed it did not work, and in this case that test is replaying a token and watching whether your server notices.

Go replay one. It takes ninety seconds, and you will learn something either way.

Sources: Cloudflare blog, Turnstile Spin · Turnstile Spin docs · Turnstile server-side validation · cloudflare/skills: turnstile-spin


Medium metadata

Title: Cloudflare Turnstile Spin: When an Agent Installs the Security Control, Who Checks That It Works? Subtitle: Spin wires Turnstile's widget and its server-side siteverify call into your codebase, and Cloudflare deliberately never sees the result. Tags: AI Agents, Cloudflare, Web Security, Software Engineering, Developer Tools Canonical: publish on fervorai.dev first, import to Medium from that URL.