AI Automation
Securely Exposing a Webhook for Cloudflare Workers AI Callbacks in Small Companies
TL;DR: Use a Cloudflare Pages or Workers site to host a HTTPS endpoint, protect it with signed JWTs or HMAC tokens, enforce rate limits via Cloudflare Transform Rules, log every request to a durable store, and rotate secrets regularly. This keeps AI callbacks private, prevents abuse, and gives you a clear audit trail.
What is a Cloudflare Workers AI callback and why do I need a webhook?
When you invoke a model with workers.ai.run(), the response can be streamed or returned synchronously. For long‑running jobs (e.g., image generation, batch summarization) the service can POST the result to a URL you provide. That URL is the webhook – a public HTTPS endpoint that receives JSON payloads once the job finishes.
How do I create a minimal webhook endpoint on Cloudflare Pages?
Cloudflare Pages supports _routes.json and serverless functions written in JavaScript. A simple function looks like this:
export async function onRequestPost({ request }) {
const payload = await request.json();
// Store payload for later processing
await MY_KV.put(`job-${payload.id}`, JSON.stringify(payload));
return new Response('ok', { status: 200 });
}
Deploy the function to /api/webhook. Cloudflare automatically provisions TLS, so the endpoint is reachable via https://your-site.pages.dev/api/webhook.
How can I authenticate the callback so only Cloudflare Workers AI can call it?
Cloudflare does not sign callbacks by default, so you must add a shared secret. Two common patterns are:
- HMAC signature header: Compute
HMAC_SHA256(secret, request.body)on the client side (the Workers AI script) and send it inX-Signature. Verify the signature in the webhook before processing. - Signed JWT: Issue a short‑lived JWT (e.g., 5 minutes) with a
subclaim identifying the job. Include it inAuthorization: Bearer <jwt>and verify with your public key.
Example HMAC verification:
import { hmac } from 'crypto';
export async function onRequestPost({ request }) {
const secret = SECRET; // stored in Workers KV or Secrets
const body = await request.clone().arrayBuffer();
const signature = request.headers.get('X-Signature');
const expected = hmac('sha256', secret).update(body).digest('hex');
if (signature !== expected) {
return new Response('Invalid signature', { status: 401 });
}
// …process payload…
}
How do I prevent abuse and accidental overload?
Even a well‑intended webhook can be hit by retries, malformed payloads, or malicious actors. Implement the following controls:
- Rate limiting: Use Cloudflare Transform Rules or the
Rate Limitingproduct to cap requests per IP (e.g., 10 rps) and per token. - Payload size check: Reject bodies larger than a few megabytes; most AI callbacks are under 1 MB.
- IP allow‑list: If you know the IP ranges used by Cloudflare Workers AI (see the Workers AI docs), restrict access to those ranges.
How should I log and store incoming callbacks for audit and debugging?
Observability is essential for small teams that need to trace a model’s output back to the request. A lightweight approach:
- Write each payload to a Cloudflare KV namespace with a key like
callback:{jobId}:{timestamp}. - Emit a structured log line to Cloudflare Logs (or a third‑party log sink) containing
jobId, status, sourceIP, verificationResult. - Periodically export KV entries to a CSV in Cloudflare R2 for long‑term retention.
What is a good rotation strategy for the shared secret?
Treat the secret like any API key:
- Store it in
Workers Secretsor a dedicated KV entry with a version suffix (e.g.,WEBHOOK_SECRET_v2). - When you need to rotate, create a new version, update the Workers AI script to use the new secret, and keep the old version valid for a short grace period (e.g., 24 h).
- Delete the old version after the grace period and audit the rotation in your weekly monitoring checklist.
How do I handle failures and retries?
Cloudflare Workers AI will retry a failed webhook up to three times with exponential back‑off. Your endpoint should be idempotent:
- Check if
jobIdalready exists in KV before writing. - Return HTTP 200 for duplicate deliveries to stop further retries.
If a permanent error occurs (e.g., signature mismatch), log the incident and alert via a Slack webhook or email.
What should be in my weekly post‑deployment checklist?
- Verify that the secret version matches the one used in the Workers AI script.
- Review rate‑limit hit counts in Cloudflare Analytics.
- Sample 5 random callback logs and confirm payload integrity.
- Check KV storage growth; prune entries older than 30 days.
Following this checklist keeps the webhook reliable and secure without adding heavy operational overhead.
When should I consider moving the webhook to a dedicated server?
If you start receiving more than a few hundred callbacks per hour, or need complex processing (e.g., image resizing, database joins), a dedicated backend (Node.js, FastAPI, etc.) behind a Cloudflare Tunnel can give you more control over runtime, scaling, and language‑specific libraries.
For most early‑stage founders, the Pages‑based function described above is sufficient and cost‑effective.
Need help designing a secure AI callback pipeline? Reach out to AISecAll for a quick architecture review.
Want this kind of automation built for your workflow?
AISecAll designs, builds, deploys, and maintains focused AI automations for small companies and independent entrepreneurs.