Back to Integrations

Cloudflare Workers Integration

Score every visitor at Cloudflare's edge using ipinsights.io and act on the response in JavaScript.

Overview

Where the WAF integration blocks IPs that are already on the public blocklist, this Worker performs a live lookup against the ipinsights.io API for any request that isn't already cached — so you catch IPs that have only just turned bad, and you can act on richer signals such as is_tor, is_proxy and ASN.

Prerequisites

  • Cloudflare account on any plan (Workers free tier is sufficient for < 100k req/day)
  • Wrangler 3.x installed locally
  • An ipinsights.io API key — your profile page

Step 1 — Scaffold the Worker

npm create cloudflare@latest ipinsights-edge -- --type=hello-world --no-deploy cd ipinsights-edge npx wrangler secret put IPINSIGHTS_API_KEY # paste your key when prompted

Step 2 — Worker Source

Replace src/index.js:

// src/index.js — IP Insights edge enforcement const API = 'https://ipinsights.io/api/v1/lookup'; const CACHE_TTL = 3600; // seconds — cache verdicts in the Worker cache const BLOCK_THRESHOLD = 80; // threat_score ≥ this → block export default { async fetch(request, env, ctx) { const ip = request.headers.get('CF-Connecting-IP'); if (!ip) return fetch(request); // Cache verdict per-IP in the local datacentre cache const cacheKey = new Request(`https://ipinsights.local/${ip}`); const cache = caches.default; let verdict = await cache.match(cacheKey); if (!verdict) { const r = await fetch(`${API}?ip=${encodeURIComponent(ip)}`, { headers: { 'X-API-Key': env.IPINSIGHTS_API_KEY }, cf: { cacheTtl: 0, cacheEverything: false }, }); if (!r.ok) return fetch(request); // fail-open const j = await r.json(); verdict = new Response(JSON.stringify(j.data || {}), { headers: { 'Cache-Control': `public, max-age=${CACHE_TTL}` }, }); ctx.waitUntil(cache.put(cacheKey, verdict.clone())); } const data = await verdict.json(); const score = data.threat_score ?? 0; if (score >= BLOCK_THRESHOLD || data.is_tor) { return new Response('Forbidden', { status: 403 }); } // Forward, but add a header your origin can log on or react to const proxied = new Request(request); proxied.headers.set('X-IPInsights-Score', String(score)); proxied.headers.set('X-IPInsights-ASN', String(data.asn ?? '')); return fetch(proxied); }, };

Step 3 — Deploy & Route

npx wrangler deploy # In the dashboard: Workers Routes → add example.com/* → ipinsights-edge

Step 4 — Verify

curl -I https://example.com/ # X-IPInsights-Score header should be present npx wrangler tail # live log stream from the Worker

Lower the BLOCK_THRESHOLD temporarily to confirm your own IP gets a 403, then restore it.

Notes

  • Rate limits: the per-datacentre cache means even high-traffic sites typically issue < 1 lookup per unique IP per hour.
  • Fail-open: if the lookup API is unreachable the Worker proxies the request unmodified. Consider Cloudflare Logpush so that failures are visible.
  • Country / ASN policies: swap the BLOCK_THRESHOLD check for a richer rule using data.country_code, data.asn or data.is_proxy.

API Key: Required — your key on your profile page. Register for free if needed.

Request Higher API Limit

Running a high-volume Cloudflare Workers deployment? If the default rate limit isn't enough for your environment, submit a request below and we'll review it.

Maximum 5,000 characters.