[{"data":1,"prerenderedAt":182},["ShallowReactive",2],{"blog-blueprints/cloudflare-workers":3},{"id":4,"title":5,"body":6,"category":161,"date":162,"dateModified":163,"description":164,"draft":165,"extension":166,"faq":167,"featured":165,"headerVariant":168,"image":167,"keywords":167,"meta":169,"navigation":170,"ogDescription":171,"ogTitle":167,"path":172,"readTime":173,"schemaOrg":174,"schemaType":175,"seo":176,"sitemap":177,"stem":178,"tags":179,"twitterCard":180,"__hash__":181},"blog/blog/blueprints/cloudflare-workers.md","Cloudflare Workers Security Guide",{"type":7,"value":8,"toc":150},"minimark",[9,20,24,30,35,50,54,63,67,76,89,93,98,101,104,107,110,113,124,138],[10,11,12],"blueprint-summary",{},[13,14,15,19],"p",{},[16,17,18],"strong",{},"To secure Cloudflare Workers,"," you need to: (1) store secrets using wrangler secret put (never in wrangler.toml), (2) implement rate limiting using Workers KV or Durable Objects, (3) validate all incoming requests including JWT verification at the edge, (4) configure CORS properly to prevent unauthorized origins, and (5) ensure error messages do not leak sensitive information. This blueprint covers edge security patterns for serverless functions.",[21,22],"blueprint-meta",{"time":23},"1-2 hours",[25,26,27],"tldr",{},[13,28,29],{},"Workers run at the edge with access to secrets via environment variables. Use wrangler secrets for sensitive data, validate all incoming requests, implement rate limiting with Workers KV or Durable Objects, and be careful with CORS configuration.",[31,32,34],"h2",{"id":33},"jwt-validation-at-the-edge-cloudflare","JWT Validation at the Edge Cloudflare",[36,37,39],"code-block",{"label":38},"src/index.ts",[40,41,46],"pre",{"className":42,"code":44,"language":45},[43],"language-text","export interface Env {\n  JWT_SECRET: string\n  ALLOWED_ORIGINS: string\n}\n\nexport default {\n  async fetch(request: Request, env: Env): Promise\u003CResponse> {\n    // CORS handling\n    if (request.method === 'OPTIONS') {\n      return handleCors(request, env)\n    }\n\n    // Authenticate\n    const authHeader = request.headers.get('Authorization')\n    if (!authHeader?.startsWith('Bearer ')) {\n      return new Response('Unauthorized', { status: 401 })\n    }\n\n    const token = authHeader.slice(7)\n\n    try {\n      const payload = await verifyJwt(token, env.JWT_SECRET)\n      // Token is valid, process request\n      return handleRequest(request, payload, env)\n    } catch {\n      return new Response('Invalid token', { status: 401 })\n    }\n  },\n}\n\nasync function verifyJwt(token: string, secret: string) {\n  const encoder = new TextEncoder()\n  const key = await crypto.subtle.importKey(\n    'raw',\n    encoder.encode(secret),\n    { name: 'HMAC', hash: 'SHA-256' },\n    false,\n    ['verify']\n  )\n\n  const [headerB64, payloadB64, signatureB64] = token.split('.')\n  const data = encoder.encode(`${headerB64}.${payloadB64}`)\n  const signature = base64UrlDecode(signatureB64)\n\n  const valid = await crypto.subtle.verify('HMAC', key, signature, data)\n  if (!valid) throw new Error('Invalid signature')\n\n  return JSON.parse(atob(payloadB64))\n}\n","text",[47,48,44],"code",{"__ignoreMap":49},"",[31,51,53],{"id":52},"rate-limiting-with-kv-cloudflare","Rate Limiting with KV Cloudflare",[36,55,57],{"label":56},"src/rate-limit.ts",[40,58,61],{"className":59,"code":60,"language":45},[43],"export interface Env {\n  RATE_LIMIT_KV: KVNamespace\n}\n\nexport async function rateLimit(\n  ip: string,\n  env: Env,\n  limit = 100,\n  window = 60\n): Promise\u003Cboolean> {\n  const key = `rate:${ip}`\n  const current = await env.RATE_LIMIT_KV.get(key)\n\n  if (!current) {\n    await env.RATE_LIMIT_KV.put(key, '1', { expirationTtl: window })\n    return true\n  }\n\n  const count = parseInt(current, 10)\n  if (count >= limit) {\n    return false\n  }\n\n  await env.RATE_LIMIT_KV.put(key, String(count + 1), { expirationTtl: window })\n  return true\n}\n\n// Usage in worker\nexport default {\n  async fetch(request: Request, env: Env): Promise\u003CResponse> {\n    const ip = request.headers.get('CF-Connecting-IP') || 'unknown'\n\n    if (!await rateLimit(ip, env)) {\n      return new Response('Too many requests', { status: 429 })\n    }\n\n    // Process request...\n  },\n}\n",[47,62,60],{"__ignoreMap":49},[31,64,66],{"id":65},"secrets-management","Secrets Management",[36,68,70],{"label":69},"wrangler.toml + CLI",[40,71,74],{"className":72,"code":73,"language":45},[43],"# wrangler.toml - Don't put secrets here!\nname = \"my-worker\"\nmain = \"src/index.ts\"\n\n[vars]\nALLOWED_ORIGINS = \"https://myapp.com\"\n\n# Add secrets via CLI (encrypted, not in source)\n# wrangler secret put JWT_SECRET\n# wrangler secret put DATABASE_URL\n",[47,75,73],{"__ignoreMap":49},[77,78,79],"warning-box",{},[13,80,81,84,85,88],{},[16,82,83],{},"Never put secrets in wrangler.toml."," Use ",[47,86,87],{},"wrangler secret put"," for sensitive values. They're encrypted and only accessible at runtime.",[31,90,92],{"id":91},"security-checklist","Security Checklist",[94,95,97],"h4",{"id":96},"pre-launch-checklist","Pre-Launch Checklist",[13,99,100],{},"Secrets stored via wrangler secret",[13,102,103],{},"Rate limiting implemented",[13,105,106],{},"CORS configured correctly",[13,108,109],{},"Request validation in place",[13,111,112],{},"Error messages don't leak info",[114,115,116,121],"stack-comparison",{},[117,118,120],"h3",{"id":119},"related-integration-stacks","Related Integration Stacks",[13,122,123],{},"S3 Secure Uploads\nRedis Session Management\nOAuth at the Edge",[125,126,127,133],"related-articles",{},[128,129],"related-card",{"description":130,"href":131,"title":132},"Edge + database","/blog/blueprints/jamstack-supabase","Jamstack + Supabase",[128,134],{"description":135,"href":136,"title":137},"Deep dive","/blog/best-practices/api-design","API Security Guide",[139,140,143,147],"cta-box",{"href":141,"label":142},"/","Start Free Scan",[31,144,146],{"id":145},"check-your-workers-security","Check Your Workers Security",[13,148,149],{},"Scan for edge function vulnerabilities.",{"title":49,"searchDepth":151,"depth":151,"links":152},2,[153,154,155,156,160],{"id":33,"depth":151,"text":34},{"id":52,"depth":151,"text":53},{"id":65,"depth":151,"text":66},{"id":91,"depth":151,"text":92,"children":157},[158],{"id":119,"depth":159,"text":120},3,{"id":145,"depth":151,"text":146},"blueprints","2026-01-30","2026-02-09","Security guide for Cloudflare Workers. Protect secrets, handle authentication at the edge, validate requests, implement rate limiting, and secure your edge functions.",false,"md",null,"purple",{},true,"Secure Cloudflare Workers implementation patterns.","/blog/blueprints/cloudflare-workers","10 min read","[object Object]","Article",{"title":5,"description":164},{"loc":172},"blog/blueprints/cloudflare-workers",[],"summary_large_image","wvNLPTiLBio6LqKRKmFolGPTNCjYLczH1KbW0l3aXgI",1775843932641]