<?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: attack-paths</title><description>Posts tagged attack-paths.</description><link>https://paragmali.com/</link><language>en-US</language><lastBuildDate>Sun, 07 Jun 2026 04:13:08 GMT</lastBuildDate><atom:link href="https://paragmali.com/tags/attack-paths/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>AD Is a Graph: How BloodHound Made Defenders Think Like Attackers</title><link>https://paragmali.com/blog/ad-is-a-graph-how-bloodhound-made-defenders-think-like-attac/</link><guid isPermaLink="true">https://paragmali.com/blog/ad-is-a-graph-how-bloodhound-made-defenders-think-like-attac/</guid><description>From Lambert&apos;s 2015 essay to Microsoft Security Exposure Management in 2024 -- how the attack-path graph became the default model for Active Directory security.</description><pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate><content:encoded>
**AD is a graph.** In April 2015 John Lambert named the missing model in two sentences. In August 2016 Andy Robbins, Rohan Vazarkar, and Will Schroeder shipped the tool that made it operational: BloodHound treats Active Directory as a directed graph of privilege relationships, queries it with Neo4j&apos;s Cypher, and turns weeks of red-team whiteboard work into a 200 ms shortest-path lookup. By November 2024 Microsoft itself shipped the same mental model as Microsoft Security Exposure Management. This article is half tool history (1998 academic attack graphs through OpenGraph 2025) and half graph-theory exposition: property graphs, BFS shortest paths, the edge taxonomy, and the open problem of *weighting* what is currently treated as one BFS hop per privilege.
&lt;h2&gt;1. How do I get from this user to Domain Admin?&lt;/h2&gt;
&lt;p&gt;In 2014, a red-team analyst with a help-desk account inside a 40,000-user Active Directory forest asks the question every red-team analyst asks: &lt;em&gt;is there a path from here to Domain Admins?&lt;/em&gt; The answer takes two analysts five days of PowerView scripts, hand-drawn whiteboard diagrams, and per-host RDP probing. The same question in 2024 is a ninety-character Cypher query that returns in 200 milliseconds.&lt;/p&gt;
&lt;p&gt;What happened in those ten years is the story of one sentence -- &lt;em&gt;defenders think in lists, attackers think in graphs&lt;/em&gt; -- becoming, in turn, a tool, a discipline, and a Microsoft product.&lt;/p&gt;
&lt;p&gt;The 2014 reality was a stack of CSV files. PowerView, the PowerShell enumeration toolkit Will Schroeder first published in August 2014 [@powersploit-repo], could dump every group membership, every &lt;a href=&quot;https://paragmali.com/blog/windows-access-control-25-years-of-attacks/&quot; rel=&quot;noopener&quot;&gt;Access Control Entry&lt;/a&gt;, and every active session from a low-privilege account [@powertools-powerview]. The outputs were rows. Hundreds of thousands of rows. Composing them into a coherent attack path was a job for a marker and a whiteboard, and the join keys were Distinguished Names that wrapped twice across an analyst&apos;s notebook page. Five days to map a single 40,000-user forest was not unusual. It was the price of doing business.&lt;/p&gt;
&lt;p&gt;The 2024 reality is a query. The analyst loads SharpHound&apos;s JSON dump into a Neo4j graph, opens the BloodHound web interface in a browser, types&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cypher&quot;&gt;MATCH p = shortestPath(
  (u:User {name:&apos;HELPDESK@CORP.LOCAL&apos;})-[*1..]-&amp;gt;(g:Group {name:&apos;DOMAIN ADMINS@CORP.LOCAL&apos;})
) RETURN p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and clicks Run. The graph renders. The shortest path is highlighted. The pivot points are circled. Time elapsed: 200 milliseconds on the database, plus a second for the browser to draw the SVG [@bloodhound-ce-repo].&lt;/p&gt;
&lt;p&gt;Whatever happened in those ten years has to be more than a software release. It has to be a change in how the entire community models the problem. The change has a date and a sentence. Both arrived in April 2015. Let us start with the sentence.&lt;/p&gt;
&lt;h2&gt;2. From ACL lists to graphs -- why the model matters&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;An access-control list is not the same as a graph -- and the difference is everything.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Consider five accounts in a hypothetical &lt;code&gt;CORP.LOCAL&lt;/code&gt; forest. Bob, a help-desk operator, has been granted &lt;code&gt;ForceChangePassword&lt;/code&gt; on Carol&apos;s account by a long-departed administrator who once needed to delegate password resets. Carol is a member of &lt;code&gt;Server Operators&lt;/code&gt;. &lt;code&gt;Server Operators&lt;/code&gt;, by default, can log on locally to Domain Controllers and back up the directory database. The Domain Controller hosts the &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; account&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Three rows in three different audit reports. One attack path.&lt;/p&gt;
&lt;p&gt;A per-object Access Control List audit looks at Bob&apos;s row, sees a &lt;code&gt;ForceChangePassword&lt;/code&gt; ACE, and flags it as &quot;an over-broad delegation.&quot; It looks at Carol&apos;s row, sees that she belongs to &lt;code&gt;Server Operators&lt;/code&gt;, and flags it as &quot;a privileged group membership.&quot; It looks at the Domain Controller and sees that &lt;code&gt;Server Operators&lt;/code&gt; has logon rights, which is the default. Nothing in the audit composes the three facts. Reachability is not a property the report computes.&lt;/p&gt;

A set of nodes (vertices) and directed edges (arrows) between them. Each edge points from one node to another. A *path* is a sequence of edges that can be traversed in the direction of their arrows. A node B is *reachable* from a node A if some path leads from A to B.

A property of two nodes A and B in a directed graph: B is reachable from A if there exists a sequence of edges leading from A to B, regardless of length. Reachability is fundamentally a graph property and cannot be answered by inspecting any single edge in isolation.
&lt;p&gt;Now draw the same five accounts as a directed graph. Bob is a node. Carol is a node. &lt;code&gt;Server Operators&lt;/code&gt; is a node. The Domain Controller is a node. The &lt;code&gt;krbtgt&lt;/code&gt; account is a node. There is an edge from Bob to Carol labelled &lt;code&gt;ForceChangePassword&lt;/code&gt;. There is an edge from Carol to &lt;code&gt;Server Operators&lt;/code&gt; labelled &lt;code&gt;MemberOf&lt;/code&gt;. There is an edge from &lt;code&gt;Server Operators&lt;/code&gt; to the Domain Controller labelled &lt;code&gt;CanRDP&lt;/code&gt;. There is an edge from the Domain Controller to &lt;code&gt;krbtgt&lt;/code&gt; labelled &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;&lt;code&gt;DCSync&lt;/code&gt;&lt;/a&gt;. Trace the arrows. Bob can reach &lt;code&gt;krbtgt&lt;/code&gt;.&lt;/p&gt;

flowchart LR
    Bob([Bob, help-desk]) --&amp;gt;|ForceChangePassword| Carol([Carol])
    Carol --&amp;gt;|MemberOf| SO([Server Operators])
    SO --&amp;gt;|CanRDP| DC([Domain Controller])
    DC --&amp;gt;|DCSync| Krb([krbtgt])
&lt;p&gt;The graph form makes reachability visually obvious. The list form does not. This is not a presentation difference. It is a data-model difference, and it is the difference that decides whether a tool can answer the question &lt;em&gt;&quot;is there a path from A to B?&quot;&lt;/em&gt; at all.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Reachability is a property of the graph that the list does not, in general, express. This is not a UX difference. It is a data-model difference, and it is the entire reason BloodHound exists.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The sentence that named this gap appeared on April 26, 2015. John Lambert, then a Distinguished Engineer in the Microsoft Threat Intelligence Center, published a short essay to a personal GitHub repository [@lambert-2015-defenders-lists-attackers-graphs]. No peer review. No formal venue. Two declarative opening sentences that every defender attack-path product since has cited approvingly.&lt;/p&gt;

Defenders don&apos;t have a list of assets -- they have a graph. Assets are connected to each other by security relationships. As long as defenders use a list and attackers use a graph, attackers win. -- John Lambert, April 26, 2015.
&lt;p&gt;Lambert then enumerated five concrete classes of &quot;security dependencies&quot; that constitute edges in any real network: shared local-admin passwords; logon scripts on file servers; print-driver propagation from print servers; certificate authorities that mint smart-card logon certificates; and database administrators who run code as a privileged DB process. The essay closed with a defender prescription: &lt;em&gt;&quot;The first step is to visualize your network by turning your lists into graphs.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If the diagnosis is so obvious in retrospect, why was every mainstream AD audit tool from 2000 through 2015 list-shaped? The answer is that the academic literature had the right model but the wrong substrate, and the operator community had the right substrate but the wrong model. The two did not meet until April 2015.&lt;/p&gt;
&lt;h2&gt;3. Attack graphs before BloodHound, 1998 to 2015&lt;/h2&gt;
&lt;p&gt;The phrase &lt;em&gt;attack graph&lt;/em&gt; is older than Active Directory itself.&lt;/p&gt;
&lt;p&gt;In September 1998, two researchers at Sandia National Laboratories presented a paper titled &lt;em&gt;A Graph-Based System for Network-Vulnerability Analysis&lt;/em&gt; at the New Security Paradigms Workshop in Charlottesville, Virginia. The authors, Cynthia Phillips and Laura Painton Swiler, proposed that a network&apos;s worst-case attack was a &lt;em&gt;graph traversal&lt;/em&gt; problem [@phillips-swiler-1998-nspw]. Nodes encoded network states (the set of attacker privileges across the set of hosts). Edges encoded atomic attack steps (an exploit that, given prerequisite privileges, granted new ones). The shortest path from &quot;attacker outside the network&quot; to &quot;attacker has goal asset&quot; was the worst-case attack.&lt;/p&gt;
&lt;p&gt;Phillips and Swiler observed in a now-canonical sentence that &lt;em&gt;&quot;the security of a network is more than the sum of the security of its hosts.&quot;&lt;/em&gt; It is the conceptual ancestor of every attack-path tool that followed.&lt;/p&gt;
&lt;p&gt;Four years later, at IEEE Symposium on Security and Privacy 2002, Oleg Sheyner (then a CMU PhD student) along with Joshua Haines and Richard Lippmann (MIT Lincoln Lab), Somesh Jha (Wisconsin), and Jeannette Wing (CMU) made the construction automatic [@sheyner-et-al-2002-attack-graphs]. They encoded the network and attacker model as an NuSMV model-checker specification, treated the negation of the security goal as a temporal-logic property, and let the model checker generate every counterexample. The union of counterexamples was the attack graph.&lt;/p&gt;
&lt;p&gt;They also proved that the &lt;em&gt;minimum&lt;/em&gt; set of edges whose removal disconnects the attacker from the goal is NP-hard, but admits an O(log n) approximation -- the first asymptotic bound for the defender-hardening problem.&lt;/p&gt;
&lt;p&gt;Sheyner&apos;s companion 2004 thesis -- &lt;em&gt;Scenario Graphs and Attack Graphs&lt;/em&gt;, CMU-CS-04-122 -- remains the most readable book-length treatment of the academic-attack-graph generation [@sheyner-2004-thesis].&lt;/p&gt;
&lt;p&gt;By 2005 the academic line had a scale solution. Xinming Ou, Sudhakar Govindavajhala, and Andrew Appel at Princeton released &lt;strong&gt;MulVAL&lt;/strong&gt; at USENIX Security 2005 [@mulval-usenix-2005], encoding network state and attacker rules as Datalog facts and running them through XSB Prolog. From the paper&apos;s abstract: &lt;em&gt;&quot;Once the information is collected, the analysis can be performed in seconds for networks with thousands of machines.&quot;&lt;/em&gt; NetSPA at MIT Lincoln Lab (2006) and TVA / CAULDRON at George Mason (2003 to 2005) achieved similar scale through different mechanisms.&lt;/p&gt;
&lt;p&gt;In parallel, on the Windows operator side, Sean Metcalf was running adsecurity.org and documenting AD misconfiguration patterns one writeup at a time [@adsecurity-org]. Microsoft was rolling out its Enhanced Security Administrative Environment (&quot;Red Forest&quot;) tiered-administration model -- the predecessor that the Enterprise Access Model later replaced [@ms-enterprise-access-model] -- which was implicitly graph-aware (the entire ESAE prescription is a tier diagram) but never exposed the tier graph as a queryable structure. ESAE was a deployment blueprint, not a tool.&lt;/p&gt;

gantt
    title Three parallel tracks converging on the attack-path graph
    dateFormat YYYY
    axisFormat %Y&lt;pre&gt;&lt;code&gt;section Academic CVE line
Phillips and Swiler NSPW   :a1, 1998, 1999
Sheyner et al. IEEE SP     :a2, 2002, 2003
MulVAL USENIX              :a3, 2005, 2006
NetSPA TVA                 :a4, 2006, 2008

section Windows operator line
adsecurity.org writeups    :b1, 2014, 2016
PowerView                  :b2, 2014, 2016
Lambert essay              :milestone, b3, 2015-04-26, 1d
BloodHound DEF CON 24      :b4, 2016, 2018
AzureHound BloodHound 4.0  :b5, 2020, 2023
BloodHound CE 5.0          :b6, 2023, 2024
ADCS attack paths          :b7, 2024, 2025
Butterfly v6.3             :b8, 2024, 2026
OpenGraph v8.0             :b9, 2025, 2026

section Microsoft defender stack
ESAE Red Forest blueprint  :c1, 2015, 2018
Azure ATP LMPs preview     :c2, 2018, 2020
Defender CSPM attack paths :c3, 2022, 2024
MSEM GA                    :milestone, c4, 2024-11-19, 1d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The April 2015 essay sat between the two tracks. Lambert was inside Microsoft. He had read the academic literature. He worked next to the threat-intelligence teams who watched real intrusions unfold. The essay was the moment the two communities&apos; vocabularies met. The diagnosis was right. The cure was sixteen months away. It would not come from Microsoft, and it would not come from academia. It would come from a red-team consultancy and a free graph database, and it would debut on a Saturday in August at a hacker convention in Las Vegas.&lt;/p&gt;
&lt;h2&gt;4. Defenders evaluating Active Directory as a list of ACLs&lt;/h2&gt;
&lt;p&gt;If you were a Microsoft-aligned AD security engineer in 2013, your job was to read ACLs. One object at a time. Down a list.&lt;/p&gt;
&lt;p&gt;The mainstream defender toolchain of the era was, almost without exception, list-shaped. Microsoft shipped &lt;code&gt;dsacls.exe&lt;/code&gt; and PowerShell&apos;s &lt;code&gt;Get-Acl&lt;/code&gt;; both produced row-oriented output that an analyst read sequentially. The commercial AD-audit market -- NetWrix Auditor [@netwrix-auditor], ManageEngine ADAudit Plus [@manageengine-adaudit-plus], Quest ActiveRoles [@quest-activeroles], and others -- produced HTML reports with one section per directory object, one row per non-default Access Control Entry, and severity classifications based on a fixed checklist of &quot;dangerous rights&quot; (&lt;code&gt;GenericAll&lt;/code&gt;, &lt;code&gt;WriteDacl&lt;/code&gt;, &lt;code&gt;WriteOwner&lt;/code&gt;, and a handful of others).&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s own &lt;em&gt;Best Practices for Securing Active Directory&lt;/em&gt; document codified this approach. Its central recommendation was &lt;em&gt;per-object delegation review&lt;/em&gt;: walk the directory tree, evaluate each object&apos;s ACL against a hardening checklist, and remediate non-default ACEs that exceed the documented privilege model [@ms-best-practices-ad]. The document is excellent at what it sets out to do. What it does not do -- because the format does not permit it -- is compose multi-hop reachability.&lt;/p&gt;
&lt;p&gt;This was the failure mode Lambert described. A help-desk operator with &lt;code&gt;ForceChangePassword&lt;/code&gt; on a junior service account appears as one row in the audit. The junior service account&apos;s &lt;code&gt;MemberOf Server Operators&lt;/code&gt; membership appears in a different report section. The &lt;code&gt;Server Operators&lt;/code&gt; group&apos;s logon rights on the Domain Controller appear in the Domain Controller&apos;s own report. Three findings in three places, with no machinery to compose them. The data model cannot represent the question.&lt;/p&gt;

A reader trained on Phillips and Swiler, Sheyner et al., MulVAL, NetSPA, and TVA might object that *the field already had* graph-based attack-path analysis a decade before BloodHound. True -- in academia. The academic line solved the scale problem (MulVAL: *&quot;seconds for networks with thousands of machines&quot;*) but spoke the wrong vocabulary. Its atomic attack step was a CVE exploit -- a buffer overflow, a format-string bug, a daemon remote code execution. The dominant AD attack primitive is not a CVE. A user with `WriteDacl` on a group is not exploiting any vulnerability; they are using the system as designed. None of MulVAL, NetSPA, or TVA developed an AD-style privilege-graph input format, and the operator community never adopted them. The academic line was substrate-mismatched and delivered as research-PDF tarballs rather than as `git clone`-able tools.
&lt;p&gt;Two communities, both wrong in different ways. The academic one had the right algorithm with the wrong substrate. The operator one had the right substrate with no algorithm at all. The fix was to fuse them. That happened on August 6, 2016.&lt;/p&gt;
&lt;h2&gt;5. The breakthrough -- BloodHound and Six Degrees of Domain Admin&lt;/h2&gt;
&lt;p&gt;Saturday, August 6, 2016. 1:00 PM. DEF CON 24, Track 2, Paris and Bally&apos;s hotel-casinos in Las Vegas [@defcon-24-archive]. Three speakers from Veris Group&apos;s adaptive threat division step on stage: Andy Robbins, Rohan Vazarkar, Will Schroeder. The talk is titled &lt;em&gt;Six Degrees of Domain Admin: Using Graph Theory to Accelerate Red Team Operations&lt;/em&gt; [@defcon24-bloodhound-slides]. The Veris Group team would spin out as SpecterOps the following year, but the August 2016 attribution -- Robbins (&lt;code&gt;@_wald0&lt;/code&gt;), Vazarkar (&lt;code&gt;@CptJesus&lt;/code&gt;), and Schroeder (&lt;code&gt;@harmj0y&lt;/code&gt;) -- is the canonical one [@bloodhound-legacy-repo].&lt;/p&gt;
&lt;p&gt;The talk demonstrated three design decisions that in retrospect look obvious and at the time were not.&lt;/p&gt;
&lt;p&gt;First, &lt;strong&gt;model Active Directory as a directed property graph&lt;/strong&gt;. Nodes are typed security principals (User, Computer, Group, Domain, OU, GPO). Edges are typed privilege relationships (MemberOf, AdminTo, HasSession, GenericAll, GenericWrite, WriteDacl, ForceChangePassword, and others). This was Lambert&apos;s framing made concrete: every ACE that grants a dangerous right becomes an edge from the trustee to the target.&lt;/p&gt;
&lt;p&gt;Second, &lt;strong&gt;reuse Neo4j as the engine&lt;/strong&gt;. Do not build a custom graph database; piggyback on Cypher&apos;s pattern-matching query language. The cost of building a path-finding engine from scratch was non-trivial; the cost of standing up Neo4j was a single Docker container.&lt;/p&gt;
&lt;p&gt;Third, &lt;strong&gt;ship a collector that emits typed JSON edges, not raw NTSecurityDescriptors&lt;/strong&gt;. The collector&apos;s value is the &lt;em&gt;interpretation&lt;/em&gt; of an ACE as a graph edge -- the mapping from a binary security descriptor to the typed edge that says &quot;trustee X has GenericWrite on object Y&quot; is the hard part, and a defender re-creating that mapping per query would lose. SharpHound (initially &lt;code&gt;SharpHound.ps1&lt;/code&gt;, then a C# binary) does the interpretation once at collection time and writes the edges to disk [@bloodhound-ce-repo].&lt;/p&gt;

SharpHound&apos;s enumeration calls are visibly descended from PowerView. The November 2020 SpecterOps blog announcing BloodHound 4.0 acknowledges the lineage explicitly, naming Schroeder&apos;s joint authorship of both projects and crediting PowerView as the data-collection precursor [@specterops-2020-bloodhound-4]. PowerView&apos;s August 2014 release was the substrate that made BloodHound&apos;s August 2016 synthesis possible. The chain is unbroken: enumeration in 2014, framing in April 2015, graph synthesis in August 2016.
&lt;p&gt;The five-day-of-whiteboard-work figure comes from the SpecterOps team&apos;s own internal benchmark from the original DEF CON 24 talk. The 200 ms query latency is the typical 2024 figure on a mid-size enterprise forest of roughly 10^5 nodes and 10^6 edges, retained as the company&apos;s marketing framing across subsequent blog posts.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; BloodHound&apos;s breakthrough was neither an algorithm nor an architecture. It was the decision to &lt;em&gt;interpret&lt;/em&gt; Active Directory&apos;s access-control data as a typed graph and ship that interpretation as a tool the operator community could actually run.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Crucially, the choice to use Neo4j&apos;s free &lt;code&gt;shortestPath()&lt;/code&gt; function rather than building a custom path-finder was a &lt;em&gt;delivery&lt;/em&gt; decision as much as a &lt;em&gt;technical&lt;/em&gt; one. Neo4j already did breadth-first shortest paths. The team did not need to invent anything. The hard work was in the edge taxonomy and the collector, not in the graph database.&lt;/p&gt;
&lt;p&gt;The talk made a promise the rest of the article must now cash: that there is a real algorithm under the hood, that the algorithm has a name, and that the name is not Dijkstra.&lt;/p&gt;
&lt;h2&gt;6. The algorithmic core -- property graphs, Cypher, and shortest paths&lt;/h2&gt;
&lt;p&gt;If you have never written a Cypher query in your life, the next ninety seconds is the entirety of the syntax you need.&lt;/p&gt;

A graph in which both nodes and edges are typed and can carry key-value properties. A node might have type `User` and properties `name=&apos;BOB@CORP.LOCAL&apos;`, `enabled=true`, `pwdlastset=1719234234`. An edge might have type `GenericWrite` and properties `source=&apos;ACE&apos;`, `isacl=true`. This is the data model Neo4j implements and the model BloodHound uses.
&lt;p&gt;A Cypher pattern is a parenthesised node, a bracketed edge, and a parenthesised node, with arrows showing direction. &lt;code&gt;(u:User)-[:MemberOf]-&amp;gt;(g:Group)&lt;/code&gt; reads &quot;find a node &lt;code&gt;u&lt;/code&gt; of type User connected by a MemberOf edge to a node &lt;code&gt;g&lt;/code&gt; of type Group.&quot; A full query has four parts: &lt;code&gt;MATCH&lt;/code&gt; for the pattern, optional &lt;code&gt;WHERE&lt;/code&gt; for filters, &lt;code&gt;RETURN&lt;/code&gt; for the output. That&apos;s it.Cypher patterns visually mimic ASCII graph drawings: parentheses are nodes, square brackets are edges, and the arrow direction matches the edge direction. The syntax was deliberately designed to look like the diagram you would sketch on a whiteboard.&lt;/p&gt;

The pattern-matching query language originally created for the Neo4j graph database. Cypher&apos;s syntax is declarative: you describe the shape of the data you want, and the engine plans the traversal. Since April 2024 Cypher has been the basis of the ISO/IEC 39075:2024 GQL standard -- the first ISO-standardised graph query language [@iso-39075-2024-gql] [@opencypher-home].
&lt;p&gt;Here is the canonical BloodHound query, with annotations:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cypher&quot;&gt;MATCH p = shortestPath(
  (u:User {name:&apos;BOB@CORP.LOCAL&apos;})       // start node: Bob
    -[*1..]-&amp;gt;                            // any number of typed edges
  (g:Group {name:&apos;DOMAIN ADMINS@CORP.LOCAL&apos;})  // end node: Domain Admins
)
RETURN p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;shortestPath()&lt;/code&gt; wrapper tells Neo4j to short-circuit at the first solution. The variable-length quantifier &lt;code&gt;[*1..]&lt;/code&gt; says &quot;one or more edges of any type.&quot; The &lt;code&gt;p =&lt;/code&gt; binds the entire matched path to the variable &lt;code&gt;p&lt;/code&gt;, which the &lt;code&gt;RETURN&lt;/code&gt; then emits as a sequence of node-edge-node triples that the BloodHound frontend renders as an SVG.&lt;/p&gt;
&lt;p&gt;What does &lt;code&gt;shortestPath()&lt;/code&gt; actually run? Here is where the misconception that BloodHound uses Dijkstra needs to die. The current Neo4j Cypher manual is explicit that &lt;code&gt;shortestPath()&lt;/code&gt; runs an unweighted &lt;strong&gt;bidirectional traversal&lt;/strong&gt; -- BFS in the classical sense -- between the source and target nodes [@neo4j-cypher-shortest-paths]. Not Dijkstra. Not A*. BFS.&lt;/p&gt;

A graph-traversal algorithm that explores all nodes at the current depth before proceeding to the next depth. Starting from the source, it visits all 1-hop neighbours, then all 2-hop neighbours, and so on. For unweighted graphs, BFS is guaranteed to find a shortest path (in number of edges) the first time it reaches the target. Worst-case time is O(V + E) where V is the node count and E is the edge count -- the trivial information-theoretic lower bound for any algorithm that must read the input.
&lt;p&gt;Cypher does support weighted shortest paths via the Neo4j Graph Data Science library, but the BloodHound CE distribution does not enable it. There is no natural cost metric on Active Directory privilege edges in 2026; every edge is treated as one hop.&lt;/p&gt;
&lt;p&gt;Why BFS rather than Dijkstra? Dijkstra is BFS&apos;s generalisation to weighted graphs. If your edges have natural costs -- road distances, link latencies, dollar prices -- Dijkstra (with a Fibonacci heap, $O(E + V\log V)$) gives you shortest paths under that cost metric. Active Directory privilege edges do not have a natural cost metric. &lt;code&gt;MemberOf&lt;/code&gt;, &lt;code&gt;GenericAll&lt;/code&gt;, and &lt;code&gt;CanRDP&lt;/code&gt; are all &quot;the attacker can take this step.&quot; Some are easier than others, but quantifying &lt;em&gt;how much&lt;/em&gt; easier is itself an unsolved problem (see Section 11). Treating every edge as one hop is the load-bearing simplification that makes the model tractable.&lt;/p&gt;

Of a binary relation R: the relation R+ that contains the pair (a, c) whenever there is a chain a R b R ... R c. For a graph, the transitive closure tells you, for every pair of nodes, whether one is reachable from the other. BloodHound&apos;s `shortestPath()` queries can be thought of as on-demand evaluation of the transitive closure restricted to one source-target pair.
&lt;p&gt;The per-query complexity is $O(V + E)$, the standard BFS bound from any algorithms textbook. On a mid-size enterprise forest -- roughly 10^5 nodes and 10^6 edges -- a single user-to-group shortest path returns in sub-second wall-clock time.&lt;/p&gt;
&lt;p&gt;The variable-length quantifier &lt;code&gt;[*1..N]&lt;/code&gt; for general path enumeration is a different matter. Cyclic graphs admit exponentially many paths in N, and Neo4j&apos;s documentation explicitly warns that quantified path patterns can return exponentially many results in the worst case [@neo4j-cypher-variable-length]. The &lt;code&gt;shortestPath()&lt;/code&gt; short-circuit avoids this by returning on the first hit; &lt;code&gt;allShortestPaths()&lt;/code&gt; enumerates only paths tied for shortest; unbounded enumeration is intractable on any non-trivial graph.&lt;/p&gt;
&lt;p&gt;A concrete demonstration is in order. The runnable snippet below is a 35-line implementation of unweighted BFS over a six-node toy graph. It returns the shortest path from a &lt;code&gt;helpdesk&lt;/code&gt; user to the &lt;code&gt;domain-admin&lt;/code&gt; group. This is, structurally, the same algorithm Neo4j&apos;s &lt;code&gt;shortestPath()&lt;/code&gt; runs. The numerical answer (&quot;path of length 4&quot;) is the same number BloodHound would report on the same graph.&lt;/p&gt;
&lt;p&gt;{`
// Edges modelled as a typed adjacency list.
const edges = {
  helpdesk:        [{ to: &apos;carol&apos;,          via: &apos;ForceChangePassword&apos; }],
  carol:           [{ to: &apos;serverops&apos;,      via: &apos;MemberOf&apos; }],
  serverops:       [{ to: &apos;dc01&apos;,           via: &apos;CanRDP&apos; }],
  dc01:            [{ to: &apos;krbtgt&apos;,         via: &apos;DCSync&apos; }],
  krbtgt:          [{ to: &apos;domain-admin&apos;,   via: &apos;GoldenTicket&apos; }],
  domain_admin:    []
};&lt;/p&gt;
&lt;p&gt;function shortestPath(start, goal) {
  const queue = [[start]];           // queue holds candidate paths
  const seen  = new Set([start]);    // each node enqueued at most once&lt;/p&gt;
&lt;p&gt;  while (queue.length) {
    const path = queue.shift();      // BFS = FIFO
    const node = path[path.length - 1];
    if (node === goal) return path;
    for (const e of (edges[node] || [])) {
      if (!seen.has(e.to)) {
        seen.add(e.to);
        queue.push([...path, e.to]);
      }
    }
  }
  return null;                       // unreachable
}&lt;/p&gt;
&lt;p&gt;const path = shortestPath(&apos;helpdesk&apos;, &apos;domain-admin&apos;);
console.log(&apos;Path:&apos;, path.join(&apos; -&amp;gt; &apos;));
console.log(&apos;Length:&apos;, path.length - 1, &apos;hops&apos;);
`}&lt;/p&gt;
&lt;p&gt;The algorithm fits on a single screen. The hard work of BloodHound is not in this loop. The hard work is in deciding &lt;em&gt;which edges to insert into the graph in the first place&lt;/em&gt;. That decision -- the edge taxonomy -- is what makes BloodHound a security tool rather than a graph-database demo.&lt;/p&gt;

sequenceDiagram
    participant Client as Cypher client
    participant Planner as Cypher planner
    participant Engine as BFS engine
    participant Graph as Property graph
    Client-&amp;gt;&amp;gt;Planner: MATCH shortestPath(u to g)
    Planner-&amp;gt;&amp;gt;Engine: plan(start=u, end=g, bidirectional=true)
    Engine-&amp;gt;&amp;gt;Graph: expand 1-hop frontier from u
    Engine-&amp;gt;&amp;gt;Graph: expand 1-hop frontier from g
    Graph--&amp;gt;&amp;gt;Engine: neighbours of u, neighbours of g
    Engine-&amp;gt;&amp;gt;Graph: expand 2-hop frontier (both sides)
    Engine-&amp;gt;&amp;gt;Graph: expand 3-hop frontier (both sides)
    Graph--&amp;gt;&amp;gt;Engine: frontiers intersect at node m
    Engine--&amp;gt;&amp;gt;Planner: reconstruct path u to m to g
    Planner--&amp;gt;&amp;gt;Client: return path
&lt;h2&gt;7. The edge taxonomy -- what Active Directory actually looks like as a graph&lt;/h2&gt;
&lt;p&gt;The BloodHound graph is not &lt;em&gt;every privilege relationship in Active Directory.&lt;/em&gt; It is the set of relationships that the SpecterOps team has decided -- by iterative discovery, often in response to specific community-reported abuse primitives -- to model. The taxonomy has grown roughly monotonically since 2016; the rate has accelerated since the BloodHound CE 5.0 reboot in August 2023 [@specterops-2023-bloodhound-ce].&lt;/p&gt;
&lt;p&gt;Eight families dominate the 2026 graph. They map, family by family, onto the substrates of a modern hybrid enterprise.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Group membership.&lt;/strong&gt; &lt;code&gt;MemberOf&lt;/code&gt; is the simplest edge. Cypher&apos;s variable-length quantifier (&lt;code&gt;[:MemberOf*1..]&lt;/code&gt;) walks transitive memberships in one expression, which is why nested-group reachability is a one-liner.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. ACL write-equivalents.&lt;/strong&gt; &lt;code&gt;GenericAll&lt;/code&gt;, &lt;code&gt;GenericWrite&lt;/code&gt;, &lt;code&gt;WriteDacl&lt;/code&gt;, &lt;code&gt;WriteOwner&lt;/code&gt;, &lt;code&gt;Owns&lt;/code&gt;, &lt;code&gt;AllExtendedRights&lt;/code&gt;, &lt;code&gt;ForceChangePassword&lt;/code&gt;, &lt;code&gt;AddSelf&lt;/code&gt;, &lt;code&gt;AddMember&lt;/code&gt;, and &lt;code&gt;AddKeyCredentialLink&lt;/code&gt; (the shadow-credentials primitive). Each names a specific dangerous-right pattern on a directory object&apos;s security descriptor. SharpHound&apos;s interpreter scans the &lt;code&gt;nTSecurityDescriptor&lt;/code&gt; attribute and emits one typed edge per matching ACE.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Sessions.&lt;/strong&gt; &lt;code&gt;HasSession&lt;/code&gt; is the dynamic edge that goes stale fastest. SharpHound enumerates active sessions via &lt;code&gt;NetSessionEnum&lt;/code&gt; and &lt;code&gt;SAMR&lt;/code&gt;; the resulting edges describe &quot;user U is currently logged into computer C.&quot; The graph is whatever the most recent collection captured.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Remote execution rights.&lt;/strong&gt; &lt;code&gt;AdminTo&lt;/code&gt;, &lt;code&gt;CanRDP&lt;/code&gt;, &lt;code&gt;ExecuteDCOM&lt;/code&gt;, &lt;code&gt;CanPSRemote&lt;/code&gt;, &lt;code&gt;SQLAdmin&lt;/code&gt;. Each describes a code-execution primitive granted to a principal on a computer object.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. &lt;a href=&quot;https://paragmali.com/blog/kerberos-in-windows-the-other-half-of-ntlmless/&quot; rel=&quot;noopener&quot;&gt;Kerberos delegation&lt;/a&gt;.&lt;/strong&gt; &lt;code&gt;AllowedToDelegate&lt;/code&gt; (constrained delegation), &lt;code&gt;AllowedToAct&lt;/code&gt; (resource-based constrained delegation, via &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt;), unconstrained delegation surfaced as node properties on Computer objects, and -- from BloodHound CE v6.3 in December 2024 [@bloodhound-v6-3-release] -- a &lt;code&gt;CoerceToTGT&lt;/code&gt; edge that replaces the older &lt;code&gt;UnconstrainedDelegation&lt;/code&gt; finding for BHE customers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. &lt;a href=&quot;https://paragmali.com/blog/certified-pre-owned-ad-cs-and-active-directorys-second-trust/&quot; rel=&quot;noopener&quot;&gt;ADCS&lt;/a&gt; edges (early-access January 2024).&lt;/strong&gt; &lt;code&gt;ADCSESC1&lt;/code&gt; through &lt;code&gt;ADCSESC10&lt;/code&gt;, plus the &lt;strong&gt;&lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt; edge for ESC8&lt;/strong&gt; [@specterops-2024-adcs-bloodhound]. These edges land in BloodHound roughly thirty months after Will Schroeder and Lee Christensen first published the ESC1 to ESC8 catalog in &lt;em&gt;Certified Pre-Owned: Abusing Active Directory Certificate Services&lt;/em&gt; [@specterops-2021-certified-preowned]. Each ADCS edge in BloodHound is the most complex in the taxonomy because each is composed from multiple raw facts (see the traversable / non-traversable discussion below).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;7. Azure / Entra ID edges&lt;/strong&gt; (via AzureHound, November 20, 2020) [@specterops-2020-bloodhound-4]. &lt;code&gt;AZGlobalAdmin&lt;/code&gt;, &lt;code&gt;AZRoleAssignment&lt;/code&gt;, &lt;code&gt;AZContains&lt;/code&gt;, &lt;code&gt;AZOwns&lt;/code&gt;, &lt;code&gt;AZUserAccessAdministrator&lt;/code&gt;, &lt;code&gt;AZAddSecret&lt;/code&gt;, &lt;code&gt;AZMGAddOwner&lt;/code&gt;, plus AzureRM-side resource roles. Microsoft Entra &lt;a href=&quot;https://paragmali.com/blog/privileged-identity-management-how-a-two-state-role-assignme/&quot; rel=&quot;noopener&quot;&gt;Privileged Identity Management (PIM)&lt;/a&gt; role coverage was added in BloodHound v8.0 in July 2025 [@specterops-2025-opengraph].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;8. OpenGraph custom edges (v8.0, July 29, 2025).&lt;/strong&gt; User-defined edges for arbitrary substrates: GitHub, Snowflake, Microsoft SQL Server, ServiceNow, Tailscale, Duo. The schema is intentionally generic so that a community contributor can ship edges for any system whose privilege model can be drawn as a graph [@bloodhound-opengraph-library].&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Family&lt;/th&gt;
&lt;th&gt;Representative edges&lt;/th&gt;
&lt;th&gt;Underlying AD mechanism&lt;/th&gt;
&lt;th&gt;What it gives the attacker&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Group membership&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MemberOf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;member&lt;/code&gt; attribute on group object&lt;/td&gt;
&lt;td&gt;Inherits all permissions held by the group&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ACL write-equivalents&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GenericAll&lt;/code&gt;, &lt;code&gt;GenericWrite&lt;/code&gt;, &lt;code&gt;WriteDacl&lt;/code&gt;, &lt;code&gt;WriteOwner&lt;/code&gt;, &lt;code&gt;ForceChangePassword&lt;/code&gt;, &lt;code&gt;AddKeyCredentialLink&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specific dangerous-right ACE patterns in &lt;code&gt;nTSecurityDescriptor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Take control of the target principal (reset password, modify object, plant shadow credentials)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sessions&lt;/td&gt;
&lt;td&gt;&lt;code&gt;HasSession&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NetSessionEnum&lt;/code&gt; and &lt;code&gt;SAMR&lt;/code&gt; enumeration on member computers&lt;/td&gt;
&lt;td&gt;Pivot via credential theft from the logged-in user&apos;s memory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remote execution&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AdminTo&lt;/code&gt;, &lt;code&gt;CanRDP&lt;/code&gt;, &lt;code&gt;ExecuteDCOM&lt;/code&gt;, &lt;code&gt;CanPSRemote&lt;/code&gt;, &lt;code&gt;SQLAdmin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Local-admin membership, RDP / DCOM / WinRM / SQL group rights&lt;/td&gt;
&lt;td&gt;Run arbitrary code as the target principal on the target host&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kerberos delegation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AllowedToDelegate&lt;/code&gt;, &lt;code&gt;AllowedToAct&lt;/code&gt;, &lt;code&gt;CoerceToTGT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Constrained and resource-based delegation attributes&lt;/td&gt;
&lt;td&gt;Forge service tickets and impersonate other accounts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ADCS composite&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ADCSESC1&lt;/code&gt; through &lt;code&gt;ADCSESC10&lt;/code&gt;, &lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Certificate template misconfigurations plus CA trust plus enrollment ACEs&lt;/td&gt;
&lt;td&gt;Obtain a certificate usable for authentication as a privileged account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure / Entra&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AZGlobalAdmin&lt;/code&gt;, &lt;code&gt;AZRoleAssignment&lt;/code&gt;, &lt;code&gt;AZAddSecret&lt;/code&gt;, &lt;code&gt;AZOwns&lt;/code&gt;, &lt;code&gt;AZMGAddOwner&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Entra role assignments, AzureRM RBAC&lt;/td&gt;
&lt;td&gt;Cross the on-prem to cloud boundary; pivot via tenant or subscription privileges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenGraph&lt;/td&gt;
&lt;td&gt;User-defined&lt;/td&gt;
&lt;td&gt;Any substrate the contributor models&lt;/td&gt;
&lt;td&gt;Anything the contributed schema encodes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The ADCS family deserves a closer look because it introduced an important new modelling vocabulary.&lt;/p&gt;

A *traversable* edge is one the shortest-path query can step through directly: `MemberOf`, `ForceChangePassword`, `CanRDP`. A *non-traversable* edge is a precondition relationship that is only exploitable when several others appear together. A certificate template&apos;s `Enroll` ACE is non-traversable on its own; combined with eight other facts about the template, the issuing CA, and the domain&apos;s trust posture, it composes into `ADCSESC1`. The post-processor scans for the full pattern and synthesises a single traversable edge that the BFS can then treat as one hop [@specterops-2024-adcs-bloodhound].
&lt;p&gt;For ESC1 the pattern has nine numbered prerequisites: six template and CA requirements, two enterprise-CA trust facts, and one implicit constraint. None of the nine raw facts is exploitable in isolation. All nine together are. The post-processor&apos;s job is to walk the candidate sub-graphs, check every requirement, and write the composed &lt;code&gt;ADCSESC1&lt;/code&gt; edge when the pattern holds.&lt;/p&gt;
&lt;p&gt;This is a non-trivial graph-modelling contribution because it gives the field a vocabulary for &quot;an edge that is real only as a join over several facts.&quot; It also generalises beyond ADCS: any future attack primitive composed from a fixed pattern of raw facts can be modelled the same way.&lt;/p&gt;
&lt;p&gt;ESC8 -- the &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;NTLM relay&lt;/a&gt; primitive against an HTTP-enrollment certificate authority -- is the most delicate case, and the one most commonly mis-modelled in early secondary writeups.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt; edge is a &lt;strong&gt;Group(&lt;code&gt;Authenticated Users&lt;/code&gt;) to Computer(coerced target)&lt;/strong&gt; edge, not a Computer to Computer edge as some early secondary writeups described. The relay-target CA and the certificate template are carried as &lt;em&gt;edge metadata&lt;/em&gt;, not as additional graph nodes. The canonical edge documentation is explicit: &lt;em&gt;Source: Authenticated Users [Group] / Destination: Computer / Traversable: Yes&lt;/em&gt; [@bloodhound-coerce-relay-edge].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The schema correction matters because the source-principal choice affects every shortest-path query that crosses ESC8. If the edge is mis-modelled as Computer to Computer, queries that begin from a low-privilege user account miss the path entirely. The Group-to-Computer schema correctly captures that &lt;em&gt;any authenticated principal&lt;/em&gt; can coerce.&lt;/p&gt;
&lt;p&gt;What the graph does not yet model is also worth naming. The &lt;code&gt;SpecterOps/TierZeroTable&lt;/code&gt; README states it verbatim: &lt;em&gt;&quot;DISCLAIMER: The table does not include all Tier Zero assets yet.&quot;&lt;/em&gt; [@specterops-tier-zero-table] Several edge classes remain partially or fully out of scope; the full enumeration appears in Section 11 (open problems). Coverage expansion is iterative and community-fed; OpenGraph (Section 9) is the structural answer to &quot;where does the graph end?&quot;&lt;/p&gt;

flowchart TD
    subgraph OnPrem[&quot;On-prem Active Directory&quot;]
        Members[&quot;MemberOf, Owns&quot;]
        ACL[&quot;ACL write-equivalents&lt;br /&gt;GenericAll, WriteDacl, ForceChangePassword,&lt;br /&gt;AddKeyCredentialLink&quot;]
        Sessions[&quot;HasSession&quot;]
        Exec[&quot;AdminTo, CanRDP, ExecuteDCOM,&lt;br /&gt;CanPSRemote, SQLAdmin&quot;]
        Krb[&quot;Kerberos delegation&lt;br /&gt;AllowedToDelegate, AllowedToAct, CoerceToTGT&quot;]
    end
    subgraph Entra[&quot;Entra ID and AzureRM&quot;]
        EntraRoles[&quot;AZGlobalAdmin, AZRoleAssignment,&lt;br /&gt;AZAddSecret, AZUserAccessAdministrator,&lt;br /&gt;PIM roles&quot;]
        AzureRM[&quot;AZContains, AZOwns,&lt;br /&gt;AzureRM resource roles&quot;]
    end
    subgraph ADCS[&quot;ADCS composite edges&quot;]
        ESC[&quot;ADCSESC1 to ADCSESC10,&lt;br /&gt;CoerceAndRelayNTLMToADCS&quot;]
    end
    subgraph Open[&quot;OpenGraph user-defined&quot;]
        Custom[&quot;GitHub, Snowflake, SQL Server,&lt;br /&gt;ServiceNow, Tailscale, Duo, custom&quot;]
    end
    OnPrem --&amp;gt; Cypher((Cypher query layer))
    Entra --&amp;gt; Cypher
    ADCS --&amp;gt; Cypher
    Open --&amp;gt; Cypher
&lt;p&gt;If this is what one community modelled, the natural question is: what did Microsoft model? And when?&lt;/p&gt;
&lt;h2&gt;8. The defender adoption -- Microsoft catches up, 2018 to 2024&lt;/h2&gt;
&lt;p&gt;The defender vendor whose product BloodHound was mapping is also a defender vendor with a graph product of its own. Three of them, in fact, shipped in three different years for three different substrates. They are easy to confuse; press releases sometimes do.&lt;/p&gt;
&lt;p&gt;The first arrived on November 27, 2018, when Tali Ash (then a Program Manager on the Azure Advanced Threat Protection team) announced a preview feature called &lt;em&gt;Lateral Movement Paths&lt;/em&gt; (LMPs) in a Microsoft tech-community post [@ms-azure-atp-lmp-2018]. LMPs were a graph-shaped visualisation, but a constrained one: restricted to &quot;sensitive accounts&quot; (a configurable set defaulting to Domain Admins and similar) plus non-sensitive accounts that had shared a session on the same host as a sensitive account.&lt;/p&gt;
&lt;p&gt;The portal rendered one- and two-hop credential-theft pivots as a static SVG. There was no Cypher equivalent, no LMP-export API, and no way to write a custom query. Azure ATP was rebranded &lt;strong&gt;Microsoft Defender for Identity&lt;/strong&gt; in 2020, and the LMP feature came along under the new name [@ms-mdi-lmp-docs].&lt;/p&gt;
&lt;p&gt;Several secondary sources date Lateral Movement Paths to &quot;June 2019,&quot; which corresponds to the general-availability and rebrand window rather than the original preview announcement. The primary Microsoft tech-community post is November 27, 2018; treat the year-not-month for any third-party claim and prefer the November 2018 preview date as the canonical first ship.&lt;/p&gt;
&lt;p&gt;The second arrived in October 2022, when Microsoft Defender for Cloud&apos;s Defender CSPM plan added a &lt;em&gt;cloud security graph&lt;/em&gt; with attack-path analysis (public preview at Ignite October 2022; generally available March 28, 2023) [@ms-defender-cloud-attack-path]. This product is a &lt;em&gt;cloud&lt;/em&gt; attack-path graph: Azure plus AWS plus GCP asset inventory, with inferred edges for permissions, network reachability, vulnerability presence, and internet exposure. It is explicitly &lt;em&gt;not&lt;/em&gt; the Active Directory identity graph; it covers the multi-cloud workload surface.&lt;/p&gt;
&lt;p&gt;A common mistake conflates this 2022-2023 product (Defender for &lt;em&gt;Cloud&lt;/em&gt;) with Microsoft Defender for &lt;em&gt;Identity&lt;/em&gt; (the LMP product from November 2018). The substrate, the team, and the year are all different. Worth flagging here because secondary writeups repeat the confusion often.&lt;/p&gt;

The Microsoft Defender XDR product family is a naming minefield. *Defender for Identity* (MDI) is the on-prem AD identity-threat product; LMPs are its graph view. *Defender for Cloud* (MDC) is the multi-cloud workload-protection product; its CSPM plan ships cloud-security-graph attack-path analysis. *Defender for Endpoint* (MDE) is the EDR product; it does not ship its own attack-path graph but feeds telemetry into MSEM. *Microsoft Security Exposure Management* (MSEM, GA November 19, 2024) is the unified exposure-graph layer that subsumes the others. Four products, four substrates, four ship dates. The naming overlap is unfortunate but the distinctions are real.
&lt;p&gt;The third arrived on November 19, 2024, at the Ignite 2024 keynote in Chicago. Satya Nadella, in the opening keynote, announced that &lt;strong&gt;Microsoft Security Exposure Management&lt;/strong&gt; (MSEM) had reached general availability [@ms-ignite-2024-msem]. MSEM is the product whose attack-path model is &lt;em&gt;structurally equivalent&lt;/em&gt; to BloodHound&apos;s: cross-substrate (identity plus endpoint plus multi-cloud), first-class attack-path objects with choke-point and blast-radius dashboards, and continuous data feed via the Defender XDR signal plane.&lt;/p&gt;

Microsoft&apos;s unified exposure-graph product, generally available November 19, 2024, at Ignite 2024 in Chicago. MSEM ingests telemetry from Defender for Endpoint, Defender for Identity, Defender for Cloud, Entra ID, and the Defender XDR plane into a single graph. Attack paths are first-class objects with three dashboard views: an attack-path list, choke-point analysis (small sets of nodes whose compromise enables disproportionately many downstream paths), and blast-radius (downstream reach of a selected node) [@ms-msem-attack-paths].
&lt;p&gt;The MSEM docs page introduces the model verbatim: &lt;em&gt;&quot;Attack paths in Microsoft Security Exposure Management help you to proactively identify and visualize potential routes that attackers can exploit using vulnerabilities, gaps, and misconfigurations across endpoints, cloud environments, and hybrid infrastructures.&quot;&lt;/em&gt; And, on choke points: &lt;em&gt;&quot;By focusing on these choke points, you can reduce risk by addressing high-impact assets.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The query interface is the Defender XDR portal plus KQL (Kusto Query Language), not Cypher. The graph engine is proprietary; Microsoft does not publish per-query latency numbers or the underlying algorithms. But the model -- nodes, typed edges, attack paths as the unit of analysis, choke-point and blast-radius views -- is the model BloodHound shipped at DEF CON 24 in August 2016.&lt;/p&gt;
&lt;p&gt;The arc takes eight years. From the August 6, 2016 BloodHound talk to the November 19, 2024 MSEM general-availability announcement is eight years and three months. The defender vendor whose product the original BloodHound was mapping ships a defender product whose attack-path model is structurally equivalent to the one a red-team consultancy shipped in a conference talk eight years earlier.&lt;/p&gt;
&lt;p&gt;Microsoft adopted the model. The community kept extending it. By 2026 the frontier is no longer &lt;em&gt;&quot;does the graph exist?&quot;&lt;/em&gt; It is &lt;em&gt;&quot;how do we make the graph weighted, complete, and substrate-independent?&quot;&lt;/em&gt; That is the state of the art.&lt;/p&gt;
&lt;h2&gt;9. State of the art -- Tier Zero, ADCS edges, and OpenGraph, 2023 to 2026&lt;/h2&gt;
&lt;p&gt;By the time MSEM shipped, SpecterOps had already moved past &lt;em&gt;&quot;is there a graph?&quot;&lt;/em&gt; and was asking three sharper questions. Where does the graph end? How do we model attack primitives that compose from raw facts? And does the AD-specific schema even matter?&lt;/p&gt;
&lt;p&gt;The first question is what &lt;em&gt;&quot;Tier Zero&quot;&lt;/em&gt; means. On June 22, 2023, Jonas Bülow Knudsen, Elad Shamir, and Justin Kohler at SpecterOps published &lt;em&gt;What is Tier Zero -- Part 1&lt;/em&gt;, which reframed Microsoft&apos;s tiered-administration concept -- introduced in the 2012-2014 Securing Privileged Access guidance and renamed the Enterprise Access Model with the &quot;Control Plane&quot; vocabulary in December 2020 [@ms-enterprise-access-model] -- as a property &lt;em&gt;of the graph&lt;/em&gt; [@specterops-2023-tier-zero].&lt;/p&gt;
&lt;p&gt;A Tier Zero asset (see Definition below) reframes Microsoft&apos;s tiered concept from &lt;em&gt;the set of things in the high-privilege tier&lt;/em&gt; to &lt;em&gt;the set of things from which the high-privilege tier is reachable&lt;/em&gt;. Microsoft&apos;s own Tier 0 definition -- &lt;em&gt;&quot;Direct Control of enterprise identities... and all the assets in it&quot;&lt;/em&gt; -- becomes a graph property. The two formulations are equivalent if and only if the graph is complete. If the graph is incomplete (which it is), the Tier Zero set computed from the graph is the floor, not the ceiling.&lt;/p&gt;

Any node in the attack-path graph whose compromise lets an attacker reach an administrative privilege in the forest. The companion `SpecterOps/TierZeroTable` GitHub project is the community-maintained inventory; the README discloses that the table is the floor, not the ceiling [@specterops-tier-zero-table].
&lt;p&gt;The Tier Zero definition is the answer to &lt;em&gt;&quot;shortest path to what?&quot;&lt;/em&gt; -- the target side of every BloodHound shortest-path query. Without a defined Tier Zero set, the question has no endpoint.&lt;/p&gt;
&lt;p&gt;The second question is how to model attack primitives that compose. The January 24, 2024 SpecterOps blog by Knudsen formalised this with the traversable / non-traversable edge distinction discussed in Section 7. The mechanism generalises: any attack primitive whose exploitability is a conjunction of raw facts can be encoded as a composed edge that the post-processor synthesises when the pattern is present.&lt;/p&gt;
&lt;p&gt;ESC1, walked through in Section 7, is the canonical example: nine numbered prerequisites that the post-processor checks before writing the composed &lt;code&gt;ADCSESC1&lt;/code&gt; edge [@specterops-2024-adcs-bloodhound]. Subsequent posts in the series extended the same machinery to ESC3, ESC4, ESC6, ESC7, ESC8 (the &lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt; edge), ESC9, ESC10, and -- on February 14, 2024 -- ESC13 [@specterops-2024-esc13].&lt;/p&gt;
&lt;p&gt;In December 2024 BloodHound v6.3 introduced an early-access &quot;improved analysis algorithm&quot; internally referred to as &lt;strong&gt;Butterfly&lt;/strong&gt; [@bloodhound-v6-3-release]. Butterfly is the first production attempt at &lt;em&gt;bi-directional impact&lt;/em&gt; analysis. Pre-v6.3 BloodHound Enterprise quantified risk as &quot;&lt;em&gt;who can reach this node?&lt;/em&gt;&quot; (incoming attack-path count). v6.3 also quantifies &quot;&lt;em&gt;who can this node reach if compromised?&lt;/em&gt;&quot; (outgoing blast radius).&lt;/p&gt;
&lt;p&gt;The release notes describe the outcome but not the algorithm: &lt;em&gt;&quot;Improve risk scoring fidelity for all finding types... Measure risk at each individual finding... Support the inclusion of hybrid paths in risk scoring (Azure assets will now contribute to measured risk in AD and vice versa).&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The same release also announced that BloodHound Enterprise had begun migrating off Neo4j onto PostgreSQL as the &lt;em&gt;graph&lt;/em&gt; database, with the release notes reporting &lt;em&gt;&quot;&amp;gt;50% improvement in the time it takes to perform post-processing during the Analysis process.&quot;&lt;/em&gt; Cypher continues to be the query language; the engine underneath changed.&lt;/p&gt;
&lt;p&gt;The third question -- whether the AD-specific schema matters -- got its answer on July 29, 2025, when SpecterOps released BloodHound v8.0 with &lt;strong&gt;OpenGraph&lt;/strong&gt; [@specterops-2025-opengraph]. OpenGraph decouples the graph engine from the AD-specific schema. Users (and SpecterOps partners) define their own node and edge kinds and ingest attack-path data from arbitrary substrates. The initial release included GitHub organisations, Snowflake role hierarchies, Microsoft SQL Server logins, ServiceNow groups, and Tailscale ACLs. Subsequent community contributions extended the library.&lt;/p&gt;

BloodHound OpenGraph is a foundational shift toward... identity risk management across the entire enterprise. -- Justin Kohler, SpecterOps Chief Product Officer, July 29, 2025.
&lt;p&gt;OpenGraph is the closing observation of an arc that began with Phillips and Swiler in 1998: &lt;em&gt;the model is the abstraction; the substrate is whatever your enterprise runs.&lt;/em&gt; The same &lt;code&gt;shortestPath()&lt;/code&gt; that finds Active Directory attack paths now finds attack paths over a GitHub organisation, a Snowflake role hierarchy, or a Microsoft SQL Server login graph, with no engine change. The 2026 BloodHound release (v9.1.0, May 6, 2026, per the public release-notes index [@bloodhound-release-notes-index]) extends OpenGraph and adds incremental edge updates -- the first step toward a streaming graph rather than a snapshot.&lt;/p&gt;
&lt;h2&gt;10. Competing approaches -- BloodHound versus Microsoft versus the alternatives&lt;/h2&gt;
&lt;p&gt;In 2026 no single product covers every substrate. The field is plural.&lt;/p&gt;
&lt;p&gt;A practitioner choosing among attack-path tools answers four questions, in order. What substrate do you need to cover? Self-host or SaaS? Snapshot or continuous? Open query language or vendor portal? The table below assembles the answers on the dimensions a 2026 practitioner actually uses.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Substrate&lt;/th&gt;
&lt;th&gt;Engine&lt;/th&gt;
&lt;th&gt;Query language&lt;/th&gt;
&lt;th&gt;Deployment&lt;/th&gt;
&lt;th&gt;Licensing&lt;/th&gt;
&lt;th&gt;Edge weighting&lt;/th&gt;
&lt;th&gt;ADCS coverage&lt;/th&gt;
&lt;th&gt;Best fit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;BloodHound CE 9.x&lt;/td&gt;
&lt;td&gt;AD + Entra + AzureRM + OpenGraph&lt;/td&gt;
&lt;td&gt;Neo4j + Postgres app DB&lt;/td&gt;
&lt;td&gt;Cypher&lt;/td&gt;
&lt;td&gt;Self-hosted Docker Compose&lt;/td&gt;
&lt;td&gt;Apache-2.0&lt;/td&gt;
&lt;td&gt;No (unweighted BFS)&lt;/td&gt;
&lt;td&gt;Yes -- ESC1 through ESC10 + ESC8 composite&lt;/td&gt;
&lt;td&gt;Authorised offensive testing + DIY blue team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BloodHound Enterprise&lt;/td&gt;
&lt;td&gt;Same as CE&lt;/td&gt;
&lt;td&gt;PostgreSQL-as-graph (in-progress migration off Neo4j)&lt;/td&gt;
&lt;td&gt;Cypher&lt;/td&gt;
&lt;td&gt;SaaS&lt;/td&gt;
&lt;td&gt;Commercial&lt;/td&gt;
&lt;td&gt;Bi-directional (Butterfly v6.3+); weighting function not public&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Continuous AD/Entra attack-surface management at enterprise scale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adalanche&lt;/td&gt;
&lt;td&gt;AD (on-prem; LDIF or live LDAP)&lt;/td&gt;
&lt;td&gt;In-memory Go&lt;/td&gt;
&lt;td&gt;AQL (GQL-like)&lt;/td&gt;
&lt;td&gt;Single Go binary&lt;/td&gt;
&lt;td&gt;Open source&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (per README)&lt;/td&gt;
&lt;td&gt;Offline / air-gapped analysis from LDIF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft Security Exposure Management&lt;/td&gt;
&lt;td&gt;Defender XDR signal: identity + endpoint + multi-cloud + Entra&lt;/td&gt;
&lt;td&gt;Proprietary&lt;/td&gt;
&lt;td&gt;KQL + portal&lt;/td&gt;
&lt;td&gt;SaaS&lt;/td&gt;
&lt;td&gt;Microsoft licensing&lt;/td&gt;
&lt;td&gt;Implicit (filter against exploitability oracle)&lt;/td&gt;
&lt;td&gt;Indirect via MDI signals&lt;/td&gt;
&lt;td&gt;Hybrid Microsoft-substrate unified exposure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MDI Lateral Movement Paths&lt;/td&gt;
&lt;td&gt;On-prem AD (sensitive-account paths only)&lt;/td&gt;
&lt;td&gt;Proprietary&lt;/td&gt;
&lt;td&gt;None -- portal only&lt;/td&gt;
&lt;td&gt;SaaS&lt;/td&gt;
&lt;td&gt;Microsoft licensing&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;Implicit via separate MDI alerts&lt;/td&gt;
&lt;td&gt;Default-on credential-hopping detection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Defender for Cloud CSPM attack-path analysis&lt;/td&gt;
&lt;td&gt;Multi-cloud (Azure + AWS + GCP)&lt;/td&gt;
&lt;td&gt;Proprietary&lt;/td&gt;
&lt;td&gt;Cloud Security Explorer + KQL&lt;/td&gt;
&lt;td&gt;SaaS&lt;/td&gt;
&lt;td&gt;Microsoft licensing&lt;/td&gt;
&lt;td&gt;Implicit&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;Multi-cloud workload protection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PingCastle / Semperis DSP / ADAudit Plus&lt;/td&gt;
&lt;td&gt;On-prem AD (+ limited Entra)&lt;/td&gt;
&lt;td&gt;None -- list-of-findings&lt;/td&gt;
&lt;td&gt;None -- HTML / portal&lt;/td&gt;
&lt;td&gt;Self-hosted or SaaS&lt;/td&gt;
&lt;td&gt;Commercial / mixed&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;Single-finding hygiene only&lt;/td&gt;
&lt;td&gt;Compliance auditing and change tracking&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;A few rows deserve commentary.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; BloodHound CE ships under &lt;strong&gt;Apache-2.0&lt;/strong&gt; per the current repository [@bloodhound-ce-repo]. The GPL-3.0 license you may see in older treatments applies only to the deprecated BloodHound Legacy v4 repository [@bloodhound-legacy-repo], which was last updated in 2023 and is no longer maintained. The licensing difference is material: GPL-3.0 is copyleft, Apache-2.0 is permissive. Downstream use cases that need permissive licensing should rely on the current CE.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Older blog posts and conference talks frequently call BloodHound CE GPL-3.0. The CE-Legacy LICENSE block does carry the GPL-3.0 copyright header, which is the source of the confusion. The &lt;em&gt;current&lt;/em&gt; CE codebase at github.com/SpecterOps/BloodHound is Apache-2.0; the GPL-3.0 LICENSE applies only to the deprecated Legacy v4 repository.&lt;/p&gt;
&lt;p&gt;Adalanche, by Lars Karlslund, is the load-bearing counter-example to the claim that &quot;the graph model requires Neo4j&quot; [@adalanche-repo]. Adalanche reads AD data from an LDIF dump or live LDAP, builds the graph entirely in process memory, and exposes a web GUI plus an Adalanche Query Language (AQL) -- described in the README as &lt;em&gt;&quot;a GQL-like language that allows for complex queries.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The README&apos;s headline claim is verbatim: &lt;em&gt;&quot;Adalanche gives instant results, showing you what permissions users and groups have in an Active Directory.&quot;&lt;/em&gt; The trade is no continuous monitoring, no multi-user web app, and a smaller community in exchange for zero deployment friction. The model is identical; the engine is replaceable.&lt;/p&gt;
&lt;p&gt;MSEM is the closest Microsoft analogue to BloodHound (see Section 8 for substrate and query interface). Reasonable defenders run &lt;em&gt;both&lt;/em&gt; MSEM and BloodHound (CE or Enterprise) on the same forest. The tools are complementary rather than substitutionary: MSEM brings the EDR plus workload-protection telemetry that BloodHound does not natively ingest, while BloodHound brings the precise AD edge semantics that SpecterOps&apos;s research community has validated. Running both is not double-counting.&lt;/p&gt;
&lt;p&gt;The hygiene scanners -- PingCastle [@pingcastle], Semperis DSP [@semperis-dsp], ManageEngine ADAudit Plus [@manageengine-adaudit-plus] -- are the surviving descendants of the per-object ACL-inspection generation, with risk-scoring layered on top. They are valuable for compliance auditing and change tracking. They do not expose a queryable attack-path graph. The compliance auditor and the attack-path analyst are different personas with different tools.&lt;/p&gt;
&lt;p&gt;If the field is plural and every tool has a gap, what is the shape of the problem that no tool yet solves? The next section is the honest answer.&lt;/p&gt;
&lt;h2&gt;11. Theoretical limits and open problems&lt;/h2&gt;
&lt;p&gt;Some of the gaps in attack-path analysis are engineering gaps. Others are not.&lt;/p&gt;
&lt;p&gt;The single most consequential open problem is &lt;strong&gt;edge weighting&lt;/strong&gt;. BloodHound&apos;s BFS treats every edge as one hop. In reality, &lt;code&gt;MemberOf&lt;/code&gt; is effectively free; &lt;code&gt;ForceChangePassword&lt;/code&gt; requires the attacker to log in as the changed principal afterwards; &lt;code&gt;AddKeyCredentialLink&lt;/code&gt; requires shadow-credential infrastructure; &lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt; requires an active SMB-coercion primitive, NTLM relay tooling, and an ESC8-vulnerable certificate authority. A shortest-&lt;em&gt;hop&lt;/em&gt; path is not in general the shortest-&lt;em&gt;exploitation-cost&lt;/em&gt; path.&lt;/p&gt;
&lt;p&gt;BloodHound Enterprise v6.3 shipped the Butterfly analysis as the first production attempt to relax this assumption. As the v6.3 release notes acknowledge (see Section 9), Butterfly&apos;s weighting function is not publicly documented [@bloodhound-v6-3-release].&lt;/p&gt;
&lt;p&gt;Academic intuition suggests weighting edges by an exploitation-success probability and computing &lt;em&gt;most-likely-exploited&lt;/em&gt; paths via shortest paths under negative-log-probability weights. The complexity ceiling is well-known: Dijkstra (with non-negative weights) runs in $O(E + V\log V)$ time with a Fibonacci heap; Bellman-Ford handles negative weights at $O(VE)$. Either fits comfortably inside the per-query budget BloodHound already operates within.&lt;/p&gt;
&lt;p&gt;The unsolved part is the &lt;em&gt;empirical calibration&lt;/em&gt;: what numerical weight is the right weight on a &lt;code&gt;ForceChangePassword&lt;/code&gt; edge versus a &lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt; edge? There is no published peer-reviewed answer.&lt;/p&gt;
&lt;p&gt;The second open problem is &lt;strong&gt;coverage&lt;/strong&gt;. The &lt;code&gt;TierZeroTable&lt;/code&gt; README is the authoritative self-disclosure: file-system ACLs on member servers, fine-grained GPO delegation, on-host service-account permissions, some Entra conditional-access logic, and cross-tenant Entra B2B trust paths remain partially or fully out of scope [@specterops-tier-zero-table]. This is an &lt;em&gt;engineering&lt;/em&gt; problem -- more collectors, more edge definitions -- rather than an algorithmic one. OpenGraph is the structural answer: shift coverage from &quot;what edges has SpecterOps modelled?&quot; to &quot;what edges has the community contributed to the shared library?&quot; [@bloodhound-opengraph-library].&lt;/p&gt;
&lt;p&gt;The third is &lt;strong&gt;graph privacy&lt;/strong&gt;. A continuously-collected, complete AD privilege graph shipped to a third-party SaaS backend is, in adversarial hands, a pre-computed attack plan for the customer&apos;s forest. Tenant isolation, encryption at rest, SOC 2 and FedRAMP attestation, and customer-managed key encryption do not eliminate the structural risk: a compromised SaaS backend yields the customer&apos;s graph regardless of compliance posture.&lt;/p&gt;
&lt;p&gt;Cryptographic approaches -- homomorphic graph queries, secure multi-party computation for path enumeration -- exist in the theoretical literature but are not in production attack-path products at time of writing. Adalanche and self-hosted BloodHound CE remain the privacy-preserving options at the cost of forgoing continuous monitoring.&lt;/p&gt;
&lt;p&gt;The fourth is the &lt;strong&gt;the graph is alive&lt;/strong&gt; problem. Session edges (&lt;code&gt;HasSession&lt;/code&gt;) go stale in hours. New ACEs, new group memberships, new sessions appear continuously. SharpHound&apos;s snapshot model is yesterday&apos;s view; continuous collectors (BloodHound Enterprise, MSEM agent streams) trade stealth for freshness. The May 6, 2026 release notes describe BloodHound CE&apos;s first move toward a streaming model: &lt;em&gt;&quot;incremental edge updates that reduce unnecessary writes during post-processing&quot;&lt;/em&gt; [@bloodhound-release-notes-index]. No production attack-path tool yet ships a fully streaming graph.&lt;/p&gt;
&lt;p&gt;The fifth is &lt;strong&gt;combinatorial intractability&lt;/strong&gt;. These are not engineering gaps; they are complexity-theoretic facts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Counting all attack paths is #P-complete.&lt;/strong&gt; Leslie Valiant&apos;s 1979 result on the complexity of counting solutions to combinatorial problems applies directly: counting the simple paths between two nodes in a general graph cannot be done in polynomial time unless P = #P [@valiant-1979-permanent]. BloodHound&apos;s path-count UI is necessarily an approximation or a length-truncation; this is the theoretical reason why.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The minimum-edge-cut &quot;defender hardening&quot; problem is NP-hard.&lt;/strong&gt; Choose the smallest set of edges whose removal disconnects the attacker from the goal. Sheyner et al. 2002 proved the result is NP-hard but admits an $O(\log n)$ approximation [@sheyner-et-al-2002-attack-graphs]. BHE choke-point ranking and MSEM choke-point analysis necessarily implement heuristic approximations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Finding regular simple paths is NP-complete.&lt;/strong&gt; Mendelzon and Wood 1995 proved that finding a simple path matching a regular expression over edge labels in a graph database is NP-complete [@mendelzon-wood-1995-dblp]. Cypher&apos;s &lt;code&gt;shortestPath()&lt;/code&gt; does not enforce simple-path semantics, which is why it remains in P; quantified path patterns with &lt;code&gt;DIFFERENT RELATIONSHIPS&lt;/code&gt; semantics (available since Neo4j 5.x and documented in the current Cypher manual [@neo4j-cypher-variable-length]) do enforce simple paths and so cross into the NP-complete regime.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; BloodHound&apos;s per-query algorithm (BFS, $O(V + E)$) is optimal up to constants. The frontier of the field is no longer the algorithm. It is what &lt;em&gt;question&lt;/em&gt; we ask the algorithm: weighted? regular-path? simple-path? bi-directional? cross-substrate? Each open question is a different model, not a different implementation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Three further honest framings deserve a mention.&lt;/p&gt;
&lt;p&gt;First, the &lt;strong&gt;standardisation of OpenGraph edge taxonomies&lt;/strong&gt; is unsettled. Without community convergence on edge naming, different contributors may model the same substrate with incompatible schemas. Historical precedent (MITRE ATT&amp;amp;CK technique IDs, CVE identifiers) suggests that convergence happens when a single high-trust curator becomes the de-facto registry; whether SpecterOps will operate OpenGraph as a vendor-neutral standards body or as a SpecterOps-owned artefact is a governance question, not an algorithmic one.&lt;/p&gt;
&lt;p&gt;Second, the &lt;strong&gt;adversarial robustness of the collector&lt;/strong&gt; is an open question: SharpHound runs as an authenticated principal, and an attacker with prior compromise can poison the collection. There is no closed-form defence.&lt;/p&gt;
&lt;p&gt;Third, the &lt;strong&gt;absence of any public head-to-head benchmark&lt;/strong&gt; of BloodHound CE versus BHE versus Adalanche versus MSEM on the same forest under controlled conditions is structural: Microsoft does not publish per-query latency, SpecterOps publishes only relative improvement claims, and the academic line uses 2005-era hardware figures that are not comparable.&lt;/p&gt;
&lt;h2&gt;12. Practical guide -- running BloodHound today&lt;/h2&gt;
&lt;p&gt;If the previous sections sold you on the model, the next few paragraphs are the minimum you need to stand it up.&lt;/p&gt;
&lt;p&gt;Stand up BloodHound CE with the Docker Compose file in the repository [@bloodhound-ce-repo]. The stack is four containers: a PostgreSQL application database (users, roles, sessions, audit logs, saved queries); a Neo4j graph database holding the property graph; a Go REST API; and a React plus Sigma.js single-page frontend. Five minutes to first boot on a developer laptop. The repository README is the authoritative deployment reference.&lt;/p&gt;
&lt;p&gt;Run &lt;strong&gt;SharpHound&lt;/strong&gt; on a domain-joined Windows host as the collection identity. The default invocation -- &lt;code&gt;SharpHound.exe --CollectionMethods all,GPOLocalGroup&lt;/code&gt; -- enumerates every group membership, every recognised ACL pattern, every active session, every local-admin relationship, and every Kerberos delegation. Run &lt;strong&gt;AzureHound&lt;/strong&gt; with appropriate Entra ID credentials for Entra and AzureRM coverage. Both emit JSON dumps in the same envelope; the BloodHound CE upload tab in the web UI ingests both.&lt;/p&gt;
&lt;p&gt;Open the web UI. The stock pre-built queries are a reasonable starting palette: &lt;em&gt;Find Shortest Paths to Domain Admins&lt;/em&gt;, &lt;em&gt;Find Principals with DCSync Rights&lt;/em&gt;, &lt;em&gt;Find Computers with Unsupported Operating Systems&lt;/em&gt;, and &lt;em&gt;Shortest Paths from Owned Principals to High-Value Targets&lt;/em&gt; (after marking some accounts as owned). Custom Cypher goes in the Cypher tab at the top right; the Section 6 query is a good template.&lt;/p&gt;
&lt;p&gt;The most important interpretation discipline: treat the result as a &lt;em&gt;risk register&lt;/em&gt;, not a vulnerability list. A finding is &quot;Bob can reach Domain Admins via a four-hop path.&quot; The &lt;em&gt;edge&lt;/em&gt; is &quot;Bob has &lt;code&gt;GenericWrite&lt;/code&gt; on Carol.&quot; Closing the edge breaks the finding &lt;em&gt;and&lt;/em&gt; every other path that passed through it. Edges are the unit of remediation, not findings. SpecterOps&apos;s own 2021 customer-anonymous essay &lt;em&gt;Active Directory Attack Paths -- Is It Always This Bad?&lt;/em&gt; reports findings from hundreds of engagements, and the recurring observation across forests is that a small number of high-blast-radius edges explain most of the discovered paths [@specterops-2021-ad-attack-paths].&lt;/p&gt;
&lt;p&gt;A few pitfalls are worth naming. &lt;code&gt;HasSession&lt;/code&gt; collection generates measurable LDAP and SAMR traffic that Microsoft Defender for Identity alerts on; coordinate with the blue team or expect detections. The stealth collection mode trades coverage for traffic volume.&lt;/p&gt;
&lt;p&gt;Unconstrained variable-length Cypher queries (&lt;code&gt;MATCH p=(a)-[*]-&amp;gt;(b)&lt;/code&gt;) can pin Neo4j&apos;s heap; CE&apos;s &quot;protected Cypher&quot; cost limits help but do not eliminate the problem, so prefer &lt;code&gt;shortestPath()&lt;/code&gt; or bound the path length explicitly. The wildcard-principal post-processing for &lt;code&gt;Authenticated Users&lt;/code&gt; and &lt;code&gt;Everyone&lt;/code&gt; requires v6.0 or later to be correct; older versions miscount these edges [@bloodhound-v6-0-release]. And the &lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt; edge is Group to Computer, not Computer to Computer, as discussed in Section 7.&lt;/p&gt;

```cypher
MATCH (n)
WHERE n.system_tags CONTAINS &apos;admin_tier_0&apos;
WITH collect(n) AS tier_zero
MATCH p = shortestPath((u:User {enabled:true})-[*1..6]-&amp;gt;(t))
WHERE t IN tier_zero AND NOT u.system_tags CONTAINS &apos;admin_tier_0&apos;
RETURN u.name AS source, t.name AS target, length(p) AS hops
ORDER BY hops ASC
LIMIT 25
```&lt;p&gt;This returns up to 25 enabled non-Tier-Zero users with the shortest paths into Tier Zero. The &lt;code&gt;[*1..6]&lt;/code&gt; bound prevents the pathological cyclic-graph cost explosion. Bound length aggressively until you have indexed your graph.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;

BloodHound is dual-use. Authorised defensive use on your own forest, or contracted penetration testing within written scope, is the standard legal posture. Running it against a directory you are not authorised to assess is unlawful in most jurisdictions: the Computer Fraud and Abuse Act in the United States; the Computer Misuse Act 1990 in the United Kingdom; equivalents in most EU jurisdictions. The dual-use posture is fundamental to the tool; the legal posture depends on you.
&lt;p&gt;The tool is the easy part. The hard part is what you do with the answer.&lt;/p&gt;
&lt;h2&gt;13. Frequently asked questions&lt;/h2&gt;
&lt;p&gt;The misconceptions worth disposing of, in order of how often they recur.&lt;/p&gt;

No. BloodHound is the SpecterOps-maintained, evolving set of edge families. File-system ACLs on member servers, fine-grained GPO delegation, on-host service-account permissions, and some Entra conditional-access logic remain partially or fully out of scope. The `SpecterOps/TierZeroTable` README is explicit about this limitation [@specterops-tier-zero-table]. Coverage expansion is iterative and community-fed; OpenGraph is the structural answer to scope generalisation.

The original BloodHound (2016) shipped Neo4j only. The modern BloodHound CE uses *both*: PostgreSQL as the application database (users, roles, sessions, audit logs) and Neo4j as the graph layer [@bloodhound-ce-repo]. BloodHound Enterprise has begun migrating entirely off Neo4j onto PostgreSQL-as-graph (announced in v6.3, December 2024) [@bloodhound-v6-3-release]; Cypher continues to be the query language on the new backend. The model is engine-independent; Adalanche proves the same point by doing it all in process memory in Go [@adalanche-repo].

Authorised defensive use on your own forest, yes. Contracted penetration testing within written scope, yes. Running it against a directory you are not authorised to assess is unlawful in most jurisdictions: the Computer Fraud and Abuse Act in the United States, the Computer Misuse Act 1990 in the United Kingdom, and equivalents in most EU jurisdictions. The dual-use posture is fundamental to the tool; legal compliance is the operator&apos;s responsibility.
&lt;h2&gt;Epilogue&lt;/h2&gt;
&lt;p&gt;The 2014 analyst with the whiteboard and the 2024 analyst with the Cypher query are doing the same work. The unit of analysis has shifted, and once the unit shifts, the field does not go back.&lt;/p&gt;
&lt;p&gt;John Lambert diagnosed it in two sentences in April 2015 [@lambert-2015-defenders-lists-attackers-graphs]. Andy Robbins, Rohan Vazarkar, and Will Schroeder shipped it as BloodHound in August 2016 [@bloodhound-legacy-repo]. SpecterOps extended it through AzureHound in 2020, the CE 5.0 web architecture in 2023, the Tier Zero formalisation in 2023, ADCS composed edges in 2024, Butterfly bi-directional analysis in 2024, and OpenGraph in 2025 [@specterops-2025-opengraph].&lt;/p&gt;
&lt;p&gt;Microsoft validated the model with Lateral Movement Paths in 2018, cloud security graph attack-path analysis in 2022 to 2023, and Microsoft Security Exposure Management at Ignite in 2024 [@ms-msem-attack-paths]. The community that shipped the graph won; the community that kept shipping lists is selling compliance reports to the auditors.&lt;/p&gt;
&lt;p&gt;The frontier in 2026 is not whether to model attacks as a graph -- that argument is settled. The frontier is how to make the graph weighted (so the shortest path approximates the easiest), how to make it complete (so the unmodelled edges shrink toward zero), and how to make it substrate-independent (so the next enterprise primitive worth modelling -- whatever it turns out to be -- can be ingested without changing the engine). Each of these is a research direction with its own asymptotic ceiling, its own engineering practice, and its own community of contributors.&lt;/p&gt;
&lt;p&gt;What started as a sentence in a 1,100-word essay on a personal GitHub repository is now an ISO-standardised query language [@iso-39075-2024-gql], a shipped Microsoft product family, an open-source repository with hundreds of thousands of downloads, and a discipline taught at most major security conferences. The graph wins because the graph is the right model. The right model wins because, eventually, the right model always does.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;bloodhound-attack-path-graph&quot; keyTerms={[
  { term: &quot;Attack-path graph&quot;, definition: &quot;A directed graph whose nodes are security principals and resources and whose edges are privilege relationships an attacker can traverse. Reachability in the graph models multi-hop privilege escalation.&quot; },
  { term: &quot;Directed property graph&quot;, definition: &quot;A graph in which both nodes and edges have types and can carry key-value properties. The data model BloodHound uses.&quot; },
  { term: &quot;Cypher&quot;, definition: &quot;The pattern-matching query language for Neo4j and now the basis of the ISO/IEC 39075:2024 GQL standard.&quot; },
  { term: &quot;Bidirectional BFS&quot;, definition: &quot;Breadth-first search executed simultaneously from source and target, meeting in the middle. The algorithm Neo4j&apos;s shortestPath() runs and the algorithm BloodHound inherits.&quot; },
  { term: &quot;Tier Zero&quot;, definition: &quot;Any node in the attack-path graph whose compromise lets an attacker reach an administrative privilege in the forest. The endpoint of every BloodHound shortest-path query.&quot; },
  { term: &quot;Traversable / non-traversable edge&quot;, definition: &quot;A traversable edge can be stepped through directly by a path query; a non-traversable edge is a precondition fact that, with others, composes into a traversable edge during post-processing. ADCS edges are the canonical example.&quot; },
  { term: &quot;OpenGraph&quot;, definition: &quot;BloodHound&apos;s v8.0 (July 2025) generalisation that decouples the graph engine from the AD-specific schema, admitting user-defined node and edge kinds for arbitrary substrates.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>active-directory</category><category>bloodhound</category><category>graph-theory</category><category>attack-paths</category><category>specterops</category><category>identity-security</category><author>noreply@paragmali.com (Parag Mali)</author></item></channel></rss>