</> MAANG.io

Expert

Design landmark systems in depth, from Dynamo, GFS, Bigtable and Kafka to payments and ads pipelines.

0 of 232 solved 0%

Section 4: Four Nouns Run the System - Data Modeling & Rule Design

Executive Summary: Section 3 drew the boxes; this section defines what flows between them. Four nouns carry the system: the event (one canonical shape for every source), the rule (versioned data in a restricted DSL), the alert (a fact with a deterministic name) and the incident (what a SOC analyst works). We show Contoso's attack in each shape, derive alertId so replays can't double-page anyone, and place each noun in the store its access pattern demands.

The interviewer points at the arrows on the board. "Every one of these lines carries something. What is it, exactly?" Name the nouns; once their shapes are fixed, most later decisions follow.

Core data model: a 400 B canonical event is evaluated by a versioned DSL rule, which fires an alert with a deterministic alertId citing up to 50 events as evidence; the alert names entities (user, IP, host, resource, service principal) and joins an incident, which the entities also lead to when shared within 1 h.

The Event: One Shape for Every Source

An Entra sign-in record, an Activity Log entry and a VNet flow record disagree on field names, timestamp formats and even on what "the user" means. The Normalizer turns each into one canonical event, modeled on Microsoft's ASIM (Advanced Security Information Model) with an OCSF mapping. Here is the first of the 40 failed sign-ins against alice:

{
  "eventId": "src:9b7e1f42",
  "tenantId": "t-4821",
  "sourceType": "SignInLogs",
  "eventTime": "2026-11-02T09:11:02Z",
  "ingestTime": "2026-11-02T09:13:32Z",
  "actor": {
    "userId": "oid:4f1da9e2",
    "upn": "alice@contoso.com",
    "ipAddress": "203.0.113.45",
    "geo": { "lat": 52.37, "lon": 4.90, "country": "NL" },
    "asn": 64500,
    "deviceId": null
  },
  "target": { "resourceId": null, "principalId": "oid:4f1da9e2", "role": null },
  "operation": "Sign-in",
  "outcome": "failure",
  "enrichment": {
    "flags": [],
    "tiMatches": [],
    "identity": { "isPrivileged": false, "department": "Finance" }
  },
  "rawRef": "raw://usw-03/raw-events/p17/offset/88421904"
}

Normalizing buys three things. One rule works across sources: outcome == "failure" means the same whether the sign-in came from Entra or from a custom identity provider using the push API. The event shrinks from 1 KB raw to 400 B binary, 34.56 TB a day instead of 86.4 TB. And enrichment is attached once, upstream, not looked up by every rule.

Three fields deserve a defense.

  • tenantId is never read from the payload. It comes from the envelope the trusted platform delivery pipeline wrote, or from the push API's verified token claims. Trust a payload field and one forged value puts an attacker's data into somebody else's detections.
  • eventId is the source's record id, or a hash of the raw record. Sources deliver at least once, so the Detection Engine keeps a recent-eventId set per key to drop repeats (Section 5 owns the mechanics).
  • rawRef records where the raw record landed (raw hub partition and offset), so for a day an analyst can go from an alert back to the original bytes without the hot path carrying them; after that, the Archive's normalized copy, found by eventId, is the evidence.

Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.