Trust and Safety Platform Low-Level Design: Signal Aggregation, Policy Engine, and Action Bus

Trust and Safety Platform Overview

A Trust and Safety Platform aggregates behavioral, network, and content signals from across a platform, evaluates them against a configurable policy engine, and dispatches enforcement actions via a unified action bus. The goal is a single, auditable control plane for detecting abuse — spam, fraud, harassment, coordinated inauthentic behavior — and taking consistent, traceable enforcement at scale.

Requirements

Functional Requirements

  • Ingest signals from multiple sources: content moderation scores, login events, graph anomaly scores, device fingerprints, and third-party threat intelligence feeds.
  • Maintain per-entity (user, device, IP, content) risk profiles updated in near real time.
  • Evaluate risk profiles against a versioned, configurable policy engine to produce enforcement recommendations.
  • Dispatch enforcement actions (suspend account, limit reach, require verification, flag for review) through a unified action bus to downstream enforcement services.
  • Support a manual override workflow for trust-and-safety analysts.
  • Log every signal ingestion, policy evaluation, and action dispatch for audit purposes.

Non-Functional Requirements

  • Signal ingestion throughput: 500,000 events per second.
  • Risk profile update latency: within 5 seconds of signal arrival.
  • Policy evaluation and action dispatch: within 1 second of profile update.

Data Model

The RiskProfile document (stored in a document database keyed by entity type and ID) contains: entity_id, entity_type ENUM (user, device, ip, content), signal_scores MAP<signal_type, float>, composite_risk_score FLOAT, risk_tier ENUM (low, medium, high, critical), last_updated TIMESTAMP, and active_enforcements LIST.

The PolicyRule object defines: rule_id, name, conditions (a tree of predicates over signal scores, entity attributes, and context), action_template, severity ENUM, effective_from TIMESTAMP, and version INT. Rules are stored in a versioned config store and hot-loaded by policy engine instances.

The AuditLog table records every platform event: event_id UUID, event_type, entity_id, payload JSON, actor_id (system or analyst), timestamp. Append-only; retained for 2 years to support legal holds.

Core Algorithms

Signal Aggregation and Composite Scoring

Incoming signals are normalized to a [0, 1] scale per signal type. The composite risk score is computed as a weighted average of normalized signal scores, with weights learned offline from labeled abuse cases. An exponential decay function reduces the weight of stale signals: a signal older than 24 hours contributes half its original weight. The risk tier is assigned by fixed score thresholds calibrated against precision-recall targets for each abuse type.

Policy Engine Evaluation

The policy engine evaluates the ordered rule list against the current risk profile using a short-circuit evaluator: the first matching rule triggers its action template. Rules are expressed as a subset of a typed predicate language (comparisons, logical AND/OR/NOT, set membership), compiled to bytecode for evaluation speed. The engine is purely functional — given the same profile and rule set, it always produces the same output — making it fully unit-testable and auditable.

Action Bus Dispatch

Enforcement actions are published to a typed Kafka topic partitioned by entity ID (ensuring ordered delivery per entity). Downstream enforcement services (account service, feed ranking, ad eligibility) subscribe to the topics relevant to them. Each action message carries a deduplication key and a TTL; consumers apply idempotency checks before executing. Reversal actions (e.g., unsuspend) are issued as compensating events on the same topic.

API Design

  • IngestSignal(SignalEvent) → Ack — accepts a signal from any upstream producer; validates schema and writes to the ingestion Kafka topic.
  • GetRiskProfile(EntityRef) → RiskProfile — returns the current risk profile for a given entity.
  • EvaluatePolicy(EntityRef) → PolicyEvaluationResult — on-demand policy evaluation for analyst tooling and testing.
  • SubmitManualAction(ManualActionRequest) → ActionId — analyst override; bypasses policy engine and dispatches action directly; logged with analyst identity.
  • GetAuditLog(EntityRef, TimeRange) → AuditEvents — returns the event history for a given entity.

Scalability and Fault Tolerance

Signal ingestion uses Kafka with 256 partitions, giving linear throughput scaling. Risk profile updates run as stateful stream processors (e.g., Flink) maintaining in-memory state per entity, checkpointed to a durable store every 30 seconds. Policy evaluation is triggered by profile updates and runs as stateless workers that read policy rules from an in-process cache refreshed every 60 seconds.

If the action bus consumer for a downstream service falls behind, the platform applies backpressure by throttling non-critical signal ingestion paths. Critical actions (critical-tier entities) are delivered via a separate high-priority topic with dedicated consumers and no throttling.

Monitoring

  • Track entity risk tier distribution over time; sudden shifts indicate new attack vectors or miscalibrated signals.
  • Alert on action bus consumer lag exceeding 30 seconds for critical-tier actions.
  • Monitor policy rule match rates; a rule with zero matches over 24 hours may indicate a misconfigured condition.
  • Publish weekly abuse escalation and overturn reports to the trust-and-safety leadership dashboard.

{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “How does multi-signal aggregation with decay work in a trust and safety platform?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Each behavioral signal (e.g., login anomaly, content flag, payment chargeback) contributes a weighted score to an entity's risk profile. Older signals are multiplied by a time-decay factor so recent behavior dominates. The aggregated score is compared against policy thresholds to trigger automated actions or human review.”
}
},
{
“@type”: “Question”,
“name”: “What is a predicate-based policy engine in trust and safety?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “A predicate-based policy engine evaluates Boolean expressions over entity attributes and signal scores (e.g., 'risk_score > 0.8 AND account_age_days < 7'). Policies are stored as data rather than code, enabling non-engineers to author and test rules without deployments. The engine is typically built on a rule evaluation library or a general-purpose policy language like OPA."
}
},
{
"@type": "Question",
"name": "How is Kafka used as an action bus in a trust and safety platform?",
"acceptedAnswer": {
"@type": "Answer",
"text": "When the policy engine decides on an action, it publishes an event to a Kafka topic. Downstream consumers (notification service, account service, logging service) subscribe and execute their portion of the action independently. This decouples the decision layer from enforcement, allows replay for debugging, and provides a durable audit trail."
}
},
{
"@type": "Question",
"name": "What are compensating events in a trust and safety event-driven architecture?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Compensating events reverse or correct a prior action when an appeal succeeds or a false positive is detected. For example, an 'AccountRestored' event triggers consumers to reinstate access, re-index content, and issue a user notification. Using explicit compensating events rather than direct state mutation keeps the audit log complete and simplifies rollback logic."
}
}
]
}

See also: Meta Interview Guide 2026: Facebook, Instagram, WhatsApp Engineering

See also: Netflix Interview Guide 2026: Streaming Architecture, Recommendation Systems, and Engineering Excellence

See also: Twitter/X Interview Guide 2026: Timeline Algorithms, Real-Time Search, and Content at Scale

Scroll to Top