Lilith Metaverse · Security

V3 DDoS and WAF Posture

The POP fleet is AWS-primary with Azure / GCP / CoreWeave / Lambda Cloud secondaries (PIXEL_STREAMING_POP_CAPACITY_MANAGEMENT.md).

6sections6 minread2tables

On this page

Manifest version: v3-ddos-waf-posture.v1

Verifier: pnpm verify:v3 ddos-waf-posture (proposed)

Evidence artifact: V3/security/ddos-waf-posture-validation.json (proposed)

Owner: Security on-call (oshun-security-oncall), joint with Capacity / Pixel Streaming on-call for backpressure interactions

V3/PIXEL_STREAMING_ABUSE_POSTURE.md covers session-level abuse of the Pixel Streaming relay (idle caps, per-user/per-network concurrency, free-tier minutes, bot classification). It does not cover volumetric DDoS or API-abuse against the public web and BFF surfaces — the launch landing, the auth routes, the launch resolver, the waitlist, and the status page. This posture closes that gap. Transport requirements (TLS 1.3 everywhere, WSS signalling, DTLS-SRTP) are already locked by V3/TRANSPORT_SECURITY.md and are assumed below.

Provider Assumption (L3/L4)#

The POP fleet is AWS-primary with Azure / GCP / CoreWeave / Lambda Cloud secondaries (PIXEL_STREAMING_POP_CAPACITY_MANAGEMENT.md). The public web/BFF edge therefore standardizes on:

  • AWS Shield Advanced on every public entry point: the CloudFront distributions fronting apps/oshun/web and the BFF API, and the ALBs they originate from. Shield Advanced gives always-on L3/L4 volumetric and state-exhaustion mitigation (SYN/UDP floods, reflection), health-based detection tied to our Route 53 health checks, access to the Shield Response Team (SRT) with the engagement contact pre-filed before GA, and DDoS cost protection.
  • Protection group: all V3 public resources in one Shield protection group with aggregation sum, so a distributed low-rate attack across surfaces is detected as one event.
  • The WebRTC media planes (voice SFU, pxstream UDP) are not behind CloudFront; they rely on provider-native L3/L4 scrubbing plus the relay's own admission control, and their signalling (WSS) is routed through the protected edge. A volumetric attack on a POP's media IPs is handled as a POP outage via the existing pixel-streaming-pop-outage runbook and multi-cloud failover drills.

Origin-Shield Architecture#

text
client → CloudFront (WAF attached, TLS 1.3)
       → CloudFront Origin Shield (us-east-1)
       → ALB (security group: CloudFront managed prefix list ONLY)
       → BFF / web origin
  • Origins accept traffic exclusively from the CloudFront managed prefix list plus a per-distribution shared-secret header (x-oshun-edge-auth, value in KMS, rotated quarterly); requests arriving at the ALB without the header are dropped at the listener rule, so the origin cannot be addressed directly even from within AWS IP space.
  • Origin Shield collapses regional cache misses to one origin fetch; /v3/landing, static assets, and /status are edge-cached (status at 30 s TTL) so a request flood against them never reaches the BFF.
  • No DNS record points at an origin: Route 53 publishes only edge distribution targets; origin hostnames are randomized and not in public zones.

WAF Rule Classes#

Attached to the edge distributions, evaluated in order:

Priority Rule class Content Action
1 ip-reputation Managed IP reputation + anonymizer/proxy list; our own incident blocklist (security runbooks feed it) Block
2 geo-policy Sanctions-prohibited geos (per wave-3 note: RU is sanctions-prohibited) blocked at edge; non-wave regions are NOT blocked here — they get the app-layer regional waitlist Block (sanctions only)
3 core-protections OWASP-class managed rules: SQLi, XSS, path traversal, known bad inputs Block
4 request-validation Method allowlist per route, body size cap 64 KB on JSON APIs (256 KB on DSAR upload), content-type enforcement, reject malformed JSON early Block
5 bot-control Managed bot control in targeted mode on auth + waitlist + signup; challenge (not block) on suspicion; verified-bot allowlist for status-page monitors Challenge
6 auth-protection ATO-focused rules on /api/v1/auth/*: credential-stuffing signatures, password-spray patterns, header-anomaly scoring; integrates the rate-limit escalation ladder from V3/runbooks/security-incident-response.md Block/Challenge
7 rate-based-global 2,000 requests / 5 min / IP across the distribution Block 10 min
8 rate-based-scoped Per-endpoint limits below Block 10 min

WAF logs stream to the security account's locked log bucket with 13-month retention; the v3-bff-auth-abuse dashboard reads from them.

Per-Endpoint Rate Limits#

Enforced as WAF scoped rate rules at the edge, with matching (slightly looser) BFF middleware limits as defense in depth — the origin never trusts the edge to have done its job:

Endpoint Limit (per source IP unless noted) Burst Rationale
POST /api/v1/auth/login 10/min (drops to 3/min under ATO ladder) 15 Stuffing chokepoint; CAPTCHA after 3 consecutive failures
POST /api/v1/auth/signup 5/min, 20/day 8 Bulk account creation
POST /api/v1/auth/refresh 6/min per session, 30/min per IP 10 Rotation is once-per-TTL; more is replay probing (JWT_REFRESH_ROTATION.md)
GET /api/v3/lilith/launch 60/min 90 Launch resolver is polled by clients; cached 10 s per identity
POST /api/v3/lilith/launch/waitlist 3/min, 10/day 5 Waitlist stuffing pollutes wave planning
GET /api/v3/lilith/launch/waitlist/:id 20/min 30 Record retrieval
Queue ticket refresh (surge plan) 12/min per ticket 20 Silent refresh cadence is 1/min; 12 allows clock skew
GET /status 30/min 60 Edge-cached 30 s; limit protects against cache-buster query spam
DSAR / privacy request routes 2/min, 10/day per account 4 Statutory workflows are human-paced
GET /api/v3/pxstream/admission/evaluate Internal only — edge returns 403 unless from operator-tooling IP set Drill/operator surface, not public

Limits apply per IPv4 address and per IPv6 /64. Institutional NAT exceptions reuse the institutional-network uplift mechanism from the abuse posture (tenant-scoped, approved, audited) rather than ad-hoc allowlisting.

Backpressure and Surge Interaction#

  • When the surge plan's waiting room is armed (V3/launch/launch-surge-plan.md), the queue sits behind the WAF: flood traffic is shed at the edge before it can occupy queue slots, so attackers cannot fill the waiting room and starve real users.
  • Rate-based blocks emit the same telemetry stream as the abuse classifier; an IP blocked at the edge ≥ 3 times in 24 h is promoted to the ip-reputation incident blocklist automatically (TTL 7 days, extensions require security on-call review).
  • WAF block-rate > 5,000 blocks/min or a Shield detected-event page the security on-call; ≥ 50,000 blocks/min or origin p95 degradation during an attack escalates to SRT engagement.

Gate#

The release gate fails closed when any of the following holds:

  • Shield Advanced is not active on every public distribution and ALB in the evidence file, or the protection group is missing;
  • the SRT engagement contact is unfiled, or the DDoS escalation path is not in the on-call rota;
  • any origin ALB security group admits sources beyond the CloudFront prefix list, or the x-oshun-edge-auth header rule is absent (verified by a direct-to-origin probe that must be dropped, recorded in evidence);
  • any endpoint in the rate-limit table lacks both its edge rule and its BFF middleware twin, or a limit is raised without a recorded security review;
  • the WAF rule classes are not attached in the documented priority order;
  • WAF logs are not flowing to the locked bucket (probe: a synthetic blocked request must appear in the log stream within 5 minutes);
  • the sanctions geo-block does not match the current wave-3 sanctions note in V3/REGION_ROLLOUT_COMPLIANCE.md;
  • the attack drill is missing: a staged drill must show (a) a 10x request flood against /api/v1/auth/login is shed at the edge with origin p95 unchanged, and (b) the queue-starvation scenario (flood while waiting room armed) admits zero attacker sessions — both with evidence snapshots in the validation artifact.