Skip to content

Clearance Enforcement

Most bot defenses enforce on IP or fingerprint — both of which rotate. Clearance enforcement flips the model: real browsers earn a signed wd_clearance token, and enforcement checks one thing per request — does this request carry a valid token? A bot on 10,000 IPs still needs a valid token on each request and can’t mint one. A real human on any IP passes silently.

The rotation-proof part is the loop with your deception surfaces: if a session that holds a token trips one of your decoys — or an SDK tripwire planted in your own pages — WebDecoy denies that browser’s fingerprint — its token is revoked within about a minute and it can never mint another, on any IP.

At the edge, each request passes if any of these hold, checked in order:

  1. Machine service token — a credential you issued for a partner, monitor, or job (see Response Actions).
  2. Verified bot — Googlebot, Bingbot, AI crawlers, and monitoring services you’ve allowed (verified by the platform / reverse-DNS, never by User-Agent).
  3. Unscoped route — the path isn’t in your token-enforced route list, so no token is required.
  4. Valid wd_clearance cookie — a real browser that already passed the client check, and whose fingerprint hasn’t been denied by tripping a decoy.

If none hold:

  • Monitor mode — the request passes anyway, tagged with an x-wd-clearance header so you can see what enforce mode would do.
  • Enforce mode — the browser gets a one-time invisible check that mints a token and reloads; non-browser clients get a 403.

Configure everything on the Enforcement page (sidebar → Enforcement): the token-enforced routes in step 2 (Set up the clearance token), the crawler allowlist and machine credentials in step 4 (Allow tokenless clients), and the Monitor/Enforce mode in step 5 (Go live).

The @webdecoy/client script mints the wd_clearance cookie for real browsers during normal browsing. Add it to your site with your site key (shown on the Enforcement page, step 2 — Set up the clearance token):

<script src="https://cdn.webdecoy.com/client/webdecoy.global.js"
data-site-key="YOUR_SITE_KEY"
async></script>
AttributeRequiredDescription
data-site-keyyesYour publishable site key (the organization ID).
data-ingestnoWebDecoy ingest origin. Defaults to https://ingest.webdecoy.com.
data-scopenoRoute-group scope for the token. Defaults to tenant-wide.

Minting is deferred to browser idle time, runs at most once per session, and skips entirely when a fresh cookie already exists — it adds no page-load cost and never blocks paint or interaction.

The validator runs at your CDN edge and fails open on any error — if it can’t reach WebDecoy or can’t verify a token, it forwards the request untouched, so it can never take your site down. Pick the one matching your CDN:

Both validators live in the public WebDecoy/clearance-validators repo, and the Enforcement page (step 3) pre-fills the config for your organization:

  • Cloudflare — one-click Deploy to Cloudflare installs the Worker into your account; then add a route for your domain using the pre-filled wrangler.toml variables shown in the dashboard.
  • AWS / CloudFront — a Lambda@Edge function on your distribution’s viewer-request behavior: set your keys in src/config.ts, build and zip, upload to S3 in us-east-1, then launch the provided CloudFormation template and attach the published function version to your distribution. Because AWS has no platform-verified-bot signal, this validator verifies crawlers itself via forward-confirmed reverse DNS.

On the Enforcement page, step 3 (Deploy the edge validator), enter your site domain and click Verify deployment. The dashboard checks — from your own browser — that the validator is answering on your zone, and reports its current mode. Since the validator fails open, this check is how you confirm it’s actually live before you rely on it. That panel also gives you the pre-filled config (your site key and route already filled in) for both Cloudflare and AWS.

This step is not optional. The token requirement applies only to paths you scope, so an organization in enforce mode with no scoped routes gates nothing — every request passes.

Add patterns under Enforcement → Setup → step 2, in Token-enforced routes:

PatternMatches
/checkout/*/checkout and everything beneath it
/api/ordersthat exact path

Start narrow. The paths worth gating are the ones that cost you when abused — checkout, login, search, expensive APIs — not your whole site.

Leave enforcement in monitor mode, watch the x-wd-clearance header in your logs to see the pass/challenge split, then flip to enforce once it looks right.

The status band at the top of the Enforcement page always shows what is live: whether you are monitoring or enforcing, and how many routes are scoped. If it reads “Enforce is on — but nothing is protected”, you have enforcement enabled with no scoped routes — the one state that looks safe and isn’t.

A token is not simply valid or invalid. It carries a grade reflecting how much positive human evidence the session presented when it was minted:

GradeEarned byWho can reach it
cleanany real browser that hasn’t tripped deceptioneveryone
human-likelybrowser-integrity checks at the interstitial, or interaction cadenceeveryone
attested-humanverified Turnstile responseanyone you’ve configured attestation for

A route can require a minimum grade, so / accepts any valid token while /checkout/* demands human-likely or higher. A session below the bar is challenged there and passes everywhere else.

Three properties are deliberate:

  • Absent means clean. Tokens minted before grading existed, and validators too old to understand it, keep working exactly as before.
  • Evidence only ever raises a grade. A session that presents none — a keyboard-only visitor, someone on an older browser — mints the same clean token it always did. Nothing here can block a request on its own.
  • A high threat score caps the grade. Positive evidence cannot lift a token whose actor is already known to be bot-like, because a real device can still be driving an attack.

Setting a per-route minimum is currently API-only:

POST /organizations/{organization_id}/enforcement/routes
{ "pattern": "/checkout/*", "min_trust": "human-likely" }

Validators that predate graded trust ignore the minimum and enforce presence alone, so raising it is safe to roll out before every edge is redeployed.

  • The wd_clearance cookie is a first-party cookie on your domain. The decoy → deny loop fires when a decoy shares an origin with your pages (decoy links/endpoints on your own site). Off-domain decoys don’t carry the cookie.
  • The device fingerprint uses stable browser characteristics (canvas, WebGL, screen, timezone, platform, language). Privacy browsers that randomize canvas will simply re-mint each visit — enforcement still holds within a session.
  • No User-Agent is used in the fingerprint, so a browser update doesn’t churn a user’s identity.