Skip to content

Security, Guardrails & Operations

Revenue Guard operates under one principle: if something goes wrong, fail loudly and stop the bleed immediately.

When budgets are at risk or traffic is suspicious, the system doesn’t guess. It blocks. It logs. It alerts. This is the opposite of “let’s scale and deal with overages later.”

Each layer catches a different class of abuse:

  • Turnstile (Entry): No session without a Turnstile challenge. Stops bots before they hit any API.
  • Rate limits (Per-session): 200/min allocations per session (per IP). Stops single-user abuse.
  • Guardrails (Budget): Virtual spend cap. Once hit, allocations are blocked until reset. Stops runaway scenarios.
  • Validation (Payload): Strict checks on SKU/user/mode. Rejects malformed requests before processing.

[!TIP] The demo’s DEMO_COST_LIMIT=0.0 means billing is literally locked to zero. Real spend can’t happen. This is the trust mechanism: “You can throw anything at this demo, and it won’t cost money.”

graph TD
  Start(["Allocation Request"]) --> CheckGuard{"Guardrail<br/>tripped?"}
  CheckGuard -- Yes --> Block["403 Forbidden<br/>guardrailTriggered: true"]
  CheckGuard -- No --> Mode{"mode=safe?"}
  Mode -- Safe --> DOAlloc["Durable Object<br/>allocate()"]
  Mode -- Eventual --> D1Alloc["D1 allocate<br/>SELECT+UPDATE"]
  DOAlloc --> Validate{"Request<br/>with valid<br/>SKU/user?"}
  D1Alloc --> Validate
  Validate -- No --> Reject["400 Bad Request<br/>error: INVALID_SKU"]
  Validate -- Yes --> Check2{"Does allocation<br/>exceed budget?"}
  Check2 -- Yes --> Trip["Set guardrail<br/>flag in KV"]
  Trip --> Block
  Check2 -- No --> Respond["200 OK<br/>allocated: true"]
  Respond --> Log["Emit to<br/>Analytics Engine"]

Reading the flow:

  1. Request arrives
  2. Check if guardrail is already tripped → if yes, block immediately (403)
  3. Route to safe or eventual path based on mode parameter
  4. Validate payload (SKU exists, user ID is UUID, etc.)
  5. Execute allocation logic
  6. Check if total cost/units now exceed budget
  7. If yes, trip the guardrail (future requests will hit step 2)
  8. If no, respond with success and emit telemetry

What goes wrong, and what happens:

ScenarioSymptomSystem ResponseOps Action
DO crashes mid-requestdurable_object_error in logsAuto-restart in 30s; in-flight requests fail with 500Wait for recovery; if persistent, rollback to SQL-only
D1 query quota exceededdatabase quota exceeded errorAllocations fail; guardrail tripsDelete old allocations; VACUUM D1; raise quota if needed
Turnstile token invalidunauthorised responseRequest rejected at entry (403)Confirm Turnstile is configured; use DEBUG_TOKEN in dev
Rate limit hit429 Too Many RequestsResponse includes Retry-After headerWhitelist demo IP if legitimate; otherwise investigate abuse
KV quota exceededkv_namespace_fullSession mirrors can’t persist; no WS recoveryDelete entries older than 24h; increase KV quota
Guardrail stuck (set but shouldn’t be)Allocations blocked mysteriouslyCheck KV: wrangler kv:key get --namespace-id=XXX guardrail_statusIf stuck, manually clear: wrangler kv:key delete guardrail_status

Revenue Guard emits data through three streams:

  1. Analytics Engine (primary): Structured events—allocation attempts, outcomes, guardrail triggers, latency breakdowns. Queryable, aggregatable, designed for trends.

    allocation_event: {
    skuId, userId, mode (safe|eventual),
    success (true|false), latency_ms,
    guardrail_triggered, cost_delta
    }
  2. Logs (immediate): wrangler tail shows real-time activity. Grep for errors, allocate calls, guardrail state changes. Human-readable, not indexed, good for live debugging.

    Terminal window
    wrangler tail --env production --filter allocate --grep "ERROR|GUARDRAIL"
  3. KV Counters (state): Rate limit keys, guardrail flag, session snapshots. Fast for checks, not queryable like Analytics Engine.

allocate: 200 requests/minute per IP
reset: 1 request/minute per IP
state: unlimited (read-only)

Why these numbers? A genuine user clicks “buy” 1–3 times per second (under panic). 200/minute handles typos, retries, and accidental double-clicks. Scripts abuse rate limits by hitting 1000+/min; we catch them at 200.

  • KV + DO can be pinned to a region via location_hint (e.g., eu for GDPR compliance). In demo mode, this is optional. In production, respect data gravity.
  • Only metadata is stored: sessionId, IP, timestamp, event type. No customer names, emails, or payment data.
  • GDPR deletion: KV entries auto-expire after 20 minutes (session length). Longer history? Store in cold storage, not hot path.

[!NOTE] Revenue Guard prioritizes safety and speed over exhaustiveness:

  • No payment processing: Allocation only; payments are downstream.
  • No user auth: Turnstile proves “not a bot,” not “authenticated user.” Pair with your auth system.
  • No encryption in flight: Relies on Cloudflare’s edge encryption. Add app-layer encryption if PCI compliance requires it.
  • No audit trail to cold storage: Analytics Engine events expire after 30 days. Export to Sentry/DataDog/BigQuery if you need long-term audit compliance.