<- blog

A Verified Bot Is a Policy Join, Not an Allowlist

Fresh BotBase and preference-sync releases expose a four-way join among request proof, declared use, site policy, and path enforcement.

#ai-agents#seo#security#web-platform

Cloudflare made both sides of automated web access more explicit this week.

On 28 August, BotBase for Operators added submission history, review status, rejection reasons, editable entries, and automated verification checks for bot operators. The intake now asks what a bot does, how it uses content, whether it acts directly or as an intermediary, and how it proves its identity.

Seven days earlier, Bot Preference Sync connected the website owner's side. A site can choose category-level treatment for Search, Agent, and Training traffic, then have the corresponding preferences reflected in robots.txt as well as enforced through edge configuration. The managed file is generated from the bot directory and updated as tracked bots change.

The tempting interpretation is that verified bots can now be safely allowed. That is too broad. Verification identifies a request and connects it to current directory metadata. Access still depends on the bot's declared uses, the site owner's current policy, the requested resource, the confidence of the identity proof, and—where an intermediary is involved—the end user behind the request.

The repeated angle to avoid

The ten most recent posts here covered AI-catalog conformance, security-dashboard denominators, chat-adapter semantics, agent compute planes, security treatment states, soft-navigation measurement, authorization control loops, credential isolation, payment routing, and MCP traffic detection. Older overlapping posts covered bot-contaminated analytics, server-side agent conversion outcomes, situation-specific AI search pages, WebMCP actions, and the difference between discovering machine-facing assets and authorizing their use.

The weak version would revive the old X needs Y formula: AI bots need transparent identities and websites need crawler policies. It would also repeat the June advice to classify bot traffic rather than treating every machine request alike.

The sharper thesis is that bot admission is becoming a temporal join between claims owned by different parties. The operator controls identity keys, user agents, infrastructure, declared behaviours, and content-use commitments. The website owner controls resource policy and enforcement. Cloudflare maintains the directory mapping between them. A verified request is useful only when those records are joined as they existed at decision time.

That temporal detail produces the information surplus. A directory entry can change after a request. A site's robots.txt can change after a crawl. A direct operator can become an intermediary. A Search-only bot can add Agent or Training behaviour. If logs preserve only verified=true and status=200, operators cannot reconstruct whether the request matched policy when it happened.

Fresh evidence and background serve different jobs

The source map separates this week's product changes from the implementation references needed to reason about them.

Source Freshness What it contributes
BotBase for Operators 28 August 2026 Visible submission states, editable records, multi-behaviour and content-use declarations, direct/intermediary classification, and automated identity checks
Bot Preference Sync 21 August 2026 Category policy for Search, Agent, and Training; generated robots.txt entries; edge-policy alignment; mixed-use crawler treatment; custom-rule limitations
Verified bots documentation Current primary documentation, updated 1 July 2026 Honest self-identification, non-abusive behaviour, multiple behaviour labels, verification methods, and transitive trust
Web Bot Auth documentation Current primary documentation, updated 1 July 2026 HTTP message signatures, key directories, expiry, replay limitation, signed components, and experimental intermediary attribution
Managed robots.txt documentation Current primary documentation, updated 3 August 2026 Preference-versus-enforcement distinction, file-prepending behaviour, Content Signals, and content-use values
AI Crawl Control documentation Current primary documentation User-agent versus detection-ID confidence, per-crawler actions, WAF enforcement, path-specific extensions, and block responses
Robots Exclusion Protocol, RFC 9309 Background standard The standard crawler access-rule grammar and matching model; not proof of request identity or authorization

The two fresh releases provide the adoption event. The older documentation supplies the mechanism and limitations. No single source turns them into an auditable admission model.

Verified is an identity-and-behaviour record

Cloudflare defines a Verified bot or agent as one that clears two bars: it identifies itself through a supported deterministic method, and its observed behaviour does not abuse the access that identification earns. Supported identity methods include Web Bot Auth signatures, published IP lists paired with stable user agents, and reverse DNS.

That is stronger than accepting any request whose User-Agent says HelpfulBot. It is still not the same claim as authorization.

Keep these questions separate:

Question Evidence What it does not prove
Is this request automated? Bot detection, traffic pattern, known user agent Which operator sent it
Which registered bot sent it? Valid signature, validated IP range, or reverse DNS mapped to a directory entry That every declared use is allowed here
What does the bot say it does? Current BotBase behaviours and content-use declaration That this request follows the declaration
Who caused this request? Direct operator identity or intermediary attribution That the end user is authorized for a private resource
May it fetch this resource for this use? Current site and path policy joined to the claims above That later reuse will remain within policy
Did enforcement apply? WAF or origin decision, status, matched rule That the response was useful or created business value

A directory entry can carry several behaviours at once: Search, Agent, Training, Transact, Data Collection, SEO, security testing, monitoring, and others. This matters because one bot name is no longer one purpose. A crawler may build an index and also collect training data. An intermediary agent may read a public product page on behalf of a shopper and later attempt a checkout action.

A boolean allowlist throws those distinctions away.

The request-time join has six inputs

A useful admission path looks like this:

incoming request
  -> classify automation signal
  -> verify request identity
  -> resolve current directory entry
  -> select declared behaviours and content use
  -> resolve site + hostname + path policy
  -> account for direct or intermediary operation
  -> enforce at edge and origin
  -> record decision with policy versions

The minimum inputs are:

  1. Request proof. Which signature key, IP range, reverse-DNS result, or weaker user-agent signal connected this request to a bot?
  2. Directory record. Which operator and bot entry did that proof resolve to, and when was the entry last reviewed?
  3. Declared behaviour. Is the bot doing Search, Agent, Training, Transact, or several of them?
  4. Content-use commitment. Does it claim immediate use, reference-style retention, full reuse, or another declared treatment?
  5. Resource policy. What does this site permit for this hostname, path class, content type, account state, and commercial agreement?
  6. Actor chain. Is the operator itself choosing the request, or is an end user operating through an intermediary?

The output should be narrower than allow bot:

allow public read for search indexing
allow public read for user-directed retrieval
allow excerpt and link, deny training reuse
challenge or rate-limit unverified automation
require payment for licensed crawl
require user authentication for private data
require ordinary checkout authorization for transact actions
block this bot, use, path, or operator chain

This turns verification into a routing input rather than a privilege.

Signatures bind requests, not motives

Web Bot Auth uses HTTP Message Signatures with an operator-hosted key directory. Cloudflare's implementation accepts Ed25519 keys, requires the key directory over HTTPS, and expects signed requests to carry Signature-Agent, Signature-Input, and Signature headers.

The signature can establish that the holder of a registered private key signed selected request components. It can bind the request to @authority, which helps prevent a signature intended for one host being reused against another. Short expires values reduce the replay window.

Three limitations should stay visible:

  • The signature proves control of a key connected to an operator record; it does not prove the truth of every purpose declaration.
  • Only signed components are protected. If path, method, query, or content matters to policy, the signature and verifier must cover the appropriate components or another trusted layer must establish them.
  • Cloudflare's current documentation says nonce inclusion is recommended but nonce reuse is not yet checked against a seen-nonce database. A valid signature with a long expiry should not be treated as unique-request proof.

Verification also does not authenticate the customer behind an intermediary. Cloudflare distinguishes Direct bots, operated by one narrow operator, from Intermediary services that many end users can drive. Its experimental use of the Forwarded header aims to carry operator and content-use information through that chain, but the documentation explicitly says the mechanism may change.

For a public article, trusting a known intermediary to fetch on behalf of an unknown user may be acceptable. For account details, a quote containing personal data, a booking change, or checkout, the application still needs its normal customer authentication, authorization, confirmation, and anti-fraud controls. A signed intermediary is not a signed-in customer.

Published preference and enforced policy are separate layers

Cloudflare's current robots.txt documentation is explicit: the file expresses preferences, and compliance is voluntary. Technical denial requires an enforcement layer such as AI Crawl Control, WAF rules, access control, rate limits, or origin authorization.

Bot Preference Sync reduces one common drift path. Category choices made in the dashboard can update the generated robots.txt material, while edge configuration enforces the corresponding bot treatment. Existing origin content is preserved by prepending the managed section.

That is useful synchronization, not universal equivalence.

Layer Primary job Main failure mode
robots.txt Publish crawl and use preferences to cooperating operators A crawler ignores it, parses only standard fields, or sees stale content
Content Signals or content-use extension Describe intended downstream use more precisely Operator does not understand, accept, or enforce the extension
Category policy Apply one choice across tracked Search, Agent, or Training bots One mixed-use bot or business exception does not fit the category default
Per-bot or custom WAF rule Enforce a narrower identity, path, or commercial exception Rule and published preference drift apart
Origin authorization Protect private data and state-changing actions Edge policy is treated as a substitute for customer authority
Analytics Show observed requests, outcomes, and possible violations Current policy is applied retrospectively to old traffic

The fresh announcement names one important boundary: Bot Preference Sync works from category-wide policy and does not read arbitrary custom rules with complex exceptions. If a publisher has a direct licensing agreement, permits one crawler only on /public-research/, or blocks an intermediary from /checkout/, the generated file cannot be assumed to describe every custom branch.

Use one declared source of truth and generate the other representations where possible. Where synchronization cannot express an exception, keep a reconciliation test instead of relying on visual similarity.

Policy history is part of the evidence

Crawler dashboards often evaluate history using current metadata. Cloudflare's Directives documentation gives a concrete example: its violations view compares past requests with the current robots.txt. Add a new Disallow today and older requests can appear as violations even though they were permitted when they occurred.

Directory history creates the mirror image. Suppose a bot was classified as Search on Monday, added Training on Thursday, and its Tuesday requests are examined on Friday. A report that joins the old requests to Friday's directory entry can imply that Tuesday's crawler declared Training at the time. That may be false.

The safe model is an as-of join:

request occurred at T
  + identity proof accepted at T
  + directory revision effective at T
  + site policy revision effective at T
  + path rule effective at T
  = decision meaning at T

Keep current-state views for operations, but do not use them as immutable history. Snapshot or version the records needed to explain access decisions.

A practical policy version can be a deployment ID, ruleset version, configuration hash, or immutable export. The directory side may offer only a last-reviewed timestamp or observed metadata snapshot. Preserve what the platform exposes and label the gap honestly; do not invent precision.

A bot admission receipt

The receipt should store decision evidence, not response content, private keys, full URLs containing secrets, or customer data.

bot_admission_receipt:
  request_id: req_01K4EXAMPLE
  occurred_at: 2026-08-28T15:04:12Z
  resource:
    hostname: shop.example.com
    path_class: public_product_detail
    method: GET
  automation:
    detected: true
    detection_confidence: verified_signature
    bot_id: directory_bot_482
    operator_id: example_agent_operator
  proof:
    method: web_bot_auth
    key_thumbprint: recorded_nonsecret_identifier
    signed_components:
      - "@authority"
      - "@path"
      - "@method"
    signature_created_at: 2026-08-28T15:04:02Z
    signature_expires_at: 2026-08-28T15:05:02Z
    replay_check: expiry_only
  directory:
    observed_revision: snapshot_2026_08_28_1500
    review_state: accepted
    behaviours:
      - search
      - agent
    content_use: reference
    operation_model: intermediary
  end_user:
    identity_available: false
    private_resource_authority: none
  site_policy:
    revision: bot-policy-deploy_7f31
    search: allow
    agent: allow_public_read
    training: disallow
    matched_path_rule: public_catalog_read
    published_preference_revision: robots_hash_91ac
  enforcement:
    edge_action: allow
    origin_action: public_read_only
    response_status: 200
  decision:
    outcome: allowed_public_reference_use
    denied_capabilities:
      - training
      - account_access
      - checkout_mutation

The denied_capabilities field prevents a narrow success from becoming ambient trust downstream. The same verified operator may be allowed to read product facts and denied permission to retrieve a customer's order or submit a purchase without customer authority.

A decision matrix for small sites

A small ecommerce, service, or content site does not need a universal bot-governance platform. It needs explicit defaults by resource consequence.

Request class Identity evidence Declared use Default treatment Additional proof
Public article or product page Verified Search bot Search/reference Allow, rate-limit fairly, keep machine traffic out of human engagement metrics Monitor fetch errors and referral value
Public page Verified mixed Search + Training bot Operator offers separable no-training mode Follow current site preference and published directives; enforce where available Evidence that the no-training mode applies to this request
Public page User-agent only Any Treat identity as lower confidence; allow, challenge, limit, or block by site strategy Do not grant a verified-bot exception
Quote or booking availability Verified intermediary agent Immediate user-directed retrieval Allow only a bounded public or authenticated read endpoint Customer session where private availability is involved
Lead submission Verified agent Agent action Run ordinary validation, idempotency, spam scoring, and qualification Customer intent and server-side business outcome
Checkout or account change Any bot identity Transact Never authorize from bot verification alone Customer authentication, scoped action authority, confirmation, fraud controls
Training crawl on opted-out content Verified or unverified Training Publish the preference and enforce the block where policy requires Commercial exception if one exists
Unknown automation on private path Unknown Unknown Deny or challenge Normal user or service authentication

The decision rule is: the more consequential the resource, the less bot identity should contribute to authorization. Verification is highly useful for public-content routing and crawler economics. It should contribute almost nothing to permission for private reads or business mutations.

Reconcile the two sides after every change

For a website owner:

  1. Inventory resource classes. Separate public discovery pages, licensed content, ad-supported pages, APIs, forms, checkout, account areas, and administrative paths.
  2. Choose policy by use, not by bot brand. Decide Search, Agent, Training, Transact, and Data Collection defaults before adding operator exceptions.
  3. Publish the cooperative preference. Verify the live robots.txt response on every hostname, including redirects and origin fallbacks.
  4. Test enforcement separately. A correct file is not proof that a WAF or origin will deny a non-cooperating request.
  5. List custom exceptions. Record rules that category-level sync cannot reproduce, along with owner, purpose, path scope, and expiry or review date.
  6. Preserve policy versions. Store enough evidence to evaluate a request against the policy effective when it occurred.
  7. Keep bot traffic out of human denominators. Record crawler access, referrals, agent-assisted outcomes, and human engagement as related but distinct measures.
  8. Protect action paths normally. Verification can classify the caller; application authorization decides whether the caller may act for this customer.

For a bot operator:

  1. Declare every behaviour. Do not submit as Search if the same identity also trains, transacts, or collects competitive data.
  2. Separate identities where policy cannot separate uses. A site cannot make a reliable choice if one indistinguishable request stream carries incompatible purposes.
  3. Prefer cryptographic request identity where practical. Keep the key directory available, rotate keys deliberately, and bound signature lifetime.
  4. Sign policy-relevant components. Test authority, method, path, redirects, proxies, clock skew, expiry, and failure responses.
  5. Keep the directory entry current. Update user-agent patterns, IP-list locations, verification method, behaviours, content use, and direct/intermediary status before traffic changes.
  6. Treat acceptance as revocable. Verified status depends on continued truthful identification and non-abusive behaviour.
  7. Expose an operator contact and recovery path. A block response or rejection reason is useful only if someone owns the fix.
  8. Separate end-user authority from platform identity. An intermediary signature must not conceal which actions require the user's authenticated session.

Failure modes worth rehearsing

Verified becomes a global bypass

A broad security rule skips rate limits, path restrictions, or application checks for every verified bot. A compromised operator key or misclassified mixed-use bot inherits access far beyond public crawling. Scope exceptions to named behaviours and public resource classes; never skip account or mutation authorization.

The bot changes purpose without changing identity

A Search crawler adds training or agent behaviour under the same key and user agent. Existing site rules continue to allow it because they match only the directory ID. Alert on classification changes and re-evaluate policies before the new behaviour is accepted.

A policy update rewrites history

A new Disallow makes old requests look non-compliant, or a new Training label is joined to traffic that predated it. Version policy and directory observations, and label retrospective dashboards as current-policy reclassification rather than historical fact.

Preference sync hides a custom exception

The generated robots.txt accurately reflects category defaults while a custom WAF rule permits one operator on a sensitive path—or blocks a bot the file appears to allow. Diff published preference against effective enforcement and list exceptions that cannot be generated.

A valid signature is replayed inside its lifetime

The verifier checks signature validity and expiry but not nonce reuse. A captured request is replayed before expiration. Keep lifetimes short, sign the policy-relevant request components, and use application idempotency or replay protection for any action-capable endpoint.

An intermediary identity is mistaken for customer identity

A known agent platform signs a request, so the application reveals an order or changes a booking without authenticating the person who initiated it. Bind private reads and state changes to the customer's current authority, not the intermediary's verified-bot status.

User-agent detection is reported as cryptographic verification

A lower-tier or custom implementation identifies a familiar user-agent string and logs verified. A scraper copies the string and receives the same treatment. Record the proof method and confidence explicitly; do not collapse user-agent, IP validation, reverse DNS, and message signatures into one boolean.

Directory unavailability changes policy silently

A request cannot resolve fresh metadata, so the edge either blocks every useful crawler or falls back to a stale global allow. Define a bounded cache, retain the last approved snapshot, fail closed for sensitive resources, and use conservative public-read treatment when classification is unavailable.

The practical conclusion

BotBase for Operators improves the operator half of automated access: submissions have visible states, rejected claims have reasons, accepted entries can be updated, and identity checks can run against concrete evidence. Bot Preference Sync improves the website half: category intent can be published and enforced from one choice instead of drifting across a hand-maintained file and edge configuration.

Their shared value is not a bigger allowlist. It is a more legible join. A request can be connected to an operator, behaviours, content use, and operation model; the site can connect those claims to a current resource policy. That enables useful distinctions among search indexing, user-directed retrieval, training, public reads, private reads, and transactions.

Keep the join temporal and narrow. Verify the request, snapshot the directory claim, resolve the policy effective at that moment, preserve custom exceptions, authorize private actions separately, and record what was denied as well as what was allowed. Then verified identity can make the open web easier to operate without becoming a permanent pass around the controls that protect customers and the business.

Need technical help?

I'm a software engineer who builds web apps, APIs, and AI tooling. If you've got a project or a problem to talk through, book a free 30-minute call.

Book time with me ->