---
title: Signed, then verified: how WatchForBot became a Cloudflare verified bot
description: Our signed probes got 403 from sites behind Cloudflare that were up. How Web Bot Auth and Cloudflare's verified bot list fixed it in seven minutes.
canonical: https://watchfor.io/blog/cloudflare-verified-bot-web-bot-auth
---

# Signed, then verified: how WatchForBot became a Cloudflare verified bot

2026-10-20 · WatchFor Team · Engineering · engineering, security, monitoring

Our signed probes got 403 from sites behind Cloudflare that were up. How Web Bot Auth and Cloudflare's verified bot list fixed it in seven minutes.

For weeks, one of our dashboards looked like a bad day on the
internet. We keep an organization that watches a set of well-known sites, the
kind of shops, banks and portals a whole country uses every day. A good part of
it was red. Fourteen sites, all behind Cloudflare, all answering our checks
with **403 Forbidden**.

None of them were down. Open any of them in a browser and they loaded. Send
the same request from the same machine with plain curl and they answered 200.
Only our monitoring probes got the door shut in their face.

This post is about why that happened, why the fix was a list we had to get
onto rather than code we could write, and what happened in the seven minutes
after we got on it.

## Every probe request is signed

Monitoring traffic has an identity problem. A check is an automated request
that arrives every minute, from servers in several countries, asking for the
same page. To a bot filter, that looks exactly like the scraping it exists to
stop. The usual answers are weak: a User-Agent string anyone can copy, and IP
lists that change and that nobody keeps up to date.

So every HTTP request our probes send is signed. We use
[Web Bot Auth](/bot), which is
[RFC 9421 HTTP message signatures](https://www.rfc-editor.org/rfc/rfc9421)
with a profile for bots. Each request carries three extra headers:

```http
Signature-Agent: "https://watchfor.io"
Signature-Input: sig1=("@authority" "signature-agent");created=…;expires=…;keyid="…";alg="ed25519";tag="web-bot-auth"
Signature: sig1=:…:
```

`Signature-Agent` says who is signing. `Signature-Input` says what was signed
(the host the request is for, plus the agent header itself), when, with which
key, and that the signature is short-lived. `Signature` is the Ed25519
signature over exactly that. The key ID is the key's JWK thumbprint, and the
public keys are published at
[`/.well-known/http-message-signatures-directory`](/.well-known/http-message-signatures-directory),
itself signed with the same key.

Anyone can verify it. If a request claims to be WatchForBot and the signature
checks out against our directory, it came from us. If it doesn't, it didn't.

## Why signing made things worse first

Here is the part we didn't expect. A signed request was treated **worse**
than an unsigned one.

The signature headers are a claim. A Cloudflare zone that sees
`Signature-Agent: "https://watchfor.io"` on a request is being told "this is a
known bot, check me." Until Cloudflare had WatchForBot in its own directory of
verified bots, it had nothing to check that claim against. Some zones treated
an unverifiable bot claim the way a careful bouncer treats an ID he can't
read: no entry. A request with no claim at all, which looked like an ordinary
client, got through.

That leaves an obvious and wrong fix: drop the signature, or send it only
when it helps. We didn't, and later in this post there's a site that shows
why.

## Getting on the list

The real fix was to be recognised. Cloudflare keeps a public
[bots directory](https://radar.cloudflare.com/bots/directory?q=watchfor) of
bots it verifies, and verification for a signing bot means Cloudflare fetches
the published key directory and checks every request's signature itself. We
applied with what we already had: the signing setup above, a public
[bot page](/bot) that says what WatchForBot does and doesn't do, and a stable
User-Agent.

WatchForBot was approved on 19 October 2026 and listed as **Verified**, in the
**Monitoring & Operations** category, as a direct-access bot.

## The seven minutes after

We didn't touch anything on our side. Here is what the probes saw that
evening:

![Fifteen sites behind Cloudflare between 18:00 and 02:00 UTC on 19 October 2026. Fourteen answer 403 Forbidden until a window between 21:52 and 21:59, then 200 OK for the rest of the night. The fifteenth answers 200 OK until 21:56 and 403 afterwards.](/blog/cloudflare-verified-bot-web-bot-auth-chart.webp)

Between **21:52 and 21:59 UTC**, all fourteen sites flipped from 403 to 200.
The **17 incidents** that had been open on them, some for months, resolved
on their own as the next checks came back clean. That included a few sites that
had previously challenged every non-browser client, signed or not; once
Cloudflare could verify who we were, they let us through too.

## The site that went the other way

Look at the last row. One site answered 200 all afternoon, and turned to 403
at 21:56, the same minute everything else turned green.

Before verification, that zone saw an ordinary-looking request and let it
through. After verification, Cloudflare could tell it exactly what we were: a
verified monitoring bot. The zone's settings block that category, so it said
no.

We could make that row green again. The trick is simple: when a signed
request gets a 403, retry once without the signature. We decided not to.

That zone's owner made a choice about monitoring bots. Retrying unsigned
would mean pretending to be something else to get past it, which is exactly
the behaviour signing exists to rule out. A monitor that quietly changes its
identity when it's refused can't also ask to be trusted. So that check stays
red, and it should.

If the site is **yours**, you're not stuck: one WAF rule that skips bot
protection for WatchForBot takes two minutes, and the
[step-by-step guide](/docs/reference/probe-locations#using-cloudflare-allowlist-us-in-two-minutes)
is in our docs.

## What this means if you monitor a site behind Cloudflare

- **Nothing to do in most cases.** Zones that allow verified bots now let our
  checks through. If your monitor showed 403s that your visitors never saw,
  they should already have stopped.
- **Your zone blocks verified or monitoring bots?** Add the
  [Skip rule](/docs/reference/probe-locations#using-cloudflare-allowlist-us-in-two-minutes)
  for your own site, so your monitor sees what your visitors see.
- **Another CDN or WAF?** Akamai and others don't use Cloudflare's list.
  Allowlist the `WatchForBot` User-Agent or our
  [published IP ranges](/ip-ranges) there, or verify the signature if your
  platform supports Web Bot Auth.
- **Want to check for yourself?** The [bot page](/bot) explains how to verify
  a request: the signature, the key directory and reverse DNS.

The short version is in the
[changelog](/changelog/2026-10-20-cloudflare-verified-bot). The longer
version is this: we signed every request so that anyone could check who we
are, and the day someone big enough started checking, the red went away.

---

Canonical page: https://watchfor.io/blog/cloudflare-verified-bot-web-bot-auth · All articles: https://watchfor.io/blog/all.md · Site guide: https://watchfor.io/llms.txt
