deploy-protection

Deploy Cloudflare protections (Turnstile, WAF)

Deploy Cloudflare Protections

1. Turnstile (reCAPTCHA Replacement) - FREE

  1. Create Widget:
    • Go to Cloudflare Dashboard > Turnstile.
    • Site Name: Legends of Hastinapur.
    • Domain: legendsofhastinapur.com (and localhost).
    • Widget Mode: Managed.
    • Copy Site Key and Secret Key.
  2. Frontend (loh-website):
    • Add Turnstile component to forms (login, register, reserve).
    • Pass token to backend via X-Turnstile-Token header or body.
  3. Backend Workers:
    • Set secret: wrangler secret put TURNSTILE_SECRET
    • Verify token with https://challenges.cloudflare.com/turnstile/v0/siteverify
    • Already implemented in: account-api, reservation-api, ticket-api

2. Rate Limiting (Free Tier: 10 rules)

Go to Security > WAF > Rate Limiting Rules:
Rule NameMatchRateAction
Auth Endpointshttp.request.uri.path contains "/auth"5 req/min per IPBlock 10 min
Reserve Endpointhttp.request.uri.path eq "/reserve"2 req/min per IPChallenge
Ticket Creationhttp.request.uri.path eq "/tickets" and http.request.method eq "POST"10 req/min per IPBlock 5 min
Shop APIhttp.request.uri.path contains "/shop"60 req/min per IPChallenge

3. WAF Custom Rules (Free Tier: 5 rules)

Go to Security > WAF > Custom Rules:
Rule NameExpressionAction
Block Known Bots(cf.client.bot)Block
Block curl/wget(http.user_agent contains "curl") or (http.user_agent contains "wget")Challenge
Geo-Challenge(ip.geoip.country ne "IN" and ip.geoip.country ne "US" and ip.geoip.country ne "GB")Managed Challenge
Block Empty UA(http.user_agent eq "")Block

4. Cache Optimization

  • Shop API: Already has Cache-Control: public, max-age=60, s-maxage=60
  • Static Assets: Page Rule legendsofhastinapur.com/assets/* -> Cache Everything, Edge TTL 1 day
  • Worker Optimization: Use KV for sessions, avoid D1 writes on read paths

5. Secrets Checklist

# account-api
wrangler secret put JWT_SECRET
wrangler secret put GOOGLE_CLIENT_ID
wrangler secret put GOOGLE_CLIENT_SECRET
wrangler secret put TURNSTILE_SECRET

# reservation-api
wrangler secret put TURNSTILE_SECRET_KEY
wrangler secret put ADMIN_API_KEY

# ticket-api
wrangler secret put TURNSTILE_SECRET
wrangler secret put GEMINI_API_KEY