effGen's core is Python. Cloudflare Workers run JS/WASM at the edge.
The deploy/cloudflare/ directory ships a thin proxy Worker that sits in
front of your backend effGen deployment (Docker/K8s/Lambda) and handles:
- ✅ CORS — preflight handling and per-origin response headers
- ✅ JWT Bearer validation — structural + expiry check at the edge; full signature verification delegated to the upstream (OIDC JWKS)
- ✅ Fixed-window rate limiting — per-IP and per-token via Cloudflare KV
- ✅ Security headers —
X-Content-Type-Options,X-Frame-Options, etc. - ✅ Request forwarding — proxies to any
EFFGEN_BACKEND_URLwithX-Forwarded-{Host,Proto}headers injected
Client
│
▼
Cloudflare Edge PoP
┌──────────────────────────────────────────────────────┐
│ Worker: effgen-edge-proxy │
│ │
│ 1. CORS preflight? → 204 immediately │
│ 2. Public path? → skip JWT check │
│ 3. JWT present? → parse, check expiry │
│ 4. Rate limit? → check KV counters │
│ 5. Forward → upstream effGen server │
│ 6. Inject headers → security + CORS │
└──────────────────────────────────────────────────────┘
│
▼
Backend effGen server (Docker / K8s / AWS Lambda)
| Tool | Install |
|---|---|
| Node.js ≥18 | https://nodejs.org |
| Wrangler CLI v4 | npm install -g wrangler |
| Cloudflare account | https://dash.cloudflare.com/sign-up |
git clone https://github.com/your-org/effgen.git
cd effgen/deploy/cloudflareEdit wrangler.toml:
[vars]
# Point to your running effGen backend
EFFGEN_BACKEND_URL = "https://api.your-domain.com"
# CORS: comma-separated allowed origins, or "*" for any
EFFGEN_CORS_ORIGINS = "https://app.your-domain.com"# Create the namespace and note the returned id
wrangler kv namespace create RATE_LIMIT
# → Created namespace "RATE_LIMIT": id = "abc123..."
wrangler kv namespace create RATE_LIMIT --preview
# → Created namespace "RATE_LIMIT_preview": id = "def456..."Update wrangler.toml:
[[kv_namespaces]]
binding = "RATE_LIMIT"
id = "abc123..." # ← real id from above
preview_id = "def456..." # ← preview id# Backend-to-worker M2M auth token (optional but recommended)
wrangler secret put EFFGEN_BACKEND_TOKEN
# Paste your secret token when prompted# Deploy to the Workers.dev subdomain (no custom domain needed)
wrangler deploy
# Or deploy to a specific environment
wrangler deploy --env staging
wrangler deploy --env production# Replace with your worker URL
curl -I https://effgen-edge-proxy.<your-account>.workers.dev/health
# → HTTP/2 200
# → X-Content-Type-Options: nosniff
curl -s https://effgen-edge-proxy.<your-account>.workers.dev/v1/models
# → {"error":{"code":"unauthorized","message":"Bearer token required"}}
# With a valid token
curl -H "Authorization: Bearer $TOKEN" \
https://effgen-edge-proxy.<your-account>.workers.dev/v1/models
# → proxied response from your backendAll configuration is in wrangler.toml [vars] or via wrangler secret put.
| Variable | Default | Description |
|---|---|---|
EFFGEN_BACKEND_URL |
https://api.example.com |
Upstream effGen server URL (no trailing slash) |
EFFGEN_CORS_ORIGINS |
* |
Allowed CORS origins (comma-separated; * = any) |
EFFGEN_RATE_LIMIT_WINDOW_SECONDS |
60 |
Rate-limit window size in seconds |
EFFGEN_RATE_LIMIT_IP_MAX |
100 |
Max requests per IP per window (0 = disabled) |
EFFGEN_RATE_LIMIT_TOKEN_MAX |
200 |
Max requests per token per window (0 = disabled) |
EFFGEN_BACKEND_TOKEN |
(secret) | Bearer token injected as X-Effgen-Proxy-Token for M2M backend auth |
The RATE_LIMIT KV namespace stores fixed-window counters. Keys are:
ip:<client-ip>— per-IP counter; TTL =EFFGEN_RATE_LIMIT_WINDOW_SECONDStok:<sub-prefix>— per-token counter; same TTL
These paths skip JWT validation and are forwarded directly:
/health /healthz /metrics /favicon.ico
Configure your effGen backend to keep these paths public as well, or add your own OIDC check there.
Every response (including errors) includes:
| Header | Value |
|---|---|
X-Content-Type-Options |
nosniff |
X-Frame-Options |
DENY |
Referrer-Policy |
strict-origin-when-cross-origin |
Permissions-Policy |
geolocation=(), camera=(), microphone=() |
X-Powered-By |
effgen |
The Worker enforces two independent fixed-window counters stored in KV:
- IP-based — keyed by
CF-Connecting-IP(Cloudflare's authoritative client IP). Limits all requests from a single IP regardless of auth status. - Token-based — keyed by the JWT
subclaim (truncated to 64 chars). Limits authenticated requests per identity.
Each window opens on the first request and is reset by the KV TTL
(EFFGEN_RATE_LIMIT_WINDOW_SECONDS). KV is eventually consistent, so counters
are best-effort across data centres; for strict global limits, back the counter
with a Durable Object.
When either limit is exceeded, the Worker returns:
HTTP/2 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1716768000
{"error":{"code":"rate_limit_exceeded","message":"IP rate limit: 100 req/60s"}}# No Cloudflare account needed for local dev (entry comes from wrangler.toml `main`)
wrangler dev
# The dev server binds a local KV namespace automatically
# Access at http://localhost:8787
curl http://localhost:8787/healthwrangler.toml ships with staging and production environments:
wrangler deploy --env staging
wrangler deploy --env productionOverride any var per-environment in wrangler.toml:
[env.production]
name = "effgen-edge-proxy"
vars = { EFFGEN_BACKEND_URL = "https://api.example.com", EFFGEN_RATE_LIMIT_IP_MAX = "100" }Unit tests for the fetch handler run with Node (no Cloudflare account):
conda activate effgen
pytest tests/deploy/test_cloudflare_worker.py -vTests cover: CORS preflight, missing auth (401), malformed JWT (401), expired JWT (401), valid token + upstream 200, upstream unreachable (502), public path bypass, IP rate limiting (429), security headers.
Wrangler config validation:
wrangler deploy --dry-run
# → prints binding summary and exits; no deployment occursTo bind to a custom hostname instead of *.workers.dev:
[[routes]]
pattern = "api.your-domain.com/*"
zone_name = "your-domain.com"Then redeploy:
wrangler deploy --env production| Symptom | Likely cause | Fix |
|---|---|---|
401 unauthorized |
No Authorization: Bearer ... header |
Add header or check client config |
401 invalid_token |
JWT has fewer than 3 dot-separated parts | Client sending wrong token format |
401 token_expired |
JWT exp claim is in the past |
Refresh the token |
429 rate_limit_exceeded |
Too many requests in window | Back off and retry after Retry-After seconds |
502 bad_gateway |
Worker cannot reach EFFGEN_BACKEND_URL |
Check backend is running and URL is correct |
| CORS errors | Origin not in EFFGEN_CORS_ORIGINS |
Add origin to the list |