Section 8: Who Watches the Watchers - Security, Compliance & Governance Architecture
Executive Summary: A threat-detection service is itself a prime target. It holds identity telemetry for 20,000 tenants and 150M identities, and one quiet change to it can blind a customer's SOC. This section hardens it in four layers. Tenant isolation starts where tenantId is assigned, not where it is checked. A threat table covers attacks on the detection system itself, led by the Contoso attacker's obvious next move: switch off the logging. Operator access holds no standing rights to tenant data. Compliance rests on in-geography processing and short, deliberate retention. The design principle throughout: we can't always make tampering impossible, but we can make it loud.
At 09:24:44 Contoso's SOC got the escalation: INC-20419 is Critical. The interviewer leans in. "Your attacker is Owner on prod-finance. They know Contoso runs your product. What do they do next?"
You: "They try to turn us off. They delete the diagnostic setting that streams prod-finance's Activity Log to us, or, if they get the rights, they suppress the rule that just caught them. So I'll treat the detection system as part of the attack surface. First the tenant boundary, then attacks on us, then our own operators, then compliance."
Tenant isolation: decided where tenantId is born
Every event in the system carries a tenantId, so the important question is who writes it. We never read it from the event payload. It comes from the delivery channel in one of two ways. Platform diagnostic streams arrive with an envelope property written by the trusted platform delivery pipeline, which knows whose diagnostic setting produced the record. Custom sources arrive through the push API, which takes tenantId from the verified token's claims. A tenantId field inside the JSON is just data. We rejected trusting a payload tenantId because a single forged field would leak data across tenants. There is no flip trigger for this one.
From that origin, every layer that follows carries the tenant along:
| Layer | Mechanism | What it stops |
|---|---|---|
| Assignment | tenantId from envelope or token claims, never the payload |
Forged cross-tenant events |
| Rules | The Rule Compiler prepends tenantId == <owner> to every compiled plan |
A custom rule that reads another tenant's events |
| State and storage | Tenant in every key: Flink key (tenantId, entityType, entityValue), Cosmos DB partition key [tenantId, day], Redis key prefixes |
Cross-tenant state collisions and reads |
| Resources | 20k events/s default ingest quota, 1 GB state budget, 500 custom rules per tenant | A noisy neighbour starving everyone else |
| Blast radius | Stamps: a bad tenant or rule hurts one 250k events/s cell, not a region | Fleet-wide outages |
| Keys (optional) | Per-tenant customer-managed keys on the Archive; crypto-shredding on offboarding | Data lingering after a customer leaves |
Interviewer: "Why not physically separate every tenant? Their own hub, their own job?"
You: "That's 20,000 pipelines, mostly idle, and nobody could operate them. The logical isolation above is enforced at assignment and again in every key, so it's no weaker. Physical separation is still on offer: a tenant above 50k events/s peak gets a stamp with reserved headroom or a dedicated stamp. That's the same flip trigger as the stamp design in Section 2 — Scaling Strategy & Non-Functional Requirements."
The customer-managed-key option has a real cost, so I state it. Event Hubs Capture writes Avro files per hub partition that every tenant shares, so the key can only apply after the compaction job has split the data by tenant: it writes that tenant's Parquet under an ADLS encryption scope backed by their Key Vault key, and the shared Avro is deleted once compacted. That is why the option is optional. What it buys is crypto-shredding. When the tenant offboards, we revoke their key and their compacted Archive becomes unreadable at once, without waiting for retention to age it out; the hubs age out within 3 days, and offboarding deletes their Alert Store partitions.
Key Insight: Isolation is won or lost where tenantId is assigned. Checks downstream only protect you if the value they check was never attacker-controlled.
Quick check before moving on:
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