Edge Function
CloudFront Lambda@Edge — request interception, identity resolution, 8-layer fraud detection. ~3,400 LOC across 10 Python modules.
Module Architecture
lambda_function.py # Entry point (28 LOC) │ ├── handlers.py # Request router (697 LOC) │ ├── /t → track event (POST) │ ├── /c → campaign data (POST) │ ├── /h.js → fingerprint bundle │ ├── /h-pro.js → behavioral bundle │ ├── /cookie-test → 1st-party cookie validation │ └── default → tracking pixel (1x1 GIF) │ ├── auth.py # Supabase auth + plans (231 LOC) │ ├── 4 plans: free/starter/pro/enterprise │ └── Upstash Redis cache (5 min TTL) │ ├── identity.py # Identity Resolver (738 LOC) │ ├── Fast path (known user: 1 query) │ ├── Parallel path (anon: 3 queries||) │ └── Domainprint aliasing system │ ├── fraud.py # 8-layer fraud detector (496 LOC) │ ├── JA4 TLS fingerprint │ ├── Headless browser detection │ ├── VPN/datacenter ASN check │ ├── HTTP/2 anomalies │ ├── WebRTC IP leak analysis │ ├── Credential stuffing (rate limit) │ ├── Bot user-agent detection │ └── JA4 ↔ context cross-validation │ ├── attribution.py # Campaign/UTM parsing ├── js_generator.py # Dynamic JS bundle generation ├── db.py # DynamoDB connection + helpers ├── cache.py # Upstash Redis REST API ├── utils.py # Browser detection, helpers └── supabase_client.py # Supabase REST client
Request Pipeline
CloudFront Intercept
Lambda@Edge catches origin-request event. Extracts URI, headers, viewer metadata.
Authentication
Validates organizationId against Supabase. Cache hit: 50ms, miss: 1500ms. Checks plan limits.
Identity Resolution
Resolves user via fingerprint → domainprint → behavioral. Fast path for known users (1 query).
Fraud Analysis
8-layer detection pipeline. Composite risk score 0-100: low/medium/high/critical.
DynamoDB Write
Event saved with identity, fraud analysis, attribution, server context. Async timestamp updates.
Response
Returns domainprint cookie (365d TTL), identity result, risk assessment. CORS validated.
8-Layer Fraud Detection
| Layer | Signal | Max Risk |
|---|---|---|
| JA4 TLS Fingerprint | Missing JA4, pattern match (t10d, t11d), Chrome != TLS 1.3 | 80 |
| JA4 ↔ Context Cross | Chrome wrong TLS, no HTTP/2, missing browser headers, UA first | 60+ |
| JA4 Structure | Outdated TLS, no SNI, few ciphers/extensions | 100 |
| Headless Browser | Missing client hints, generic language, headless keyword in UA | 100 |
| VPN/Datacenter | ASN matches: Cloudflare, AWS, GCloud, Azure, DigitalOcean, Equinix | 40 |
| HTTP/2 Anomalies | Version mismatch, missing pseudo-headers, minimal headers | 100 |
| WebRTC Analysis | No NAT (datacenter), multiple IPs, IPv6 leak, relay connection | 100 |
| Credential Stuffing | Rate limit via Upstash Redis: >20 logins/hour per JA4 | 70 |
Risk Level → Action
Low
allowMedium
monitorHigh
captchaCritical
blockPlan System
| Feature | Free | Starter | Pro | Enterprise |
|---|---|---|---|---|
| Identity | ✅ | ✅ | ✅ | ✅ |
| Anti-Bot | ✅ | ✅ | ✅ | ✅ |
| Campaigns | ❌ | ✅ | ✅ | ✅ |
| digitalData | ❌ | ✅ | ✅ | ✅ |
| Service Worker | ❌ | ❌ | ✅ | ✅ |
| SSR | ❌ | ❌ | ❌ | ✅ |
| Events/month | 10K | 50K | 200K | 1M |
| Domains | 1 | 3 | 10 | ∞ |
Deep Dive: Identity Resolver
Fast path vs parallel path, domainprint aliasing, reverse indexes, confidence scoring.
View Identity Resolver