<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Parag Mali - tag: identity-protection</title><description>Posts tagged identity-protection.</description><link>https://paragmali.com/</link><language>en-US</language><lastBuildDate>Sun, 07 Jun 2026 04:13:14 GMT</lastBuildDate><atom:link href="https://paragmali.com/tags/identity-protection/rss.xml" rel="self" type="application/rss+xml"/><item><title>Microsoft Defender for Identity: The Defensive AD Stack That Sees What BloodHound Maps</title><link>https://paragmali.com/blog/microsoft-defender-for-identity-the-defensive-ad-stack-that-/</link><guid isPermaLink="true">https://paragmali.com/blog/microsoft-defender-for-identity-the-defensive-ad-stack-that-/</guid><description>A field guide to Microsoft Defender for Identity, the on-DC sensor and cloud analytics engine descended from Aorato, that fires named alerts on almost every offensive AD primitive in the corpus -- and the five structural blind spots it cannot close.</description><pubDate>Wed, 27 May 2026 00:00:00 GMT</pubDate><content:encoded>
**Microsoft Defender for Identity (MDI) is the cloud-backed, on-DC defensive sensor that watches for almost every offensive Active Directory primitive in the SpecterOps / Mimikatz / Certipy corpus** -- DCSync, DCShadow, Golden / Silver / Diamond ticket forgery, Kerberoasting, AS-REP roasting, NTLM relay, and AD CS abuse -- by parsing Kerberos, NTLM, LDAP, and DRSUAPI on the wire and running per-principal behavioural baselines in a multi-tenant cloud backend. The product began as the Israeli startup Aorato (acquired by Microsoft in November 2014), shipped on-prem as Microsoft ATA in 2015, moved to the cloud as Azure ATP in 2018, was renamed to MDI in 2020, folded into Microsoft Defender XDR at Ignite 2023, and reached its current MDE-integrated v3.x sensor in October 2025. The alert catalogue maps cleanly onto MITRE ATT&amp;amp;CK, and the residual blind spots are knowable: the Credential Guard wall, the Sapphire Ticket&apos;s cryptographic indistinguishability, the encrypted-channel DCSync class, the cross-forest under-instrumentation tail, and legitimate-principal compromise. The operator question in 2026 is not whether MDI detects the attack, but whether the sensor is deployed, the alert was triaged inside the batched-emission window, and the residuals are covered by KQL, Sigma rules, or out-of-band controls.
&lt;h2&gt;1. A Friday Afternoon at the Domain Controller&lt;/h2&gt;
&lt;p&gt;Friday, 14:33. A red-team contractor in conference room C runs &lt;code&gt;Rubeus.exe asreproast&lt;/code&gt; on a corporate laptop she was issued an hour ago. A junior auditor on the fourth floor, working from a desk with read-only Active Directory access, runs &lt;code&gt;bloodhound-python -c All&lt;/code&gt; for a routine quarterly review. A quiet service account on the SQL host in rack 14 runs &lt;code&gt;mimikatz &quot;lsadump::dcsync /domain:contoso.com /user:Administrator&quot;&lt;/code&gt;. The operator at the other end of that session is not on the payroll. Three different workstations. Three different intents. One domain controller on the receiving end of all three.&lt;/p&gt;
&lt;p&gt;The Security Operations Center has not noticed any of them yet. The watcher on the domain controller, however, has. By 14:35 three named alerts are sitting in the Defender XDR queue, each tagged with a MITRE ATT&amp;amp;CK technique ID, each waiting for someone to triage. &lt;em&gt;Suspected AS-REP Roasting attack&lt;/em&gt; (T1558.004) for the Rubeus invocation [@mslearn-mdi-alerts-xdr]. &lt;em&gt;Security principal reconnaissance (LDAP)&lt;/em&gt; for the BloodHound enumeration [@mslearn-mdi-alerts-mdi-classic]. &lt;em&gt;Suspected DCSync attack -- replication of directory services&lt;/em&gt;, External ID 2006, T1003.006, for the Mimikatz call [@mslearn-mdi-alerts-mdi-classic][@mitre-t1003-006]. The watcher is Microsoft Defender for Identity.SOC operators inside Microsoft customers describe this with a stock phrase: &quot;the watcher was already on the DC.&quot; The phrase shows up in incident-response runbooks, vendor training decks, and the Microsoft Defender for Identity Tech Community archive. It captures what is, architecturally, a strange thing -- the defender&apos;s sensor is co-located with the attacker&apos;s target, not perched outside it.&lt;/p&gt;

A Windows Server hosting the Active Directory Domain Services role, responsible for processing Kerberos authentication, NTLM challenges, LDAP queries, and inter-DC directory replication (DRSUAPI) for a domain. Every named MDI runtime alert in this article fires on signal that originates on or transits a domain controller; the deployment model assumes one MDI sensor per DC, plus optional sensors on AD FS, AD CS, and Microsoft Entra Connect servers when those identity roles run on dedicated hosts.
&lt;p&gt;Almost every offensive AD primitive a reader of the SpecterOps, Mimikatz, and Certipy corpus already knows has a runtime alert or a posture assessment shipped by Microsoft on that same DC. &lt;em&gt;Almost&lt;/em&gt; is the load-bearing word. The alert fires only if three things are true: the sensor is deployed on the surface the attack touches, the audit subcategory the alert depends on is enabled, and the SOC opens the Defender XDR incident inside the batched-emission window the cloud backend uses to aggregate signal. This article is about all three conditions, the twelve-year arc that built the watcher, and the structural blind spots no future MDI release will close.&lt;/p&gt;
&lt;p&gt;The watcher was not always on the domain controller. For the first decade of Active Directory, nothing on the DC saw what &lt;a href=&quot;https://paragmali.com/blog/ad-is-a-graph-how-bloodhound-made-defenders-think-like-attac/&quot; rel=&quot;noopener&quot;&gt;BloodHound&lt;/a&gt; today maps. To understand where the watcher came from -- and why its blind spots look the way they do -- we have to start with three founders in Herzliya and a Kerberos forgery presentation in Las Vegas.&lt;/p&gt;
&lt;h2&gt;2. Origins -- Aorato, the Israeli Startup That Became the Watcher&lt;/h2&gt;
&lt;p&gt;August 2014, Black Hat USA. Tal Be&apos;ery and Michael Cherny take the stage with Alva Duckwall and Benjamin Delpy to present &lt;em&gt;&quot;Abusing Microsoft Kerberos: Sorry You Guys Don&apos;t Get It,&quot;&lt;/em&gt; a demonstration that a stolen &lt;a href=&quot;https://paragmali.com/blog/krbtgt-the-account-that-owns-active-directory/&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;krbtgt&lt;/code&gt;&lt;/a&gt; key lets an attacker mint Kerberos ticket-granting tickets that survive every password rotation in the standard remediation playbook [@blackhat-us14-briefings]. The audience is Active Directory operators who thought their password-reset runbook covered them. By the end of the talk it does not. The startup behind the research is &lt;strong&gt;Aorato&lt;/strong&gt;, three years old, headquartered in Herzliya, Israel. Three months later, Microsoft buys it.&lt;/p&gt;

The credential a Kerberos client receives from the Key Distribution Center (the KDC, which on a Windows network runs on every DC) after successful pre-authentication. The TGT is encrypted with the KDC&apos;s own long-term key -- on Active Directory, the password hash of the `krbtgt` account. Possession of the `krbtgt` hash therefore lets an attacker forge a valid TGT for any principal in the domain, since the KDC has no other way to distinguish a forged ticket from a real one. This forged-ticket class is what MITRE catalogues as T1558.001 Golden Ticket [@mitre-t1558-001].
&lt;p&gt;The Aorato deal closed on &lt;strong&gt;November 13, 2014&lt;/strong&gt;, announced on the Microsoft Official Blog by Takeshi Numoto, then Corporate Vice President of Cloud and Enterprise Marketing [@msblog-aorato]. The post named the central technology Microsoft was acquiring: Aorato&apos;s &lt;em&gt;Organizational Security Graph&lt;/em&gt;, described as &quot;a living, continuously-updated view of all of the people and machines accessing an organization&apos;s Windows Server Active Directory.&quot; Pre-acquisition Microsoft had Azure AD on the cloud side and per-DC event log auditing on the on-prem side, but no first-party behavioural-analytics product over Active Directory. Aorato&apos;s pre-acquisition product, the &lt;em&gt;Directory Services Application Firewall&lt;/em&gt;, did exactly that -- it parsed Kerberos, NTLM, LDAP, and DRSUAPI on the wire and ran per-principal behavioural baselines against the parsed protocol stream. Microsoft wanted that capability inside Windows Server, and inside Office 365.Aorato&apos;s three founders, per the Globes coverage of the acquisition in November 2014, were Idan Plotnik (CEO), Michael Dolinsky (VP R&amp;amp;D), and Ohad Plotnik (VP professional services). Tal Be&apos;ery was VP of Research. A popular reading of the deal names &quot;the Plotnik brothers and Tal Be&apos;ery&quot; as the co-founder trio, which compresses out Dolinsky&apos;s role -- the contemporaneous record names four people, not three [@globes-aorato-2014].&lt;/p&gt;
&lt;p&gt;The product lineage that follows is twelve years long and runs through five names. &lt;strong&gt;Microsoft Advanced Threat Analytics (ATA)&lt;/strong&gt; was announced as generally available on August 27, 2015 (build 1.4.2457, dated August 31, 2015) -- the on-prem productisation of Aorato&apos;s wire-side parser, packaged as a SPAN-mirror appliance (&quot;ATA Gateway&quot;) plus an on-prem analytics server (&quot;ATA Center&quot;) with its own MongoDB-style document store [@mstc-ata-ga][@atadocs-versions]. &lt;strong&gt;Azure ATP&lt;/strong&gt; went GA on March 1, 2018 -- the cloud-side rewrite that kept the on-DC sensor but moved the analytics engine to a multi-tenant cloud backend [@mstc-azureatp-ga][@mstc-azureatp-intro]. &lt;strong&gt;Microsoft Defender for Identity&lt;/strong&gt; was the September 22, 2020 rename announced at Ignite 2020, part of Microsoft&apos;s broader brand consolidation that also rebranded Office 365 ATP to Microsoft Defender for Office 365 and Microsoft Defender ATP to Microsoft Defender for Endpoint [@mssecblog-unified-xdr][@itpro-defender-rebrand][@infusedinnov-names]. The November 2023 Ignite keynote consolidated Microsoft 365 Defender into &lt;strong&gt;Microsoft Defender XDR&lt;/strong&gt; [@virtreview-ignite2023][@handsontek-defender-rebrand]. In October 2025 the &lt;strong&gt;v3.x sensor&lt;/strong&gt; GA folded MDI&apos;s on-DC sensor into the Microsoft Defender for Endpoint agent that organisations were already running on every server [@mslearn-mdi-whats-new][@modernsec-v3x][@jeffreyappel-v2v3]. The May 2026 release notes extended the v3.x sensor to cover AD FS, AD CS, and Microsoft Entra Connect identity roles directly when those roles run on a domain controller, and raised the per-workspace sensor cap from 350 to 1,000 [@mslearn-mdi-whats-new].&lt;/p&gt;

gantt
    title Microsoft Defender for Identity lineage, 2012-2026
    dateFormat YYYY-MM-DD
    axisFormat %Y
    section Aorato
    Aorato startup (DSAF product)        :a1, 2012-01-01, 2014-11-13
    section Microsoft ATA
    ATA initial release SPAN-mirror Gateway :a2, 2015-08-27, 2016-05-01
    ATA 1.6-1.9 Lightweight Gateway      :a3, 2016-05-01, 2018-03-01
    ATA Extended Support window          :a4, 2018-03-01, 2026-01-31
    section Cloud rewrite
    Azure ATP GA                          :a5, 2018-03-01, 2020-09-22
    Microsoft Defender for Identity name :a6, 2020-09-22, 2023-11-15
    section Defender XDR era
    MDI inside Defender XDR (v2.x)        :a7, 2023-11-15, 2025-10-01
    MDI v3.x MDE-integrated sensor        :a8, 2025-10-01, 2026-05-27
&lt;p&gt;Aorato&apos;s pitch in 2014 was that the Windows Security event log -- the thing every SIEM in the world was ingesting -- could not see the attacks an Active Directory operator most needed to catch. To believe that pitch you have to know exactly what the event log misses.&lt;/p&gt;
&lt;h2&gt;3. Why the Event Log Could Not See Golden Tickets&lt;/h2&gt;
&lt;p&gt;Present a Golden Ticket to a domain controller, and the LSA writes a successful event 4769 -- a &lt;a href=&quot;https://paragmali.com/blog/kerberos-in-windows-the-other-half-of-ntlmless/&quot; rel=&quot;noopener&quot;&gt;Kerberos service ticket request&lt;/a&gt;. Present a legitimate ticket from the same principal, and the LSA writes a successful event 4769. Nothing in the event log&apos;s schema, anywhere in any field, distinguishes the two. The ticket is forged with the real &lt;code&gt;krbtgt&lt;/code&gt; key, so the KDC&apos;s signature checks pass. The event log records &lt;em&gt;that an authentication happened&lt;/em&gt;, not &lt;em&gt;whether the ticket presented was genuine&lt;/em&gt;. This is the structural ceiling the SIEM industry could not work around for the first decade of its existence, and it is the gap Aorato was built to close [@mitre-t1558-001][@semperis-golden-ticket].&lt;/p&gt;
&lt;p&gt;The bare-event-log model has three structural failure modes, each of which drove a generation of detection engineering. &lt;strong&gt;Forged-ticket invisibility&lt;/strong&gt; is the first: the LSA logs that an auth happened, but every byte in the 4769 event matches the legitimate case. &lt;strong&gt;Per-DC silo&lt;/strong&gt; is the second: a Kerberos auth against one DC and a follow-up auth against another DC five seconds later sit in two different &lt;code&gt;Security.evtx&lt;/code&gt; files, on two different machines, with no aggregation layer to ask &quot;did the same principal hit ten DCs in five minutes?&quot; &lt;strong&gt;Manual-review throughput collapse&lt;/strong&gt; is the third: a medium-sized forest emits thousands of 4624, 4768, 4769 events per minute per DC, and the human analyst hand-walking them never catches up.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://paragmali.com/blog/two-checkmarks-and-the-keys-to-the-kingdom-how-active-direct/&quot; rel=&quot;noopener&quot;&gt;DCSync&lt;/a&gt; makes the first two failure modes vivid. Sean Metcalf&apos;s September 2015 ADSecurity writeup walks through running &lt;code&gt;lsadump::dcsync /domain:contoso.com /user:Administrator&lt;/code&gt; from a workstation: the DC handles the DRSUAPI replication request, the LSA emits a 4662 event for the directory-service-object access, and the attacker walks away with the password hash [@adsec-dcsync].Metcalf&apos;s companion DerbyCon V talk, &lt;em&gt;Red vs. Blue: Modern Active Directory Attacks &amp;amp; Defense&lt;/em&gt; (September 2015), is the canonical operator-grade introduction to the same material [@adsec-dump-ad]. The 4662 event is structurally indistinguishable from a legitimate replication request between two DCs. A SIEM rule that flagged 4662 events whose source IP was not a DC could catch it -- but only if the analyst maintained the IP allowlist (a single Microsoft Entra Connect server in the wrong subnet broke the rule), and only if 4662 was enabled at all (it was high-volume, and many SOCs disabled it to stay under the SIEM&apos;s GB/day licence).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The SIEM was not failing at Active Directory detection because the rules were wrong. It was failing because the event log -- the data source every SIEM relied on -- could not see what the SIEM needed it to see. Better rules over the same event log would not have closed the gap. Aorato&apos;s contribution was to find a different data source: the wire itself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Aorato&apos;s three primitives, none of which the SIEM-plus-event-log model had, were: &lt;strong&gt;per-principal behavioural baselines&lt;/strong&gt; so that a long-tail anomaly stood out without anybody writing a rule for it; &lt;strong&gt;on-DC network capture&lt;/strong&gt; so that the ticket structure, the DRSUAPI opnum, and the LDAP search filter were available to detection logic; and &lt;strong&gt;a graph over the directory&lt;/strong&gt; so that the path from compromised workstation to crown-jewel asset could be computed rather than inferred. ATA shipped the first two in 2015. The graph took longer.&lt;/p&gt;
&lt;h2&gt;4. Early Approaches -- ATA 1.x and the Generations That Tried Before&lt;/h2&gt;
&lt;p&gt;By the time Aorato shipped its first product, four prior generations of Active Directory detection had already tried and stalled. Each one could see something the previous generation could not. Each one had a structural ceiling an attacker primitive eventually pushed through. The seven generations that follow are the real spine of the article.&lt;/p&gt;

flowchart LR
    G1[&quot;Gen 1: bare per-DC&lt;br /&gt;event log audit&quot;] --&amp;gt; G2[&quot;Gen 2: SIEM-centralised&lt;br /&gt;events with static rules&quot;]
    G2 --&amp;gt; G3[&quot;Gen 3: first-generation UEBA&lt;br /&gt;over SIEM events&quot;]
    G3 --&amp;gt; G4[&quot;Gen 4: Aorato DSAF and&lt;br /&gt;ATA 1.4-1.5 (SPAN mirror)&quot;]
    G4 --&amp;gt; G5[&quot;Gen 5: ATA 1.6-1.9&lt;br /&gt;(Lightweight Gateway + LMP)&quot;]
    G5 --&amp;gt; G6[&quot;Gen 6: Azure ATP, MDI v1.x-v2.x&lt;br /&gt;(cloud analytics)&quot;]
    G6 --&amp;gt; G7[&quot;Gen 7: MDI v3.x&lt;br /&gt;(MDE-integrated + Identity Explorer)&quot;]
&lt;p&gt;&lt;strong&gt;Generation 1 -- bare per-DC event log auditing (1999-2008)&lt;/strong&gt; was already covered above. It was the only model that existed for the first decade of Active Directory, and its structural ceilings became Aorato&apos;s pitch deck.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generation 2 -- SIEM-centralised event log ingestion with static correlation rules (2005-2014)&lt;/strong&gt; is the era of ArcSight, Splunk, QRadar, and LogRhythm. Windows Event Forwarder agents on every DC streamed Security event log entries into a central index, and SOC operators wrote rule-based correlation searches in the vendor&apos;s query language. The model gave the SOC cross-DC correlation, a query language, and an audit trail that satisfied PCI-DSS Requirement 10. It did not give the SOC anything new about the data the LSA emitted. Mimikatz&apos;s &lt;code&gt;lsadump::dcsync&lt;/code&gt; was committed to the public Mimikatz repository in March 2015 [@mimikatz-github][@adsec-dcsync]. Sean Metcalf&apos;s longer ADSecurity writeup of the technique followed in September 2015. At commit time, every SIEM in production was correlating DC event logs and not one was emitting a DCSync alert, because the 4662 event was structurally identical to a legitimate DC-to-DC replication.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generation 3 -- first-generation UEBA on SIEM event data (2013-2017)&lt;/strong&gt; was Securonix, Exabeam, and Splunk UBA. Per-principal behavioural baselines layered on top of the SIEM event index could catch novel TTPs without prior signatures -- a Kerberoasting variant whose SPN list had never been seen before could still trip &quot;this account is requesting an unusual number of service tickets compared to its baseline.&quot; UEBA also closed Generation 2&apos;s per-principal context gap. It did not, however, see ticket structure: a Golden Ticket replayed against ten DCs produces ten successful auths that are behaviourally indistinguishable from the legitimate Domain Admin&apos;s pattern unless the attacker&apos;s source IP or geographic distribution breaks the baseline. This is the &lt;em&gt;legitimate-principal-compromise non-detection class&lt;/em&gt; that survives every defensive generation into 2026.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generation 4 -- on-wire protocol analytics via off-DC SPAN-mirror Gateway&lt;/strong&gt; is where Aorato&apos;s product, and then Microsoft ATA 1.4 and 1.5, lived. A switch SPAN port mirrored DC traffic to a dedicated ATA Gateway appliance, which ran libpcap-equivalent capture and parsed Kerberos AS-REQ / TGS-REQ / AP-REQ, NTLM challenges, LDAP searches, and DRSUAPI replication calls. Parsed events streamed to the on-prem ATA Center, which ran detection logic and surfaced alerts in a web console [@mstc-ata-ga]. The wire-side parse closed Generation 1-3&apos;s biggest blind spot: ticket structure was finally visible. The SPAN-port operational tax killed the architecture in nine months. Many enterprises could not provision a SPAN mirror. Virtualised DCs on shared hypervisors had no equivalent of a physical SPAN. And the security review of &quot;all DC traffic now mirrors to this appliance&quot; was non-trivial.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generation 5 -- ATA 1.6 Lightweight Gateway through ATA 1.9 (May 2016 to March 2020)&lt;/strong&gt; moved the Gateway in-process onto the DC itself. ATA 1.6 (May 2016) introduced the Lightweight Gateway with dynamic resource management that capped the sensor&apos;s CPU and memory footprint and let the sensor consume events locally rather than via mirrored network traffic [@mslearn-ata-1-6]. ATA 1.7 (August 31, 2016) added Role-Based Access Control for the ATA Console, Windows Server Core support, and detection of reconnaissance through directory-services enumeration [@mssupport-ata-1-7][@atadocs-versions]. &lt;strong&gt;ATA 1.8 (June 30, 2017; announced July 26, 2017)&lt;/strong&gt; shipped behavioural-brute-force detection, a Golden Ticket lifetime detector, and the abnormal-modification-of-sensitive-groups alert [@mslearn-ata-1-8][@mstc-ata-1-8][@ataversions-1-8-availability]. &lt;strong&gt;ATA 1.9 (March 21, 2018)&lt;/strong&gt; shipped both the entity-profile lateral-movement-aware view and the &lt;em&gt;Lateral movement paths to sensitive accounts&lt;/em&gt; report [@mslearn-ata-1-9][@atadocs-versions][@atadocs-lmp-usecase].A widespread reading of the ATA timeline anchors LMP to ATA 1.7 in late 2017. The primary record contradicts this on both date and feature: ATA 1.7 shipped on August 31, 2016 per the Microsoft Support KB and the ATA-versions table, and the 1.7 release notes do not mention Lateral Movement Paths. Neither do the 1.8 release notes -- LMP first appears in ATA 1.9 (March 21, 2018), which introduced both the entity-profile lateral-movement view and the full Lateral movement paths to sensitive accounts report in the same release [@mssupport-ata-1-7][@atadocs-versions][@mslearn-ata-1-8][@mslearn-ata-1-9].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A popular framing of the LMP timeline says &quot;Microsoft adopted BloodHound-style graph attack paths in 2022.&quot; The primary sources contradict this. Graph-anchored attack-path evaluation in Microsoft&apos;s defensive stack originates in &lt;strong&gt;ATA 1.9 (March 2018)&lt;/strong&gt;, not in any 2022 adoption event. What did happen in 2022 was the start of the deprecation arc for the SAM-R-based discovery the LMP graph depended on, which culminated in Message Center notice &lt;strong&gt;MC1073068 in May 2025&lt;/strong&gt; when Microsoft disabled SAM-R-based local-administrators collection across MDI tenants [@handsontek-mc1073068]. The 2022 date that lingers in operator memory is the &lt;em&gt;deprecation&lt;/em&gt; anchor, not the adoption anchor.&lt;/p&gt;
&lt;/blockquote&gt;

An attack chain through Active Directory in which a non-sensitive account whose credentials are exposed on one workstation can be used to authenticate to a second workstation where a sensitive account&apos;s credentials are cached, which in turn can be used to reach a third workstation, and so on until a Domain Admin or comparable target is reached. ATA 1.9&apos;s Lateral Movement Paths report was the first graph-anchored defensive surface that computed the chain in advance; the report was populated by SAM-R queries that enumerated each host&apos;s local-administrators group. Microsoft disabled the SAM-R-based collection in May 2025 (MC1073068), and the post-LMP graph layer migrated to the Defender XDR hunting graph plus the April 2026 Identity Explorer preview.
&lt;p&gt;The limitation that drove Generation 5 into Generation 6 was the on-prem ATA Center&apos;s release cadence. Benjamin Delpy and Vincent Le Toux disclosed &lt;strong&gt;DCShadow&lt;/strong&gt; at BlueHat IL 2018 in January 2018 -- the technique of registering a rogue domain controller via &lt;code&gt;nTDSDSA&lt;/code&gt; object creation plus SPN registration, then pushing arbitrary updates into AD via legitimate DRSUAPI replication that the event log records as ordinary inter-DC traffic [@dcshadow-com][@mitre-t1207]. ATA 1.9 shipped two months later, in March 2018, with no DCShadow detection. Azure ATP -- the cloud-side rewrite, also GA in March 2018 -- shipped paired alerts External ID 2028 (&lt;em&gt;Suspected DCShadow attack -- domain controller promotion&lt;/em&gt;) and External ID 2029 (&lt;em&gt;Suspected DCShadow attack -- domain controller replication request&lt;/em&gt;) &lt;strong&gt;five months later, in July 2018&lt;/strong&gt; [@mslearn-mdi-alerts-mdi-classic][@mslearn-mdi-whats-new-archive]. The on-prem release cadence could not have closed that five-month gap. The cloud rewrite was the structural answer.&lt;/p&gt;
&lt;h2&gt;5. The Breakthrough -- Azure ATP and the Inverted Data Path&lt;/h2&gt;
&lt;p&gt;If the wire was the right data layer, the cloud was the right place to run the analytics. That is the architectural decision Azure ATP committed to in March 2018, and it is what distinguishes the Microsoft defensive product from every prior generation. The on-DC sensor stayed on the DC. The analytics engine moved.&lt;/p&gt;
&lt;p&gt;Four architectural shifts followed. &lt;strong&gt;First&lt;/strong&gt;, the on-DC sensor became a thin parser. Sensors no longer hosted detection logic; they captured the Kerberos / NTLM / LDAP / DRSUAPI traffic, parsed it into a stream of structured events, and shipped the stream upstream. &lt;strong&gt;Second&lt;/strong&gt;, the data path inverted. Generation 4 sent unparsed packets from the wire to the off-DC Gateway, which parsed them and stored them on-prem; Azure ATP sent parsed events from the on-DC sensor upstream to a multi-tenant cloud backend that ran detection logic and wrote alerts back into a tenant-specific workspace. &lt;strong&gt;Third&lt;/strong&gt;, per-principal behavioural baselines accumulated centrally rather than per-DC, so a baseline survived DC reboots, sensor restarts, and migrations across data centres. &lt;strong&gt;Fourth&lt;/strong&gt;, identity signal joined endpoint and email signal in the same incident queue once Azure ATP folded into Microsoft 365 Defender -- the cross-product correlation that no on-prem product had ever offered [@mstc-azureatp-ga][@mstc-azureatp-intro][@mslearn-xdr-overview].&lt;/p&gt;
&lt;p&gt;Then came the brand-and-architecture history every operator has to know to read a 2026 runbook. The &lt;strong&gt;September 22, 2020&lt;/strong&gt; rename from Azure Advanced Threat Protection to Microsoft Defender for Identity was a brand consolidation, not an architecture change -- the same sensor, the same alerts, the same workspace [@mssecblog-unified-xdr]. The legacy &lt;code&gt;portal.atp.azure.com&lt;/code&gt; standalone portal was &lt;strong&gt;retired on June 30, 2023&lt;/strong&gt; via Message Center notice MC567494, with all requests automatically redirected to &lt;code&gt;security.microsoft.com&lt;/code&gt; [@handsontek-mc567494][@mslearn-mdi-portal]. The &lt;strong&gt;November 15, 2023&lt;/strong&gt; Ignite keynote renamed Microsoft 365 Defender to Microsoft Defender XDR (Message Center MC696570) [@handsontek-defender-rebrand][@virtreview-ignite2023]. Again a brand change, again not an architecture change: the sensors stayed on the DC, the analytics stayed in the cloud, and the KQL schema -- &lt;code&gt;IdentityLogonEvents&lt;/code&gt;, &lt;code&gt;IdentityQueryEvents&lt;/code&gt;, &lt;code&gt;IdentityDirectoryEvents&lt;/code&gt; -- stayed the same [@mslearn-xdr-identitylogon][@mslearn-xdr-identityquery][@mslearn-xdr-identitydirectory].The legacy &lt;code&gt;portal.atp.azure.com&lt;/code&gt; URL is worth remembering because runbooks and SOAR rules from 2018 to 2023 frequently hard-coded it. Any rule that referenced the old portal needs an update; the redirect handles browser traffic but not API calls.&lt;/p&gt;
&lt;p&gt;What the sensor actually feeds into the cloud backend, in 2026, is four data-input layers, ordered roughly by evidence strength. &lt;strong&gt;First&lt;/strong&gt;, the Windows Security event log -- the audit subcategories that the MDI event-collection page lists as required, including &lt;em&gt;Audit Credential Validation&lt;/em&gt;, &lt;em&gt;Audit Kerberos Authentication Service&lt;/em&gt;, &lt;em&gt;Audit Kerberos Service Ticket Operations&lt;/em&gt;, &lt;em&gt;Audit Directory Service Access&lt;/em&gt;, and &lt;em&gt;Audit Computer Account Management&lt;/em&gt; among others [@mslearn-mdi-event-collection]. These are public, documented, and easy to verify with &lt;code&gt;auditpol /get /category:*&lt;/code&gt;. &lt;strong&gt;Second&lt;/strong&gt;, on-DC network capture of Kerberos, NTLM, LDAP, and DRSUAPI -- well-documented because the sensor&apos;s network requirements are part of the public deployment guide. &lt;strong&gt;Third&lt;/strong&gt;, &lt;a href=&quot;https://paragmali.com/blog/etw-how-windows-2000s-performance-hack-became-the-edr-substr/&quot; rel=&quot;noopener&quot;&gt;Event Tracing for Windows&lt;/a&gt; providers that the sensor subscribes to in order to get signal the event log does not surface. &lt;strong&gt;Fourth&lt;/strong&gt;, AD CS audit-log subscriptions added with the AD CS sensor release in August 2023 [@mstc-adcs-sensor][@dirteam-sander-aug2023].&lt;/p&gt;

Microsoft has never published the canonical list of Event Tracing for Windows providers that the MDI sensor subscribes to. Any specific list of providers a reader encounters traces back to community reverse-engineering: Synacktiv&apos;s *A primer on Microsoft Defender for Identity* by Guillaume Andre and Mickael Benassouli (November 2022) is the canonical operator-research primary [@synacktiv-primer-mdi][@synacktiv-primer-mdi-archive]. The methodological precedent is Olaf Hartong&apos;s *Microsoft Defender for Endpoint Internals* series, specifically the 0x02 entry on audit settings and telemetry, which documents the binary-side enumeration approach: run Matt Graeber&apos;s Get-TraceLoggingMetadata script against the sensor executable to enumerate the providers it registers, then use Sealighter to trace those providers to a file for further analysis [@falconforce-mde-0x02][@gist-tracelogging-metadata][@github-sealighter]. Hartong&apos;s 0x02 article reports &quot;roughly 111 public and MDE-exclusive providers used&quot; by MsSense.exe -- the MDI sensor binary is amenable to the same technique, and the provider mix differs (MDI subscribes heavily to LDAP, Kerberos, DRSUAPI, and SAM-R-class providers; MDE subscribes heavily to process, file, network, and image-load providers) but the methodology is shared [@falconforce-mde-0x03][@github-olafhartong]. Read any community-published MDI provider list as a snapshot of what the community has reverse-engineered, not as Microsoft-published ground truth.

The breakthrough was not better detection algorithms. The breakthrough was moving the analytics off the DC entirely, so the per-principal baselines could accumulate centrally and the detection set could ship on a cloud cadence instead of an on-prem one. That decision is why MDI shipped DCShadow detection within five months of disclosure -- a cadence the on-prem product could not have matched.
&lt;p&gt;That is the move that turned a wire-side parse into a sustained detection program. The proof is the DCShadow timeline: five months from disclosure to detection, on a cadence the on-prem product could not have matched. Now we can ask the question every reader of the offensive-AD corpus actually wants answered. What does the watcher catch in 2026?&lt;/p&gt;
&lt;h2&gt;6. MDI in 2026 -- Sensors, Alerts, KQL, and the Graph in Transition&lt;/h2&gt;
&lt;p&gt;This is the article&apos;s bookmarking section. Four parts: what is on the DC, what alerts fire, what KQL the operator writes when the alerts miss, and where the graph layer that began as ATA 1.9&apos;s Lateral Movement Paths report actually lives in 2026.&lt;/p&gt;
&lt;h3&gt;6.1 Sensor topology in 2026&lt;/h3&gt;
&lt;p&gt;What is on a Windows Server 2022 (or 2025) domain controller running MDI in May 2026? Two sensor families, two target-server matrices, and a workspace cap.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;v2.x sensor&lt;/strong&gt; is the legacy standalone agent: supported on Windows Server 2016 and earlier domain controllers, and on AD FS, AD CS issuing certificate authorities, and Microsoft Entra Connect servers that are not themselves domain controllers, per the v2.x prerequisites page [@mslearn-mdi-prereq-sensor-v2]. v2.x carries its own installer, its own update cadence, and its own packet capture stack (NPCap). It also requires a &lt;em&gt;Directory Service Account&lt;/em&gt; (DSA) -- a gMSA configured during install whose forest-wide read rights let the sensor enumerate AD objects.&lt;/p&gt;

A group Managed Service Account configured during MDI v2.x sensor installation, granted forest-wide read permissions on Active Directory objects so the sensor can resolve principal identities, enumerate group memberships, and read schema attributes that the wire-side parse refers to by SID. The v3.x sensor replaces the DSA pattern with LocalSystem impersonation -- the sensor impersonates the local-system account of the domain controller it runs on, which has equivalent on-DC read rights without needing a separate gMSA per tenant [@mslearn-mdi-deploy-sensor-v3][@mslearn-mdi-action-accounts].
&lt;p&gt;The &lt;strong&gt;v3.x sensor&lt;/strong&gt; is the current path. It requires Windows Server 2019 or later with the March 2026 (or later) cumulative update installed, the Defender for Endpoint agent already deployed and onboarded, and -- critically -- there is no separate MDI installer at all. The MDI sensor capability ships as an extension of the MDE SENSE service. Self-imposed resource caps: &lt;strong&gt;CPU at most 30% of the host DC&apos;s CPU, memory at most 1.5 GB&lt;/strong&gt;, with explicit Hyper-V Dynamic Memory and VMware reservation guidance that ensures the cap is honoured under contention [@mslearn-mdi-deploy-sensor-v3]. v3.x uses LocalSystem impersonation for AD reads rather than a gMSA-based DSA. The May 2026 release notes added direct v3.x support for AD FS, AD CS, and Microsoft Entra Connect identity roles &lt;em&gt;when those roles run on a domain controller&lt;/em&gt; (which is the recommended deployment pattern for most mid-sized tenants) [@mslearn-mdi-whats-new].The 30% CPU cap is honoured by the MDE SENSE service&apos;s scheduling, but Hyper-V Dynamic Memory and VMware ballooning can break the assumption -- if the hypervisor reclaims memory under contention the sensor cannot get its 1.5 GB and the local capture buffer drops events. Microsoft&apos;s deployment guide recommends a static memory reservation on virtualised DCs for that reason.&lt;/p&gt;
&lt;p&gt;The four target server roles are domain controllers (every DC, including RODCs), AD FS federation servers (not Web Application Proxies), AD CS online issuing certificate authorities (not offline root CAs), and Microsoft Entra Connect servers (both active and staging). The May 2026 release notes also raised the per-workspace capacity ceiling from 350 sensors to &lt;strong&gt;1,000 sensors per workspace&lt;/strong&gt; [@mslearn-mdi-whats-new].&lt;/p&gt;

flowchart TD
    DC1[&quot;Domain Controller&lt;br /&gt;(WS2019+, v3.x sensor&lt;br /&gt;inside MDE SENSE)&quot;]
    DC2[&quot;Domain Controller&lt;br /&gt;(WS2016, v2.x sensor)&quot;]
    ADFS[&quot;AD FS server&lt;br /&gt;(v2.x sensor, non-DC)&quot;]
    ADCS[&quot;AD CS issuing CA&lt;br /&gt;(v2.x or v3.x sensor)&quot;]
    EC[&quot;Entra Connect server&lt;br /&gt;(v2.x sensor)&quot;]
    CLOUD[&quot;MDI cloud backend&lt;br /&gt;(multi-tenant analytics,&lt;br /&gt;per-principal baselines)&quot;]
    XDR[&quot;Microsoft Defender XDR&lt;br /&gt;(security.microsoft.com)&lt;br /&gt;Identity tables + alerts&quot;]
    DC1 --&amp;gt; CLOUD
    DC2 --&amp;gt; CLOUD
    ADFS --&amp;gt; CLOUD
    ADCS --&amp;gt; CLOUD
    EC --&amp;gt; CLOUD
    CLOUD --&amp;gt; XDR
&lt;p&gt;The deployment matrix below is the operator-grade reference -- which role gets which sensor, which audit subcategories the sensor depends on, and what posture data the role unlocks.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Server role&lt;/th&gt;
&lt;th&gt;Sensor version&lt;/th&gt;
&lt;th&gt;Required audit subcategories&lt;/th&gt;
&lt;th&gt;Posture coverage unlocked&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Domain controller (WS 2019+)&lt;/td&gt;
&lt;td&gt;v3.x (preferred)&lt;/td&gt;
&lt;td&gt;Credential Validation; Kerberos AS; Kerberos TGS; Logon; DS Access; Computer Account Mgmt&lt;/td&gt;
&lt;td&gt;Full Identity Security Posture (entity hygiene, dormant accounts, weak crypto)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Domain controller (WS 2016)&lt;/td&gt;
&lt;td&gt;v2.x&lt;/td&gt;
&lt;td&gt;Same as above&lt;/td&gt;
&lt;td&gt;Same as above, minus v3.x-only enhancements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AD FS federation server&lt;/td&gt;
&lt;td&gt;v2.x (or v3.x if also a DC)&lt;/td&gt;
&lt;td&gt;AD FS audit logs (Application + Security)&lt;/td&gt;
&lt;td&gt;Hybrid auth signal (Entra ID + on-prem)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AD CS issuing CA&lt;/td&gt;
&lt;td&gt;v2.x (or v3.x if also a DC)&lt;/td&gt;
&lt;td&gt;AD CS audit logs (certificate request and template events)&lt;/td&gt;
&lt;td&gt;Nine ESC posture assessments (ESC1-Preview, ESC2, ESC3, ESC4, ESC6-Preview, ESC7, ESC8, ESC11, ESC15) [@mslearn-mdi-certificates-posture]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entra Connect server&lt;/td&gt;
&lt;td&gt;v2.x (or v3.x if also a DC)&lt;/td&gt;
&lt;td&gt;Sync engine event log&lt;/td&gt;
&lt;td&gt;Sync-engine attribute-flow signal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For new DC deployments on Windows Server 2019 or later, use &lt;strong&gt;v3.x&lt;/strong&gt;: no separate installer, no gMSA, no NPCap, and the sensor ships its updates with the MDE agent. For AD FS, AD CS, or Entra Connect roles that run on dedicated Windows Server 2016 hosts, &lt;strong&gt;v2.x&lt;/strong&gt; is the supported path until those hosts are upgraded. Mixed environments are normal during the migration window; the cloud backend handles both versions without operator intervention [@modernsec-v3x][@jeffreyappel-v2v3]. &lt;strong&gt;One known limitation as of May 2026&lt;/strong&gt;: Windows Server 2025 domain controllers that currently run a v2.x sensor cannot be migrated to v3.x; Microsoft&apos;s What&apos;s New page is explicit that &quot;migration of domain controllers with Windows Server 2025 from sensor v2.x to sensor v3.x is not supported&quot; and the operator should continue on v2.x on those hosts until migration support ships [@mslearn-mdi-whats-new].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sensor topology determines coverage. Coverage determines which alerts can fire.&lt;/p&gt;
&lt;h3&gt;6.2 The alert taxonomy mapped to MITRE ATT&amp;amp;CK&lt;/h3&gt;
&lt;p&gt;Every offensive Active Directory primitive a reader of the SpecterOps, Mimikatz, and Certipy corpus knows has a row in MDI&apos;s alert catalogue. The catalogue is the article&apos;s bookmarkable artifact, and the table below is the load-bearing data-density object. Four MITRE-aligned categories, the named alert for each primitive, and the ATT&amp;amp;CK technique ID the alert maps to.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;MDI alert (External ID / detector)&lt;/th&gt;
&lt;th&gt;MITRE ATT&amp;amp;CK technique&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Reconnaissance&lt;/td&gt;
&lt;td&gt;Account enumeration reconnaissance (LDAP) -- External ID 2437&lt;/td&gt;
&lt;td&gt;T1087 Account Discovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reconnaissance&lt;/td&gt;
&lt;td&gt;Network-mapping reconnaissance (DNS)&lt;/td&gt;
&lt;td&gt;T1018 Remote System Discovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reconnaissance&lt;/td&gt;
&lt;td&gt;Security principal reconnaissance (LDAP)&lt;/td&gt;
&lt;td&gt;T1069 Permission Groups Discovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reconnaissance&lt;/td&gt;
&lt;td&gt;User and IP address reconnaissance (SMB)&lt;/td&gt;
&lt;td&gt;T1018&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence and privilege escalation&lt;/td&gt;
&lt;td&gt;Honeytoken activity (authentication / attribute / group)&lt;/td&gt;
&lt;td&gt;T1098 Account Manipulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence and privilege escalation&lt;/td&gt;
&lt;td&gt;Suspected Skeleton Key attack&lt;/td&gt;
&lt;td&gt;T1556 (Modify Authentication Process)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence and privilege escalation&lt;/td&gt;
&lt;td&gt;Suspected Golden Ticket usage (encryption downgrade)&lt;/td&gt;
&lt;td&gt;T1558.001 Golden Ticket [@mitre-t1558-001]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence and privilege escalation&lt;/td&gt;
&lt;td&gt;Suspected Golden Ticket usage (forged authorization data)&lt;/td&gt;
&lt;td&gt;T1558.001&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence and privilege escalation&lt;/td&gt;
&lt;td&gt;Suspected DCShadow attack (DC promotion) -- External ID 2028&lt;/td&gt;
&lt;td&gt;T1207 Rogue Domain Controller [@mitre-t1207]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence and privilege escalation&lt;/td&gt;
&lt;td&gt;Suspected DCShadow attack (DC replication request) -- External ID 2029&lt;/td&gt;
&lt;td&gt;T1207&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence and privilege escalation&lt;/td&gt;
&lt;td&gt;Suspicious additions to sensitive groups&lt;/td&gt;
&lt;td&gt;T1098 Account Manipulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credential access&lt;/td&gt;
&lt;td&gt;Suspected DCSync attack (replication of directory services) -- External ID 2006&lt;/td&gt;
&lt;td&gt;T1003.006 DCSync [@mitre-t1003-006]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credential access&lt;/td&gt;
&lt;td&gt;Suspected Brute Force attack (Kerberos, NTLM)&lt;/td&gt;
&lt;td&gt;T1110 Brute Force&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credential access&lt;/td&gt;
&lt;td&gt;Suspected AS-REP Roasting attack&lt;/td&gt;
&lt;td&gt;T1558.004 AS-REP Roasting [@mitre-t1558-004]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credential access&lt;/td&gt;
&lt;td&gt;Suspected Kerberos SPN exposure / Kerberoasting&lt;/td&gt;
&lt;td&gt;T1558.003 Kerberoasting [@mitre-t1558-003]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credential access&lt;/td&gt;
&lt;td&gt;Suspected over-pass-the-hash attack&lt;/td&gt;
&lt;td&gt;T1550.002 Pass the Hash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lateral movement&lt;/td&gt;
&lt;td&gt;Suspected identity theft (pass-the-hash)&lt;/td&gt;
&lt;td&gt;T1550.002&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lateral movement&lt;/td&gt;
&lt;td&gt;Suspected identity theft (pass-the-ticket)&lt;/td&gt;
&lt;td&gt;T1550.003 Pass the Ticket&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lateral movement&lt;/td&gt;
&lt;td&gt;Remote code execution attempt&lt;/td&gt;
&lt;td&gt;T1021 Remote Services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lateral movement&lt;/td&gt;
&lt;td&gt;Suspected NTLM relay attack (the ESC8 class)&lt;/td&gt;
&lt;td&gt;T1187 Forced Authentication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lateral movement&lt;/td&gt;
&lt;td&gt;Suspected NTLM authentication tampering&lt;/td&gt;
&lt;td&gt;T1557.001 LLMNR / NBT-NS / Man-in-the-Middle&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Both alert documentation surfaces -- the classic-format alert reference and the XDR-format alert reference -- are the canonical primaries for this catalogue [@mslearn-mdi-alerts-mdi-classic][@mslearn-mdi-alerts-xdr]. Reading either page in sequence is the single most useful afternoon a SOC operator new to MDI can spend.The numeric External IDs (2006 for DCSync, 2028 and 2029 for DCShadow, 2437 for LDAP account enumeration, and so on) are a Microsoft-internal stability anchor that survives alert-name renames over time. Microsoft has renamed alerts -- &quot;Suspected DCSync attack&quot; was named differently in early Azure ATP -- but the External IDs do not change. Production SOAR rules should match on the External ID, not the alert name string.&lt;/p&gt;

An offensive primitive in which a principal that has been granted the *Replicating Directory Changes* and *Replicating Directory Changes All* extended rights uses the DRSUAPI replication interface (specifically `IDL_DRSGetNCChanges`) to request a full or partial replication of directory contents from a domain controller -- typically targeting the `unicodePwd` attribute on sensitive accounts like `krbtgt` and `Administrator`. The technique requires no code execution on the DC, no `Ntds.dit` copy, and no presence on a domain-joined machine other than network connectivity to a DC. Mimikatz&apos;s `lsadump::dcsync` command, written by Benjamin Delpy and Vincent Le Toux, is the canonical implementation; MITRE catalogues the technique as T1003.006 [@mitre-t1003-006][@adsec-dcsync].

A specific adversary behaviour catalogued in the MITRE ATT&amp;amp;CK framework, identified by a stable ID (for example T1003.006 for DCSync, T1558.001 for Golden Ticket, T1207 for Rogue Domain Controller). MITRE updates the framework periodically; the IDs themselves do not change, which is why detection-engineering tooling -- including MDI&apos;s per-alert MITRE mapping -- anchors to the IDs rather than the human-readable names.
&lt;p&gt;Concrete mechanism, for one named alert. &lt;em&gt;Suspected DCSync attack -- replication of directory services&lt;/em&gt;, External ID 2006, fires on the structural pattern that an &lt;code&gt;IDL_DRSGetNCChanges&lt;/code&gt; request reached a domain controller from a source that is not itself a domain controller. The mechanism is the one place where MDI&apos;s wire-side capture pays for itself most visibly -- the 4662 event the LSA emits records the directory-service-object access but does not identify the source as not-a-DC; only the wire view sees the calling host&apos;s IP and resolves it against the directory&apos;s &lt;code&gt;serverReference&lt;/code&gt; set.&lt;/p&gt;

sequenceDiagram
    autonumber
    participant Attacker as Attacker workstation (Mimikatz)
    participant DC as Domain Controller
    participant MDI as MDI v3.x sensor (on DC)
    participant Cloud as MDI cloud backend
    participant XDR as Defender XDR portal
    Attacker-&amp;gt;&amp;gt;DC: IDL_DRSGetNCChanges (DRSUAPI replication request)
    DC-&amp;gt;&amp;gt;DC: LSA writes event 4662 (DS object access)
    DC--&amp;gt;&amp;gt;Attacker: Replication response (unicodePwd, supplementalCredentials)
    MDI-&amp;gt;&amp;gt;MDI: Wire parse: caller IP not in serverReference set
    MDI-&amp;gt;&amp;gt;Cloud: Stream parsed event (caller, target object, attributes)
    Cloud-&amp;gt;&amp;gt;Cloud: Correlate against known-DC IPs, fire detector
    Cloud-&amp;gt;&amp;gt;XDR: Write alert External ID 2006 (T1003.006)
    XDR-&amp;gt;&amp;gt;XDR: Surface in unified incident queue
&lt;p&gt;The alert taxonomy makes the bookmarkable promise the rest of the article rests on. The trigger logic that fires each row, however, depends on signal the sensor can only acquire on the wire or in the event log -- and when the trigger logic misses, the operator&apos;s last-mile coverage is KQL.&lt;/p&gt;
&lt;h3&gt;6.3 The advanced-hunting schema and a worked KQL example&lt;/h3&gt;
&lt;p&gt;When the alert template misses, the hunter writes Kusto Query Language. Defender XDR exposes three identity-specific tables that the MDI sensor populates -- &lt;code&gt;IdentityLogonEvents&lt;/code&gt; for authentication activity captured against on-prem AD, &lt;code&gt;IdentityQueryEvents&lt;/code&gt; for queries performed against AD objects, and &lt;code&gt;IdentityDirectoryEvents&lt;/code&gt; for events involving an on-prem domain controller including password changes, expirations, UPN changes, scheduled tasks, and PowerShell activity [@mslearn-xdr-identitylogon][@mslearn-xdr-identityquery][@mslearn-xdr-identitydirectory]. Cross-product context is available from the unified &lt;code&gt;AlertInfo&lt;/code&gt;, &lt;code&gt;AlertEvidence&lt;/code&gt;, and &lt;code&gt;DeviceLogonEvents&lt;/code&gt; tables.&lt;/p&gt;
&lt;p&gt;The worked example below is the structural DCSync detector that catches the encrypted-channel case the alert can miss. The runner in this environment cannot execute KQL directly, so the block is annotated rather than runnable -- a non-runnable KQL detector is stronger pedagogy here than a hand-rolled Python simulation, because the query as written is exactly what an operator would paste into the Defender XDR advanced-hunting console against the actual &lt;code&gt;IdentityDirectoryEvents&lt;/code&gt; table.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kql&quot;&gt;// Structural DCSync detector -- DRSUAPI from non-DC IPs
// Run against the Defender XDR advanced-hunting IdentityDirectoryEvents table.
IdentityDirectoryEvents
| where Timestamp &amp;gt; ago(24h)                                  // tune window per triage cadence
| where ActionType == &quot;DRSReplicate&quot;                          // the DRSUAPI replication call
| extend SourceIP = tostring(parse_json(AdditionalFields).SourceIPAddress)
| where SourceIP !in (&quot;10.0.1.10&quot;, &quot;10.0.1.11&quot;, &quot;10.0.1.12&quot;)  // tenant DC IPs go here
| where AccountName !startswith &quot;MSOL_&quot;                       // Entra Connect Cloud Sync FP class
| where AccountName !in (&quot;ADConnectSync&quot;)                     // Entra Connect on-prem FP class
| project Timestamp, AccountName, SourceIP, TargetDeviceName, AdditionalFields
| order by Timestamp desc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The output rows that survive the filters are the operator&apos;s investigation queue: DRSUAPI replication requests against a DC from a source that is not itself a DC, and not a recognised hybrid-identity sync principal. The two cleanup principals -- &lt;code&gt;MSOL_*&lt;/code&gt; (the Microsoft Entra Connect Cloud Sync service account, with a stable &lt;code&gt;MSOL_&lt;/code&gt; prefix and an 8-character random suffix) and &lt;code&gt;ADConnectSync&lt;/code&gt; (the on-prem Entra Connect service account) -- are the two most common false positives every MDI tenant sees. Adding them to the &lt;code&gt;!startswith&lt;/code&gt; and &lt;code&gt;!in&lt;/code&gt; clauses cuts the FP rate by an order of magnitude in most environments. The third FP class that operators tune for is &lt;strong&gt;legitimate vulnerability scanners&lt;/strong&gt; triggering the LDAP / SMB reconnaissance alerts -- the scanner&apos;s authenticated enumeration looks behaviourally identical to a SharpHound collector unless the scanner&apos;s source IP is in an allowlist.&lt;/p&gt;

flowchart LR
    A[&quot;IdentityDirectoryEvents&lt;br /&gt;(DRSReplicate)&quot;] --&amp;gt; B[&quot;Filter: source IP&lt;br /&gt;not in known_dc_ips&quot;]
    B --&amp;gt; C[&quot;Filter: account&lt;br /&gt;not in sync allowlist&quot;]
    C --&amp;gt; D[&quot;Suspect rows&lt;br /&gt;(operator triage)&quot;]
&lt;p&gt;Beyond the three identity tables there is one more surface worth naming. The April 2026 &lt;em&gt;Identity Explorer&lt;/em&gt; Preview in the Defender XDR Identity page builds on the Microsoft Sentinel data lake -- Microsoft&apos;s 2026 cross-product cold-storage and analytics layer with up to 12 years of retention in Parquet format [@mslearn-sentinel-datalake][@mslearn-mdi-whats-new]. Identity Explorer uses the Defender XDR hunting graph to visualise identity attack paths as interactive graphs with predefined scenarios for lateral movement, privilege escalation, and credential-access risk [@mslearn-xdr-hunting-graph][@mslearn-xdr-investigate-users].&lt;/p&gt;
&lt;p&gt;The query language is the operator&apos;s last-mile coverage layer. Everything in section 6 so far is what MDI gives you. KQL is what you do when MDI does not.&lt;/p&gt;
&lt;h3&gt;6.4 The graph layer in transition&lt;/h3&gt;
&lt;p&gt;The graph that began as ATA 1.9&apos;s Lateral Movement Paths report no longer exists in the form most operators remember. The history is a clean three-step arc and a transition still in progress.&lt;/p&gt;
&lt;p&gt;ATA 1.9 (March 2018) shipped the &lt;em&gt;Lateral movement paths to sensitive accounts&lt;/em&gt; report, built on SAM-R-based local-administrator discovery: the sensor remotely enumerated each member host&apos;s local-administrators group and computed the chain of &quot;who can become whom&quot; through cached credentials [@mslearn-ata-1-9][@atadocs-lmp-usecase]. That report carried through Azure ATP, through the Microsoft Defender for Identity rename, and through the Microsoft Defender XDR rebrand essentially unchanged for seven years.&lt;/p&gt;
&lt;p&gt;In May 2025, Microsoft disabled the SAM-R-based discovery via Message Center notice MC1073068, citing alignment with the broader &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;Windows NTLM-deprecation roadmap&lt;/a&gt; [@handsontek-mc1073068]. The message body is explicit: &lt;em&gt;&quot;Disabling this feature will impact the ability to map potential lateral movement paths (using SAM-R queries) because the data used to calculate potential lateral movement paths will no longer be collected by the Defender for Identity sensor.&quot;&lt;/em&gt; SAM-R as a remote-discovery primitive had become a security debt as much as a feature; the deprecation brought MDI&apos;s collection behaviour into line with Restricted SAM and Microsoft&apos;s NTLM-deprecation posture, but it left the LMP surface without its primary data source.&lt;/p&gt;
&lt;p&gt;The replacement is in two pieces. The first is the unified &lt;strong&gt;attack-path exploration&lt;/strong&gt; surface in Microsoft Defender XDR, driven primarily by Microsoft Defender for Cloud&apos;s Cloud Security Posture Management (CSPM) attack-path engine [@mslearn-defenderforcloud-attack-path], with MDI feeding identity signal into the same correlation. The second is the &lt;strong&gt;Identity Explorer&lt;/strong&gt; Preview that launched in April 2026 on the Microsoft Sentinel data lake, specifically for identity attack paths -- visible from the Identity page in Defender XDR for tenants with a Sentinel data lake licence [@mslearn-mdi-whats-new][@mslearn-xdr-hunting-graph][@mslearn-xdr-investigate-users]. The honest framing in 2026 is that the post-SAM-R LMP coverage is &lt;strong&gt;not yet fully closed&lt;/strong&gt; by either replacement -- the Defender XDR hunting graph is rich, the Identity Explorer is improving, but the seven-year-old SAM-R-derived LMP report had operator workflows around it that the new surfaces have not all reproduced.&lt;/p&gt;
&lt;p&gt;MDI&apos;s graph layer is in transition. The cloud rewrite handed Microsoft the platform to ship a better graph than ATA ever could; in 2026 the build-out is still in progress. Section 9 will name this as one of the article&apos;s open problems. First, though, we have to look at the competitive market the watcher sits inside.&lt;/p&gt;
&lt;h2&gt;7. Competing Approaches -- the 2026 Identity-Detection Market&lt;/h2&gt;
&lt;p&gt;If MDI is the watcher on the DC, what is everybody else? Five named methods share the 2026 identity-threat detection market with MDI, each optimising for a different trade-off. The table below is the six-column shorthand; the prose that follows is the per-method analysis.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vendor / project&lt;/th&gt;
&lt;th&gt;On-DC sensor model&lt;/th&gt;
&lt;th&gt;Data-input mix&lt;/th&gt;
&lt;th&gt;Alert taxonomy&lt;/th&gt;
&lt;th&gt;Graph model&lt;/th&gt;
&lt;th&gt;Pricing model&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;MDI&lt;/td&gt;
&lt;td&gt;On-DC sensor (v2.x standalone or v3.x MDE-integrated)&lt;/td&gt;
&lt;td&gt;Wire + event log + ETW + AD CS audit&lt;/td&gt;
&lt;td&gt;MITRE-aligned alert catalogue + nine ESC posture&lt;/td&gt;
&lt;td&gt;Hunting graph + Identity Explorer Preview&lt;/td&gt;
&lt;td&gt;Bundled with M365 E5 / E5 Security / F5 Security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CrowdStrike Falcon Identity Protection&lt;/td&gt;
&lt;td&gt;Connector on/near DC + endpoint agent&lt;/td&gt;
&lt;td&gt;Wire (via connector) + endpoint telemetry&lt;/td&gt;
&lt;td&gt;ITDR-style alerts, less granular ATT&amp;amp;CK mapping&lt;/td&gt;
&lt;td&gt;Identity attack-path view (inline enforcement)&lt;/td&gt;
&lt;td&gt;Falcon ITDR module add-on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semperis DSP + ADFR&lt;/td&gt;
&lt;td&gt;Off-DC change-tracking agent&lt;/td&gt;
&lt;td&gt;AD object-change events (LDAP / replication)&lt;/td&gt;
&lt;td&gt;IoC and IoE runtime alerts plus drift / tamper alerts&lt;/td&gt;
&lt;td&gt;Tier 0 exposure graph + rollback graph&lt;/td&gt;
&lt;td&gt;Standalone licence per AD object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SpecterOps BloodHound Enterprise&lt;/td&gt;
&lt;td&gt;Off-DC collector (SharpHound CE)&lt;/td&gt;
&lt;td&gt;AD permissions graph + Azure / Okta / Mac extensions&lt;/td&gt;
&lt;td&gt;Attack-path exposure findings&lt;/td&gt;
&lt;td&gt;Pure graph (Cypher over Postgres / Neo4j)&lt;/td&gt;
&lt;td&gt;Standalone SaaS licence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft Sentinel native UEBA&lt;/td&gt;
&lt;td&gt;None on DC (consumes MDI + other sources)&lt;/td&gt;
&lt;td&gt;Sentinel data lake (cross-product)&lt;/td&gt;
&lt;td&gt;UEBA risk scores, anomaly events&lt;/td&gt;
&lt;td&gt;None on identity graph directly&lt;/td&gt;
&lt;td&gt;Sentinel ingestion + UEBA add-on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sigma + SIEM (open source)&lt;/td&gt;
&lt;td&gt;None on DC (event forwarder agents)&lt;/td&gt;
&lt;td&gt;Windows event logs, ETW via OSQuery / Velociraptor&lt;/td&gt;
&lt;td&gt;Custom rule library&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Free (rule library); SIEM cost separate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;CrowdStrike Falcon Identity Protection&lt;/strong&gt; is the post-acquisition rename of &lt;em&gt;Preempt Platform&lt;/em&gt;, the product line CrowdStrike bought when it completed the &lt;strong&gt;Preempt Security acquisition on September 30, 2020&lt;/strong&gt; [@businesswire-cs-preempt]. Architecturally distinct from MDI: rather than relying on an on-DC sensor that parses wire traffic and event logs, Falcon Identity Protection inspects authentication traffic via a connector deployed on or near each DC and correlates it with Falcon-agent telemetry already collected from every protected endpoint. Identity-policy enforcement is &lt;em&gt;inline&lt;/em&gt; -- the product can require an MFA challenge or block an authentication at the point of decision rather than emit a post-hoc alert [@crowdstrike-falcon-id]. This is the only commercial product in the survey that does inline enforcement on AD Kerberos and NTLM authentications; it is also the only one that is not bundled with a Microsoft 365 licence.&lt;/p&gt;

The product category that combines runtime detection of identity-targeted attacks (Kerberos forgery, credential theft, lateral movement) with response capabilities (force MFA, disable user, revoke session). Gartner formalised the term in 2022. CrowdStrike Falcon Identity Protection and SentinelOne Singularity Identity are the largest ITDR-positioned products outside the Microsoft stack; MDI plus the Defender XDR remediation actions surface effectively functions as Microsoft&apos;s ITDR offering for tenants already inside the Microsoft 365 estate [@mslearn-mdi-remediation-actions].
&lt;p&gt;&lt;strong&gt;Semperis Directory Services Protector (DSP)&lt;/strong&gt; and the companion &lt;strong&gt;Active Directory Forest Recovery (ADFR)&lt;/strong&gt; product are best known for change-tracking and recovery, layered over a runtime Indicators-of-Compromise and Indicators-of-Exposure detection set that overlaps with MDI&apos;s alert taxonomy on classes like DCSync, DCShadow, and Golden Ticket replay [@semperis-dsp][@semperis-adfr]. DSP tracks AD object changes in near-real-time, fires IoC and IoE alerts on the same primitives MDI watches, and offers post-attack rollback as its primary differentiator; ADFR handles malware-free forest recovery in minutes-to-hours rather than days-to-weeks. The pair is partly complementary, partly overlapping with MDI: DSP catches the post-attack drift (the unauthorised group membership change, the rogue ACL) and offers a rollback path MDI does not have; MDI&apos;s per-principal behavioural baselines and unified Defender XDR incident queue are the differentiator on the in-flight detection axis; ADFR handles &quot;the worst day of your career&quot; forest-recovery scenarios where rebuilding the directory is the only remediation. Many tenants run all three.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SpecterOps BloodHound Enterprise (BHE)&lt;/strong&gt; is the commercial form of the BloodHound 2016 graph model that Andy Robbins, Rohan Vazarkar, and Will Schroeder published at DEF CON 24 [@defcon-six-degrees][@bloodhound-github-specterops][@neo4j-bh]. Pure graph attack-path exposure model: BHE maps the paths that &lt;em&gt;exist&lt;/em&gt; (Tier Zero hygiene, principal-to-principal cross-domain trust paths, Entra to on-prem pivots) rather than alerts on attacks in flight [@specterops-bhe]. Complementary to MDI: BHE tells you the attack path exists in the directory, MDI tells you someone is walking it right now. The SpecterOps team&apos;s &lt;em&gt;Certified Pre-Owned&lt;/em&gt; whitepaper (June 2021) by Will Schroeder and Lee Christensen is the source of the &lt;a href=&quot;https://paragmali.com/blog/certified-pre-owned-ad-cs-and-active-directorys-second-trust/&quot; rel=&quot;noopener&quot;&gt;ESC1-ESC8 vocabulary&lt;/a&gt; that downstream MDI ADCS posture assessments map to [@specterops-cpo-pdf][@specterops-cpo-blog].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Microsoft Sentinel native UEBA&lt;/strong&gt; is the SIEM-side behavioural-baselines product over the broader event corpus that Sentinel ingests. Sentinel UEBA uses machine learning to build dynamic behavioural profiles for users, hosts, IP addresses, applications, and other entities, with named data-source connectors including Defender for Identity [@mslearn-sentinel-ueba]. Sentinel UEBA is the &quot;outside the identity tables&quot; layer -- detection that needs to correlate identity signal with email, endpoint, network, and SaaS signal lives there rather than in the identity tables themselves. The Defender XDR-to-Sentinel connector unifies the surfaces [@mslearn-sentinel-defender-connector].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open-source detection stacks&lt;/strong&gt; -- Sigma rules deployed against Sentinel, Splunk, or Elastic, plus Velociraptor and Wazuh -- can match many of MDI&apos;s pattern-based alerts but cannot match MDI&apos;s per-principal behavioural baselines without significant in-house investment [@sigmahq-github]. The SigmaHQ rule corpus contains over 3,000 detection rules in a vendor-neutral SIEM format. Olaf Hartong&apos;s FalconForce team publishes the &lt;em&gt;FalconFriday&lt;/em&gt; hunting-query repository (MDE-schema KQL queries for DLL injection, COM hijacking, LOLBins, LDAP anomalies, and SMB NULL sessions) -- the operator-side companion to community-built detection libraries [@github-falconfriday][@falconforce-blog].&lt;/p&gt;
&lt;p&gt;MDI is the high-coverage, low-effort identity-threat detection product if you already have Microsoft 365 E5 or E5 Security. The third-party products in this market win on differentiation -- inline enforcement, change-tracking, exposure-graph mastery -- rather than baseline coverage. The interesting question for an architect in 2026 is not which to buy. The interesting question is what MDI, by design, cannot see at all.&lt;/p&gt;
&lt;h2&gt;8. Theoretical Limits -- the Five Structural Ceilings&lt;/h2&gt;
&lt;p&gt;There are attacks no version of MDI will ever detect. Not because Microsoft has not shipped the alert yet, and not because the engineering team has not gotten around to it. Because the alert is structurally impossible.&lt;/p&gt;
&lt;p&gt;Five named ceilings, each anchored to a primary source. Together they are the residual blind-spot inventory every operator should be able to name from memory.&lt;/p&gt;

flowchart TD
    subgraph causes [&quot;Attacker-side cause&quot;]
        C1[&quot;OS does not expose&lt;br /&gt;the credential operation&quot;]
        C2[&quot;Forged ticket is&lt;br /&gt;cryptographically identical&quot;]
        C3[&quot;Wire traffic is wrapped&lt;br /&gt;in an encrypted channel&quot;]
        C4[&quot;Attack pivots through&lt;br /&gt;a forest without a sensor&quot;]
        C5[&quot;Attacker uses real DA&lt;br /&gt;real credentials&quot;]
    end
    subgraph gaps [&quot;Defender-side gap&quot;]
        G1[&quot;Credential Guard wall&quot;]
        G2[&quot;Sapphire Ticket class&quot;]
        G3[&quot;Encrypted-channel DCSync&quot;]
        G4[&quot;Cross-forest tail&quot;]
        G5[&quot;Legitimate principal&lt;br /&gt;non-detection&quot;]
    end
    C1 --&amp;gt; G1
    C2 --&amp;gt; G2
    C3 --&amp;gt; G3
    C4 --&amp;gt; G4
    C5 --&amp;gt; G5
&lt;p&gt;&lt;strong&gt;Ceiling 1 -- the Credential Guard wall.&lt;/strong&gt; Anything the operating system itself cannot see is invisible to MDI. The DCSync class is the canonical example with a twist: &lt;a href=&quot;https://paragmali.com/blog/the-empty-hash-credential-guard-the-lsaiso-trustlet-and-the-/&quot; rel=&quot;noopener&quot;&gt;Credential Guard&lt;/a&gt; isolates the LSASS process so that credentials in memory cannot be scraped from a compromised endpoint, but it does not prevent DRSUAPI-level secret extraction against the DC because the DRSUAPI replication interface is &lt;em&gt;supposed&lt;/em&gt; to return password hashes to legitimate replication partners. MDI catches DCSync by detecting the wire-side pattern (DRSUAPI from a non-DC source), not by Credential Guard&apos;s protection. Anything the OS does not expose in event log, wire traffic, or instrumented API -- a custom kernel driver that reads secrets through a side channel, a hypervisor-level credential extraction on a non-Secured-core host -- is, by construction, outside MDI&apos;s data layer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ceiling 2 -- forged-ticket cryptographic indistinguishability, the Sapphire Ticket.&lt;/strong&gt; This is the most important ceiling, and the one whose permanence the rest of this section orbits.&lt;/p&gt;

A forged Kerberos Ticket Granting Ticket whose Privileged Attribute Certificate (PAC) is a verbatim copy of a legitimate principal&apos;s PAC, obtained via the S4U2self plus User-to-User PAC-copy flow against the target principal and then encrypted with the stolen `krbtgt` key. The technique was disclosed by Charlie Bromberg (Synacktiv / Shutdown) in October 2022 and documented on The Hacker Recipes wiki [@hackerrecipes-sapphire]. The defining property: every byte of the forged ticket&apos;s PAC matches the byte pattern of a ticket the genuine KDC would have issued for the legitimate principal, including the group SID set, the user ID, the logon time, and the authorisation-data fields. The classic Golden Ticket leaves PAC anomalies that MDI&apos;s *Suspected Golden Ticket usage (forged authorization data)* alert fires on; the Sapphire Ticket leaves no PAC anomaly because there is no anomaly to leave.

The Sapphire Ticket attack obtains a target principal&apos;s PAC via the S4U2self plus User-to-User PAC-copy technique -- a Kerberos protocol flow Microsoft published as part of MS-SFU and MS-KILE -- which extracts a genuine PAC into a usable form without ever needing to authenticate as the target. The attacker then forges a new ticket whose PAC is the captured PAC, encrypted with the stolen `krbtgt` key. The mechanical sequence is: S4U2self against the target produces a ticket containing the target&apos;s PAC; the U2U flow lets the attacker decrypt the embedded PAC blob; the attacker then mints a fresh TGT around that PAC with the genuine signing key. The KDC&apos;s signature checks pass because the signing key is real, and the PAC&apos;s structural fields pass because they were lifted from a ticket the genuine KDC just issued. Only the original credential compromise that produced the `krbtgt` hash leaves a trail.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Cryptographic indistinguishability is a permanent class. No future MDI release fixes the Sapphire Ticket without breaking Kerberos itself.&lt;/p&gt;
&lt;/blockquote&gt;

Rotate `krbtgt` twice on a defined cadence -- 90 days is common; some Tier Zero playbooks rotate every 30 days. The &quot;twice&quot; is non-optional: a single rotation leaves the prior `krbtgt` key valid for the duration of any tickets the KDC has previously issued, so the stolen key is still usable for up to 10 hours (or longer, on `MaxRenewAge` extensions). Combine with Authentication Policy Silos for Tier Zero service accounts, Tier Zero access reviews, and Privileged Access Workstations for any administrator who can read `krbtgt`. None of these closes the Sapphire Ticket; together they shrink the window in which a stolen key remains weaponisable. Sample PowerShell for the double rotation is in the Microsoft-published `Reset-KrbTgt` script in the GitHub samples repository [@msdefender-id-github].
&lt;p&gt;&lt;strong&gt;Ceiling 3 -- the encrypted-channel DCSync class.&lt;/strong&gt; When DRSUAPI is wrapped in a transport the on-DC capture cannot decode -- DCSync over LDAPS via a SPN-bound impersonation chain, for instance -- the wire-side pattern recognition that powers the External ID 2006 alert degrades. The structural detector in Section 6.3 catches the unencrypted case; the encrypted case requires either a different observation surface (the DRSUAPI handler&apos;s own instrumentation) or behavioural baselining on the post-fact replication-log signal. MDI&apos;s coverage in this case is partial, not complete.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ceiling 4 -- the cross-forest under-instrumentation tail.&lt;/strong&gt; MDI sees the forests its sensors are deployed in. Pivot through an external trust to a forest without MDI coverage and the signal is incomplete -- the attacker&apos;s pre-pivot reconnaissance, the actual trust traversal, and any post-pivot actions on the trusting side that do not also touch an MDI-monitored forest will be invisible. This is a deployment property, not a product property: a tenant with MDI on every forest in its environment does not have this ceiling. A tenant whose acquisition portfolio includes three forests it does not yet monitor does.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ceiling 5 -- legitimate-principal compromise non-detection.&lt;/strong&gt; When the attacker uses a real Domain Admin&apos;s real credentials, every action is behaviourally indistinguishable from the legitimate principal unless timing, geolocation, or device fingerprint breaks the baseline. The 2025 and 2026 &lt;em&gt;Suspected session cookie theft&lt;/em&gt; and related XDR-format alerts close part of this gap by adding behavioural side channels that the older Azure ATP alert catalogue did not cover [@mslearn-mdi-alerts-xdr]. The residual is permanent: a sufficiently disciplined attacker operating from the legitimate principal&apos;s normal workstation, during the legitimate principal&apos;s normal hours, doing things the legitimate principal might plausibly do, is, by construction, indistinguishable from the legitimate principal.&lt;/p&gt;
&lt;p&gt;A sixth honourable mention sits adjacent to these five: &lt;strong&gt;out-of-band physical access&lt;/strong&gt; -- a stolen &lt;code&gt;Ntds.dit&lt;/code&gt; backup, an attacker-controlled DC&apos;s offline export, supply-chain firmware compromise on the DC hardware -- is outside the data layer MDI operates over. The hardware-trust-root community owns this class of mitigation, not the identity-threat detection community.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The five structural ceilings are knowable, not surprises. A SOC that names them ahead of time has a better incident-response runbook than one that does not -- specifically, the runbook for &quot;we just realised the attacker used a Sapphire Ticket&quot; is fundamentally different from the runbook for &quot;MDI fired and we ignored it.&quot; The first runbook starts with &lt;code&gt;krbtgt&lt;/code&gt; rotation and Tier Zero hygiene review; the second starts with disciplinary review and SOAR-rule tuning. Knowing which runbook to pick depends on naming the ceiling correctly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These five named residuals are why the rest of the article exists. If MDI caught everything, the operator playbook in Section 10 would be unnecessary. Because MDI does not, and because the gaps are knowable, the playbook in Section 10 is the difference between MDI as a licence line item and MDI as a working part of the SOC&apos;s day. But before the playbook, one last open-problem inventory: where is the research roadmap actually working?&lt;/p&gt;
&lt;h2&gt;9. Open Problems -- What the Research Roadmap Is Working On&lt;/h2&gt;
&lt;p&gt;Five open problems sit between the 2026 floor and a hypothetically perfect identity-threat detector. Each one has a current best partial result and a citation. None of them is closed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Problem 1 -- the post-PKINIT NTLM-relay class beyond ESC8.&lt;/strong&gt; Synacktiv&apos;s &lt;em&gt;Understanding and evading Microsoft Defender for Identity PKINIT detection&lt;/em&gt; paper (Guillaume Andre, 2024) reverse-engineered MDI&apos;s PKINIT-class detection: MDI fingerprints offensive-tool-generated AS-REQ messages by the encryption types they advertise, which differ from the encryption-type list a legitimate Windows API PKINIT request generates [@synacktiv-pkinit-evasion][@synacktiv-pkinit-evasion-archive]. The companion &lt;code&gt;Invoke-RunAsWithCert&lt;/code&gt; PowerShell tool generates AS-REQ messages via the Windows API itself, producing requests structurally identical to legitimate enterprise PKINIT authentication and bypassing the fingerprint-based detection [@synacktiv-runascert-gh][@deepwiki-runascert]. Aura Security&apos;s follow-on writeup confirms the technique against the current MDI version and walks through modifying Certipy to produce matching AS-REQ shapes [@aurainfosec-mdi-pkinit]. The partial mitigation in 2026 is the additional posture-side coverage in the nine MDI Certificates assessments, which closes some of the configurations the offensive tools target [@mslearn-mdi-certificates-posture]. The runtime detection arms race continues.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Problem 2 -- the graph-layer transition from SAM-R LMP to Identity Explorer.&lt;/strong&gt; Section 6.4 covered the deprecation of SAM-R-based LMP discovery in May 2025 (MC1073068) and the two replacement surfaces: the Defender XDR attack-path exploration driven by Defender for Cloud&apos;s CSPM engine, and the April 2026 Identity Explorer Preview on the Sentinel data lake [@handsontek-mc1073068][@mslearn-defenderforcloud-attack-path][@mslearn-mdi-whats-new][@mslearn-xdr-hunting-graph]. The honest open question is whether either surface reproduces, in 2026, the operator workflows the seven-year-old SAM-R-derived LMP report had built up around itself. The Defender XDR hunting graph is richer than the LMP report ever was, but its data model is different; the Identity Explorer is closer in spirit but in Preview rather than GA.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Problem 3 -- the Sentinel data lake correlation and the Identity Explorer GA path.&lt;/strong&gt; Microsoft Sentinel data lake, the cross-product cold-storage and analytics layer, went public preview in 2025 and ships with up to 12 years of retention in Parquet format, a clean separation of storage and compute, and KQL plus Jupyter notebook query surfaces [@mslearn-sentinel-datalake][@mstc-sentinel-datalake-preview]. Identity Explorer is the first identity-specific surface built on top of the data lake; it is in Preview as of April 2026 with no GA date published. The open problem is whether the data-lake-tier correlation can match the alert-tier MDI quality for long-running attacker dwell -- the &lt;em&gt;months between Sapphire Ticket use and discovery&lt;/em&gt; class -- without producing more noise than signal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Problem 4 -- the MDI evasion research arms race.&lt;/strong&gt; Synacktiv&apos;s two papers (the sensor primer by Andre and Benassouli in 2022; the PKINIT evasion paper by Andre in 2024) plus the operator notes on alert-timing exploitation that show up in adsecurity.org and SpecterOps content are the public record of the offensive-research community&apos;s targeting of MDI specifically [@synacktiv-primer-mdi][@synacktiv-primer-mdi-archive][@synacktiv-pkinit-evasion][@synacktiv-pkinit-evasion-archive]. FalconForce&apos;s reverse-engineering of the MDE sensor (via Olaf Hartong&apos;s MDE Internals series) is the methodological precedent for the same approach against MDI; the FalconForce blog and the FalconFriday hunting-query repository are the operator-facing primaries [@falconforce-mde-0x02][@falconforce-mde-0x03][@falconforce-blog][@github-falconfriday][@github-olafhartong]. The Charlie Bromberg Sapphire Ticket disclosure (October 2022) is the cryptographic-attack-class research that Section 8&apos;s third ceiling rests on [@hackerrecipes-sapphire]. The arms-race property is permanent; the defensive product team&apos;s job is to keep the detection-shipping cadence faster than the evasion-shipping cadence, which the cloud rewrite (see Section 5) made structurally possible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Problem 5 -- the non-Windows directory coverage tail.&lt;/strong&gt; MDI covers Active Directory and (via the Microsoft Entra Connect sensor) the on-prem-to-Entra-ID sync surface. Native Entra ID attacks (token theft against Entra ID itself, OAuth consent phishing, Conditional Access bypass) are covered by Defender for Cloud Apps and Entra ID Protection, not by MDI. The boundary between MDI&apos;s scope and the adjacent products is operationally meaningful: a SOC operator reading &quot;MDI did not fire&quot; on an Entra-ID-only attack should not conclude the attack went undetected -- another product likely did fire, in another part of the same Defender XDR portal. The unified incident queue stitches the alerts together; the operator&apos;s mental model has to know which sensor surface to look at when triaging.&lt;/p&gt;
&lt;p&gt;The article does &lt;em&gt;not&lt;/em&gt; claim &quot;BloodHound CE forced MDI to add ADCS detections in 2024.&quot; The framing is parallel evolution: as BloodHound CE expanded ADCS attack-path coverage in 2024-2025, MDI extended its ADCS posture assessments and PKINIT-class runtime detections during the same window. The two product communities watch each other; neither one &quot;forces&quot; the other.&lt;/p&gt;
&lt;p&gt;The roadmap is real, the build-out is in progress, and the operator decision in 2026 is not &quot;wait for the perfect product.&quot; It is &quot;deploy what works now, and cover the residuals with KQL.&quot;&lt;/p&gt;
&lt;h2&gt;10. The MDI Deployment and Triage Playbook&lt;/h2&gt;
&lt;p&gt;Four lanes, mapped to four operator personas: the architect who designs the sensor footprint, the SOC analyst who triages the alerts, the threat hunter who writes the KQL that fills the gaps, and everyone who needs to know what does not work.&lt;/p&gt;
&lt;h3&gt;Lane 1 -- sensor placement and prerequisite hygiene&lt;/h3&gt;
&lt;p&gt;Deploy the &lt;strong&gt;v3.x sensor on every domain controller running Windows Server 2019 or later&lt;/strong&gt;, paired with the MDE agent. The deployment path is the Microsoft Defender portal&apos;s migration wizard or the standalone install via the MDE agent&apos;s onboarding flow [@mslearn-mdi-deploy-sensor-v3][@modernsec-v3x][@jeffreyappel-v2v3].&lt;/p&gt;
&lt;p&gt;Deploy the &lt;strong&gt;v2.x sensor&lt;/strong&gt; on every AD FS federation server, every AD CS online issuing certificate authority, and every Microsoft Entra Connect server (both active and staging), unless those roles already run on a domain controller covered by a v3.x sensor with the May 2026 identity-role extension enabled [@mslearn-mdi-prereq-sensor-v2][@mslearn-mdi-whats-new].&lt;/p&gt;
&lt;p&gt;Configure the &lt;strong&gt;required Windows audit subcategories&lt;/strong&gt; via the Group Policy &lt;em&gt;Subcategory Settings&lt;/em&gt; path that the MDI event-collection page enumerates -- &lt;em&gt;Audit Credential Validation&lt;/em&gt;, &lt;em&gt;Audit Kerberos Authentication Service&lt;/em&gt;, &lt;em&gt;Audit Kerberos Service Ticket Operations&lt;/em&gt;, &lt;em&gt;Audit Logon&lt;/em&gt;, &lt;em&gt;Audit Directory Service Access&lt;/em&gt;, &lt;em&gt;Audit Computer Account Management&lt;/em&gt;, plus the additional subcategories for AD CS and AD FS roles. The v3.x sensor includes an &lt;em&gt;Automatic Windows auditing configuration&lt;/em&gt; toggle that uses the Windows LSA audit-policy APIs to set the subcategories directly, eliminating the GPO step [@mslearn-mdi-event-collection].&lt;/p&gt;
&lt;p&gt;Set the &lt;strong&gt;MDI Action Account&lt;/strong&gt; in the Defender portal. The default is LocalSystem impersonation on the sensor host, which works for response actions targeting AD objects (force password reset, disable user). A gMSA-based Action Account is the alternative for tenants that want least-privilege response identities scoped per workspace [@mslearn-mdi-action-accounts][@mslearn-mdi-remediation-actions]. Avoid configuring the same gMSA across multiple sensor hosts -- the documented anti-pattern is to use one Action Account for DC-side actions only.&lt;/p&gt;
&lt;p&gt;Verify the &lt;strong&gt;Microsoft Defender portal role assignments&lt;/strong&gt; so that SOC analysts have the correct read-and-respond permissions on identity alerts. The Microsoft Defender for Identity enterprise application (ID &lt;code&gt;60ca1954-583c-4d1f-86de-39d835f3e452&lt;/code&gt;) is the consent surface for the response actions; tenants that have not granted consent will see &quot;remediation action unavailable&quot; on identity-targeted incidents [@mslearn-mdi-remediation-actions].&lt;/p&gt;
&lt;h3&gt;Lane 2 -- alert triage SLAs&lt;/h3&gt;
&lt;p&gt;The triage matrix maps alert category to response-time target and the named SOC role that owns triage. Numbers below are typical Tier 1 / Tier 2 SOC targets; tune to your environment&apos;s incident-response policy.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Alert category&lt;/th&gt;
&lt;th&gt;Response-time target&lt;/th&gt;
&lt;th&gt;Owning SOC role&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;DCSync, DCShadow, Golden Ticket&lt;/td&gt;
&lt;td&gt;1 hour&lt;/td&gt;
&lt;td&gt;Tier 2 (privileged-account-compromise specialist)&lt;/td&gt;
&lt;td&gt;Treat as confirmed compromise pending evidence to the contrary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AS-REP Roasting, Kerberoasting&lt;/td&gt;
&lt;td&gt;4 hours&lt;/td&gt;
&lt;td&gt;Tier 2&lt;/td&gt;
&lt;td&gt;Higher-FP class; verify offending principal pattern before escalation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NTLM relay (ESC8 class)&lt;/td&gt;
&lt;td&gt;4 hours&lt;/td&gt;
&lt;td&gt;Tier 2&lt;/td&gt;
&lt;td&gt;ADCS-aware; coordinates with CA team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reconnaissance (LDAP / SMB / DNS)&lt;/td&gt;
&lt;td&gt;24 hours&lt;/td&gt;
&lt;td&gt;Tier 1&lt;/td&gt;
&lt;td&gt;Highest-FP class; allowlist legitimate scanners&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Honeytoken activity&lt;/td&gt;
&lt;td&gt;1 hour&lt;/td&gt;
&lt;td&gt;Tier 1 plus Tier 2 escalation&lt;/td&gt;
&lt;td&gt;Near-zero FP; any hit is investigation-worthy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Two false-positive cleanup patterns appear in nearly every tenant. The Azure AD Connect Cloud Sync service principal -- &lt;code&gt;MSOL_&lt;/code&gt; plus an 8-character random suffix -- legitimately performs DRSUAPI-like operations as part of the hybrid identity sync flow, and will fire DCSync-class alerts unless allowlisted. Legitimate vulnerability scanners (Tenable, Rapid7, Qualys) perform authenticated enumeration that triggers the LDAP and SMB reconnaissance alerts; scanner IPs go in an exclusion list per the Defender XDR portal&apos;s identity-alert tuning surface.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;MDI Action Accounts and Remediation Actions&lt;/strong&gt; surface lets the responder disable a user, force a password reset, revoke an Entra ID session, or mark an account as compromised -- triggered manually from the alert flow or automatically via the Defender XDR &lt;em&gt;automatic attack disruption&lt;/em&gt; engine, which requires 99 percent or higher detector precision before taking containment action [@mslearn-xdr-attack-disruption][@mslearn-mdi-remediation-actions][@mslearn-xdr-investigate-users]. Automatic attack disruption is opt-in per containment action; the conservative default leaves analyst confirmation in the loop for password-reset-class actions and automates disable-user only on the highest-precision detector classes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The cloud-side analytics pipeline aggregates signal across the per-principal baseline window before deciding to emit. Empirically the alert latency is &lt;strong&gt;minutes-cadence, not seconds-cadence&lt;/strong&gt;. Incident response runbooks that assume sub-second alert arrival will be wrong; the operator clock starts when the alert hits the Defender XDR queue, which is itself minutes after the wire-side event. Plan for this in the SLA matrix above -- the &quot;1 hour&quot; target for DCSync starts from the alert timestamp, not the attack timestamp, and the attack itself may have happened five or ten minutes earlier. The Microsoft alerts-overview page is explicit that MDI is &quot;not designed to serve as an auditing or logging solution that captures every single operation or activity on the servers where the sensor is installed; it only captures the data required for its detection and recommendation mechanisms&quot; [@mslearn-mdi-alerts-overview].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Lane 3 -- advanced-hunting queries that fill the gaps&lt;/h3&gt;
&lt;p&gt;Three structural detectors in KQL form, each one targeting a class the named alerts can miss. Each query names the table, the columns, and the threshold tuning the operator will need.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;structural DCSync detector&lt;/strong&gt; runs against &lt;code&gt;IdentityDirectoryEvents&lt;/code&gt; and catches the encrypted-channel case the External ID 2006 alert may miss:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kql&quot;&gt;IdentityDirectoryEvents
| where Timestamp &amp;gt; ago(24h)
| where ActionType == &quot;DRSReplicate&quot;
| extend SourceIP = tostring(parse_json(AdditionalFields).SourceIPAddress)
| where SourceIP !in (&quot;10.0.1.10&quot;, &quot;10.0.1.11&quot;, &quot;10.0.1.12&quot;)   // tenant DC IPs
| where AccountName !startswith &quot;MSOL_&quot; and AccountName !in (&quot;ADConnectSync&quot;)
| project Timestamp, AccountName, SourceIP, TargetDeviceName, AdditionalFields
| order by Timestamp desc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Threshold tuning: keep the time window short (24 hours) for daily triage. Cleanup principals (&lt;code&gt;MSOL_*&lt;/code&gt;, &lt;code&gt;ADConnectSync&lt;/code&gt;, plus any per-tenant sync identities) go in the &lt;code&gt;!startswith&lt;/code&gt; and &lt;code&gt;!in&lt;/code&gt; clauses. The query produces a clean queue of &quot;DRSUAPI replication from a host that should not be doing DRSUAPI.&quot; False-positive class: legitimate Azure AD Connect Cloud Sync service principals; resolve by adding the principal to the allowlist.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;slow-burn Kerberoasting detector&lt;/strong&gt; runs against &lt;code&gt;IdentityLogonEvents&lt;/code&gt; and catches the rate-limited Kerberoast pattern that modern attackers use to stay below the MDI behavioural-baseline threshold:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kql&quot;&gt;IdentityLogonEvents
| where Timestamp &amp;gt; ago(7d)
| where Protocol == &quot;Kerberos&quot;
| where ActionType == &quot;ServiceTicketRequest&quot;
| extend EncType = tostring(parse_json(AdditionalFields).EncryptionType)
| where EncType in (&quot;RC4-HMAC&quot;, &quot;DES-CBC-MD5&quot;)
| summarize SpnCount = dcount(TargetSpn), SpnList = make_set(TargetSpn) by AccountName, bin(Timestamp, 1d)
| where SpnCount &amp;gt; 5     // tune per tenant baseline
| order by Timestamp desc, SpnCount desc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Threshold tuning: the &lt;code&gt;SpnCount &amp;gt; 5&lt;/code&gt; threshold is the load-bearing knob. Tenants with legitimate operational accounts that request many SPNs per day (privileged service accounts running scheduled tasks across many target hosts) will need a higher threshold and an allowlist. The seven-day window catches the slow-burn pattern that a one-hour window misses.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;PKINIT-relay structural detector&lt;/strong&gt; runs against &lt;code&gt;IdentityLogonEvents&lt;/code&gt; and watches for AS-REQ with PA-PK-AS-REQ pre-auth coming from unexpected client subnets:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kql&quot;&gt;IdentityLogonEvents
| where Timestamp &amp;gt; ago(24h)
| where Protocol == &quot;Kerberos&quot;
| where ActionType == &quot;InitialAuthentication&quot;
| extend PreAuth = tostring(parse_json(AdditionalFields).PreAuthType)
| where PreAuth == &quot;PA-PK-AS-REQ&quot;
| extend ClientSubnet = strcat(split(IPAddress, &quot;.&quot;)[0], &quot;.&quot;, split(IPAddress, &quot;.&quot;)[1])
| where ClientSubnet !in (&quot;10.0.5&quot;, &quot;10.0.6&quot;)    // legitimate smartcard subnets
| project Timestamp, AccountName, IPAddress, DeviceName, AdditionalFields
| order by Timestamp desc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Threshold tuning: PKINIT is legitimate when smartcard logon is in use. Identify the legitimate smartcard-issuing subnets and add them to the &lt;code&gt;!in&lt;/code&gt; clause. The residual queue is PKINIT from unexpected sources -- the structural pattern behind both the post-ESC8 NTLM-relay class and the Synacktiv &lt;code&gt;Invoke-RunAsWithCert&lt;/code&gt; evasion class.&lt;/p&gt;
&lt;p&gt;Tenants that want the alert and event corpus in their SIEM as well as in Defender XDR should configure the &lt;strong&gt;MDI to Microsoft Sentinel connector&lt;/strong&gt; through the Defender XDR-to-Sentinel integration; the connector is auto-enabled when Sentinel is onboarded to the Defender portal [@mslearn-sentinel-defender-connector].&lt;/p&gt;
&lt;h3&gt;Lane 4 -- what does NOT work&lt;/h3&gt;
&lt;p&gt;Five named operator myths, each refuted with a one-paragraph structural reason.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Myth 1: &quot;MDI without the DC sensor still catches Kerberos attacks via the Entra ID side.&quot;&lt;/strong&gt; Wrong. The Kerberos protocol layer is on-prem; the analytics require on-DC capture of the AS-REQ / TGS-REQ / AP-REQ exchange. Entra ID&apos;s side of the hybrid auth flow does not carry the same protocol detail. A tenant with MDI licensed but the sensor not deployed on the DCs has no Kerberos detection at all -- the licensed state is necessary but not sufficient.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Myth 2: &quot;Disabling the v2.x sensor on AD FS is fine since it is covered by the DC sensor.&quot;&lt;/strong&gt; Wrong. The AD FS authentication flow generates federation-side events (SAML assertions, OAuth tokens, the Application and Security event logs that AD FS itself writes) that the DC sensor does not see. AD FS deserves its own sensor unless the AD FS role is collapsed onto a domain controller, in which case the May 2026 v3.x identity-role extension covers it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Myth 3: &quot;Defender for Endpoint covers what MDI covers.&quot;&lt;/strong&gt; Wrong. MDE catches endpoint behaviour -- process creation, file access, network connections, registry writes. MDI catches protocol-level Kerberos, NTLM, LDAP, and DRSUAPI patterns. The two products share an agent surface in the v3.x architecture, but the &lt;em&gt;signal classes&lt;/em&gt; are different. An MDE-only deployment will not catch a DCSync from a workstation if MDI is not licensed and the sensor is not deployed; the MDE agent on the DC sees the local process activity but not the wire-side replication call&apos;s source.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Myth 4: &quot;MDI alerts are real-time.&quot;&lt;/strong&gt; Wrong. As Callout in Lane 2 above. The cloud-side batched-emission cadence is minutes-not-seconds, and incident response runbooks need to account for it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Myth 5: &quot;MDI requires no tuning.&quot;&lt;/strong&gt; Wrong. Every environment has unique false-positive patterns from internal tooling that need exclusions. Microsoft ships the default detector thresholds; tenants tune them through the Defender XDR portal&apos;s identity-alert configuration surface. A tenant that has not tuned the recon-alert allowlist for its vulnerability scanners will receive far more noise than signal.&lt;/p&gt;
&lt;p&gt;Coverage, triage, KQL, and humility about what does not work. The four lanes are the difference between MDI as a licence item on a renewal sheet and MDI as a working part of the SOC&apos;s day.&lt;/p&gt;
&lt;h2&gt;11. Frequently Asked Questions and Closing&lt;/h2&gt;
&lt;p&gt;Six questions that come up every time MDI is on a whiteboard, each in the misconception-removal pattern: wrong answer named first, then refuted.&lt;/p&gt;

No. See the *common misreading worth fixing* Callout in Section 4: graph-anchored attack-path evaluation in Microsoft&apos;s defensive stack originates in ATA 1.9 (March 2018), and the 2022 anchor in operator memory is the start of the SAM-R-discovery deprecation arc that culminated in MC1073068 in May 2025 [@mslearn-ata-1-9][@handsontek-mc1073068].

Not as one alert per ESC class. The MDI Certificates posture page documents **nine ADCS posture assessments** -- ESC1 (Preview), ESC2, ESC3, ESC4 (template-owner and template-ACL variants), ESC6 (Preview), ESC7, ESC8, ESC11, and ESC15 [@mslearn-mdi-certificates-posture]. The runtime detection surface for the ESC8 NTLM-relay class is the *Suspected NTLM relay attack* alert in the XDR catalogue [@mslearn-mdi-alerts-xdr]. PKINIT-class runtime detection (the post-ESC8 chain) is the AS-REQ encryption-type fingerprint that Synacktiv documented and partially evaded; the August 2023 AD CS sensor release is the prerequisite for posture coverage [@mstc-adcs-sensor][@synacktiv-pkinit-evasion][@synacktiv-pkinit-evasion-archive]. Coverage is &quot;nine posture assessments plus one runtime alert,&quot; not &quot;one alert per ESC1 through ESC15.&quot;

Microsoft has never published the canonical list; community reverse-engineering is the only source. See the *honest provenance of the ETW provider list* Aside in Section 5 for the full provenance (Synacktiv&apos;s November 2022 primer; Olaf Hartong&apos;s FalconForce MDE Internals 0x02 methodology; the Get-TraceLoggingMetadata + Sealighter toolchain) and the snapshot-not-ground-truth framing [@synacktiv-primer-mdi][@falconforce-mde-0x02].

In the cloud since Azure ATP went GA in March 2018 [@mstc-azureatp-ga][@mstc-azureatp-intro]. The on-DC sensor is a thin parser that captures Kerberos / NTLM / LDAP / DRSUAPI on the wire, parses the protocols into structured events, and streams the parsed signal to the multi-tenant cloud backend over HTTPS. The detection logic, the per-principal behavioural baselines, and the alert-emission pipeline all run in the cloud. The legacy on-prem ATA Center model ended with Azure ATP; ATA itself shipped its last release (1.9.3) in September 2020 and Extended Support ends January 2026 [@mstc-ata-eol][@atadocs-versions].

No. The framing is parallel evolution, not a &quot;forcing&quot; relationship. BloodHound CE expanded ADCS attack-path coverage substantially in 2024 and 2025; during the same window MDI extended its ADCS posture assessment surface and added the AD CS sensor release in August 2023 [@mstc-adcs-sensor][@dirteam-sander-aug2023]. Both product communities watch each other -- the Defender team uses BloodHound to red-team its own environments, the SpecterOps team uses MDI when consulting in enterprise Microsoft shops -- but the causal claim &quot;BloodHound forced MDI&quot; is not supported by the public release record. The two communities&apos; work has been concurrent and mutually informing.

Almost. The MITRE-aligned alert catalogue in Section 6.2 covers the most-prevalent offensive primitives. Section 8 names the five structural ceilings that remain by-construction unclosable; *almost* is the load-bearing word.
&lt;p&gt;Friday, 14:35. The watcher on the domain controller has written three named alerts into the Defender XDR queue. The red-team contractor&apos;s &lt;code&gt;Rubeus.exe asreproast&lt;/code&gt; fired &lt;em&gt;Suspected AS-REP Roasting attack&lt;/em&gt; (T1558.004). The junior auditor&apos;s &lt;code&gt;bloodhound-python -c All&lt;/code&gt; fired &lt;em&gt;Security principal reconnaissance (LDAP)&lt;/em&gt;. The Mimikatz DCSync against the SQL host&apos;s service account fired &lt;em&gt;Suspected DCSync attack -- replication of directory services&lt;/em&gt;, External ID 2006, T1003.006. Three alerts. Three MITRE technique IDs. Three rows in a Tier 1 analyst&apos;s queue.&lt;/p&gt;
&lt;p&gt;The watcher&apos;s job is done. Whether the analyst opens the right one first, whether the Tier 2 escalation happens inside the one-hour SLA, whether the response action gets approved before the attacker has moved on -- none of that is MDI&apos;s problem to solve. It is yours.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;microsoft-defender-for-identity-the-defensive-ad-stack-that-sees-what-bloodhound&quot; keyTerms={[
  { term: &quot;DCSync&quot;, definition: &quot;An offensive primitive in which a principal with replication rights uses DRSUAPI&apos;s IDL_DRSGetNCChanges to extract password hashes from a DC; MDI alert External ID 2006, MITRE T1003.006.&quot; },
  { term: &quot;DCShadow&quot;, definition: &quot;Registering a rogue DC via nTDSDSA object creation plus SPN registration, then writing arbitrary updates via legitimate DRSUAPI replication; MDI alerts External ID 2028 and 2029, MITRE T1207.&quot; },
  { term: &quot;Golden Ticket&quot;, definition: &quot;A forged Kerberos TGT minted with the stolen krbtgt key, valid for any principal in the domain; MDI catches via encryption-downgrade and forged-authorisation-data anomalies, MITRE T1558.001.&quot; },
  { term: &quot;Sapphire Ticket&quot;, definition: &quot;A Golden Ticket whose PAC is bit-for-bit identical to a legitimate principal&apos;s PAC (via S4U2self plus U2U PAC copy); cryptographically indistinguishable from a genuine ticket, structurally invisible to PAC-anomaly detectors.&quot; },
  { term: &quot;Lateral Movement Path (LMP)&quot;, definition: &quot;A graph-anchored attack chain through Active Directory; the ATA 1.9 LMP report (March 2018) shipped on SAM-R discovery, which was deprecated in May 2025 via MC1073068.&quot; },
  { term: &quot;Directory Service Account (DSA)&quot;, definition: &quot;The gMSA the MDI v2.x sensor uses for forest-wide AD reads; replaced by LocalSystem impersonation in the v3.x sensor.&quot; },
  { term: &quot;MDI sensor v3.x&quot;, definition: &quot;The October 2025 MDE-integrated sensor; requires Windows Server 2019+, ships inside the MDE SENSE service, capped at 30 percent CPU and 1.5 GB RAM per DC.&quot; },
  { term: &quot;Identity Security Posture Assessment&quot;, definition: &quot;MDI&apos;s posture (non-runtime) detection surface; the AD CS subset enumerates nine ESC posture assessments aligned to the SpecterOps Certified Pre-Owned vocabulary.&quot; },
  { term: &quot;KQL hunting graph&quot;, definition: &quot;The Defender XDR interactive attack-path visualisation surface that operates over the unified hunting schema; the post-LMP replacement for graph-anchored identity attack-path analysis.&quot; },
  { term: &quot;Identity Explorer (Preview)&quot;, definition: &quot;The April 2026 Sentinel-data-lake-backed identity-attack-path surface in the Defender XDR Identity page; uses the hunting graph to visualise lateral movement, privilege escalation, and credential-access risks.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>active-directory</category><category>microsoft-defender</category><category>identity-protection</category><category>threat-detection</category><category>kerberos</category><category>attack-paths</category><category>soc-operations</category><category>windows-security</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>Who Decided This Token Is Good? A Field Guide to Conditional Access and Entra ID Protection</title><link>https://paragmali.com/blog/who-decided-this-token-is-good-a-field-guide-to-conditional-/</link><guid isPermaLink="true">https://paragmali.com/blog/who-decided-this-token-is-good-a-field-guide-to-conditional-/</guid><description>A wire-level tour of Microsoft Entra Conditional Access, Identity Protection, and Continuous Access Evaluation, plus the five things they cannot do.</description><pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate><content:encoded>
**Conditional Access is Microsoft&apos;s Zero Trust policy engine, not a feature.** Every interactive sign-in to a licensed Microsoft 365 tenant flows through three planes: a signal plane (Entra ID Protection&apos;s machine-learning risk scoring), a policy plane (Conditional Access&apos;s JSON rule evaluator), and a session plane (Continuous Access Evaluation&apos;s event-driven revocation channel). This article assembles the wire format of all three -- the `riskDetection` resource on Microsoft Graph, the `conditionalAccessPolicy` schema, the `cp1` client capability that opts a client into 28-hour tokens, and the `401 + insufficient_claims` claims challenge -- into one end-to-end picture, then names the five things this architecture fundamentally cannot do.
&lt;h2&gt;1. Who decided this token is good?&lt;/h2&gt;
&lt;p&gt;It is 09:02 on a Tuesday in Lisbon. Alice opens Outlook on a managed laptop in a hotel and the reading pane populates with mail in under a second. She did not type a password. She did not approve a push. She did not touch a hardware key.&lt;/p&gt;
&lt;p&gt;Who decided that was fine?&lt;/p&gt;
&lt;p&gt;The question is harder than it looks. Alice&apos;s password lives in a token cache from yesterday&apos;s sign-in at the office. Outlook&apos;s client silently acquires a fresh access token from Entra. That request may match a Conditional Access policy. The policy may consult an Identity Protection risk score. The result is either an access token or a refusal. Exchange Online receives the token, validates it, and may yet revoke it mid-session because something changed in the last sixty seconds. Bytes return to Alice.&lt;/p&gt;

Microsoft Entra ID&apos;s policy engine for evaluating sign-in attempts. A Conditional Access policy is a JSON object that matches a set of users, cloud apps, and conditions (network location, device state, sign-in risk, user risk, client app, platform) against a set of grants (block, require MFA, require compliant device, require Authentication Strength, and so on). Policies are evaluated after first-factor authentication; a block grant in any matching policy overrides all allow grants [@ms-ca-overview].

The machine-learning signal plane that scores sign-ins and users for risk. ID Protection emits `riskDetection` events tagged with `riskEventType` (anonymized IP, leaked credentials, password spray, atypical travel, and roughly two dozen others), `riskLevel` (low, medium, high), `riskState`, and `detectionTimingType` (realtime, nearRealtime, or offline). Available only on Microsoft Entra ID P2 [@ms-id-protection-overview].

The session plane. CAE is an event-driven channel between Microsoft Entra and CAE-aware resource APIs (Exchange Online, SharePoint Online, Teams, Microsoft Graph). When a critical event fires -- account disabled, password reset, high user risk, network location change -- the resource API returns `HTTP 401` with a `WWW-Authenticate: Bearer error=&quot;insufficient_claims&quot;` challenge. The client replays the embedded claims to Entra and acquires a fresh token. In exchange for this channel, CAE tokens live up to 28 hours [@ms-cae-concept].
&lt;p&gt;Every component in this chain is individually documented on Microsoft Learn. The Conditional Access policy schema is on the Graph reference [@ms-graph-capolicy]. The &lt;code&gt;riskDetection&lt;/code&gt; resource is on the Graph reference too [@ms-graph-riskdetection]. The &lt;code&gt;cp1&lt;/code&gt; client capability is in the claims-challenge document [@ms-claims-challenge]. The &quot;up to 15 minutes&quot; propagation ceiling for CAE non-IP events is in the CAE concept document [@ms-cae-concept].&lt;/p&gt;
&lt;p&gt;But the chain is not assembled anywhere. That is what this article does.&lt;/p&gt;
&lt;p&gt;This article is for the architect or the detection engineer who already knows what a JWT is, what a service principal is, and what an MDM does. If you have ever stared at a Sign-in log entry that reads &quot;Conditional Access: Success&quot; and wondered what &lt;em&gt;exactly&lt;/em&gt; the policy engine concluded, this is for you.&lt;/p&gt;
&lt;p&gt;Three moments of insight are coming. First, why MFA without context fails not because MFA is weak but because the &lt;em&gt;unit&lt;/em&gt; is wrong (Section 3). Second, why the architectural breakthrough was a &lt;em&gt;separation&lt;/em&gt; and not a new algorithm (Section 5). Third, why the system has limits that no engineering will fix (Section 8).&lt;/p&gt;
&lt;p&gt;How did the industry end up with a token-issuance and claims-challenge model? The answer begins in 1975, with a paper that did not mention identity once.&lt;/p&gt;
&lt;h2&gt;2. From perimeter to identity boundary&lt;/h2&gt;
&lt;p&gt;In September 1975, Jerome Saltzer and Michael Schroeder published an eight-principle paper on operating-system protection that nobody at MIT thought of as a paper about cloud identity [@saltzer-schroeder-1975]. Half a century later, two of those eight -- &lt;em&gt;complete mediation&lt;/em&gt; and &lt;em&gt;least privilege&lt;/em&gt; -- are the implicit theorems every Conditional Access policy evaluates against. Where did the industry go in between?&lt;/p&gt;
&lt;h3&gt;Saltzer and Schroeder: the unstated theorems&lt;/h3&gt;
&lt;p&gt;Complete mediation says &quot;every access to every object must be checked for authority.&quot; Least privilege says &quot;every program and every user of the system should operate using the least set of privileges necessary to complete the job.&quot; These are stated as design &lt;em&gt;principles&lt;/em&gt;, not theorems. But they function as theorems for anyone building an access-control system: violate either of them and you have, by construction, a vulnerability. Conditional Access does not derive the principles. It re-states them as a JSON schema and a runtime evaluator.&lt;/p&gt;
&lt;h3&gt;Jericho Forum: the perimeter dissolves&lt;/h3&gt;
&lt;p&gt;In 2003, David Lacey of the Royal Mail and a loose affiliation of corporate CISOs began arguing, against the prevailing castle-and-moat consensus, that the corporate network perimeter could no longer be relied on as the trust boundary. The Jericho Forum formally launched under the Open Group umbrella in January 2004 [@wikipedia-jericho-forum]. They coined the term &quot;de-perimeterisation&quot; to describe what their member firms were already living: data and identity travelling outside the firewall faster than the firewall could be moved.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s own retrospective puts the quote precisely: the Jericho Forum &quot;promoted a new concept of security called de-perimeterisation that focused on how to protect enterprise data flowing in and out of your enterprise network boundary instead of striving to convince users and the business to keep it on the corporate network&quot; [@simos-2020-jericho]. The first sentence of Microsoft Learn&apos;s CA overview today is a direct descendant: &quot;modern security extends beyond an organization&apos;s network perimeter&quot; [@ms-ca-overview].&lt;/p&gt;
&lt;h3&gt;Kindervag: the name&lt;/h3&gt;
&lt;p&gt;John Kindervag, then a principal analyst at Forrester Research, gave the model its marketable name in a September 2010 report titled &quot;No More Chewy Centers: Introducing the Zero Trust Model of Information Security&quot; [@kindervag-2010-zero-trust]. Three tenets: all resources are accessed securely regardless of location; access control is on strict need-to-know and strictly enforced; all traffic is inspected and logged.&lt;/p&gt;
&lt;p&gt;The label stuck. Microsoft Learn now calls CA &quot;Microsoft&apos;s Zero Trust policy engine&quot; in its first sentence [@ms-ca-overview]. The lineage from Kindervag&apos;s 14-page Forrester report to that sentence is direct.&lt;/p&gt;
&lt;p&gt;The original Kindervag PDF is gated behind Forrester&apos;s paywall. The widely cited copy on &lt;code&gt;ndm.net&lt;/code&gt; redirects to an unrelated managed-IT-services company; the only reliably accessible mirror is the Wayback Machine snapshot. Treat the lineage as well documented and the URL as a curiosity of how academic ideas survive the open web.&lt;/p&gt;
&lt;h3&gt;BeyondCorp: the alternative&lt;/h3&gt;
&lt;p&gt;In December 2014, Rory Ward and Betsy Beyer published &quot;BeyondCorp: A New Approach to Enterprise Security&quot; in USENIX &lt;code&gt;;login:&lt;/code&gt; [@ward-beyer-2014-beyondcorp]. The paper described Google&apos;s internal Zero Trust deployment: every request authenticated and authorized by an access proxy, no implicit network trust, device inventory and user identity as the inputs to access decisions. A follow-up in 2016 documented the production rollout [@osborn-2016-beyondcorp].&lt;/p&gt;
&lt;p&gt;This is the architectural fork Section 7 returns to. BeyondCorp puts the policy engine in the data path, as a reverse proxy that sees every HTTP request. CA puts the policy engine at &lt;em&gt;token issuance&lt;/em&gt; and re-evaluates via &lt;em&gt;claims challenges&lt;/em&gt;. Both work. They are not interchangeable.&lt;/p&gt;
&lt;h3&gt;NIST SP 800-207: the vocabulary&lt;/h3&gt;
&lt;p&gt;In August 2020, NIST published Special Publication 800-207, &lt;em&gt;Zero Trust Architecture&lt;/em&gt; [@nist-sp-800-207-2020]. It codified the U.S. federal reference architecture: a Policy Engine that decides, a Policy Administrator that effects the decision, and a Policy Enforcement Point that intercepts the access.&lt;/p&gt;
&lt;p&gt;That trio is the vocabulary the Microsoft Learn CA documentation now uses. In the SP 800-207 mapping, Conditional Access is the Policy Engine and Policy Administrator; Exchange Online, SharePoint Online, Teams, and Microsoft Graph are the Policy Enforcement Points; Entra ID Protection is the trust algorithm that feeds the Policy Engine.&lt;/p&gt;

If you ever have to map Conditional Access to SP 800-207 for a compliance review, the cleanest correspondences are: PE = the CA evaluator inside Entra; PA = Entra&apos;s token issuer (because the decision is effected by issuing or refusing a token); PEP = the resource API (Exchange, SharePoint, Graph) that validates the token, plus, for CAE-aware resources, the same API enforcing claims-challenge revocation mid-session. ID Protection is the &quot;trust algorithm&quot; input to the PE.
&lt;p&gt;The doctrine was settled by 2020. But Microsoft had already been trying to build a perimeter on identity for six years, starting in 2014 with a much smaller idea.&lt;/p&gt;
&lt;h2&gt;3. Per-user MFA and the limits of binary controls&lt;/h2&gt;
&lt;p&gt;In 2014, Microsoft&apos;s only cloud-era access control was a per-user toggle that said &lt;em&gt;MFA: yes&lt;/em&gt; or &lt;em&gt;MFA: no&lt;/em&gt;. The toggle worked. It was a real improvement over passwords alone. It also produced the most exploited security failure of the next decade: MFA fatigue [@weinert-2023-managed-policies].&lt;/p&gt;
&lt;p&gt;How does a control improve security &lt;em&gt;and&lt;/em&gt; create a new attack class at the same time?&lt;/p&gt;
&lt;h3&gt;The per-user MFA state machine&lt;/h3&gt;
&lt;p&gt;Per-user MFA lives on the user object as a tri-state: &lt;code&gt;Disabled&lt;/code&gt;, &lt;code&gt;Enabled&lt;/code&gt;, or &lt;code&gt;Enforced&lt;/code&gt;. Microsoft Learn now says the quiet part out loud: &quot;The best way to protect users with Microsoft Entra MFA is to create a Conditional Access policy&quot; and &quot;Don&apos;t enable or enforce per-user Microsoft Entra multifactor authentication if you use Conditional Access policies&quot; [@ms-howto-mfa-userstates]. That guidance carries a generation of operational pain inside it. Mixing the two surfaces, in practice, produces unpredictable prompts: a CA policy says &quot;no MFA required for this location,&quot; the per-user state says &quot;always MFA,&quot; and the user gets prompted twice.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Microsoft&apos;s explicit guidance is to pick one surface. If you have Entra ID P1 or higher, use Conditional Access. The per-user state should remain &lt;code&gt;Disabled&lt;/code&gt; for those accounts. Mixed configurations produce both false-positive prompts and, occasionally, false-negative skips [@ms-howto-mfa-userstates].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Trusted IP rules: one-dimensional context&lt;/h3&gt;
&lt;p&gt;Office 365 added a second knob in the same era: &quot;trusted IPs.&quot; Sign-ins from a configured public IP range would skip the MFA challenge [@ms-ca-network]. The idea was that &quot;on the corporate network&quot; meant &quot;more trustworthy.&quot; This was reasonable in 2014. By 2017, it was already eroded by full-tunnel VPNs (every employee egresses through the corporate /16 from home), split-tunnel VPNs (some traffic does, some does not), and the realisation that &quot;corporate network&quot; had stopped being a useful synonym for &quot;trusted.&quot; Trusted IP is one-dimensional context, and one dimension was not enough.&lt;/p&gt;
&lt;h3&gt;Security Defaults: the Free-SKU descendant&lt;/h3&gt;
&lt;p&gt;Since 22 October 2019, every new Entra ID tenant has Security Defaults turned on by default at creation [@ms-security-defaults]. Security Defaults is a tenant-wide on/off switch that requires MFA for all admin roles, MFA for users when they show risk, blocks legacy authentication, and forces MFA registration. Microsoft&apos;s number on the impact is striking: &quot;more than 99.9% of those common identity-related attacks are stopped by using multifactor authentication and blocking legacy authentication&quot; [@ms-security-defaults].&lt;/p&gt;
&lt;p&gt;For Entra ID Free tenants in 2026, Security Defaults is still the only available baseline. There is no per-app policy, no per-risk gating, no Conditional Access. This is the licensing reality Section 10 returns to.&lt;/p&gt;
&lt;p&gt;Active Directory Federation Services -- AD FS -- is the on-prem federation product that ran the access-control story before any of this. It is still operational in many tenants. It is no longer Microsoft&apos;s strategic identity provider; the Microsoft Learn AD FS overview now opens with the explicit guidance &quot;Instead of upgrading to the latest version of AD FS, Microsoft highly recommends migrating to Microsoft Entra ID&quot; [@ms-ad-fs-overview]. AD FS claim rules functioned as a kind of policy engine, but they evaluated only at federation time and they had no concept of risk.&lt;/p&gt;
&lt;h3&gt;The four failure modes of the binary toggle&lt;/h3&gt;
&lt;p&gt;The first-generation controls -- per-user MFA, trusted IPs, Security Defaults -- share four documented limits:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;No expression of context.&lt;/strong&gt; The toggle is either on or off. It cannot say &quot;MFA from a new country but not from the office.&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trusted IP is thin context.&lt;/strong&gt; A public IP range is one bit of information; modern attacks include matching network egress.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No per-app policy.&lt;/strong&gt; The toggle applies to all apps the user accesses. You cannot say &quot;MFA for the admin portal, not for Outlook.&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No exclusion semantics for break-glass accounts.&lt;/strong&gt; Emergency-access accounts need to be reachable when everything else has failed. The binary toggle either includes them or excludes them; it does not let you say &quot;exclude these accounts but log every sign-in as a high-priority alert.&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;MFA fatigue: when a control becomes a credential&lt;/h3&gt;
&lt;p&gt;The canonical failure of the binary toggle is push-bombing. The attacker has the password. The system requires MFA. The user gets four &quot;approve sign-in?&quot; notifications during a morning meeting. One gets a thumbs-up by reflex. The system did exactly what it was configured to do.&lt;/p&gt;
&lt;p&gt;The attack works because the control has no concept of &lt;em&gt;whether this is a normal sign-in&lt;/em&gt;. The same flow runs whether the request originates from the user&apos;s office WiFi or an anonymizing proxy in another country. The MFA challenge carries no risk-weighted information; the user has no signal that this prompt is different from yesterday&apos;s prompt. Fatigue is the consequence. Microsoft&apos;s own Entra blog catalogued the attack pattern and the operational mitigations in the wake of the 2022 incident cluster [@ms-techcom-mfa-fatigue].&lt;/p&gt;

Focusing on password rules, rather than things that can really help -- like multi-factor authentication (MFA), or great threat detection -- is just a distraction. -- Alex Weinert, Microsoft Identity, July 2019 [@weinert-2019-password]
&lt;p&gt;Weinert&apos;s 2019 piece is now infamous in the identity community for its title alone -- &quot;Your Pa$$word doesn&apos;t matter.&quot; The argument was that a password&apos;s composition rules carry no information that helps the system tell a real user from an attacker; what does carry information is &lt;em&gt;context&lt;/em&gt;. The system needed a place to put that context.&lt;/p&gt;
&lt;p&gt;If &lt;em&gt;MFA yes/no&lt;/em&gt; cannot express context, the next step is obvious: make context the input. But to make context the input, the system needs a place to &lt;em&gt;put&lt;/em&gt; it. The history of CA from 2015 forward is the history of giving context a home.&lt;/p&gt;
&lt;h2&gt;4. Generation by generation&lt;/h2&gt;
&lt;p&gt;The next eight years produced six generations of access control, each one closing a specific failure of the previous one. They look like product launches in a marketing chronology. They are something more interesting: a sequence of negative results, each followed by a positive engineering response.&lt;/p&gt;

timeline
    title Conditional Access timeline
    2014 : Gen 1 per-user MFA and trusted IPs
    2015 : CA enters public preview
    2016 : Gen 2 Conditional Access general availability
    2016 : ID Protection enters preview
    2018 : Gen 3 risk-based CA conditions broadly available
    2020 : CAE enters preview
    2022 : Gen 4 Continuous Access Evaluation general availability
    2023 : Gen 5 CA for workload identities
    2023 : Gen 6 Microsoft-managed policies and Authentication Strengths
    2026 : CA for AI agent identities
&lt;p&gt;The 2026 milestone -- Conditional Access for AI agent identities -- is itself still emerging; Microsoft&apos;s current framing in the Conditional Access Optimization Agent announcement names it explicitly as a frontier rather than a finished generation [@ms-techcom-ca-optimization-agent]. Section 9.1 returns to the open problems.&lt;/p&gt;
&lt;h3&gt;Gen 1 (2014 to 2016): per-user MFA&lt;/h3&gt;
&lt;p&gt;Documented in Section 3. The control has no concept of context. The failure motivates Gen 2.&lt;/p&gt;
&lt;h3&gt;Gen 2 (September 2016 GA): Conditional Access with static rules&lt;/h3&gt;
&lt;p&gt;The September 27, 2016 CloudBlogs post announcing CA general availability framed it as &quot;Protect your data at the front door&quot; -- the &quot;front door&quot; framing that Microsoft documentation still uses [@ms-techcom-ca-frontdoor-2016]. The policy schema (users + cloud apps + conditions to grants) was introduced in the 2015 preview [@ms-techcom-ca-preview-2015] and survived essentially unchanged into 2016 GA.&lt;/p&gt;
&lt;p&gt;Gen 2 closed Gen 1&apos;s failure mode: context now had a home. A policy could match on network location, on the app being accessed, on the user&apos;s group membership, on the device platform. It could express &quot;block country X&quot; or &quot;require MFA when not on the corporate network.&quot;&lt;/p&gt;
&lt;p&gt;The remaining documented limit: no risk feed. The engine could express &lt;em&gt;what to check for&lt;/em&gt; but not &lt;em&gt;whether this specific sign-in looks suspicious&lt;/em&gt;. A policy could block credential-stuffing attempts only if you happened to know in advance which IPs to deny. Motivated Gen 3.&lt;/p&gt;
&lt;h3&gt;Gen 3 (2017 to 2018): risk-based fusion&lt;/h3&gt;
&lt;p&gt;Identity Protection had been generating risk signals since its March 2016 preview. Through 2017 and 2018, two new condition keys appeared in the CA policy schema: &lt;code&gt;signInRiskLevels&lt;/code&gt; and &lt;code&gt;userRiskLevels&lt;/code&gt;. Both take values from the set &lt;code&gt;low&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, &lt;code&gt;high&lt;/code&gt;. The risk feed plugged into the policy plane through exactly two keys. The legacy ID-Protection-side risk policies (which were a parallel policy surface inside ID Protection itself) are now retiring on 1 October 2026; the canonical surface is CA [@ms-id-protection-policies].&lt;/p&gt;
&lt;p&gt;The remaining limit: pre-issuance only. The CA evaluator runs at sign-in time. Once a token is issued, the policy plane has no way to undo the decision until the token expires. Microsoft&apos;s own retrospective is honest about what they tried first: &quot;Microsoft experimented with the &apos;blunt object&apos; approach of reduced token lifetimes but found they degrade user experiences and reliability without eliminating risks&quot; [@ms-cae-concept]. A one-hour token cuts the worst-case revocation latency to an hour, but it also means a user with intermittent connectivity gets prompted every hour, and a mobile app with retry storms can hammer the IdP. The trade-off was unacceptable. Motivated Gen 4.&lt;/p&gt;
&lt;h3&gt;Gen 4 (January 2022 GA): Continuous Access Evaluation&lt;/h3&gt;
&lt;p&gt;CAE inverted the trade-off. Instead of shortening the token, lengthen it -- up to 28 hours [@ms-cae-concept]. Then add a side channel: when a critical event fires (account disabled, password reset, high user risk, IP location change), the resource API issues an &lt;code&gt;HTTP 401&lt;/code&gt; with a &lt;code&gt;WWW-Authenticate&lt;/code&gt; claims challenge, and the client replays to Entra for a fresh token. Latency on the side channel is bounded: &quot;up to 15 minutes&quot; for non-IP events, &quot;instant&quot; for IP locations [@ms-cae-concept]. CAE was tied to an emerging open standard from day one, the OpenID Continuous Access Evaluation Profile [@ms-cae-concept]. The general-availability announcement landed on 10 January 2022 [@ms-techcom-cae-ga-2022].&lt;/p&gt;
&lt;p&gt;Remaining limit: applies to humans only. Service principals do not consume CAE-aware client libraries; they cannot perform a claims challenge. Motivated Gen 5.&lt;/p&gt;
&lt;h3&gt;Gen 5 (2023 GA): Conditional Access for workload identities&lt;/h3&gt;
&lt;p&gt;Same engine, constrained grant set. The Microsoft Learn page is blunt on the boundaries: &quot;Workload Identities Premium licenses are required&quot; and the constraint set is unusual -- &quot;Policy can be applied to single tenant service principals that are registered in your tenant. Microsoft and third-party SaaS applications, including multitenant apps, are not covered by these policies. Managed identities aren&apos;t covered by policy&quot; and &quot;Under Grant, Block access is the only available option&quot; [@ms-workload-identity-ca]. The public preview of CA filters for workload identities opened on 26 October 2022 [@vansurksum-2022-workload-ca]; the Microsoft Entra Workload Identities standalone product followed in late November 2022, and the Conditional Access feature for workload identities itself reached general availability later in 2023.&lt;/p&gt;
&lt;p&gt;The single-tenant restriction is a structural choice. Multi-tenant SaaS apps appear in many tenants&apos; service principal directories at once; policy scoping on them would require a cross-tenant resolution protocol the engine does not have. Managed identities are excluded because they belong to Azure subscriptions, not to user identity, and Microsoft has chosen not to extend the surface there. Group assignments do not work either: &quot;Conditional Access policies assigned to a group that contains a service principal are not enforced for that service principal&quot; [@ms-workload-identity-ca].&lt;/p&gt;
&lt;p&gt;Remaining limit: under-configured in most tenants because the grant taxonomy is so narrow that admins do not see immediate value. Motivated Gen 6.&lt;/p&gt;
&lt;h3&gt;Gen 6 (November 2023 onwards): Microsoft-managed policies and Authentication Strengths&lt;/h3&gt;
&lt;p&gt;In November 2023, Alex Weinert announced Microsoft-managed Conditional Access policies: a set of baselines that Microsoft would auto-deploy into tenants in Report-only mode and then auto-enable after a waiting period [@weinert-2023-managed-policies]. The launch announcement specified a 90-day window [@helpnet-2023-microsoft-entra-policies]. The current Microsoft Learn documentation specifies &quot;Microsoft enables these policies no less than 45 days after they&apos;re introduced in your tenant if they&apos;re left in the Report-only state&quot; with a 28-day pre-enablement notification [@ms-managed-policies].&lt;/p&gt;
&lt;p&gt;The window shrank deliberately. The 90-day window in the 2023 launch announcement was a calibration window; the 45-day window in current documentation is the post-calibration setting. Both numbers are correct in their respective time frames. The article uses the current number throughout.&lt;/p&gt;
&lt;p&gt;Parallel to the managed policies, Microsoft shipped &lt;em&gt;Authentication Strengths&lt;/em&gt; -- a named bundle of acceptable authentication methods that can be required as a grant. The three built-in strengths are &lt;em&gt;MFA strength&lt;/em&gt;, &lt;em&gt;Passwordless MFA strength&lt;/em&gt;, and &lt;em&gt;Phishing-resistant MFA strength&lt;/em&gt; (FIDO2 security key, &lt;a href=&quot;https://paragmali.com/blog/your-face-is-not-your-password-inside-windows-hellos-hardwar/&quot; rel=&quot;noopener&quot;&gt;Windows Hello for Business&lt;/a&gt;, multifactor certificate-based authentication) [@ms-auth-strengths]. The phishing-resistant strength is the modern way to express &quot;no adversary-in-the-middle phishing kit should be able to defeat this grant.&quot;&lt;/p&gt;
&lt;h3&gt;The pattern: extension, not replacement&lt;/h3&gt;
&lt;p&gt;From Gen 3 onward, each generation &lt;em&gt;extends&lt;/em&gt; the prior schema rather than replacing it. The &lt;code&gt;conditionalAccessPolicy&lt;/code&gt; JSON shape that shipped in 2016 still drives the engine in 2026 -- with new condition keys added, new grant types added, new session controls added. By the standards of cloud control surfaces, that is a long run without a rewrite.&lt;/p&gt;
&lt;p&gt;The reason is the architectural decision the next section is about.&lt;/p&gt;
&lt;h2&gt;5. The two-plane separation&lt;/h2&gt;
&lt;p&gt;The breakthrough is not a model, not a token format, not a wire protocol. It is a &lt;em&gt;separation&lt;/em&gt;: the &lt;strong&gt;signal plane&lt;/strong&gt; that produces risk detections from the &lt;strong&gt;policy plane&lt;/strong&gt; that consumes them.&lt;/p&gt;
&lt;p&gt;Stated like that, it sounds banal. Read it the other direction -- a policy engine whose risk model can change without changing the policy semantics, and whose policy can change without retraining the model -- and it is the design that makes the system maintainable at trillions of daily signals across hundreds of thousands of tenants.&lt;/p&gt;
&lt;h3&gt;The two planes, precisely&lt;/h3&gt;
&lt;p&gt;The signal plane is Microsoft Entra ID Protection. It runs detection logic on every interactive sign-in (and, for offline detections, on historical sign-ins) and emits a &lt;code&gt;riskDetection&lt;/code&gt; resource into a per-tenant log on Microsoft Graph at &lt;code&gt;/identityProtection/riskDetections&lt;/code&gt;. Each detection carries five fields you care about: &lt;code&gt;riskEventType&lt;/code&gt; (one of about two dozen named detection types like &lt;code&gt;anonymizedIPAddress&lt;/code&gt;, &lt;code&gt;leakedCredentials&lt;/code&gt;, &lt;code&gt;unlikelyTravel&lt;/code&gt;), &lt;code&gt;riskLevel&lt;/code&gt; (&lt;code&gt;low&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, &lt;code&gt;high&lt;/code&gt;, plus the bookkeeping values &lt;code&gt;hidden&lt;/code&gt; and &lt;code&gt;none&lt;/code&gt;), &lt;code&gt;riskState&lt;/code&gt; (&lt;code&gt;atRisk&lt;/code&gt;, &lt;code&gt;confirmedCompromised&lt;/code&gt;, &lt;code&gt;dismissed&lt;/code&gt;, &lt;code&gt;remediated&lt;/code&gt;), &lt;code&gt;detectionTimingType&lt;/code&gt; (&lt;code&gt;realtime&lt;/code&gt;, &lt;code&gt;nearRealtime&lt;/code&gt;, &lt;code&gt;offline&lt;/code&gt;), and &lt;code&gt;additionalInfo&lt;/code&gt; (a JSON blob with user-agent, IP, alert URL, reason codes) [@ms-graph-riskdetection][@ms-id-protection-risks].&lt;/p&gt;
&lt;p&gt;The policy plane is Conditional Access. It is a JSON object at &lt;code&gt;/identity/conditionalAccess/policies/{id}&lt;/code&gt; on the Graph API [@ms-graph-capolicy]. Each policy has &lt;code&gt;displayName&lt;/code&gt;, &lt;code&gt;state&lt;/code&gt; (&lt;code&gt;enabled&lt;/code&gt;, &lt;code&gt;disabled&lt;/code&gt;, &lt;code&gt;enabledForReportingButNotEnforced&lt;/code&gt;), &lt;code&gt;conditions&lt;/code&gt;, &lt;code&gt;grantControls&lt;/code&gt;, and &lt;code&gt;sessionControls&lt;/code&gt;. The conditions block contains the per-policy targeting: which users, which apps, which platforms, which network locations -- and two condition keys named &lt;code&gt;signInRiskLevels&lt;/code&gt; and &lt;code&gt;userRiskLevels&lt;/code&gt;.&lt;/p&gt;

**Sign-in risk** is a per-sign-in probability that the credential being used is being used by someone other than the legitimate owner *at this moment*. **User risk** is a per-user probability that the account itself has been compromised over its recent history. A user with leaked credentials in a breach corpus carries persistent user risk until the password is reset; a user signing in from an anonymizing proxy carries sign-in risk for that session. CA policies can match on either, both, or neither. Risk-based conditions require Entra ID P2 [@ms-id-protection-policies].
&lt;p&gt;Those two condition keys -- &lt;code&gt;signInRiskLevels&lt;/code&gt; and &lt;code&gt;userRiskLevels&lt;/code&gt; -- are the entire API surface between the signal plane and the policy plane. Everything else about ID Protection is hidden behind them. The policy plane does not know whether &lt;code&gt;high&lt;/code&gt; came from a transformer or a logistic regression or a hardcoded rule. The signal plane does not know which policies will read its output. The contract is two strings.&lt;/p&gt;

flowchart LR
    subgraph SP[Signal plane Entra ID Protection]
        DET[Detection pipeline]
        RD[(riskDetection log)]
        RL[Risk level low medium high]
    end
    subgraph PP[Policy plane Conditional Access]
        EV[Policy evaluator]
        POL[(conditionalAccessPolicy JSON)]
        TOK[Token issuer]
    end
    subgraph SES[Session plane CAE]
        CH[Critical event channel]
        RP[Resource API]
    end
    DET --&amp;gt; RD
    DET --&amp;gt; RL
    RL -. signInRiskLevels userRiskLevels .-&amp;gt; EV
    POL --&amp;gt; EV
    EV --&amp;gt; TOK
    TOK -- access token --&amp;gt; RP
    DET -. user risk events .-&amp;gt; CH
    CH -. 401 insufficient claims .-&amp;gt; RP
&lt;h3&gt;Why the separation matters&lt;/h3&gt;
&lt;p&gt;Three concrete consequences fall out of the design:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The risk model is re-trainable without policy rewrites.&lt;/strong&gt; Microsoft&apos;s ID Protection team can change the underlying detection algorithm tomorrow. Add a new &lt;code&gt;riskEventType&lt;/code&gt;. Replace the classifier for &lt;code&gt;unlikelyTravel&lt;/code&gt;. Re-tune the threshold that maps a score to &lt;code&gt;low&lt;/code&gt;/&lt;code&gt;medium&lt;/code&gt;/&lt;code&gt;high&lt;/code&gt;. None of these require tenants to rewrite their CA policies, because policies match on the &lt;em&gt;level&lt;/em&gt;, not the &lt;em&gt;signal&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tenants without the licence simply do not use the risk conditions.&lt;/strong&gt; An Entra ID P1 tenant can deploy CA policies that match on users, apps, locations, devices, client apps, and platforms. P2 unlocks the risk conditions. The schema accommodates both: P1 policies just leave the risk arrays empty. There is no parallel policy surface for the non-risk-aware tenants; they use the same engine.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CAE is a third plane layered onto the same skeleton.&lt;/strong&gt; Continuous Access Evaluation did not require redesign of the policy plane. The CAE channel is a new &lt;em&gt;event delivery&lt;/em&gt; mechanism; the events it propagates are things the signal plane already knew about (high user risk, password reset, account disabled) plus new ones the policy plane introduced (network-location-policy changed). The architecture absorbed CAE because the design was already a separation of concerns.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The signal plane and the policy plane are separable; the contract between them is &lt;em&gt;two condition keys&lt;/em&gt; (&lt;code&gt;signInRiskLevels&lt;/code&gt; and &lt;code&gt;userRiskLevels&lt;/code&gt;). That is what makes the system maintainable across a decade of evolution.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;The &quot;pit of success&quot; framing&lt;/h3&gt;
&lt;p&gt;Alex Weinert calls this the &quot;pit of success.&quot; His November 2023 piece on Microsoft-managed policies put the metric on it: a decade ago Microsoft turned on a &quot;radical&quot; tenant-wide policy requiring MFA for every consumer Microsoft account, and &quot;today, 100 percent of consumer Microsoft accounts older than 60 days have multifactor authentication&quot; [@weinert-2023-managed-policies].&lt;/p&gt;
&lt;p&gt;The 100 percent number is achievable because the policy plane and the signal plane can each evolve independently. Microsoft can ship a managed policy that says &quot;require MFA for high-risk sign-ins&quot; without committing to a fixed definition of &quot;high risk.&quot; The definition lives on the signal plane and changes weekly. The policy lives on the policy plane and is stable for years.&lt;/p&gt;
&lt;p&gt;With the separation as the spine, the next section walks the end-to-end pipeline in one continuous trace, from signal to grant to token to session, on a real sign-in -- the trace no public Microsoft document assembles in one place.&lt;/p&gt;
&lt;h2&gt;6. The end-to-end pipeline&lt;/h2&gt;
&lt;p&gt;Take Alice&apos;s Tuesday morning from Section 1 and walk it forward. This section has six subsections. By the end of them, the question &quot;who decided?&quot; has six independently sourced answers and one combined picture.&lt;/p&gt;
&lt;h3&gt;6.1 What the signal plane sees&lt;/h3&gt;
&lt;p&gt;Identity Protection&apos;s detection taxonomy splits into five rough groups, based on what kind of information triggered the detection. The canonical taxonomy is the Microsoft Learn page on risk types [@ms-id-protection-risks]; the wire-format enum on the Graph schema is at [@ms-graph-riskdetection].&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Network signals.&lt;/em&gt; &lt;code&gt;anonymizedIPAddress&lt;/code&gt;, &lt;code&gt;maliciousIPAddress&lt;/code&gt;, &lt;code&gt;nationStateIP&lt;/code&gt;, &lt;code&gt;riskyIPAddress&lt;/code&gt;. The signal is the source IP and reputation databases that ID Protection ingests.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Behavioural signals.&lt;/em&gt; &lt;code&gt;unlikelyTravel&lt;/code&gt;, &lt;code&gt;mcasImpossibleTravel&lt;/code&gt;, &lt;code&gt;newCountry&lt;/code&gt;, &lt;code&gt;unfamiliarFeatures&lt;/code&gt;, &lt;code&gt;anomalousUserActivity&lt;/code&gt;. The signal is a deviation from the tenant&apos;s or the user&apos;s historical baseline.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Credential signals.&lt;/em&gt; &lt;code&gt;leakedCredentials&lt;/code&gt;, &lt;code&gt;passwordSpray&lt;/code&gt;. The signal is a match against a corpus of breached credentials or a velocity-based pattern across tenants.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Token and session signals.&lt;/em&gt; &lt;code&gt;anomalousToken&lt;/code&gt;, &lt;code&gt;tokenIssuerAnomaly&lt;/code&gt;, &lt;code&gt;attemptedPrtAccess&lt;/code&gt;, &lt;code&gt;attackerinTheMiddle&lt;/code&gt;, &lt;code&gt;authenticatorPhishing&lt;/code&gt;. The signal is on the token itself or on the way the authenticator flow ran.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Inbox behaviour.&lt;/em&gt; &lt;code&gt;suspiciousInboxForwarding&lt;/code&gt;, &lt;code&gt;mcasSuspiciousInboxManipulationRules&lt;/code&gt;. The signal is on what happened &lt;em&gt;after&lt;/em&gt; the sign-in -- a post-compromise indicator that retroactively flags the sign-in that enabled it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each detection is also tagged with a timing: real-time, near-real-time, or offline. Microsoft Learn is precise about the latencies: &quot;Detections triggered in real-time take 5-10 minutes to surface details in the reports. Offline detections take up to 48 hours&quot; [@ms-risk-detection-types].&lt;/p&gt;
&lt;p&gt;The detection is mapped to a risk &lt;em&gt;level&lt;/em&gt;, not a probability. Microsoft Learn calls the level &quot;calculated by our machine learning algorithms&quot; and explicitly notes the meaning: low/medium/high &quot;represent how confident Microsoft is that one or more of the user&apos;s credentials are known by an unauthorized entity&quot; [@ms-risk-detection-types].&quot;Confidence&quot; here is meant in the everyday sense, not the strict statistical sense of a confidence interval. Microsoft has not published a calibration study that would let you map a &quot;high&quot; risk level to a frequentist probability of compromise.&lt;/p&gt;
&lt;p&gt;The figure you sometimes see in Microsoft marketing materials -- &quot;more than 100 trillion signals processed per day&quot; [@ms-managed-policies], or, in older sources, &quot;78 trillion&quot; [@ms-id-protection-overview] -- is the &lt;em&gt;aggregate signal volume across all tenants and product surfaces&lt;/em&gt;, not per-sign-in features per user. The article keeps the two carefully separate.&lt;/p&gt;
&lt;p&gt;Microsoft has not publicly disclosed the production model architecture, the feature vector size, or per-detection precision and recall. The 2021 Microsoft Security Blog interview with Maria Puertas Calvo describes the existence of the ML team and the operational scale (&quot;hundreds of terabytes every day&quot;) but stops well short of architecture details [@ms-puertas-calvo-interview]. The model class is publicly unspecified; the taxonomy and the operating output are both public.&lt;/p&gt;
&lt;h3&gt;6.2 How risk surfaces&lt;/h3&gt;
&lt;p&gt;Two parallel logs matter for risk. The Sign-in log is the universe: every interactive and non-interactive sign-in produces an entry. The &lt;code&gt;riskDetections&lt;/code&gt; log is the &lt;em&gt;sparse overlay&lt;/em&gt;: a &lt;code&gt;riskDetection&lt;/code&gt; is emitted only when a detection fires for the sign-in. Most sign-ins produce a Sign-in log entry with no corresponding &lt;code&gt;riskDetection&lt;/code&gt;. Only flagged sign-ins do [@ms-graph-riskdetection].&lt;/p&gt;
&lt;p&gt;This is a common source of confusion. It is tempting to assume &quot;ID Protection scored every sign-in,&quot; and in a sense it did -- the detectors ran -- but the &lt;em&gt;durable artefact&lt;/em&gt; exists only when at least one detector fired. To compute a per-sign-in distribution of risk you need to &lt;em&gt;join&lt;/em&gt; the Sign-in log with the riskDetections log and treat the unjoined rows as &quot;no risk flagged at the moment of issuance.&quot;&lt;/p&gt;
&lt;p&gt;There is one more wrinkle. The detection taxonomy on the Microsoft Learn concept page and the &lt;code&gt;riskEventType&lt;/code&gt; enum on the Graph schema are not perfectly aligned. The concept page lists &lt;code&gt;mcasImpossibleTravel&lt;/code&gt; and &lt;code&gt;authenticatorPhishing&lt;/code&gt; as named detection types; the Graph enum lists &lt;code&gt;impossibleTravel&lt;/code&gt; (without the &lt;code&gt;mcas&lt;/code&gt; prefix). The two surfaces sometimes use different value names for the same logical detection -- a UI display string versus a Graph enum value. Detection engineers writing KQL against the Sign-in logs should account for both.&lt;/p&gt;
&lt;h3&gt;6.3 How CA consumes risk&lt;/h3&gt;
&lt;p&gt;Conditional Access evaluation runs in a fixed order: assignments are checked first (does this sign-in match this policy at all?), then conditions (do all the condition predicates hold?), then grants (which controls are demanded?), then session controls (which token lifetime, sign-in frequency, persistent browser).&lt;/p&gt;
&lt;p&gt;The key semantic, repeated across the Microsoft Learn documentation: a &lt;em&gt;block&lt;/em&gt; grant in any policy matching the sign-in overrides any allow grant in any other policy. The policy plane is not just additive; it has an explicit precedence rule.&lt;/p&gt;

flowchart TD
    A[Sign-in request] --&amp;gt; B[First-factor auth]
    B --&amp;gt; C[Enumerate matching policies]
    C --&amp;gt; D{Any policy matches?}
    D -- No --&amp;gt; E[Default allow with token]
    D -- Yes --&amp;gt; F[Evaluate conditions per policy]
    F --&amp;gt; G{Block grant in any match?}
    G -- Yes --&amp;gt; H[Deny access return error]
    G -- No --&amp;gt; I[Aggregate required grants]
    I --&amp;gt; J{All grants satisfied?}
    J -- No --&amp;gt; K[Issue challenge MFA or device]
    J -- Yes --&amp;gt; L[Apply session controls]
    L --&amp;gt; M[Issue access token]
&lt;p&gt;The pseudocode below is a compressed restatement of that flow. It is not Microsoft source code; it is the algorithmic shape an admin should keep in their head when reading a policy or debugging a sign-in.&lt;/p&gt;
&lt;p&gt;{`
function evaluate(signin) {
  const matching = allPolicies.filter(p =&amp;gt;
    p.state !== &apos;disabled&apos; &amp;amp;&amp;amp;
    matchesAssignments(p.conditions, signin) &amp;amp;&amp;amp;
    matchesConditions(p.conditions, signin)
  );&lt;/p&gt;
&lt;p&gt;  // Block precedence: any block grant wins
  if (matching.some(p =&amp;gt; p.grantControls.builtInControls.includes(&apos;block&apos;))) {
    return { decision: &apos;DENY&apos;, reason: &apos;block grant matched&apos; };
  }&lt;/p&gt;
&lt;p&gt;  // Aggregate required grants across matching policies
  const requiredGrants = new Set();
  for (const p of matching) {
    for (const g of p.grantControls.builtInControls) requiredGrants.add(g);
    if (p.grantControls.authenticationStrength) {
      requiredGrants.add(&apos;authStrength:&apos; + p.grantControls.authenticationStrength.id);
    }
  }&lt;/p&gt;
&lt;p&gt;  const satisfied = [...requiredGrants].every(g =&amp;gt; signin.satisfies(g));
  if (!satisfied) {
    return { decision: &apos;CHALLENGE&apos;, missing: [...requiredGrants].filter(g =&amp;gt; !signin.satisfies(g)) };
  }&lt;/p&gt;
&lt;p&gt;  // Apply session controls (token lifetime, sign-in frequency, persistent browser)
  const session = mergeSessionControls(matching.map(p =&amp;gt; p.sessionControls));
  return { decision: &apos;ALLOW&apos;, session };
}&lt;/p&gt;
&lt;p&gt;const result = evaluate({
  user: &apos;&lt;a href=&quot;mailto:alice@contoso.com&quot; rel=&quot;noopener&quot;&gt;alice@contoso.com&lt;/a&gt;&apos;,
  app: &apos;Office365 Exchange Online&apos;,
  location: { ip: &apos;203.0.113.42&apos;, country: &apos;PT&apos; },
  device: { compliant: true, joinType: &apos;Entra&apos; },
  signInRisk: &apos;low&apos;,
  userRisk: &apos;none&apos;,
  satisfies(grant) {
    const mfa = [&apos;mfa&apos;, &apos;authStrength:phishingResistantMfa&apos;];
    return mfa.includes(grant) || grant === &apos;compliantDevice&apos;;
  },
});
console.log(JSON.stringify(result, null, 2));
`}&lt;/p&gt;
&lt;p&gt;Risk-based conditions require Entra ID P2 [@ms-id-protection-overview]. Without that licence, the &lt;code&gt;signInRiskLevels&lt;/code&gt; and &lt;code&gt;userRiskLevels&lt;/code&gt; arrays in a policy are ignored. The rest of the engine works the same.&lt;/p&gt;
&lt;h3&gt;6.4 The grants&lt;/h3&gt;
&lt;p&gt;Each policy declares a set of grants. The grants are &lt;em&gt;additive within a policy&lt;/em&gt; (all required to satisfy the policy) but the &lt;em&gt;block grant in any matching policy&lt;/em&gt; takes precedence over allow grants in any other policy. Here are the grants currently in the schema:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Grant&lt;/th&gt;
&lt;th&gt;What it requires&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;block&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deny access.&lt;/td&gt;
&lt;td&gt;Always wins against allow grants.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mfa&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Any MFA method registered for the user.&lt;/td&gt;
&lt;td&gt;The legacy generic-MFA grant; replaced in modern deployments by Authentication Strength.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;requireAuthenticationStrength&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A named bundle of acceptable methods.&lt;/td&gt;
&lt;td&gt;The modern grant. Built-in strengths include phishing-resistant [@ms-auth-strengths].&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;compliantDevice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The device record has &lt;code&gt;isCompliant: true&lt;/code&gt;.&lt;/td&gt;
&lt;td&gt;Set by Intune or a third-party compliance partner.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;domainJoinedDevice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hybrid Azure AD joined device.&lt;/td&gt;
&lt;td&gt;Requires Entra Connect on-prem trust.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;approvedApplication&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Use an approved client app.&lt;/td&gt;
&lt;td&gt;A small allow-list of Microsoft mobile apps.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;compliantApplication&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;An app under an Intune App Protection Policy.&lt;/td&gt;
&lt;td&gt;Mobile app management.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;passwordChange&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;User must change their password.&lt;/td&gt;
&lt;td&gt;Used for password-leaked recovery.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;requireTermsOfUse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;User must accept a terms-of-use document.&lt;/td&gt;
&lt;td&gt;Used for compliance and guest scenarios.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

A named, ordered bundle of acceptable authentication methods that a CA grant can demand. The three built-in strengths are *MFA strength* (any registered second factor), *Passwordless MFA strength* (no password used), and *Phishing-resistant MFA strength* (FIDO2 security key, Windows Hello for Business or a platform credential, or multifactor certificate-based authentication) [@ms-auth-strengths]. The phishing-resistant strength is the canonical modern grant for high-value access.
&lt;p&gt;The Authentication Strength grant is where the phishing-resistance story lives in 2026. A policy that demands the phishing-resistant strength refuses to accept TOTP or SMS or push as the second factor. Only credentials with cryptographic binding to the device or hardware token will satisfy the grant. That class of credential, by construction, cannot be replayed by an adversary-in-the-middle phishing kit -- because the underlying &lt;a href=&quot;https://paragmali.com/blog/webauthn-and-passkeys-on-windows-from-ctap-to-the-credential/&quot; rel=&quot;noopener&quot;&gt;WebAuthn&lt;/a&gt; ceremony is bound to the origin of the relying party.&lt;/p&gt;
&lt;h3&gt;6.5 The Windows-side handoff&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://paragmali.com/blog/inside-the-primary-refresh-token-the-cryptographic-seam-betw/&quot; rel=&quot;noopener&quot;&gt;PRT&lt;/a&gt; issuance is an interactive sign-in. It goes through CA like any other.&lt;/p&gt;

A long-lived refresh token issued to a Windows session at user sign-in to Entra-joined or hybrid-Entra-joined devices. The PRT is bound to the device&apos;s TPM where one is available, and it grants the user single sign-on to all CA-targeted apps from that Windows session. Issuance is subject to CA evaluation; if a CA policy demands compliant device, the device must already be marked `isCompliant` before the PRT is issued.
&lt;p&gt;The compliance state lands on the device object as &lt;code&gt;isCompliant&lt;/code&gt;. Intune (or a third-party MDM through Intune&apos;s compliance-partner API) writes that field after evaluating the device against a compliance policy: disk encrypted, OS patched, antivirus running, jailbreak detection clean, and so on. CA reads it on subsequent policy evaluations. If a policy requires &lt;code&gt;compliantDevice&lt;/code&gt; and the device object says &lt;code&gt;isCompliant: false&lt;/code&gt;, the grant is not satisfied.&lt;/p&gt;
&lt;p&gt;The operational seam to on-prem Active Directory runs the other direction. &lt;a href=&quot;https://paragmali.com/blog/kerberos-in-windows-the-other-half-of-ntlmless/&quot; rel=&quot;noopener&quot;&gt;Kerberos&lt;/a&gt; and &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;NTLM&lt;/a&gt; against on-prem domain controllers never consult Entra. The Microsoft Learn CA overview is explicit: CA is a &lt;em&gt;cloud control plane&lt;/em&gt;; on-prem authentication is outside its scope [@ms-ca-overview]. This is the limit Section 8 will name precisely.&lt;/p&gt;
&lt;h3&gt;6.6 CAE in session&lt;/h3&gt;
&lt;p&gt;The third plane. Wire format lives in two Microsoft Learn pages: the claims-challenge page [@ms-claims-challenge] and the app-resilience CAE page [@ms-app-resilience-cae].&lt;/p&gt;
&lt;p&gt;A client opts in to CAE by advertising the &lt;code&gt;cp1&lt;/code&gt; capability via the &lt;code&gt;xms_cc&lt;/code&gt; claim in token requests. In MSAL, that opt-in looks like &lt;code&gt;WithClientCapabilities(new[] { &quot;cp1&quot; })&lt;/code&gt; [@ms-app-resilience-cae]. The Microsoft Learn claims-challenge page says it cleanly: &quot;The only currently known value is &lt;code&gt;cp1&lt;/code&gt;&quot; [@ms-claims-challenge].&lt;/p&gt;
&lt;p&gt;When the policy plane sees a critical event after the token was issued, the resource API responds to the next call with &lt;code&gt;HTTP 401 Unauthorized&lt;/code&gt; and a &lt;code&gt;WWW-Authenticate&lt;/code&gt; header of the shape:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer authorization_uri=&quot;&amp;lt;entra-authorize-endpoint&amp;gt;&quot;, error=&quot;insufficient_claims&quot;, claims=&quot;&amp;lt;base64-encoded JSON&amp;gt;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;claims&lt;/code&gt; value is a base64-encoded JSON object that the client passes verbatim to the token endpoint when acquiring a fresh token [@ms-claims-challenge][@ms-app-resilience-cae]. The IdP evaluates the embedded claims, runs CA again with the new context, and issues a new token (or refuses).&lt;/p&gt;

The HTTP wire format CAE uses to revoke a session mid-flight. A CAE-aware resource API returns `HTTP 401` with `WWW-Authenticate: Bearer error=&quot;insufficient_claims&quot;, claims=&quot;&quot;`. The client replays the base64 blob to Entra; Entra re-runs CA with the new context; the client receives a fresh token or a definitive refusal. The wire format is documented at [@ms-claims-challenge] and demonstrated at [@ms-app-resilience-cae].
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The CAE-aware capability is signalled by the &lt;em&gt;client&lt;/em&gt;, not by the &lt;em&gt;token&lt;/em&gt;. The client advertises &lt;code&gt;cp1&lt;/code&gt; via &lt;code&gt;xms_cc&lt;/code&gt;; the token&apos;s CAE-awareness shows up as its lifetime (up to 28 hours) and the resource API&apos;s willingness to issue a claims challenge. Folk knowledge that says &quot;look for a &lt;code&gt;cae&lt;/code&gt; claim in the JWT&quot; is incorrect.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Microsoft Learn CAE document enumerates five critical events: account disabled or deleted, password change or reset, MFA enabled by an administrator, administrator token revocation, and high user risk detected by ID Protection [@ms-cae-concept]. A parallel pathway, &lt;em&gt;Conditional Access policy evaluation&lt;/em&gt;, propagates network-location and policy changes to CAE-aware resource providers on the same channel. For IP-location changes the latency is &quot;instant&quot;; for everything else the ceiling is up to 15 minutes [@ms-cae-concept].&lt;/p&gt;

sequenceDiagram
    participant C as Client app
    participant R as Resource API CAE aware
    participant E as Entra token issuer
    participant P as ID Protection
    Note over C: Client holds long-lived CAE token
    C-&amp;gt;&amp;gt;R: GET messages with bearer token
    R-&amp;gt;&amp;gt;R: Token still cryptographically valid
    P-&amp;gt;&amp;gt;E: High user risk event for Alice
    E-&amp;gt;&amp;gt;R: Push critical event Alice high risk
    C-&amp;gt;&amp;gt;R: GET messages with bearer token again
    R-&amp;gt;&amp;gt;C: 401 WWW-Authenticate insufficient_claims claims base64
    C-&amp;gt;&amp;gt;E: Token request with claims blob and cp1 capability
    E-&amp;gt;&amp;gt;E: Re-run CA with new context
    E--&amp;gt;&amp;gt;C: New token or definitive refusal
    C-&amp;gt;&amp;gt;R: Retry with new token
&lt;p&gt;{`
// Simplified MSAL.js-shaped pseudocode for CAE opt-in and challenge handling
const ENTRA_AUTHORITY = &apos;&apos;;
const EXCHANGE_ENDPOINT = &apos;&apos;;
const MAIL_READ_SCOPE = &apos;&apos;;&lt;/p&gt;
&lt;p&gt;const msal = new PublicClientApplication({
  auth: { clientId: &apos;&apos;, authority: ENTRA_AUTHORITY },
});&lt;/p&gt;
&lt;p&gt;async function callExchange() {
  let token = await msal.acquireTokenSilent({
    scopes: [MAIL_READ_SCOPE],
    clientCapabilities: [&apos;cp1&apos;], // advertise CAE awareness
  });&lt;/p&gt;
&lt;p&gt;  let res = await fetch(EXCHANGE_ENDPOINT, {
    headers: { Authorization: &apos;Bearer &apos; + token.accessToken },
  });&lt;/p&gt;
&lt;p&gt;  if (res.status === 401) {
    const header = res.headers.get(&apos;WWW-Authenticate&apos;) || &apos;&apos;;
    const m = /claims=&quot;([^&quot;]+)&quot;/.exec(header);
    if (m) {
      // Replay the embedded claims to acquire a fresh token
      token = await msal.acquireTokenSilent({
        scopes: [MAIL_READ_SCOPE],
        claims: Buffer.from(m[1], &apos;base64&apos;).toString(&apos;utf8&apos;),
        clientCapabilities: [&apos;cp1&apos;],
      });
      res = await fetch(EXCHANGE_ENDPOINT, {
        headers: { Authorization: &apos;Bearer &apos; + token.accessToken },
      });
    }
  }&lt;/p&gt;
&lt;p&gt;  console.log(&apos;HTTP&apos;, res.status);
}&lt;/p&gt;
&lt;p&gt;callExchange();
`}&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; CAE inverts the conventional trade-off: lengthen the token, shorten the revocation. The token can live 28 hours because revocation is an event, not a clock.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The chain is now visible. The signal plane scored Alice&apos;s Tuesday sign-in. The policy plane evaluated the policies. The token issuer issued an access token (CAE-aware because Outlook advertises &lt;code&gt;cp1&lt;/code&gt;). Exchange Online accepted the token and returned mail. If, twelve minutes from now, Alice&apos;s account is flagged high risk because a different sign-in attempt fires &lt;code&gt;leakedCredentials&lt;/code&gt;, the critical event will fire, Exchange will issue a claims challenge, and Outlook will either acquire a fresh token (passing the new CA evaluation) or surface the refusal to the user.&lt;/p&gt;
&lt;p&gt;Six independent components co-decided on one access event. Microsoft is one vendor. The same problem has been solved differently by Google, Okta, AWS, Cloudflare, and Zscaler. The Microsoft answer is not the only correct answer.&lt;/p&gt;
&lt;h2&gt;7. How others do it&lt;/h2&gt;
&lt;p&gt;Microsoft chose to enforce at &lt;em&gt;token issuance and claims challenge&lt;/em&gt;. Google chose to enforce at &lt;em&gt;every HTTP request via a reverse proxy&lt;/em&gt;. AWS chose a decidable policy DSL. These are not minor variations; they are different answers to &quot;where does the policy engine live in the data path?&quot;&lt;/p&gt;
&lt;p&gt;Both Microsoft&apos;s and Google&apos;s models scale. Neither is strictly better. The choice is a function of what the enterprise already runs.&lt;/p&gt;
&lt;h3&gt;Google BeyondCorp, IAP, Chrome Enterprise Premium&lt;/h3&gt;
&lt;p&gt;Google&apos;s Identity-Aware Proxy puts the policy engine in the data path. The documentation calls it bluntly: &quot;IAP lets you establish a central authorization layer for applications accessed by HTTPS, so you can use an application-level access control model instead of relying on network-level firewalls&quot; [@google-iap]. Every HTTP request to an IAP-protected app passes through the proxy. The proxy authenticates the user (via Google Account, Workforce Identity Federation, or Identity Platform), evaluates a Common Expression Language policy against the request context, and -- on allow -- forwards the request to the backend with signed identity headers.&lt;/p&gt;
&lt;p&gt;The BeyondCorp Enterprise product (recently rebranded as Chrome Enterprise Premium) layers context-aware access on top: device posture, geographic location, time of day [@google-bce-overview]. The architecture matches the 2014 USENIX paper [@ward-beyer-2014-beyondcorp] and the 2016 production follow-up [@osborn-2016-beyondcorp].&lt;/p&gt;
&lt;p&gt;The strength is per-request authorization: every HTTP call is its own decision point. The weakness, from the M365 perspective, is that IAP does not gate Microsoft 365 first-party API traffic. The Outlook client does not route through Google&apos;s IAP; it routes through Entra and Exchange Online. For Microsoft 365 workloads, IAP is complementary at best.&lt;/p&gt;
&lt;h3&gt;Okta Identity Engine and ThreatInsight&lt;/h3&gt;
&lt;p&gt;Okta&apos;s policy engine is closer to Microsoft&apos;s structurally: the identity provider is the policy engine, app sign-on policies live on the IdP, and the resource side relies on the IdP&apos;s token rather than a per-request proxy. The Okta Identity Engine documents the rule shape: &quot;App sign-in policies define how a user must authenticate to gain access to an app. They verify ... group membership, the IP zone they&apos;re signing in from, risk level, and others&quot; [@okta-sign-on-policies]. Every new app gets a default policy with a single catch-all rule that allows access with two factors.&lt;/p&gt;
&lt;p&gt;Okta ThreatInsight is the IP-reputation feed. The documentation describes it operationally: &quot;Okta ThreatInsight aggregates data about sign-in activity across the Okta customer base to analyze and detect potentially malicious IP addresses ... password spraying, credential stuffing, brute-force cryptographic attacks&quot; [@okta-threatinsight]. The signal coverage is narrower than ID Protection: ThreatInsight is IP-centric, where ID Protection runs a multi-detection ML pipeline on tokens, sessions, behaviour, and credentials.&lt;/p&gt;
&lt;h3&gt;AWS IAM Identity Center and Verified Access&lt;/h3&gt;
&lt;p&gt;AWS splits the problem. IAM Identity Center handles workforce SSO and trusted identity propagation to AWS services [@aws-iam-identity-center]. AWS Verified Access handles per-request authorization for HTTPS-fronted apps -- the ZTNA piece. The Verified Access docs put it plainly: &quot;Verified Access evaluates each application access request in real time&quot; and &quot;verifies the trustworthiness of users and devices against a set of security requirements&quot; [@aws-verified-access].&lt;/p&gt;
&lt;p&gt;The interesting bit is the policy language: Cedar. Cedar is a deliberately decidable language for authorization policy. &quot;Decidable&quot; here is a precise term: the safety question (will some policy edit, in some future edit chain, leak this right?) is answerable by a static analyser for any Cedar policy [@cedar-security].&lt;/p&gt;
&lt;p&gt;Cedar&apos;s intentional non-Turing-completeness is the language-design hedge against the Harrison-Ruzzo-Ullman undecidability result the next section will name. The trade-off is expressiveness: Cedar cannot express arbitrary computational predicates, which is the price of being analysable [@cedar-security].&lt;/p&gt;
&lt;h3&gt;Cloudflare Access and Zscaler Private Access&lt;/h3&gt;
&lt;p&gt;Cloudflare Access is an edge proxy. Policies are deny-by-default, with four building blocks: Actions (Allow, Block, Bypass, Service Auth), Rule types (Include, Require, Exclude), Selectors, and Values [@cloudflare-access-policies]. The deny-by-default semantics are explicit: &quot;Since Access is deny by default, users who do not match a Block policy will still be denied access unless they explicitly match an Allow policy&quot; [@cloudflare-access-policies]. Cloudflare also ships a policy tester that lets administrators dry-run a policy against the existing user population [@cloudflare-access-policy-mgmt].&lt;/p&gt;
&lt;p&gt;Zscaler Private Access is a broker-based ZTNA: the user connects to a Zscaler edge node, the broker establishes a connection to the private app, and &quot;users never access the corporate network, and apps are never exposed to the public internet&quot; [@zscaler-zpa]. Zscaler&apos;s own marketing surveys put the VPN-replacement framing in numbers: &quot;91% of organizations are concerned that VPNs compromise their security&quot; and &quot;56% of organizations suffered one or more VPN-related attacks in 2023-2024&quot; [@zscaler-zpa].&lt;/p&gt;
&lt;p&gt;Architecturally, Cloudflare Access and ZPA both sit closer to BeyondCorp than to Microsoft CA: the policy engine is in the data path; the protected resource is fronted by the proxy rather than gated at token issuance.&lt;/p&gt;
&lt;h3&gt;OpenID Shared Signals Framework and CAEP&lt;/h3&gt;
&lt;p&gt;Not a competitor: the &lt;em&gt;cross-vendor wire format&lt;/em&gt; for what Microsoft built into CAE. On 22 September 2025, the OpenID Foundation approved three Final Specifications: the Shared Signals Framework 1.0, the Continuous Access Evaluation Profile 1.0, and the Risk Incident Sharing and Coordination Profile 1.0 [@helpnet-2025-openid][@openid-caep-final]. CAEP defines five event types -- Session Revoked, Token Claims Change, Credential Change, Assurance Level Change, Device Compliance Change -- as the cross-vendor revocation vocabulary.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s CAE implementation is, in Microsoft&apos;s own words, &quot;an industry standard based on Open ID Continuous Access Evaluation Profile&quot; [@ms-cae-concept]. The Final Specifications from September 2025 are the canonical post-2025 reference; older drafts at OpenID&apos;s site are superseded.&lt;/p&gt;
&lt;h3&gt;Head-to-head comparison&lt;/h3&gt;
&lt;p&gt;The differences worth memorising:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;System&lt;/th&gt;
&lt;th&gt;Enforcement point&lt;/th&gt;
&lt;th&gt;Native risk feed&lt;/th&gt;
&lt;th&gt;Post-issuance revocation&lt;/th&gt;
&lt;th&gt;Gates M365 first-party?&lt;/th&gt;
&lt;th&gt;Best suited for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Microsoft Entra CA + ID Protection + CAE&lt;/td&gt;
&lt;td&gt;Token issuer + CAE-aware resource APIs&lt;/td&gt;
&lt;td&gt;ID Protection ML pipeline&lt;/td&gt;
&lt;td&gt;CAE up to 15 min, instant for IP&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;M365 tenants&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google IAP / Chrome Enterprise Premium&lt;/td&gt;
&lt;td&gt;HTTPS reverse proxy&lt;/td&gt;
&lt;td&gt;Context-aware access signals&lt;/td&gt;
&lt;td&gt;Per-request (always re-decides)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Google Cloud workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Okta Identity Engine + ThreatInsight&lt;/td&gt;
&lt;td&gt;IdP token issuance&lt;/td&gt;
&lt;td&gt;ThreatInsight IP feed&lt;/td&gt;
&lt;td&gt;Limited, IdP-dependent&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Vendor-neutral front door&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS IAM Identity Center + Verified Access&lt;/td&gt;
&lt;td&gt;Verified Access proxy + IAM&lt;/td&gt;
&lt;td&gt;Trust providers (third-party)&lt;/td&gt;
&lt;td&gt;Per-request for Verified Access&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;AWS-hosted apps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudflare Access&lt;/td&gt;
&lt;td&gt;Edge proxy&lt;/td&gt;
&lt;td&gt;Risk score + identity factors&lt;/td&gt;
&lt;td&gt;Per-request&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Public web apps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zscaler Private Access&lt;/td&gt;
&lt;td&gt;Broker / edge node&lt;/td&gt;
&lt;td&gt;Posture + identity&lt;/td&gt;
&lt;td&gt;Per-request&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Private app access&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Per-cell sourcing for the table: the Microsoft row&apos;s &quot;Yes&quot; cell on M365 first-party gating is the directly-stated claim from the Microsoft Learn CA overview [@ms-ca-overview]. The other rows&apos; &quot;No&quot; cells are &lt;em&gt;negative inferences&lt;/em&gt; drawn from each peer&apos;s own product documentation, none of which advertises Microsoft 365 first-party API gating: Google IAP gates HTTPS-fronted apps behind the proxy [@google-iap]; Cloudflare Access deny-by-default applies to the apps fronted by Cloudflare [@cloudflare-access-policies]; Verified Access &quot;evaluates each application access request&quot; for HTTPS apps behind AWS [@aws-verified-access]; Zscaler ZPA brokers private app access [@zscaler-zpa]; Okta sign-on policies gate apps wired into Okta&apos;s IdP [@okta-sign-on-policies]. The cell semantics are &quot;does the system gate Outlook/Teams/SharePoint/Graph first-party traffic&quot; and the answer is structurally No outside Microsoft.&lt;/p&gt;

flowchart LR
    subgraph TOK[Token issuance model Microsoft Okta]
        U1[User] --&amp;gt; AT[Acquire token]
        AT --&amp;gt; CA1[CA evaluator]
        CA1 --&amp;gt; IS[Issue token]
        IS --&amp;gt; R1[Resource API validates token]
        R1 -. CAE 401 .-&amp;gt; AT
    end
    subgraph PRX[Data path proxy model Google BeyondCorp AWS Verified Access Cloudflare Zscaler]
        U2[User] --&amp;gt; PXY[Proxy intercepts every request]
        PXY --&amp;gt; POL[Policy evaluator at the proxy]
        POL --&amp;gt; BCK[Backend application]
    end
&lt;p&gt;The honest observation worth sitting with: none of the proxy systems gates M365 first-party API traffic. Outlook, Teams, SharePoint, and Microsoft Graph route through Entra. For those workloads, Entra remains the only effective policy plane. The proxy systems gate &lt;em&gt;the apps that sit behind the proxy&lt;/em&gt; -- internal apps, partner-facing apps, custom workloads. That makes BeyondCorp, Okta, Cloudflare Access, and ZPA &lt;em&gt;complementary to&lt;/em&gt; Entra CA in an M365 environment, not substitutes for it.&lt;/p&gt;
&lt;p&gt;Six systems, six architectural choices. None of them wrong. But what do they &lt;em&gt;all&lt;/em&gt; leave on the table?&lt;/p&gt;
&lt;h2&gt;8. What Conditional Access fundamentally cannot do&lt;/h2&gt;
&lt;p&gt;Section 7 cannot be the ending. There are at least five things Conditional Access -- and every peer in Section 7 -- &lt;em&gt;cannot&lt;/em&gt; do. Some are engineering limits; some are theorems. Both classes are worth naming.&lt;/p&gt;
&lt;h3&gt;(a) On-prem authentication&lt;/h3&gt;
&lt;p&gt;CA is a cloud control plane. Kerberos and NTLM against on-prem domain controllers do not consult Entra. There is no policy hook for the legacy Windows protocols. If a domain user signs in to a domain-joined workstation, authenticates to a file server, and accesses a share, no piece of that flow touches Conditional Access. The Microsoft Learn overview is explicit about the scope [@ms-ca-overview].&lt;/p&gt;
&lt;p&gt;This is the operational seam between cloud identity and on-prem identity. State it plainly; do not soften.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Conditional Access does not gate Kerberos or NTLM against on-prem domain controllers. If your threat model includes lateral movement after credential theft on the on-prem side, CA is not your defence. Layer in Defender for Identity, on-prem MFA gateways, or a privileged-access workstation architecture instead.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;(b) Post-issuance token theft&lt;/h3&gt;
&lt;p&gt;Once a refresh token is exfiltrated -- whether via an adversary-in-the-middle phishing kit like Evilginx [@ms-aitm-phishing-blog], an infostealer that scrapes the token cache, or a malicious browser extension -- the pre-issuance CA evaluation is bypassed. The attacker has a bearer token. They can present it to the resource API directly. CAE-aware resource providers can revoke mid-session on the published critical-event list, but the latency ceiling is &quot;up to 15 minutes&quot; for non-IP events [@ms-cae-concept]. In fifteen minutes a competent attacker has done plenty.&lt;/p&gt;
&lt;p&gt;The mitigation is &lt;em&gt;device-bound&lt;/em&gt; credentials: Primary Refresh Tokens bound to &lt;a href=&quot;https://paragmali.com/blog/the-tpm-in-windows-one-primitive-twenty-five-years-and-the-c/&quot; rel=&quot;noopener&quot;&gt;TPM&lt;/a&gt; hardware, FIDO2 with hardware attestation, certificate-based authentication with hardware-protected keys [@ms-prt-concept]. A bearer token bound to a TPM is not exfiltratable in the same way; the wrapped key material never leaves the device.&lt;/p&gt;
&lt;h3&gt;(c) Consent-grant phishing&lt;/h3&gt;
&lt;p&gt;CA evaluates &lt;em&gt;authentication&lt;/em&gt;, not &lt;em&gt;authorization grants&lt;/em&gt; that a user makes to a malicious OAuth app. A user who clicks &quot;Allow&quot; on a permissions-consent prompt for an attacker-controlled app has performed an OAuth authorization, not a sign-in. The malicious app now has the user&apos;s delegated permissions for whatever scopes were granted. CA was not invoked because CA gates the user&apos;s sign-ins; it does not inspect the user&apos;s OAuth grants. Microsoft Defender for Cloud Apps documents the attack class as &quot;risky OAuth apps&quot; and ships investigation and remediation tooling on a separate plane from CA [@ms-illicit-consent-grant].&lt;/p&gt;
&lt;p&gt;Admin consent settings, app governance policies, and explicit allow-listing of acceptable publishers live on that different plane. The policy admin who deploys CA needs to deploy app governance separately.&lt;/p&gt;
&lt;h3&gt;(d) Risk evaluation is probabilistic&lt;/h3&gt;
&lt;p&gt;Identity Protection produces a &lt;em&gt;score&lt;/em&gt;, not a &lt;em&gt;proof&lt;/em&gt;. A &quot;high&quot; risk level is a confidence; it is not the assertion &quot;this sign-in is definitely an attack.&quot; No vendor in the Section 7 survey publishes precision or recall numbers for its risk engine. The operating point -- the threshold that maps a continuous score to discrete buckets -- is a trade-off that the vendor calibrates and the customer does not see.&lt;/p&gt;
&lt;p&gt;This is a &lt;em&gt;structural&lt;/em&gt; lower bound on any ML-driven risk plane, not a Microsoft-specific failure. Any classifier has false positives and false negatives. A risk-aware CA policy that says &quot;block at high risk&quot; will, with non-zero probability, block a legitimate sign-in. A policy that says &quot;require MFA at medium risk&quot; will, with non-zero probability, let through a sophisticated attacker whose detections fall under the threshold.&lt;/p&gt;
&lt;h3&gt;(e) Workload-identity CA is constrained by design&lt;/h3&gt;
&lt;p&gt;Block-only grants. No managed identities. No group assignments. The full human grant taxonomy does not transfer because a service principal cannot perform an MFA challenge, cannot register a FIDO2 key, cannot accept a terms-of-use document. The Microsoft Learn page on workload-identity CA enumerates the constraints precisely [@ms-workload-identity-ca]. Section 9 will name this as an &lt;em&gt;open&lt;/em&gt; problem; for now, treat it as a documented limit.&lt;/p&gt;
&lt;h3&gt;The theorems behind the limits&lt;/h3&gt;
&lt;p&gt;Some of these limits are engineering choices that could be different in a future product. Some are deeper.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Saltzer and Schroeder 1975&lt;/strong&gt; [@saltzer-schroeder-1975] give the upper bound on aspirations: complete mediation across every authentication and authorization decision &lt;em&gt;within scope of mediation&lt;/em&gt;. The principle does not constrain what is in scope. It constrains what you must do for whatever you have decided is in scope. On-prem AD is out of scope for CA by Microsoft&apos;s product decision; complete mediation cannot fix that, because the principle is about consistency &lt;em&gt;within&lt;/em&gt; the boundary, not about expanding the boundary.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Harrison-Ruzzo-Ullman 1976&lt;/strong&gt; -- usually shortened to HRU [@harrison-ruzzo-ullman-1976] -- gives the lower bound on static analysis. The safety question in the general access-matrix model is &lt;em&gt;undecidable&lt;/em&gt;. In informal terms: there is no general algorithm that proves a Conditional Access policy edit cannot, under some future edit chain, leak a sensitive right. This is why every vendor in the survey relies on &lt;em&gt;evaluation-time&lt;/em&gt; mediation (the engine decides at the moment of the request) rather than &lt;em&gt;static-proof&lt;/em&gt; analysis (the engine certifies in advance that no edit can ever leak). Cedar&apos;s intentional restriction to a decidable fragment, in AWS Verified Access, is the counter-strategy: trade expressiveness for analysability.&lt;/p&gt;
&lt;p&gt;The bearer-token revocation trade-off is informal but real: the worst-case revocation latency is bounded below by the token&apos;s natural lifetime, unless a side channel exists. CAE is that side channel. Its latency is bounded by the propagation time of the channel (up to 15 minutes for non-IP events, instant for IP). Shorten the channel further and you discover that the IdP-to-resource-API event delivery has its own infrastructure costs.&lt;/p&gt;

The practical implication of HRU for a CA admin is that there is no tool, anywhere, that can examine your tenant&apos;s CA policies and certify that no sequence of policy edits could ever leak access to a sensitive resource. Vendors offer policy *testers* that simulate a single edit against the current population; that is decidable. The question &quot;is the system safe under all possible future edits?&quot; is not. This is why audit trails, change-control gates, and least-privilege role assignments on the CA admin role matter as much as the CA policies themselves.
&lt;p&gt;Naming the limits clears the way to name the &lt;em&gt;active&lt;/em&gt; unsolved problems -- the ones the field is still working on, where the current state of the art admits it is partial.&lt;/p&gt;
&lt;h2&gt;9. Where the policy plane is still incomplete&lt;/h2&gt;
&lt;p&gt;Microsoft&apos;s own 2026 documentation for Conditional Access on AI agents calls the current implementation &quot;a lightweight enforcement mechanism designed to block unauthorized or risky agents, not a full policy suite.&quot; That is not marketing modesty. It is an admission that the most active frontier of policy enforcement -- &lt;a href=&quot;https://paragmali.com/blog/agentic-identity-on-windows-when-the-process-acting-on-your-/&quot; rel=&quot;noopener&quot;&gt;agent identities&lt;/a&gt; -- is deliberately under-specified.&lt;/p&gt;
&lt;p&gt;Five open problems sit on that frontier in 2026.&lt;/p&gt;

Organizations are expanding Zero Trust across more users, applications, and now a growing population of AI agent identities ... the Conditional Access Optimization Agent moves beyond static guidance to continuous, context-aware identity posture optimization. [@ms-techcom-ca-optimization-agent]
&lt;h3&gt;9.1 Agent identity policy semantics&lt;/h3&gt;
&lt;p&gt;What grants should exist for AI agents beyond block and allow? Useful candidate grants include: &quot;read-but-not-move&quot; for mail or files; &quot;business-hours-only&quot;; &quot;any autonomous action requires a fresh sign-off from the on-behalf-of human.&quot; None of these exist as first-class CA grant types in 2026.&lt;/p&gt;
&lt;p&gt;What does exist: CA targeting of agent identities -- the ability to &lt;em&gt;match&lt;/em&gt; a policy on the agent identity rather than the human -- and the Conditional Access Optimization Agent, which gives administrators continuous recommendations on policy posture [@ms-techcom-ca-optimization-agent]. The targeting is there. The grant taxonomy is still mostly the human one, applied imperfectly.&lt;/p&gt;
&lt;h3&gt;9.2 Cross-vendor CAEP interop&lt;/h3&gt;
&lt;p&gt;The wire format was finalised in September 2025 [@helpnet-2025-openid][@openid-caep-final]. Production receiver coverage outside Microsoft Entra-internal resource providers is partial. Two large vendors agreeing on an event schema is necessary but not sufficient for cross-vendor revocation to work in practice; the receiving side needs to &lt;em&gt;act&lt;/em&gt; on the events. The next eighteen months are the period in which CAEP either becomes the cross-vendor wire format for revocation, or it does not.&lt;/p&gt;
&lt;h3&gt;9.3 Workload-identity grant set&lt;/h3&gt;
&lt;p&gt;What richer expressions could exist for non-human identities? The current Microsoft Learn page lists workload-identity detections: &lt;code&gt;investigationsThreatIntelligence&lt;/code&gt;, &lt;code&gt;suspiciousSignins&lt;/code&gt;, &lt;code&gt;adminConfirmedServicePrincipalCompromised&lt;/code&gt;, &lt;code&gt;leakedCredentials&lt;/code&gt;, &lt;code&gt;maliciousApplication&lt;/code&gt;, &lt;code&gt;suspiciousApplication&lt;/code&gt;, &lt;code&gt;anomalousServicePrincipalActivity&lt;/code&gt;, &lt;code&gt;suspiciousAPITraffic&lt;/code&gt; [@ms-workload-identity-risk]. The detections exist; the grant taxonomy stops at block.&lt;/p&gt;
&lt;p&gt;Candidate richer grants: &quot;workload attestation&quot; (the service principal proves it is running on attested infrastructure), &quot;verifiable claim from a trusted attester&quot; (a third party signs a statement about the workload), &quot;step-up authorization for sensitive scopes&quot; (a higher-privilege scope requires a separate per-request authorization step). None of these is generally available in 2026.&lt;/p&gt;

A non-human identity in Entra ID: a service principal, an application registration&apos;s owned service principal, or a managed identity in Azure. Workload identities authenticate via client secrets, client certificates, federated credentials, or (for managed identities) instance-metadata-service tokens. Conditional Access for workload identities currently applies only to single-tenant service principals registered in the tenant; it does not cover multi-tenant SaaS apps or managed identities [@ms-workload-identity-ca].
&lt;h3&gt;9.4 The break-glass paradox&lt;/h3&gt;
&lt;p&gt;Emergency-access accounts must be excluded from CA. If a CA misconfiguration locks out every admin, the break-glass account is the recovery path. But exclusion creates a high-value bypass: an attacker who compromises a break-glass account inherits its exclusion.&lt;/p&gt;
&lt;p&gt;There is no clean answer. Microsoft&apos;s guidance is exclusion plus FIDO2 binding plus alerting: the break-glass accounts have hardware-bound FIDO2 keys (so they cannot be phished), they are excluded from all CA policies (so misconfiguration cannot lock them out), and &lt;em&gt;every&lt;/em&gt; sign-in is alerted on (so misuse is detected within minutes) [@ms-emergency-access].&lt;/p&gt;

Run two break-glass accounts, not one. Store the FIDO2 keys in separate physical safes under separate custodians. Never use them for anything but a recovery exercise once per quarter; if they sign in unexpectedly, treat the alert as a P1 incident. The operational pattern accepts that you have a bypass and treats the bypass as the highest-value alert in the tenant [@ms-emergency-access].
&lt;h3&gt;9.5 The risk-engine transparency problem&lt;/h3&gt;
&lt;p&gt;No vendor in the Section 7 survey publishes model architecture, feature vector size, or per-detection precision and recall. Microsoft does not. Okta does not. Google does not. Defenders, auditors, and regulators must accept a black-box score.&lt;/p&gt;
&lt;p&gt;This matters in three places. First, for incident response: when an &quot;atypical travel&quot; detection fires for an executive, the responder cannot see which features contributed and how strongly. Second, for compliance: an auditor asked to evidence the effectiveness of the control plane gets the operating output (3-tier risk levels) but not a quantitative evaluation. Third, for the risk-engine vendors themselves, who must respond to legitimate regulatory questions about model bias and operational reliability without revealing the architecture that attackers would use to evade detection.&lt;/p&gt;
&lt;p&gt;The article does not predict a resolution. It names the gap.&lt;/p&gt;
&lt;p&gt;The architecture is incomplete by admission. It is also actionable today. A competent tenant administrator can deploy a sensible baseline in an afternoon.&lt;/p&gt;
&lt;h2&gt;10. Using Conditional Access today&lt;/h2&gt;
&lt;p&gt;The architectural story ends; the operational story begins. Here is what a competent tenant looks like in 2026.&lt;/p&gt;
&lt;h3&gt;The licensing reality&lt;/h3&gt;
&lt;p&gt;Conditional Access is not a feature every Microsoft 365 tenant gets. It is a feature gated by SKU. The licensing tiers are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Entra ID Free.&lt;/strong&gt; Security Defaults only [@ms-security-defaults]. No Conditional Access policies. No risk-based conditions. No CA-driven CAE (the critical-event-evaluation subsystem -- for events like account disable, password reset, and high user risk -- still propagates to CAE-aware M365 services at the service layer regardless of SKU; see Section 6.6) [@ms-cae-concept].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Entra ID P1.&lt;/strong&gt; Conditional Access is unlocked [@ms-ca-overview]. You can author policies with any of the non-risk conditions: users, apps, locations, devices, client app, platform. You can demand any of the non-risk grants.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Entra ID P2.&lt;/strong&gt; Adds risk-based conditions. &lt;code&gt;signInRiskLevels&lt;/code&gt; and &lt;code&gt;userRiskLevels&lt;/code&gt; become usable [@ms-id-protection-overview]. ID Protection&apos;s full report pane (risky users, risky sign-ins, risk detections) is accessible. The legacy ID-Protection-side risk policies retire 1 October 2026 [@ms-id-protection-policies].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Workload Identities Premium.&lt;/strong&gt; A separate SKU. Unlocks CA scoped to service principals [@ms-workload-identity-ca].&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This corrects a premise discarded earlier: &quot;Conditional Access is the policy plane every M365 tenant runs on&quot; is &lt;em&gt;not&lt;/em&gt; true. Many tenants run on Security Defaults. The &quot;policy plane every tenant runs on&quot; is the cloud sign-in pipeline; CA is the configurable richer layer that P1+ tenants opt into.&lt;/p&gt;
&lt;h3&gt;Start with the managed baselines&lt;/h3&gt;
&lt;p&gt;Microsoft-managed Conditional Access policies are the recommended starting point [@ms-managed-policies]. They auto-deploy in Report-only mode, run for at least 45 days while administrators review the impact in the Sign-in logs, and are auto-enabled with a 28-day pre-enablement notification unless administrators opt out [@ms-managed-policies]. The currently shipping baselines, per Microsoft Learn, include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MFA for admins accessing Microsoft admin portals (the most-privileged roles).&lt;/li&gt;
&lt;li&gt;MFA for users who already have per-user MFA enabled (a migration aid).&lt;/li&gt;
&lt;li&gt;MFA and reauthentication for risky sign-ins (the P2 baseline).&lt;/li&gt;
&lt;li&gt;Block legacy authentication.&lt;/li&gt;
&lt;li&gt;Block access for high-risk users (P2-tier protection on the user-risk surface).&lt;/li&gt;
&lt;li&gt;Block all high-risk agents accessing all resources (Preview, AI-agent surface).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The original announcement called for a 90-day report-only window [@weinert-2023-managed-policies][@helpnet-2023-microsoft-entra-policies]. The current default is 45 days [@ms-managed-policies]; the window shrank as Microsoft gained confidence that customers were not surprised by the auto-enablement.&lt;/p&gt;
&lt;h3&gt;Five custom policies on top of the baselines&lt;/h3&gt;
&lt;p&gt;Beyond the managed policies, every well-run tenant in operational experience runs five custom policies on top of the baselines [@ms-ca-policy-common]: block legacy authentication unconditionally [@ms-managed-policies]; require the phishing-resistant Authentication Strength for any user in a privileged role [@ms-auth-strengths]; require &lt;code&gt;compliantDevice&lt;/code&gt; for admin centres, finance apps, and customer-data exports [@ms-intune-compliance-partners]; restrict privileged sign-ins to a named-location allow-list with block-or-step-up outside it [@ms-ca-network]; and, where Entra ID P2 is licensed, demand a sign-in-risk-based step-up (MFA at high risk, a passwordless or phishing-resistant method at medium risk) [@ms-id-protection-policies].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; 1. Block legacy authentication. 2. Phishing-resistant Authentication Strength for admin roles. 3. Require compliant device for sensitive applications. 4. Named-location restrictions for privileged roles. 5. Sign-in-risk-based step-up where Entra ID P2 is available.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Automation entry points (Microsoft Graph)&lt;/h3&gt;
&lt;p&gt;The Graph endpoints administrators care about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GET /identity/conditionalAccess/policies&lt;/code&gt; -- list policies. &lt;code&gt;POST&lt;/code&gt; to create, &lt;code&gt;PATCH&lt;/code&gt; to update [@ms-graph-capolicy].&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /identityProtection/riskDetections&lt;/code&gt; -- the per-detection log. Filterable by &lt;code&gt;riskLevel&lt;/code&gt;, &lt;code&gt;riskState&lt;/code&gt;, &lt;code&gt;userPrincipalName&lt;/code&gt;, &lt;code&gt;activityDateTime&lt;/code&gt; [@ms-graph-riskdetection].&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /identityProtection/riskyUsers&lt;/code&gt; -- the per-user risk view.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A policy authored in code looks like this (truncated for readability):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;displayName&quot;: &quot;Require phishing-resistant for admins&quot;,
  &quot;state&quot;: &quot;enabledForReportingButNotEnforced&quot;,
  &quot;conditions&quot;: {
    &quot;users&quot;: { &quot;includeRoles&quot;: [&quot;62e90394-69f5-4237-9190-012177145e10&quot;] },
    &quot;applications&quot;: { &quot;includeApplications&quot;: [&quot;All&quot;] }
  },
  &quot;grantControls&quot;: {
    &quot;operator&quot;: &quot;OR&quot;,
    &quot;authenticationStrength&quot;: { &quot;id&quot;: &quot;00000000-0000-0000-0000-000000000004&quot; }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The recommended deployment dance is &lt;code&gt;enabledForReportingButNotEnforced&lt;/code&gt; first; let the Sign-in log show you the impact for a calibration window; promote to &lt;code&gt;enabled&lt;/code&gt; only after the report-only data matches expectations [@ms-ca-report-only].&lt;/p&gt;
&lt;h3&gt;Audit-time visibility&lt;/h3&gt;
&lt;p&gt;Three surfaces matter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sign-in logs&lt;/strong&gt; in the Entra portal show the per-sign-in evaluation, including which CA policies matched and which grants were satisfied.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Risk-detection log&lt;/strong&gt; in Identity Protection (P2 only) shows the per-detection narrative: which &lt;code&gt;riskEventType&lt;/code&gt; fired, with what &lt;code&gt;additionalInfo&lt;/code&gt;, against which user.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The What-If tool&lt;/strong&gt; simulates a policy evaluation for a hypothetical sign-in, before you enable a policy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Detection engineering&lt;/h3&gt;
&lt;p&gt;For E5 tenants, the Sign-in logs and risk detections flow into Microsoft Sentinel (via the Microsoft Entra ID connector) or Defender XDR [@ms-sentinel-aad-connector]. A KQL skeleton for high-risk-with-CA-failure looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kusto&quot;&gt;SigninLogs
| where ResultType != 0
| join kind=inner (AADRiskDetections | where RiskLevel == &quot;high&quot;) on UserPrincipalName, CorrelationId
| project TimeGenerated, UserPrincipalName, IPAddress, ConditionalAccessStatus, RiskEventType, FailureReason
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The aggregate scale figure is worth remembering: Microsoft processes &quot;more than 100 trillion security signals&quot; daily across all identity products [@ms-managed-policies]. The detection engineer is consuming a small slice that landed in their tenant.&lt;/p&gt;

Run the following in Microsoft Sentinel or the Entra advanced hunting blade to surface sign-ins that succeeded *despite* a high-confidence risk detection -- the most operationally interesting subset. The query is original to this article; the schema it targets is the canonical Microsoft Sentinel Entra ID connector tables `SigninLogs` and `AADRiskDetections` [@ms-sentinel-aad-connector], and the join-and-filter pattern follows the practice documented in Microsoft&apos;s Sentinel hunting guidance [@ms-sentinel-hunting].&lt;pre&gt;&lt;code class=&quot;language-kusto&quot;&gt;let window = 7d;
SigninLogs
| where TimeGenerated &amp;gt; ago(window)
| where ResultType == 0
| where ConditionalAccessStatus == &quot;success&quot;
| join kind=inner (
    AADRiskDetections
    | where TimeGenerated &amp;gt; ago(window)
    | where RiskLevel == &quot;high&quot;
) on UserPrincipalName, CorrelationId
| project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, RiskEventType, ConditionalAccessPolicies
| order by TimeGenerated desc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The expected count for a well-tuned tenant is small. Spikes warrant a P2 investigation.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Break-glass&lt;/h3&gt;
&lt;p&gt;Two emergency-access accounts. FIDO2-bound. Excluded from every CA policy. Stored as separate hardware tokens in separate safes. Every sign-in is wired to a P1 alert. Per Section 9.4 and Microsoft Learn&apos;s emergency-access guidance, this is the acknowledged operational compromise to the break-glass paradox [@ms-emergency-access].&lt;/p&gt;

A non-personal Entra ID administrator account excluded from Conditional Access and from MFA enforcement, used only when the primary identity infrastructure has failed. Best practice: at least two such accounts, with hardware FIDO2 keys stored separately, monitored by an unconditional alert on any sign-in.
&lt;p&gt;The article has answered &quot;who decided?&quot; five times over: by signal, by policy, by token, by session, by operational pattern. One section remains: the misconceptions that keep recurring.&lt;/p&gt;
&lt;h2&gt;11. Misconceptions that recur&lt;/h2&gt;
&lt;p&gt;Every time these questions come up in practice, the same wrong answers come back. The corrections are worth memorising.&lt;/p&gt;

Only if you have Entra ID P1 or higher and have configured CA policies. Free SKU tenants run Security Defaults, which is a coarse tenant-wide on/off switch, not CA [@ms-security-defaults]. CA is unlocked at P1 [@ms-ca-overview]; risk-based conditions are unlocked at P2 [@ms-id-protection-overview]. The &quot;every tenant runs on CA&quot; framing you sometimes see in marketing material is incorrect.

No. CA is a cloud control plane. Kerberos and NTLM against on-prem domain controllers do not consult Entra at all [@ms-ca-overview]. If your threat model includes on-prem lateral movement, layer in Defender for Identity and the standard on-prem hardening playbook.

No. CAE is event-driven push from the policy plane to CAE-aware resource APIs. The Microsoft Learn CAE document gives the latency ceiling precisely: &quot;the goal for critical event evaluation is for response to be near real time, but latency of up to 15 minutes might be observed because of event propagation time; however, IP locations policy enforcement is instant&quot; [@ms-cae-concept]. There is no 30-second poll. The token can live up to 28 hours because the revocation is event-driven.

No. Clients advertise CAE-readiness via the `cp1` client capability in token requests, specifically by adding `cp1` to the `xms_cc` claim mechanism (or by calling `WithClientCapabilities(new[] { &quot;cp1&quot; })` in MSAL) [@ms-claims-challenge][@ms-app-resilience-cae]. The Microsoft Learn claims-challenge page is explicit: &quot;The only currently known value is `cp1`&quot; [@ms-claims-challenge]. The CAE-aware token is recognisable by its long lifetime (up to 28 hours) and by the resource API&apos;s willingness to issue an `insufficient_claims` challenge, not by a Boolean claim.

No. Third-party MDM compliance partners can write the device compliance state into Entra via Intune&apos;s compliance-partner API [@ms-intune-compliance-partners]. The CA grant reads `isCompliant` on the device object; it does not care which MDM wrote that value. Microsoft&apos;s preferred deployment is Intune, but the integration point is open by design.

In 2023. The public preview of CA filters for workload identities opened on 26 October 2022 [@vansurksum-2022-workload-ca]; the Microsoft Entra Workload Identities standalone product reached GA in late November 2022, and the Conditional Access feature itself reached general availability later in 2023 [@ms-workload-identity-ca]. Any article asserting a 2025 GA date for workload-identity CA is incorrect.

No. Every sign-in produces a Sign-in log entry; ID Protection emits a `riskDetection` only when at least one detector fires for that sign-in [@ms-graph-riskdetection]. Most sign-ins produce no `riskDetection`. Detection engineers querying for risk should join the Sign-in log with the riskDetections log and treat unjoined rows as &quot;no risk flagged at the moment.&quot;

No Microsoft primary source publicly describes the production model architecture or names a per-sign-in feature-vector size. What is published is the detection taxonomy (about two dozen named `riskEventType` values [@ms-id-protection-risks][@ms-graph-riskdetection]), the timing split (real-time / near-real-time / offline [@ms-risk-detection-types]), and the three-tier risk output. The &quot;transformer with 80+ signals&quot; framing is folk knowledge with no Microsoft primary source behind it. The article reframes it as &quot;ML-based with detailed architecture publicly undisclosed.&quot;

Not on its own. A standard MFA grant does not defeat a kit like Evilginx, which proxies both the password and the MFA challenge in real time. The defence is to require the *phishing-resistant Authentication Strength* in CA: FIDO2 with hardware attestation, Windows Hello for Business, or multifactor certificate-based authentication [@ms-auth-strengths]. The cryptographic origin-binding in WebAuthn-class credentials defeats AitM by construction. But the defence only works *when the grant is applied*. A CA policy that demands phishing-resistant for admin roles but not for users will block AitM against admins and not against users.
&lt;h2&gt;12. Two planes, one boundary&lt;/h2&gt;
&lt;p&gt;Replay Alice&apos;s Tuesday.&lt;/p&gt;
&lt;p&gt;Identity Protection&apos;s signal plane scored her 09:02 sign-in. The score was below the medium-risk threshold. Conditional Access&apos;s policy plane evaluated four matching policies. Two demanded MFA; her cached refresh token already satisfied that grant from yesterday. One demanded a compliant device; Intune had marked her laptop compliant overnight. None demanded the block grant. The token issuer issued a CAE-aware bearer token with a 28-hour lifetime. Exchange Online accepted the token. Outlook&apos;s data path opened. Bytes returned to Alice.&lt;/p&gt;
&lt;p&gt;If, twelve minutes later, an attacker tries to sign in with Alice&apos;s credentials from an anonymizing proxy, ID Protection will fire a detection. The detection will lift her user risk to high. CAE will deliver the high-user-risk event to Exchange. Exchange will issue a claims challenge on the next call from Alice&apos;s Outlook. Outlook will replay the challenge to Entra. Entra will re-run CA, see the elevated risk, demand step-up MFA, and either issue a fresh token (after Alice satisfies the step-up) or refuse.&lt;/p&gt;
&lt;p&gt;The modern identity boundary is not a wall. It is a conversation between planes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The boundary is a conversation between planes, not a wall.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The open frontier is real. Agent identities want a richer grant taxonomy than the human one provides. Cross-vendor CAEP wants production receivers outside Microsoft. Workload-identity policy wants grants that go beyond block. The break-glass paradox wants an answer that does not depend on operational discipline. None of these problems will resolve in 2026. They are the next frontier.&lt;/p&gt;
&lt;p&gt;What the reader should now be able to do: trace a sign-in through the signal, policy, token, and session planes; read a &lt;code&gt;conditionalAccessPolicy&lt;/code&gt; JSON and predict the evaluation outcome; identify which class of attack each grant defends against; and name, by reference to specific Microsoft Learn pages, what CA does &lt;em&gt;not&lt;/em&gt; defend against. The promise from Section 1 is delivered.&lt;/p&gt;

Today, 100 percent of consumer Microsoft accounts older than 60 days have multifactor authentication. -- Alex Weinert, Microsoft Identity, November 2023 [@weinert-2023-managed-policies]
&lt;p&gt;Who decided this token is good? The boundary itself decided, by composing the work of every plane named above.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;conditional-access-and-entra-id-protection&quot; keyTerms={[
  { term: &quot;Conditional Access (CA)&quot;, definition: &quot;Microsoft Entra&apos;s JSON-driven policy engine that matches users, apps, and conditions against grants such as block, MFA, and phishing-resistant Authentication Strength.&quot; },
  { term: &quot;Microsoft Entra ID Protection&quot;, definition: &quot;The ML-driven signal plane that emits riskDetection events tagged with riskEventType, riskLevel, riskState, and detectionTimingType.&quot; },
  { term: &quot;Continuous Access Evaluation (CAE)&quot;, definition: &quot;The event-driven session plane between Entra and CAE-aware resource APIs; uses HTTP 401 with WWW-Authenticate insufficient_claims to trigger mid-session re-evaluation.&quot; },
  { term: &quot;Sign-in risk vs user risk&quot;, definition: &quot;Sign-in risk is per-session probability the credential is being used by an attacker; user risk is per-user probability the account is compromised over recent history.&quot; },
  { term: &quot;Authentication Strength&quot;, definition: &quot;A named bundle of acceptable authentication methods that a CA grant can demand; the phishing-resistant strength defeats AitM by binding the credential to the relying-party origin via WebAuthn.&quot; },
  { term: &quot;Primary Refresh Token (PRT)&quot;, definition: &quot;A long-lived refresh token issued to a Windows session at user sign-in to Entra-joined or hybrid-joined devices, bound to the TPM where available, subject to CA at issuance.&quot; },
  { term: &quot;Claims challenge (insufficient_claims)&quot;, definition: &quot;HTTP 401 wire format CAE uses to demand a fresh token: WWW-Authenticate: Bearer error=&quot;insufficient_claims&quot;, claims=&quot;&quot;.&quot; },
  { term: &quot;Workload identity&quot;, definition: &quot;A non-human Entra identity (service principal, managed identity, or app registration&apos;s owned service principal); CA for workload identities applies only to single-tenant service principals with a block-only grant set.&quot; },
  { term: &quot;Break-glass account&quot;, definition: &quot;An emergency-access account excluded from Conditional Access, ideally FIDO2-bound, monitored by an unconditional sign-in alert.&quot; }
]} questions={[
  { q: &quot;What is the only API surface between Entra ID Protection (the signal plane) and Conditional Access (the policy plane), and why does the answer explain the maintainability of the architecture across a decade?&quot;, a: &quot;Two condition keys on the CA policy: signInRiskLevels and userRiskLevels. Because the contract is two strings, the risk model can be re-trained without policy rewrites, and policies can evolve without retraining the model.&quot; },
  { q: &quot;Why did Microsoft reject the &apos;shortened token lifetime&apos; approach to revocation, and what did they ship instead?&quot;, a: &quot;Shortened token lifetimes degraded user experience and reliability without eliminating risks (Microsoft&apos;s documented &apos;blunt object&apos; framing). CAE lengthens tokens (up to 28 hours) and adds an event-driven side channel that fires HTTP 401 with insufficient_claims when a critical event occurs.&quot; },
  { q: &quot;Name the documented critical events that fire a CAE claims challenge, and the documented latency ceiling.&quot;, a: &quot;Five critical events: account disabled or deleted, password change or reset, MFA enabled by an admin, admin token revocation, and high user risk detected by ID Protection. A parallel pathway propagates network-location and CA policy changes on the same channel. Latency is up to 15 minutes for non-IP events, instant for IP locations.&quot; },
  { q: &quot;Why does Conditional Access not gate on-prem Active Directory logons?&quot;, a: &quot;CA is a cloud control plane. Kerberos and NTLM against on-prem domain controllers authenticate against the on-prem KDC and do not consult Entra. This is a documented scope limit, not a bug.&quot; },
  { q: &quot;What HRU result establishes a theoretical lower bound on what CA can guarantee, and what is the practical implication?&quot;, a: &quot;Harrison-Ruzzo-Ullman 1976 proves the safety question in the general access-matrix model is undecidable. Practically, no tool can certify that no sequence of policy edits will ever leak access to a sensitive resource; vendors rely on evaluation-time mediation rather than static proof.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>conditional-access</category><category>entra-id</category><category>identity-protection</category><category>continuous-access-evaluation</category><category>zero-trust</category><category>security</category><author>noreply@paragmali.com (Parag Mali)</author></item></channel></rss>