Brand safety—preventing ads from appearing next to inappropriate, offensive, or illegal content—is a critical advertiser concern. A family-oriented brand (Disney, Nestle, American Express) will not tolerate ads appearing on pages containing violence, hate speech, explicit sexual content, illegal drugs, or hate groups. A single brand-safety failure (ad for children's toy next to graphic violence) triggers advertiser backlash, media coverage, and contract disputes. Publishers suffer: major advertisers blacklist them, CPMs fall 30–50%, and relationships take months to rebuild.
The detection challenge combines content understanding (is this page safe?), real-time decision latency (block/allow within RTB <100 ms), and continuous adaptation (new unsafe content types emerge daily). Solutions range from static allowlist/blocklists (pre-classified URLs stored in DynamoDB) to real-time AI classification via Amazon Comprehend (text moderation), Amazon Rekognition (image/video moderation), and Amazon Bedrock (LLM-based nuanced classification) to hybrid approaches combining pre-classified known content with dynamic fallback. Advertiser-defined keyword and content exclusion lists add a second layer: allow advertiser to block "weapons," "cryptocurrency," "alcohol" even if not inherently unsafe.
This case examines three architectures: pre-classified allowlist/blocklist (simple, fast, limited coverage), real-time AI inference via AWS services (comprehensive, latency-sensitive, requires ML infrastructure), and hybrid (fast known content + real-time fallback + keyword filters).
Key Requirements
Functional Requirements
Content classification: Automatically classify web pages and video frames as safe/unsafe (GARM categories or custom taxonomy).
Real-time decisions: Flag unsafe content within RTB latency (<100 ms bid timeout); serve-time blocking via ECS Fargate.
GARM compliance: Support Global Alliance for Responsible Media (GARM) categories (13 brand-safety tiers: hate speech, violence, sexual content, obscenity, misinformation, etc.).
Advertiser controls: Allow advertisers to define custom exclusion lists (e.g., "no alcohol," "no political content," "no low-quality sites") stored in DynamoDB per advertiser.
Publisher controls: Allow publishers to self-classify sensitive inventory (e.g., "news politics" → lower brand-safety tier) stored in Aurora.
Category transparency: Return content category with ad decision for audits and reporting.
Dispute resolution: Maintain content sample (screenshot, text excerpt) in S3 for advertiser/publisher review.
Non-Functional Requirements
Latency: <5 ms for pre-classified content lookup via DynamoDB; <20 ms for real-time classification (must not break RTB).
Throughput: Classify 100K–500K URLs/day via SageMaker batch; handle 500K–2M impressions/sec.
Accuracy: Precision >98% (false positives are costly—blocking safe content = lost revenue); recall >90% (miss <10% of unsafe).
Availability: 99.95% uptime; degrade gracefully to conservative (allow-all) if AI service fails.
Cost: Classification and filtering ~$20–100K/month (AWS services + SageMaker).
Option 1: Pre-Classified URL/Content Allowlist + Blocklist via DynamoDB
Description: Maintain offline allowlist (whitelist of known-safe domains and publishers, stored in DynamoDB) and blocklist (blacklist of known-unsafe sites, malware hosts, etc., also in DynamoDB). URLs are classified once, stored with TTL (7 days), and queried at serve time via ECS Fargate services with DynamoDB DAX (DynamoDB Accelerator) for <5 ms lookup. Additional signals: domain reputation (WHOIS age via Lambda enrichment, SSL certificate validity), ASN blocklist (known hosting providers for spam, updated daily from external feed), and manual reports from users/vendors (logged to DynamoDB). Updates occur daily via Lambda ingesting external feeds; classification is deterministic (same URL always gets same decision). Blue-green deployment for rule updates.
Pros:
Extremely fast: <1 ms per lookup via DAX (O(1), no network call overhead).
Cost-effective: no ML infrastructure; only DynamoDB storage and update Lambda function.
Deterministic: reproducible decisions; easy to audit and explain.
No latency tail: fixed lookup time; scales to billions of impressions.
Limited coverage: only domains with explicit classification are handled; long tail is defaulted.
Update lag: new unsafe content is available 24–48 h after discovery; attackers exploit the gap.
False positives: domains are not content-specific (example.com may have safe news and unsafe forum sections).
Rich media limitation: can't classify video frames, embedded content, or dynamically loaded pages without headless browser.
Advertiser frustration: can't block specific topics (e.g., "alcohol") if not on blocklist; requires keyword filtering as fallback.
Cat-and-mouse: malicious actors register new domains constantly; classification lags behind.
Failure Modes & Mitigations:
Allowlist false positive: Domain is on allowlist but content was hacked/changed to unsafe. Mitigation: monitor user reports via Lambda; remove domain from allowlist if abuse reports spike (threshold: >10 reports/day); set DynamoDB TTL to 7 days, refresh weekly.
Blocklist bloat: Maintain 10M domains on blocklist; lookup becomes slow. Mitigation: use DynamoDB hash set with DAX caching (O(1) lookup); partition by first 2 chars of domain for efficient scans.
Domain migration: Unsafe domain redirects to new domain not on blocklist. Mitigation: Lambda crawler tracks redirect chains; classify final destination domain.
When to Choose:
Starting point for brand safety; low cost and complexity.
Publishers with limited ML infrastructure (no SageMaker).
Categories where domain-level classification is sufficient (e.g., B2B software, finance).
Option 2: Real-Time AI Inference via AWS Services (Comprehend, Rekognition, Bedrock)
Description: Deploy a content classification pipeline as an ECS Fargate microservice queried during RTB. When an impression is requested, the serving platform fetches the page content (via headless browser Lambda or API) and passes it to AWS managed services: Amazon Comprehend for text moderation (toxic comments, profanity, abuse), Amazon Rekognition for image/video frame moderation (explicit, graphic violence, hate symbols), and optionally Amazon Bedrock (Claude LLM) for nuanced classification (satire detection, context understanding). The models return toxicity/safety scores (0–100%) and GARM category (violence, hate speech, explicit, etc.). The serving logic applies advertiser-specific thresholds: brand A allows "violence" ≤20%; brand B blocks all "hate speech." Scores are cached in DynamoDB (7-day TTL) and ElastiCache (5-min TTL) to avoid re-classification. Classification results are retrained via SageMaker Autopilot weekly on ground-truth labels (user reports, advertiser feedback).
Pros:
Comprehensive: classifies page text, images, video frames; handles all media types.
Granular: returns per-category scores; advertiser can block specific topics ("no violence" but allow "controversial news").
Flexible: advertiser can tune thresholds per campaign via DynamoDB allowlist/denylist tables.
Future-proof: learns from evolving content (deepfakes, new hate speech slang) via Bedrock + SageMaker.
Transparent: Amazon Comprehend and Bedrock provide reasoning; SageMaker Clarify provides SHAP explanations.
AWS-managed: no model training burden; Comprehend and Rekognition APIs handle scale.
Cons:
Latency cost: page fetch (500 ms headless browser) + classification (Comprehend 50 ms + Rekognition 100–200 ms + Bedrock 500+ ms) = 800+ ms overhead; breaks RTB timing unless async.
Model drift: safety definitions change; models become stale; requires monitoring and custom tuning via SageMaker.
False positives: ML models can misclassify satire/news as unsafe; requires manual review queue (DynamoDB + Lambda).
Cold start: new URLs have no history; model must make decision on first impression (high confidence risk).
Adversarial attacks: bad actors craft content to evade classifier (pixel noise, text obfuscation); AWS services have mitigation but not perfect.
Cost: Comprehend (~$0.0001/unit), Rekognition (~$0.10–1 per image), Bedrock (~$0.01 per request); at scale, $50–200K/month for inference.
Bedrock cost: Claude 3 Opus is expensive for high-volume; recommend for spot checks, not all impressions.
Failure Modes & Mitigations:
Inference latency spikes: Rekognition or Bedrock API reaches capacity, classification queues; RTB timeouts increase. Mitigation: implement request queue with 200 ms timeout, fall back to pre-classified blocklist if timeout triggers; use SQS for async classification, cache results in DynamoDB.
Model accuracy drop: New adversarial attack emerges; model accuracy drops from 96% to 88%. Mitigation: CloudWatch dashboard monitors user report rate (may spike if model is confused); trigger SageMaker retraining if accuracy drops >3%; require model performance review before production deployment.
Content extraction failure: Page is JavaScript-heavy; Lambda headless browser can't render. Mitigation: set timeout on page fetch (5 sec), fall back to static HTML/text extraction if JS rendering fails; implement retry logic.
When to Choose:
Premium publishers (high-value brand advertisers) prioritizing brand safety over latency.
Description: Fast DynamoDB + DAX lookup for known content (allowlist/blocklist): if domain is on allowlist, serve immediately. If unknown domain, trigger asynchronous real-time classification (Lambda + Comprehend + Rekognition, cache results in DynamoDB with 7-day TTL). Meanwhile, apply keyword filters (advertiser-defined exclusion list stored in DynamoDB per advertiser: "weapons," "alcohol," "gambling") against page text extracted via Comprehend. Keyword match blocks immediately. If all checks pass, serve; if any fail, respect advertiser threshold (hard block or downrank). Batch overnight process picks top 10K new domains (tracked in DynamoDB), pre-classifies them via SageMaker batch transform job, and adds to allowlist. Advertiser denylist management via ECS Fargate UI service.
Pros:
Cost balanced: simple rules handle 90% of requests (<1 ms via DAX); expensive ML handles 10% (unknown domains, async).
Fast common case: known domains serve in <5 ms; RTB latency is unaffected.
For most publishers, adopt Option 3 (Hybrid) as the standard architecture, with Option 2 (real-time AWS services) as a premium tier for high-value brand deals.
The hybrid approach balances speed and coverage: pre-classified domains via DynamoDB + DAX (90% of traffic) are served sub-5 ms, unknown domains are classified asynchronously via Comprehend/Rekognition without breaking RTB timing, and keyword filters provide immediate veto for advertiser-defined exclusions. This scales to 1M+ impr/sec and costs only $30–50K/month (cheaper than full real-time ML). Nightly SageMaker batch pre-classification reduces real-time load.
For premium direct deals (e.g., Ford automotive brand guarantee >99% brand-safe inventory), offer Option 2: page is fetched and scored via Comprehend (text) + Rekognition (images/video) within 200 ms async (cached, avoids RTB impact); optionally use Bedrock Claude for nuanced satire/context detection. This provides per-content granularity (e.g., "no violence <10%" or "no hate speech <1%") and strong audit trail (Bedrock reasoning + Comprehend confidence scores) for contract compliance.
Option 1 (pre-classified only) is acceptable for small publishers (<10K impr/sec) with limited advertiser diversity, but limits upside (major advertisers increasingly demand rich safety controls and keyword filtering).
GARM & IAB Taxonomy Integration: Standardize on GARM's 13 brand-safety tiers (Hate Speech, Violence, Sexual Content, Obscenity, Misinformation, etc.) and IAB's content taxonomy (400+ categories including brand-appropriate segmentation). Use GARM as advertiser-facing classification; map internal Comprehend/Rekognition categories to GARM for reporting and disputes. Store category mapping in DynamoDB.
Capacity & Performance Notes
Pre-Classification (Option 1):
Domain space: ~1B unique domains on internet; pre-classify top 100M (covers 95% of ad traffic).