Skip to content

Spike Scout Edge Interop

Spike: Cloudflare Edge Interoperability & Bot Challenge Bypass for Synthetic QA Scouts

Executive Summary: This architectural spike investigates edge security interoperability to permit automated local browser scouts (Epic #762) to reliably test Cloudflare-hosted staging and preview deployments without triggering Cloudflare Bot Management, Turnstile challenges, or WAF rate limits. We specify and validate an HMAC-SHA256 signed request header protocol with strict replay protection ($\le$ 300s TTL), Cloudflare Turnstile dummy testing credential orchestration, and a hard negative production lockdown invariant that guarantees zero weakening of production security postures.


1. Context & Problem Statement

1.1 Epic #762 Scope & The Residential Scout Challenge

SiteSwarm’s synthetic QA scout platform runs autonomous local-model agents driving real headless Chromium browsers to validate staging and preview deployments across client applications. Unlike static synthetic probes originating from fixed data center CIDR blocks, synthetic scouts run on developer workstations, residential broadband connections, and distributed local runners.

When these browser sessions interact with Cloudflare-fronted staging environments, they encounter multiple layers of edge security designed to detect and block automated traffic:

  1. Cloudflare Bot Management & Super Bot Fight Mode (SBFM): Analyzes TLS client handshakes (JA3/JA4 fingerprints), HTTP/2 frame parameters, TCP window sizes, browser canvas/audio fingerprint heuristics, and headless automation attributes (e.g. navigator.webdriver, missing browser plugins).
  2. Cloudflare Turnstile Challenges: Interactive or non-interactive CAPTCHA widgets placed on inquiry forms, newsletter signups, and admin portals that stall or fail headless automated browser sessions.
  3. Cloudflare WAF Custom & Rate Limiting Rules: Aggressive request rate limits that throttle high-frequency synthetic user exploratory journeys.

1.2 Spike Research Questions (#768)

  1. The Unknown Question: What is the most secure, maintainable mechanism to allow automated local browser scouts to test Cloudflare-hosted staging and preview deployments without triggering Cloudflare Bot Management or Turnstile challenges, while preserving production security postures?
  2. Decision Blocked: Edge security rule configuration, scout request authentication headers, and staging Turnstile bypass strategy.
  3. Hard Negative Constraint: No predetermined security approach. Do NOT whitelist all headless User-Agents or disable WAF entirely on staging. Bypass rules must be strictly scoped to preview/staging hostnames with cryptographic authentication.

2. Threat Modeling & Failure-Mode Analysis

Threat / Anti-Pattern Attack Vector / Risk Architectural Mitigation in #768
Insecure Global UA Whitelist Attacker spoofing User-Agent: SiteSwarm-Scout/1.0 bypasses all security. Rejected: User-Agent headers are never used as authentication tokens. Cryptographic HMAC-SHA256 signature required.
Static Cleartext Shared Secret Static header value (e.g. X-Bypass: my-secret) leaked in client bundles or network logs. Rejected: Shared secret is never transmitted. Signatures are one-way HMAC-SHA256 digests over a canonical request payload.
Signature Replay Attack Malicious actor captures valid signed request and replays it indefinitely against staging. Mitigated: Canonical string embeds UNIX timestamp; edge verifier strictly rejects requests with age $>300$ seconds or clock skew $>60$ seconds.
Cross-Method Privilege Escalation Signature generated for safe GET /menu replayed as destructive POST /api/inquiries. Mitigated: HTTP method and full request path/query are baked into the canonical signature preimage.
Production Apex Leakage Bypass rule or test credentials mistakenly applied to production domains (jacobmiller22.com). Mitigated: Edge verifier and browser signer enforce a Hard Negative Guardrail: requests to production hostnames are unconditionally rejected (HTTP 403).
Turnstile Widget Stalling Interactive Turnstile challenge on form submission blocks headless scout runner. Mitigated: Dual-layer staging bypass: Cloudflare official dummy test keys (1x00000000000000000000AA) + Playwright DOM auto-fill helper.

3. Cryptographic Bypass Protocol Specification

3.1 Header Schema

Every outbound HTTP request initiated by a synthetic scout browser context is dynamically injected with three authentication headers:

X-Synthetic-Scout-Signature: 8f4a7c1b3e9d2a6... (64-character lowercase hex string)
X-Synthetic-Scout-Timestamp: 1773000500 (UNIX timestamp in integer seconds)
X-Synthetic-Scout-Key-Id: scout-v1 (Key identifier string for rotation)

3.2 Canonical Preimage Format

The signature is generated as HMAC-SHA256(canonicalString, secret). The canonical string format is strictly normalized as:

${METHOD}\n
${HOST}\n
${PATH_AND_QUERY}\n
${TIMESTAMP}\n
${KEY_ID}

Preimage Normalization Invariants:

  1. Method: Normalized to uppercase (GET, POST, PUT, DELETE, PATCH, HEAD).
  2. Host: Normalized to lowercase, including non-standard port if present (e.g. bakery-staging.jacobmiller22.com or localhost:8787).
  3. Path and Query: Normalized to ensure leading slash /, preserving exact query parameter string (e.g. /api/menu?category=pastries).
  4. Timestamp: ASCII integer string representing UTC epoch seconds.
  5. Key-ID: ASCII identifier string matching registered edge secret (default: scout-v1).
// Canonical string construction example
export function buildCanonicalScoutString(params: {
method: string;
host: string;
pathnameAndSearch: string;
timestamp: number | string;
keyId?: string;
}): string {
const method = params.method.trim().toUpperCase();
const host = params.host.trim().toLowerCase();
let path = params.pathnameAndSearch.trim();
if (!path.startsWith('/')) path = `/${path}`;
const timestamp = String(params.timestamp).trim();
const keyId = (params.keyId || 'scout-v1').trim();
return `${method}\n${host}\n${path}\n${timestamp}\n${keyId}`;
}

3.3 Replay Protection & Validity Windows

  • Maximum Permitted Age (maxAgeSeconds): 300 seconds (5 minutes). Requests where now - timestamp > 300 fail closed with TIMESTAMP_EXPIRED.
  • Clock Skew Tolerance (maxClockSkewSeconds): 60 seconds. Requests where timestamp - now > 60 fail closed with TIMESTAMP_FUTURE_SKEW.
  • Constant-Time Verification: Verification evaluates crypto.timingSafeEqual between expected and received signature digests to prevent side-channel timing attacks.

4. Staging Turnstile Testing Strategy

Cloudflare Turnstile provides official dummy test sitekeys and secret keys designed specifically for automated testing environments.

4.1 Cloudflare Official Turnstile Test Credentials

Environment Turnstile Sitekey Turnstile Secret Key Behavior
Staging / Preview / Local 1x00000000000000000000AA 1x0000000000000000000000000000000AA Always passes; emits dummy token XXXX.DUMMY.TOKEN.XXXX
Always Block Test 2x00000000000000000000AB 2x0000000000000000000000000000000AA Always fails validation
Interactive Test 3x00000000000000000000FF 1x0000000000000000000000000000000AA Always forces interactive visual puzzle
Production Real Cloudflare Sitekey Real Cloudflare Secret Key Full Cloudflare ML bot risk scoring

4.2 Playwright DOM Auto-Fill Helper

Headless synthetic scouts running on staging environments utilize setupTurnstilePageBypass(page):

  1. Injects a lightweight init script before document load.
  2. Intercepts window.turnstile.render() to immediately invoke options.callback('XXXX.DUMMY.TOKEN.XXXX').
  3. Attaches a MutationObserver that automatically populates any <input name="cf-turnstile-response"> elements dynamically created in the DOM.
  4. Server-side verification helper verifyTurnstileToken validates dummy tokens offline for test secrets without calling external Cloudflare APIs.

5. Cloudflare Edge Architecture & Integration Options

5.1 Architecture Comparison

flowchart TD
Scout["Headless QA Scout (Playwright)"] -->|"Outbound Request + Signed Headers"| Edge{"Cloudflare Edge"}
subgraph Staging_Zone ["Staging & Preview Deployment Zone"]
Edge -->|"Host matches *-staging.* or *-preview.*"| GateCheck{"Verify Scout Headers"}
GateCheck -->|"Valid HMAC + Fresh TS"| BypassPass["Skip SBFM / WAF Challenges (HTTP 200)"]
GateCheck -->|"Invalid / Missing / Expired"| NormalSec["Enforce Standard Turnstile / WAF (HTTP 403)"]
end
subgraph Production_Zone ["Production Deployment Zone"]
Edge -->|"Host matches apex production"| ProdLockdown["Production Lockdown (HTTP 403)"]
ProdLockdown -->|"Unconditional Deny"| ProdSec["Full Production Bot Management & WAF"]
end
  • Mechanism: Cloudflare Worker isolate receives the incoming Request, extracts X-Synthetic-Scout-* headers, recomputes the HMAC-SHA256 signature using crypto.subtle, validates the timestamp against Date.now(), and checks host policy.
  • Latency Impact: $<1$ ms execution overhead in V8 isolate.
  • Benefits: True cryptographic security, dynamic replay protection, multi-key rotation, structured error diagnostics, and 100% environment isolation.

5.3 Pattern B: Cloudflare WAF Custom Skip Rules

  • Mechanism: Cloudflare WAF Custom Rule configured with the Skip action:
    • Expression:
      (http.host in {"bakery-staging.jacobmiller22.com", "software-agency-staging.jacobmiller22.com"}
      and any(http.request.headers.names[*] == "x-synthetic-scout-signature"))
    • Action: Skip http_request_sbfm (Super Bot Fight Mode) and http_ratelimit (Rate Limiting).
  • Limitation: Cloudflare’s WAF Ruleset Expression engine cannot natively verify HMAC-SHA256 signatures or calculate timestamp arithmetic.
  • Synthesized Recommendation: Deploy Cloudflare WAF Skip Rules at the zone boundary to exempt traffic bearing the signed scout headers from Super Bot Fight Mode, coupled with Cloudflare Worker Ingress Middleware (scoutEdgeMiddleware) to enforce cryptographic signature authenticity and timestamp replay freshness.

6. Implementation Reference

The complete exploratory toolkit is implemented under scripts/scout/edge/:


7. Two-Tier Verification Results

Tier 1: Machine Gate

  • Unit tests: 29/29 tests passed across 8 test suites in scripts/scout/edge/edge-interop.test.ts.
  • Architecture & documentation taxonomy lint: pnpm run lint:arch 0 errors.

Tier 2: Behavioral Runtime Proof (Live Network & Headless Chromium)

Executed via tsx scripts/scout/edge/verify-edge-runtime.ts against an active edge HTTP server:

Step Scenario Action / Probe Expected Actual Pass/Fail Notes
1 Authenticated Staging Ingress GET /api/resource (Host: bakery-staging.jacobmiller22.com, valid HMAC) 200 200 🟢 PASS Valid HMAC-SHA256 signature granted bypass cleanly
2 Unsigned Staging Request GET /api/resource (Host: bakery-staging.jacobmiller22.com, no headers) 403 403 🟢 PASS Blocked: missing required synthetic scout headers
3 Tampered Signature GET /api/resource (corrupted signature hash) 403 403 🟢 PASS Blocked: cryptographic HMAC mismatch
4 Tampered HTTP Method POST /api/resource using GET signature 403 403 🟢 PASS Blocked: signature bound to GET method, cannot be replayed as POST
5 Tampered URL Path GET /admin using /api/resource signature 403 403 🟢 PASS Blocked: signature bound to /api/resource path, cannot access /admin
6 Replay Protection: Expired Timestamp GET /api/resource (timestamp 350s old) 403 403 🟢 PASS Blocked: timestamp exceeds 300s expiration TTL
7 Clock Skew Guardrail: Future Timestamp GET /api/resource (timestamp +120s in future) 403 403 🟢 PASS Blocked: forward clock skew exceeds 60s tolerance
8 Production Domain Lockdown (Hard Negative) GET /api/resource (Host: bakery.jacobmiller22.com, valid HMAC) 403 403 🟢 PASS Blocked: bypass strictly forbidden on production hostnames
9 Key Identifier Validation GET /api/resource (unknown keyId: scout-revoked-or-unknown) 403 403 🟢 PASS Blocked: keyId not registered in edge secret store
10 Turnstile Staging Bypass POST /api/submit-form with dummy token XXXX.DUMMY.TOKEN.XXXX 200 200 🟢 PASS Verified: Cloudflare Turnstile dummy token passed staging gate
11 Playwright Dynamic Request Signing signedPage.goto(/storefront) via configureScoutBrowserContext 200 200 🟢 PASS Browser requests dynamically signed on-the-fly with 100% pass rate
12 Playwright Unsigned Browser Interception unsignedPage.goto(/storefront) without scout context 403 403 🟢 PASS Blocked: headless browser without signed headers rejected (HTTP 403)

8. Mandatory Cleanup & Teardown Roadmap

Per the architectural constraints established in Epic #762 and Issue #766:

  1. Exploratory Workspace: All code in scripts/scout/ is exploratory spike prototyping.
  2. Mandatory Teardown Invariant: Prior to productionizing the synthetic scout runner (whether as an isolated daemon repo siteswarm-scout or dedicated platform package), the temporary scripts/scout/ directory will be cleanly deprecated and reaped.
  3. Canonical Documentation Ingestion: The edge authentication specifications and Cloudflare configuration patterns in this write-up will be distilled into docs/architecture/EDGE_SECURITY.md and docs/architecture/SCOUT_RUNNER.md.