<?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: kerberos</title><description>Posts tagged kerberos.</description><link>https://paragmali.com/</link><language>en-US</language><lastBuildDate>Sun, 07 Jun 2026 04:13:09 GMT</lastBuildDate><atom:link href="https://paragmali.com/tags/kerberos/rss.xml" rel="self" type="application/rss+xml"/><item><title>Pass-the-Hash to Pass-the-PRT: Twenty-Nine Years of Windows Credential Replay in One Family Tree</title><link>https://paragmali.com/blog/pass-the-hash-to-pass-the-prt-twenty-nine-years-of-windows-c/</link><guid isPermaLink="true">https://paragmali.com/blog/pass-the-hash-to-pass-the-prt-twenty-nine-years-of-windows-c/</guid><description>Pass-the-Hash, Pass-the-Ticket, Overpass-the-Hash, Pass-the-Certificate, and Pass-the-PRT are one architectural lineage. Each defense bought years; none closed the family.</description><pubDate>Thu, 28 May 2026 00:00:00 GMT</pubDate><content:encoded>
Twenty-nine years of Windows credential-replay attacks -- Pass-the-Hash, Pass-the-Ticket, Overpass-the-Hash, Pass-the-Certificate, Pass-the-PRT -- are a single lineage, not five techniques. Each generation finds the next long-term authentication artefact that lives outside the latest Microsoft isolation boundary, then commoditises extraction in tooling that runs anywhere with local administrator. Credential Guard (2015) and KB5014754 (2022) bought years but not closure; Pass-the-PRT (Mollema + Delpy, 2020) already defeats both because the Primary Refresh Token lives in the CloudAP plug-in, which is not inside any current isolation scope. The next decade of Windows credential theft turns on whether Microsoft extends hypervisor-based isolation to CloudAP before commodity offensive tooling makes the attack universal.
&lt;h2&gt;1. Two Afternoons, Twenty-Nine Years Apart&lt;/h2&gt;
&lt;p&gt;On the afternoon of Tuesday, April 8, 1997, between 5:27 p.m. and 8:57 p.m. -- a window we can narrow to about three and a half hours from the file timestamps preserved in the patch he posted -- a researcher named Paul Ashton sat down with the Samba source tree and made the smallest possible change to &lt;code&gt;smbclient&lt;/code&gt;.The bracketing mtimes &lt;code&gt;Tue Apr  8 17:27:29 1997&lt;/code&gt; and &lt;code&gt;Tue Apr  8 20:57:43 1997&lt;/code&gt; are preserved verbatim in the unified diff&apos;s &lt;code&gt;***&lt;/code&gt; and &lt;code&gt;---&lt;/code&gt; header lines on Exploit-DB advisory 19197 [@ashton-exploitdb-19197]. You can still download the diff today and confirm the timestamps yourself. Where the unpatched client computed a network response from a typed-in password, his version read the password&apos;s LM hash from &lt;code&gt;smbpasswd&lt;/code&gt; on disk and fed it straight to the same encryption primitive, skipping the password entirely.&lt;/p&gt;
&lt;p&gt;He posted the diff to NTBugtraq the same evening with a five-line advisory: &quot;A modified SMB client can mount shares on an SMB host by passing the username and corresponding LanMan hash of an account that is authorized to access the host and share. The modified SMB client removes the need for the user to &apos;decrypt&apos; the password hash into its clear-text equivalent.&quot; [@ashton-exploitdb-19197]&lt;/p&gt;
&lt;p&gt;Twenty-nine years later, every Windows credential-replay attack in commodity offensive tooling is a direct descendant of that afternoon.&lt;/p&gt;
&lt;p&gt;Fast-forward to 2026. A Windows 11 23H2 laptop, hardened to Microsoft&apos;s published baseline. &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; on. KB5014754 strong certificate mapping in full enforcement. Conditional Access enabled, with Token Protection where supported. An attacker has local admin -- the same starting position the 1997 attack assumed.&lt;/p&gt;
&lt;p&gt;Two commands run on that machine, in the same paragraph. Mimikatz &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; returns empty NT hash and TGT buffers; Credential Guard has done its job. Then Mimikatz &lt;code&gt;dpapi::cloudapkd /unprotect&lt;/code&gt; returns a valid Primary Refresh Token session key and proof-of-possession material [@mollema-prt-digging]. On a &lt;em&gt;different&lt;/em&gt; machine across the internet, the attacker pastes that material into Dirk-jan Mollema&apos;s &lt;code&gt;roadtx prt&lt;/code&gt;, mints an &lt;code&gt;x-ms-RefreshTokenCredential&lt;/code&gt; cookie, and authenticates to Entra ID as the laptop&apos;s user [@mollema-prt-abusing] [@roadtools-github]. Every Microsoft defense shipped in 2015, 2022, and 2024 is running. The attack still wins.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The empty buffer from &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; is the artefact of twenty-nine years of architectural lessons. The PRT extraction from &lt;code&gt;dpapi::cloudapkd&lt;/code&gt; is the architecture of the &lt;em&gt;next&lt;/em&gt; five-to-ten years. Both scenes are the same attack class. The credential changed; the protocol that consumes it changed; the long-term storage location changed; the lineage did not.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You will meet seven people in this article. Paul Ashton (1997, the patch). Hernan Ochoa (2008, the toolkit that put the technique inside Windows itself). Benjamin Delpy (2011, Mimikatz; and the Kerberos generations that followed). Sean Metcalf (2014, who named Overpass-the-Hash and wrote the practitioner reference that taught a generation of red and blue teams).&lt;/p&gt;
&lt;p&gt;Will Schroeder and Lee Christensen (2021, &quot;Certified Pre-Owned,&quot; the AD CS catalog that became Pass-the-Certificate). Oliver Lyak (2022, Certifried, the CVE that forced Microsoft to ship KB5014754). And Dirk-jan Mollema (2020, the Primary Refresh Token research this article argues is the most consequential credential-theft work since 2008). The cast is small. The lineage they built is the load-bearing structure of every Windows penetration test in 2026.&lt;/p&gt;
&lt;p&gt;How is it possible that the same attack works in 1997 and 2026? The answer is structural, not coincidental -- and once you see it, you cannot unsee it.&lt;/p&gt;
&lt;h2&gt;2. The Architectural Property the Family Shares&lt;/h2&gt;
&lt;p&gt;NTLM authentication never asks for the password as a string. It asks for a function of the hash. The hash &lt;em&gt;is&lt;/em&gt; the password.&lt;/p&gt;
&lt;p&gt;That sentence is the article&apos;s load-bearing claim, and the rest of this section is its proof.&lt;/p&gt;
&lt;p&gt;The Microsoft specification for the NTLM protocol -- &lt;code&gt;[MS-NLMP]&lt;/code&gt;, sections 3.3.1 and 3.3.2 -- writes the response computation in pseudocode. For NTLMv1, the server sends an 8-byte challenge; the client computes &lt;code&gt;NtChallengeResponse = DESL(ResponseKeyNT, challenge)&lt;/code&gt;, where &lt;code&gt;ResponseKeyNT = NTOWFv1(password) = MD4(UNICODE(password))&lt;/code&gt; [@ms-nlmp-3-3-1]. &lt;code&gt;DESL&lt;/code&gt; is a variant of DES that pads the 16-byte NT hash to 21 bytes with five zero bytes, splits the result into three 7-byte sub-keys, runs DES on the 8-byte challenge under each sub-key, and concatenates the three 8-byte ciphertexts to form a 24-byte response.&lt;/p&gt;
&lt;p&gt;NTLMv2 is more elaborate -- the response key is &lt;code&gt;NTOWFv2 = HMAC_MD5(MD4(UNICODE(password)), UNICODE(Uppercase(User) + UserDom))&lt;/code&gt;, and the proof string is &lt;code&gt;HMAC_MD5&lt;/code&gt; of the challenge concatenated with a target-info structure -- but the structural property is identical: the cleartext password appears in exactly one place in the entire protocol, the input to the hash function on the client. The verifier performs the same computation against the stored NT hash from the SAM or NTDS.dit, and compares. Neither side ever transmits the password [@ms-nlmp-3-3-2].&lt;/p&gt;
&lt;p&gt;This is what Microsoft means when its institutional documentation says Pass-the-Hash &quot;cannot be patched at the protocol level.&quot; There is nothing to patch.The same property holds for any challenge-response protocol whose verifier stores a determinable function of the password rather than the password itself: Kerberos with stored long-term keys, CHAP with shared secrets, OAuth client_credentials with shared secrets, every HMAC-based proof-of-possession scheme.&lt;/p&gt;
&lt;p&gt;The protocol takes a stored hash and produces a response. Swap the user&apos;s hash for the attacker&apos;s hash, and the protocol still produces a valid response, signed by the substituted key. The bug is not a bug; it is a documented property.&lt;/p&gt;

A family of Windows authentication protocols (NTLMv1 and NTLMv2) in which a server sends a random challenge and the client returns a response computed by applying a keyed cryptographic primitive (DES or HMAC-MD5) to that challenge under a key derived from the user&apos;s password. The verifier holds the same key and recomputes the response to confirm. The cleartext password is never transmitted [@ms-nlmp-3-3-1] [@ms-nlmp-3-3-2].

The 16-byte MD4 of the user&apos;s password as UTF-16 little-endian (`MD4(UNICODE(Passwd))` in the NLMP pseudocode). Unsalted by design, because NT was originally specified for an offline domain controller that has to verify against a fixed reference value. The NT hash is the long-term symmetric Windows authentication secret for every account, stored locally in the SAM and centrally in the NTDS.dit Active Directory database [@ms-nlmp-3-3-1].

The technique of authenticating to a service that uses NTLM (or any protocol descended from the same family) by feeding a stolen NT hash directly to the response-construction function, instead of typing a password the function would then hash. The terminology and the first working demonstration are due to Paul Ashton, NTBugtraq, April 1997 [@ashton-exploitdb-19197].

sequenceDiagram
    participant Client
    participant Server
    participant Verifier as SAM or NTDS.dit
    Client-&amp;gt;&amp;gt;Server: NTLM_NEGOTIATE
    Server-&amp;gt;&amp;gt;Client: NTLM_CHALLENGE with 8-byte nonce
    Note over Client: ResponseKeyNT equals NTOWFv1 of stored NT hash
    Note over Client: NtChallengeResponse equals DESL of ResponseKeyNT and nonce
    Client-&amp;gt;&amp;gt;Server: NTLM_AUTHENTICATE with response
    Server-&amp;gt;&amp;gt;Verifier: Look up stored NT hash for user
    Verifier--&amp;gt;&amp;gt;Server: Stored NT hash
    Note over Server: Recompute DESL of stored hash and nonce
    Server-&amp;gt;&amp;gt;Client: Authentication succeeds if responses match
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The hash is the password. Any long-term authentication artefact reachable by the process that uses it is replayable -- and every credential type the rest of this article discusses (Kerberos TGT, certificate private key, Primary Refresh Token session key) is a different instance of this same property. Defenses can isolate one artefact at a time; the property is intrinsic to the architecture.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ashton&apos;s 1997 patch was the protocol-disclosure proof. He swapped a single function call -- &lt;code&gt;SMBencrypt(pass, cryptkey, pword)&lt;/code&gt; became &lt;code&gt;E_P24(p21, cryptkey, pword)&lt;/code&gt;, where &lt;code&gt;p21&lt;/code&gt; is the user&apos;s LM hash read directly from &lt;code&gt;smbpasswd&lt;/code&gt; -- and Samba&apos;s &lt;code&gt;smbclient&lt;/code&gt; authenticated to NT 3.51 and NT 4.0 file servers without ever knowing the user&apos;s password [@ashton-exploitdb-19197]. You can read the patch in five minutes. It is also, in a precise sense, the first proof that NTLM&apos;s response computation is hash-equivalent: if substituting the hash works, then mathematically the hash is what the protocol wanted all along.&lt;/p&gt;
&lt;p&gt;And then nothing happened for eleven years.&lt;/p&gt;
&lt;p&gt;That gap deserves its own explanation, because the eleven-year interregnum is the cleanest failure mode in the lineage.&lt;/p&gt;
&lt;p&gt;Wikipedia&apos;s modern summary of the pre-2008 limitation reads: &quot;even after performing NTLM authentication successfully using the pass the hash technique, tools like Samba&apos;s SMB client might not have implemented the functionality the attacker might want to use. This meant that it was difficult to attack Windows programs that use DCOM or RPC. Also, because attackers were restricted to using third-party clients when carrying out attacks, it was not possible to use built-in Windows applications, like Net.exe or the Active Directory Users and Computers tool amongst others, because they asked the attacker or user to enter the cleartext password to authenticate, and not the corresponding password hash value.&quot; [@wikipedia-pass-the-hash]&lt;/p&gt;

Inside Microsoft the 1997 patch was treated as confirming a known property of LSASS-resident credentials, not as a new attack class. The institutional position was that any compromise yielding the hash already implied SYSTEM-equivalent access, and that the realistic chain was &quot;exfiltrate the hash and crack it offline,&quot; not &quot;replay the hash.&quot; The architectural counter-claim -- that *replaying* the hash from inside a Windows process bypasses every native-tool obstacle -- took a decade to land in the practitioner literature. The 2012 Duckwall + Campbell Black Hat USA paper named the lag in its title: &quot;Still Passing the Hash 15 Years Later.&quot; [@duckwall-campbell-bh2012]
&lt;p&gt;If the obstacle is &quot;built-in Windows tools ask for cleartext,&quot; the architectural answer is to put the substituted hash &lt;em&gt;inside&lt;/em&gt; the Windows process that those tools rely on. That insight took eleven years to operationalise. The person who operationalised it was Hernan Ochoa, in 2008.&lt;/p&gt;
&lt;h2&gt;3. From Patch to Toolkit: The Windows-Native Pivot&lt;/h2&gt;
&lt;p&gt;By 2008, Ashton&apos;s 1997 patch had been sitting on NTBugtraq for eleven years. Hernan Ochoa had a different idea: instead of patching the client, patch the &lt;em&gt;credential cache&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The artefact Ochoa shipped at CanSecWest 2008 and Black Hat USA 2008 was called the &lt;em&gt;Pass-the-Hash Toolkit&lt;/em&gt;, distributed through Core Security Technologies&apos; open-source projects page [@corelabs-pshtoolkit-wayback]. It contained two executables. &lt;code&gt;IAM.EXE&lt;/code&gt; opened the LSASS process with &lt;code&gt;PROCESS_VM_WRITE&lt;/code&gt;, located the cached credential block for the current interactive logon session, and overwrote the NT hash and username fields with attacker-supplied values. &lt;code&gt;PTH.EXE&lt;/code&gt; spawned a target process under a substituted hash.&lt;/p&gt;
&lt;p&gt;Once the substitution was in place, every native Windows SSO consumer -- &lt;code&gt;net.exe&lt;/code&gt;, &lt;code&gt;wmic&lt;/code&gt;, &lt;code&gt;mstsc&lt;/code&gt; once Restricted Admin RDP shipped years later, SMB, RPC, DCOM -- transparently picked up the attacker-supplied hash, because the OS handed them what it believed were the legitimate user&apos;s credentials.&lt;/p&gt;
&lt;p&gt;Wikipedia summarises the architectural pivot in one paragraph: &quot;It allowed the user name, domain name, and password hashes cached in memory by the Local Security Authority to be changed at runtime &lt;em&gt;after&lt;/em&gt; a user was authenticated -- this made it possible to &apos;pass the hash&apos; using standard Windows applications, and thereby to undermine fundamental authentication mechanisms built into the operating system.&quot; [@wikipedia-pass-the-hash] The eleven-year limitation was gone. Pass-the-Hash was now a Windows-native attack that worked against any tool that read its credentials from LSASS -- which in practice meant &lt;em&gt;every&lt;/em&gt; Windows tool.&lt;/p&gt;

The user-mode Windows process (`lsass.exe`) that handles interactive logon, owns the Security Reference Monitor&apos;s policy decisions, and -- relevant to this article -- caches the in-memory credential material that supports Single Sign-On for the duration of each logon session: NT hashes for NTLM, Kerberos TGTs and session keys, certificate handles, and (since Azure AD / Entra ID device join) Primary Refresh Token material in the CloudAP plug-in. Every credential-replay technique in this article reaches its target by reading LSASS in some form.
&lt;p&gt;The 2012 retrospective is where the security industry stopped pretending Pass-the-Hash was solved. Alva Duckwall and Christopher Campbell shipped a Black Hat USA 2012 paper titled, unambiguously, &quot;Still Passing the Hash 15 Years Later.&quot; [@duckwall-campbell-bh2012] The title is the load-bearing pull-quote: it named Ashton 1997 as the origin, Ochoa 2008 as the Windows-native pivot, and the industry&apos;s continued failure to ship a structural fix as the central fact. From this point onwards Microsoft itself acknowledged Pass-the-Hash as a structural property of NTLM rather than a fixable bug.&lt;/p&gt;
&lt;p&gt;Hernan Ochoa&apos;s Windows Credentials Editor (WCE), released a year after the Pass-the-Hash Toolkit, developed the same LSASS-injection primitive on a separate code base. Two independent implementations converging on the same memory-access pattern in the same window is the clearest indication that the architectural insight -- &quot;the credential is sitting in a process you can write to&quot; -- was overdetermined once anyone went looking for it.&lt;/p&gt;
&lt;p&gt;What did Ashton&apos;s 1997 patch leave on the table? The other long-term credentials that LSASS held. The NT hash was the first. There would be more.&lt;/p&gt;
&lt;p&gt;If you can read the NT hash from LSASS, you can read the Kerberos TGT from LSASS. The same memory-access primitive that animates &lt;code&gt;IAM.EXE&lt;/code&gt; is one commit away from animating &lt;code&gt;sekurlsa::tickets&lt;/code&gt;. That commit shipped in May 2011. Its author was a twenty-five-year-old French programmer named Benjamin Delpy.&lt;/p&gt;
&lt;h2&gt;4. Mimikatz and the Kerberos Turn&lt;/h2&gt;
&lt;p&gt;In May 2011, Benjamin Delpy posted his first public release of a program he had been writing as a side project to learn C. He was twenty-five, working as an IT manager at an institution he has never publicly named. Andy Greenberg&apos;s Wired profile records the date: &quot;He released it publicly in May 2011, but as a closed source program.&quot; [@wired-greenberg-mimikatz] Wikipedia corroborates: &quot;He released the first version of the software in May 2011 as closed source software.&quot; [@wikipedia-mimikatz] The program was called Mimikatz.&lt;/p&gt;
&lt;p&gt;What made Mimikatz architecturally different from Ochoa&apos;s toolkit was that it was &lt;em&gt;modular&lt;/em&gt;. The credential-extraction primitives lived in named command groups: &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; dumped NT hashes from LSASS; &lt;code&gt;sekurlsa::tickets&lt;/code&gt; dumped Kerberos tickets from LSASS; &lt;code&gt;kerberos::ptt&lt;/code&gt; injected a stolen ticket into the current Kerberos cache via the documented &lt;code&gt;LsaCallAuthenticationPackage&lt;/code&gt; API with the &lt;code&gt;KerbSubmitTicketMessage&lt;/code&gt; message [@ms-lsa-call-auth-package]; &lt;code&gt;lsadump::dcsync&lt;/code&gt; (added August 2015, in collaboration with Vincent Le Toux) impersonated a domain controller and asked another DC for the krbtgt hash via the IDL_DRSGetNCChanges replication RPC [@adsec-dcsync-p1729].&lt;/p&gt;
&lt;p&gt;Same LSASS, different artefact, different protocol surface. The architectural property section 2 named had two artefacts to work with on Windows: the NT hash, and the Kerberos TGT.&lt;/p&gt;
&lt;p&gt;This is &lt;strong&gt;Pass-the-Ticket&lt;/strong&gt; (Generation 2). The stolen TGT plus its session key authenticates the holder as the original principal for the ticket&apos;s lifetime, which on a default AD deployment is ten hours, renewable for seven days. Time complexity per replay: O(1). The TGT session key is the load-bearing piece -- without it, the ticket is opaque encrypted bytes that the holder cannot decrypt, sign, or present back to the KDC. Mimikatz&apos;s &lt;code&gt;sekurlsa::tickets /export&lt;/code&gt; writes the ticket as a &lt;code&gt;.kirbi&lt;/code&gt; file on disk; &lt;code&gt;kerberos::ptt &amp;lt;file&amp;gt;&lt;/code&gt; re-injects on any machine where the user has a Kerberos credentials cache.&lt;/p&gt;

The long-lived Kerberos credential issued by the KDC&apos;s Authentication Service (AS-REP) in response to a successful AS-REQ. The TGT is encrypted under the KDC&apos;s own krbtgt-account long-term key and contains a session key that the client uses to subsequently request service tickets from the Ticket Granting Service (TGS). Specification: RFC 4120, section 3 [@rfc-4120]. On a Windows Active Directory deployment the default TGT lifetime is 10 hours with renewal up to 7 days.

The technique of extracting a Kerberos TGT (and its session key) from one machine&apos;s LSASS-resident Kerberos cache and injecting it into another machine&apos;s cache, so that subsequent service-ticket requests authenticate as the ticket&apos;s original principal. Tool of record: Mimikatz `sekurlsa::tickets` + `kerberos::ptt`; equivalent functionality in Rubeus and Impacket.

sequenceDiagram
    participant Victim as Victim host
    participant Attacker as Attacker host
    participant KDC
    Note over Victim: User logged in, TGT cached in LSASS Kerberos package
    Attacker-&amp;gt;&amp;gt;Victim: mimikatz sekurlsa::tickets export
    Victim--&amp;gt;&amp;gt;Attacker: TGT.kirbi (ticket plus session key)
    Note over Attacker: mimikatz kerberos::ptt TGT.kirbi
    Attacker-&amp;gt;&amp;gt;KDC: TGS-REQ presenting injected TGT
    KDC--&amp;gt;&amp;gt;Attacker: TGS-REP service ticket
    Attacker-&amp;gt;&amp;gt;Attacker: Authenticate to any Kerberos service as the victim
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A common shorthand says that Microsoft&apos;s Credential Guard isolated NT hashes, so attackers shifted to TGTs. That arrow runs backwards in time. Pass-the-Ticket predates Credential Guard by years -- the Mimikatz Kerberos primitives developed between the May 2011 closed-source release and the April 6, 2014 open-source commit (the earliest verifiable source-level evidence for &lt;code&gt;sekurlsa::tickets&lt;/code&gt; and &lt;code&gt;kerberos::ptt&lt;/code&gt;), and were presented in detail at Black Hat USA 2014 by Duckwall and Delpy [@infocondb-bh2014-duckwall] [@duckwall-delpy-bh2014-wp]. Pass-the-Ticket exists because TGTs are also in LSASS, not as a defensive response. The shift to a new artefact happened because the &lt;em&gt;architectural property&lt;/em&gt; of credential extraction generalised, not because Credential Guard pushed attackers there.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The third generation followed shortly. &lt;strong&gt;Overpass-the-Hash&lt;/strong&gt; observes that for the RC4-HMAC Kerberos encryption type -- the Windows default from Windows 2000 through November 2022 -- the user&apos;s long-term Kerberos key is the unchanged NT hash.&lt;/p&gt;
&lt;p&gt;RFC 4757, authored by K. Jaganathan, L. Zhu, and J. Brezak of Microsoft and published as informational in December 2006, specifies the RC4-HMAC enctype&apos;s long-term key as the existing NT hash without modification [@rfc-4757]. An attacker who holds the NT hash can drive a legitimate Kerberos AS-REQ to the KDC, encrypt the timestamp pre-auth blob with the NT hash as the RC4-HMAC key, and receive a real TGT signed by the real krbtgt.&lt;/p&gt;
&lt;p&gt;The economic effect is large. Pass-the-Hash gets you NTLM-based services -- SMB, RPC, and any protocol over them. Overpass-the-Hash gets you the entire Kerberos surface: Kerberos-only services, services that require Kerberos for delegation, services with NTLM disabled at the GPO level. Same NT hash. Different downstream protocol. Strictly larger attack surface.&lt;/p&gt;

The technique of presenting a stolen NT hash to the KDC as the user&apos;s long-term RC4-HMAC Kerberos key (per RFC 4757 [@rfc-4757]), obtaining a real TGT signed by the real krbtgt, and operating as a real Kerberos client for the ticket&apos;s lifetime. Tool of record: Mimikatz `sekurlsa::pth /user: /domain: /ntlm: /run:` and Rubeus `asktgt /user: /rc4:`. Per Sean Metcalf&apos;s adsecurity.org reference, the technique is named &quot;over&quot; because the hash is promoted one notch up the protocol stack from NTLM into Kerberos [@adsec-mimikatz-p556] [@adsec-kerberos-p2293].

sequenceDiagram
    participant Attacker
    participant KDC
    participant Service as Kerberos service
    Note over Attacker: Holds NT hash for user (e.g. from sekurlsa::logonpasswords)
    Attacker-&amp;gt;&amp;gt;KDC: AS-REQ with PA-ENC-TIMESTAMP encrypted under RC4-HMAC(NT hash)
    KDC-&amp;gt;&amp;gt;KDC: Verify PA-ENC-TIMESTAMP decrypts cleanly
    KDC--&amp;gt;&amp;gt;Attacker: AS-REP with real TGT signed by krbtgt
    Attacker-&amp;gt;&amp;gt;KDC: TGS-REQ for Service
    KDC--&amp;gt;&amp;gt;Attacker: TGS-REP service ticket
    Attacker-&amp;gt;&amp;gt;Service: AP-REQ authenticate as user
    Service--&amp;gt;&amp;gt;Attacker: Access granted
&lt;p&gt;The naming has its own story. The Mimikatz capability is Delpy&apos;s; the term &quot;Overpass-the-Hash&quot; and the taxonomic framing that distinguishes it from straight Pass-the-Hash spread through the practitioner community via Sean Metcalf&apos;s adsecurity.org reference [@adsec-mimikatz-p556] and the Duckwall + Delpy Black Hat USA 2014 talk and whitepaper [@infocondb-bh2014-duckwall] [@duckwall-delpy-bh2014-wp]. The earliest archived snapshot of the adsecurity.org reference is October 1, 2014; the talk timestamp is August 7, 2014. The two sources are essentially contemporaneous, and Metcalf&apos;s later &quot;Red vs. Blue&quot; Black Hat USA 2015 whitepaper consolidates the practitioner taxonomy [@metcalf-bh2015-red-vs-blue].&lt;/p&gt;
&lt;p&gt;The &quot;Overpass&quot; coinage is a deliberate semantic argument that the technique is one notch &lt;em&gt;above&lt;/em&gt; Pass-the-Hash on the protocol stack: the NT hash, which began life as an NTLM response key, is being promoted into Kerberos as a long-term encryption key. The naming credit is socially distributed -- Metcalf, Delpy, Duckwall, and Mimikatz&apos;s own command group all carry traces of it -- so this article uses Metcalf&apos;s reference as the canonical practitioner explainer rather than as a single inventor citation.&lt;/p&gt;
&lt;p&gt;The DigiNotar incident in September 2011 is the first publicly attributed criminal use of Mimikatz, four months after Delpy&apos;s first public release. The Dutch certificate authority DigiNotar -- founded 1998, acquired by VASCO in January 2011, hacked in June 2011, declared bankrupt in September 2011 [@wikipedia-diginotar] -- was used to issue hundreds of fraudulent certificates that were then used in man-in-the-middle attacks on Iranian Gmail users [@wikipedia-diginotar] [@fox-it-operation-black-tulip].&lt;/p&gt;
&lt;p&gt;Greenberg&apos;s Wired profile records that Delpy was told by the breach investigators that Mimikatz had been used during the intrusion [@wired-greenberg-mimikatz]. The single-source attribution warrants a hedge -- Greenberg&apos;s source is Delpy himself, quoting investigators -- but the underlying breach timeline is solid.&lt;/p&gt;

The decision to open-source Mimikatz on April 6, 2014 is dated by the GitHub repository banner: `mimikatz 2.0 alpha (x86) release &quot;Kiwi en C&quot; (Apr  6 2014 22:02:03)` [@mimikatz-github]. The precipitating event, as Delpy told Wired, was a trip to Moscow: he returned to his hotel room to find a stranger at his laptop; a second man approached him in the lobby that evening and demanded source code on a USB stick. He decided defenders needed the source as much as the attackers already did, and pushed it to GitHub when he got home [@wired-greenberg-mimikatz].
&lt;p&gt;By 2014, the credential-replay family had three generations -- Pass-the-Hash, Pass-the-Ticket, Overpass-the-Hash -- and Microsoft&apos;s only documented response was a forty-page PDF. The next section is what that PDF said, and why documentation alone cannot end an attack class.&lt;/p&gt;
&lt;h2&gt;5. Documentation Is Not Defense&lt;/h2&gt;
&lt;p&gt;By December 2012, Microsoft had a problem. Duckwall and Campbell had just shipped a Black Hat USA paper titled &quot;Still Passing the Hash 15 Years Later&quot; [@duckwall-campbell-bh2012]. Mimikatz was eighteen months old. The institutional position that Pass-the-Hash was a &quot;post-compromise issue&quot; -- the line Microsoft had held since 1997 -- was no longer survivable in public.&lt;/p&gt;
&lt;p&gt;The institutional response came in two waves. &lt;em&gt;Mitigating Pass-the-Hash Attacks and Other Credential Theft&lt;/em&gt;, version 1, shipped in late 2012 (most practitioner secondaries place it in December 2012; no primary Microsoft URL with a verifiable v1 timestamp survives today).&lt;/p&gt;
&lt;p&gt;Version 2 followed in July 2014, extending the v1 playbook with the new defensive surfaces that shipped in Windows 8.1 and Windows Server 2012 R2: &lt;a href=&quot;https://paragmali.com/blog/who-is-allowed-to-log-in-where-the-kdc-side-answer-to-creden/&quot; rel=&quot;noopener&quot;&gt;Protected Users&lt;/a&gt; as a deployable security group, Restricted Admin RDP as a default-available feature, LSA Protection (RunAsPPL) as a registry-toggleable defense, and Authentication Policies and Silos as KDC-side restrictions [@ms-download-mitigating-pth-v2]. The two whitepapers are the closest thing the industry got to an institutional Microsoft acknowledgment that Pass-the-Hash was a load-bearing operational problem requiring a defensive playbook rather than a patch.&lt;/p&gt;
&lt;p&gt;What did the playbook recommend? Three orthogonal stopgaps, each with a published bypass.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Protected Users&lt;/strong&gt; (Windows Server 2012 R2). A security group whose membership bans, on the DC side, NTLM authentication, DES and RC4 Kerberos pre-authentication, and Kerberos unconstrained delegation; and, on the device side, NTLM caching of the user&apos;s plaintext credentials or NTOWF and Kerberos DES/RC4 long-term keys. Member TGTs are capped at 240 minutes (four hours) with no renewal [@ms-protected-users]. Documented bypasses: requires explicit opt-in per account, breaks any service that depended on unconstrained delegation, does not apply to computer accounts or service accounts by default, and has no effect on Kerberos AES-key extraction from LSASS (since AES keys are not banned; only RC4 is).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Restricted Admin RDP&lt;/strong&gt; (introduced in Windows 8.1 / Server 2012 R2 RTM, October 2013; backported to Windows 7 / Server 2008 R2 / Windows 8 / Server 2012 by KB2871997 on May 13, 2014 [@ms-kb2871997-may2014]). An opt-in RDP mode that authenticates to the target without sending credentials, so a compromised target cannot harvest the RDP user&apos;s hash from its own LSASS. Documented bypass: opt-in per session, applies only to RDP, leaves SMB, WMI, and RPC unprotected. And it &lt;em&gt;enables&lt;/em&gt; Pass-the-Hash for RDP -- the BloodHound &lt;code&gt;CanRDP&lt;/code&gt; edge documents the abuse path with the exact Mimikatz command for injecting a stolen NT hash into &lt;code&gt;mstsc.exe /restrictedadmin&lt;/code&gt; [@bloodhound-canrdp].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LSA Protection / RunAsPPL&lt;/strong&gt; (Windows 8.1). A registry toggle that marks LSASS as a &lt;a href=&quot;https://paragmali.com/blog/protected-process-light-when-the-administrator-isnt-enough/&quot; rel=&quot;noopener&quot;&gt;Protected Process Light&lt;/a&gt;, so non-PPL processes (including unsigned admin tools) cannot open it with &lt;code&gt;PROCESS_VM_READ&lt;/code&gt;. Documented bypass: any signed kernel driver -- including loadable third-party drivers -- can still read PPL memory, and an attacker with local admin can load such a driver. The itm4n analysis includes the verbatim Mimikatz output where &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; returns access-denied against a PPL-marked LSASS, and shows that an attacker who loads a signed driver via the BYOVD pattern (&quot;bring your own vulnerable driver&quot;) or escalates to kernel mode bypasses the marking. itm4n&apos;s framing -- &quot;Credential Guard and LSA Protection are actually complementary&quot; [@itm4n-lsass-runasppl] -- is also the prediction: PPL is part of the answer, but only when paired with the architectural pivot still to come.&lt;/p&gt;

A Windows Server 2012 R2 security group whose membership applies a set of restrictions, enforced jointly by the device and the domain controller, that block the most commonly extracted long-term credential material: no NTLM, no Kerberos RC4 or DES pre-auth, no unconstrained delegation, no NT-hash caching, and a 240-minute TGT lifetime with no renewal [@ms-protected-users].
&lt;p&gt;The structural point is this. Documentation tells administrators &lt;em&gt;what to do&lt;/em&gt;. It does not prevent the underlying LSASS-resident credential extraction. Every defense documented in v1 and v2 of the Mitigating-PtH whitepapers is bypassable, with a known and published technique, on any system where the attacker already has local administrator -- and local administrator is exactly what Pass-the-Hash exploitation &lt;em&gt;already implies&lt;/em&gt;. The defender&apos;s win condition is to keep the attacker from ever getting to local admin in the first place; once they have it, every documented mitigation is a speed bump rather than a wall.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The 2012-2014 era&apos;s load-bearing failure mode was assuming that telling administrators where credentials &lt;em&gt;should&lt;/em&gt; live would prevent extraction from where they &lt;em&gt;do&lt;/em&gt; live. Protected Users, Restricted Admin RDP, RunAsPPL, and Authentication Silos are all useful, and stacked together they raise the cost of post-admin exploitation. None of them moves the credential out of the address space the attacker can read.&lt;/p&gt;
&lt;/blockquote&gt;

A common secondary characterisation cites a &quot;v3 2017&quot; of the whitepaper alongside v1 and v2. That document does not exist in Microsoft Download Center ID 36036; the page lists Version 2.0; the 2023 Wayback snapshot of the same Download Center page records Date Published 7/7/2014, while the live page now shows a 2024 republication date for the same Version 2.0 PDF without a version bump [@ms-download-mitigating-pth-v2]. The Download Center page carries v2 metadata only -- v1&apos;s late-2012 date is sourced through contemporary practitioner literature rather than a primary Microsoft timestamp. After 2014 the post-v2 institutional documentation moves to the Microsoft Learn Credential Guard page rather than to a third whitepaper revision -- a structural choice, because by 2015 the architectural answer has shifted from prose to code.
&lt;p&gt;By mid-2014 Microsoft&apos;s institutional position was that the protocol-level fix was unavailable and the architectural answer would need to &lt;em&gt;relocate the credentials&lt;/em&gt;. If credentials cannot stay in LSASS where every admin process can read them, the credentials have to be moved to a place admin processes cannot read. That insight produces Credential Guard.&lt;/p&gt;
&lt;h2&gt;6. Credential Guard and the Architectural Pivot&lt;/h2&gt;
&lt;p&gt;On July 29, 2015, Microsoft shipped Windows 10 Enterprise [@ms-lifecycle-w10-enterprise]. Hidden in the RTM build was the first defense in the credential-replay lineage that wasn&apos;t documentation: hardware-rooted isolation. They called it Credential Guard.&lt;/p&gt;
&lt;p&gt;The architecture is worth unpacking carefully, because every later generation of the family is best read as &quot;what does this attack do to the assumptions Credential Guard makes?&quot;&lt;/p&gt;
&lt;p&gt;Credential Guard runs on top of Virtualization-Based Security. The Windows hypervisor partitions user mode into two virtual trust levels. VTL0 is the normal user partition: normal user-mode processes, including the normal LSASS, and the normal kernel. VTL1 is the isolated user partition: a small set of &lt;em&gt;trustlets&lt;/em&gt;, signed user-mode processes the hypervisor protects from VTL0 inspection. Credential Guard&apos;s trustlet is LSAISO (&quot;LSA Isolated&quot;), a stripped-down clone of the LSA credential cache holding the material Microsoft wants out of VTL0. Hypervisor-enforced Code Integrity (HVCI) below enforces W^X on the VTL0 kernel, blocking kernel-mode bypasses that would otherwise read VTL1 memory directly.&lt;/p&gt;

The Windows architecture that runs a Type-1 hypervisor below the normal Windows kernel and partitions user mode into VTL0 (the normal partition) and VTL1 (the isolated partition). VTL1 hosts trustlets that the hypervisor protects from VTL0 inspection, even from kernel-mode VTL0 code. VBS is the substrate for Credential Guard, HVCI, the System Guard secure-launch chain, and the secure kernel.

The Windows feature that relocates NT hashes, Kerberos TGT session keys, and &quot;credentials stored by applications as domain credentials&quot; from the in-VTL0 LSASS to the in-VTL1 LSAISO trustlet, so that the credential cache is unreadable from any VTL0 process or driver. Shipped in Windows 10 RTM (July 2015); default-enabled on hardware-eligible domain-joined non-DC systems in Windows 11 22H2 (September 2022) [@ms-learn-credential-guard].

The isolated-user-mode LSA process (`lsaiso.exe`) that holds Credential Guard&apos;s protected credential material. Runs in VTL1, unreadable from VTL0 kernel or user processes. Communicates with the VTL0 LSASS through a small RPC surface for authorised authentication operations only.
&lt;p&gt;What does Credential Guard isolate? The Microsoft Learn page is unambiguous: &quot;Credential Guard prevents credential theft attacks by protecting NTLM password hashes, Kerberos Ticket Granting Tickets (TGTs), and credentials stored by applications as domain credentials.&quot; [@ms-learn-credential-guard] Those three categories are also the three categories the previous three generations of the family targeted. Pass-the-Hash hits NTLM password hashes. Pass-the-Ticket hits Kerberos TGTs. Overpass-the-Hash hits NTLM password hashes promoted into Kerberos. Credential Guard moves all three out of VTL0 LSASS into VTL1 LSAISO. On a hardware-eligible domain-joined Windows 10/11 system with Credential Guard enabled, all three attacks return empty buffers.&lt;/p&gt;
&lt;p&gt;The institutional importance of the change is that under Microsoft&apos;s own &lt;em&gt;Windows Security Servicing Criteria&lt;/em&gt;, Credential Guard is a &lt;em&gt;security boundary&lt;/em&gt; -- which means a bypass is a CVE-class vulnerability rather than a documentation gap.&lt;/p&gt;
&lt;p&gt;The criteria&apos;s load-bearing definitions: &quot;A security boundary provides a logical separation between the code and data of security domains with different levels of trust&quot; and &quot;Does the vulnerability violate the goal or intent of a security boundary or a security feature?&quot; [@msrc-windows-servicing-criteria] Pre-2015 Pass-the-Hash defenses were documentation; Credential Guard is the first defense the criteria treats as CVE-class under the boundary &quot;admin -&amp;gt; VBS (LSAISO trustlet).&quot;&lt;/p&gt;

flowchart TD
    subgraph VTL0[VTL0 normal partition]
        A[User processes]
        B[LSASS]
        K[VTL0 kernel]
    end
    subgraph VTL1[VTL1 isolated partition]
        L[LSAISO trustlet]
        SK[Secure kernel]
    end
    H[Hypervisor]
    A --&amp;gt; B
    K --&amp;gt; B
    B -- authorised RPC only --&amp;gt; L
    H --&amp;gt; VTL0
    H --&amp;gt; VTL1
    SK --&amp;gt; L
    K -. blocked by HVCI .-&amp;gt; L
&lt;p&gt;What does Credential Guard &lt;em&gt;not&lt;/em&gt; isolate? This is the load-bearing question for the rest of the article. The same Microsoft Learn page enumerates four caveats, each verbatim.&lt;/p&gt;
&lt;p&gt;First, the Active Directory database and the SAM. &quot;Credential Guard doesn&apos;t provide protections for the Active Directory database or the Security Accounts Manager (SAM).&quot; [@ms-learn-credential-guard] This is the &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; gap: an attacker with the right replication privileges can ask a DC to hand over every hash in the directory, and Credential Guard cannot intervene because the data is being released through a legitimate, authorised API rather than being read from LSASS.&lt;/p&gt;
&lt;p&gt;Second, domain controllers. &quot;Enabling Credential Guard on domain controllers isn&apos;t recommended. Credential Guard doesn&apos;t provide any added security to domain controllers.&quot; [@ms-learn-credential-guard] The KDC must read the krbtgt account&apos;s long-term key in cleartext to issue tickets; the architectural exception is intrinsic to Kerberos rather than a Microsoft oversight.&lt;/p&gt;
&lt;p&gt;Third, application credentials outside the &quot;domain credentials&quot; scope. Certificate private keys held by CryptoAPI key containers, third-party authentication package secrets, and -- the one this article eventually argues is the most consequential -- the Primary Refresh Token material held by the CloudAP authentication plug-in, are all out of scope by construction.&lt;/p&gt;
&lt;p&gt;Fourth, and most importantly, the institutional acknowledgment of the supersession pattern. Microsoft Learn reproduces it verbatim on the same page, the prophecy the rest of this article spends its time documenting being fulfilled:&lt;/p&gt;

While Credential Guard is a powerful mitigation, persistent threat attacks will likely shift to new attack techniques, and you should also incorporate other security strategies and architectures. -- Microsoft Learn, *Credential Guard overview* [@ms-learn-credential-guard]
&lt;p&gt;That sentence, written about the 2015 Credential Guard architecture, accurately predicts the 2021-2022 shift to Pass-the-Certificate and the 2020-present shift to Pass-the-PRT. It is Microsoft&apos;s own structural prediction that the family will continue to evolve to the next artefact Credential Guard&apos;s verbatim scope does not cover. The rest of this article reads as the unfolding of that prediction.&lt;/p&gt;

The Kerberos KDC must read the krbtgt account&apos;s long-term key to encrypt the TGT issued in every AS-REP. That key has to be available to the LSA process in cleartext, on every DC, on every ticket issuance, by protocol. Putting krbtgt behind LSAISO would mean issuing every TGT through an inter-trust-level RPC call -- a non-trivial performance penalty on every authentication in an Active Directory forest -- and would not actually close the architectural gap, because the trustlet itself would still need to do the cleartext work that LSASS does today. The exception is honest about an architectural reality rather than concealing it.
&lt;p&gt;PPL and Credential Guard are &lt;em&gt;complementary&lt;/em&gt;, not alternatives. itm4n&apos;s analysis [@itm4n-lsass-runasppl] makes the case carefully: RunAsPPL raises the bar from &quot;any admin process can read LSASS&quot; to &quot;any signed driver can read LSASS,&quot; and Credential Guard closes the signed-driver bypass with hardware-rooted hypervisor isolation. They stack. The 2026 best-practice Windows endpoint has both turned on.&lt;/p&gt;
&lt;p&gt;The default-enablement window shows how long this took to land. Credential Guard shipped enabled-by-policy in Windows 10 RTM in 2015, but did not become &lt;em&gt;default-enabled on hardware-eligible domain-joined non-DC systems&lt;/em&gt; until Windows 11 22H2 in September 2022 [@ms-learn-credential-guard]. Seven years of uneven deployment.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Four residuals from the Microsoft Learn page: the Active Directory database and the SAM are out of scope; domain controllers are out of scope by recommendation; application credentials outside the &quot;domain credentials&quot; category (certificates, CloudAP material, third-party authentication packages) are out of scope by construction; and persistent threats are &lt;em&gt;expected&lt;/em&gt; to shift to new attack techniques. Each residual maps to a later generation of this article: AD database -&amp;gt; DCSync; certificates -&amp;gt; Pass-the-Certificate; CloudAP -&amp;gt; Pass-the-PRT.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Each new credential type needs its own isolation boundary. Credential Guard isolates NT hashes and TGT session keys. It does not isolate certificate private keys, because in 2015 nobody was replaying certificates at scale. And it does not isolate the Primary Refresh Token, because in 2015 the Primary Refresh Token did not yet exist.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Each new credential type needs its own isolation boundary. The pattern is reusable but does not transfer automatically -- and the gap between &quot;what fits in the boundary&quot; and &quot;what credentials Windows actually uses&quot; is exactly the territory where the next attack generation grows.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;7. Pass-the-Certificate: The Predictable Response&lt;/h2&gt;
&lt;p&gt;If the NT hash is isolated and RC4-HMAC is banned, what is the next long-term credential Windows accepts? The answer was hiding in plain sight: every Active-Directory-integrated enterprise had been running Microsoft&apos;s PKI since 2008, and almost every PKI deployment had at least one template-level catastrophe.&lt;/p&gt;
&lt;p&gt;On June 17, 2021, Will Schroeder and Lee Christensen posted &quot;Certified Pre-Owned&quot; on Medium, with the accompanying 143-page whitepaper [@specterops-certified-pre-owned] [@specterops-certified-pre-owned-pdf]. The post named ESC1 through ESC8 in a single document, with paired DETECT and PREVENT recommendations, and shipped three pieces of tooling at the same Black Hat USA 2021 cycle: Certify (offensive enrollment), ForgeCert (golden-certificate forging using a stolen CA private key), and PSPKIAudit (defensive enumeration). The Medium post&apos;s tone was unsubtle:&lt;/p&gt;

Of note, nearly every environment with AD CS that we&apos;ve examined for domain escalation misconfigurations has been vulnerable. It&apos;s hard for us to overstate what a big deal these issues are. -- Will Schroeder and Lee Christensen, *Certified Pre-Owned* [@specterops-certified-pre-owned]
&lt;p&gt;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;ESC catalog&lt;/a&gt; organises certificate misconfigurations by the abuse primitive they enable. ESC1 is the canonical example: a published certificate template that allows the enrollee to supply the Subject Alternative Name, contains a client-authentication Extended Key Usage, has permissive enrollment rights, and has no effective approval gates.&lt;/p&gt;
&lt;p&gt;An attacker who can enroll for such a template requests a certificate naming a victim principal -- say, the domain administrator -- in the SAN. The certificate&apos;s private key is now the attacker&apos;s. PKINIT-authenticate to the KDC with that certificate, and the KDC issues a TGT for the named principal. Domain escalation, in three commands.&lt;/p&gt;

Microsoft&apos;s enterprise PKI. Issues X.509 certificates from administrator-defined templates that pin a certificate&apos;s permitted uses (Extended Key Usages), its enrollment authorisation rules, its subject and SAN generation policy, and its revocation behaviour. Ships as a Windows Server role; deployed in essentially every Active-Directory-integrated enterprise.

Kerberos pre-authentication using a certificate&apos;s private key in place of a long-term symmetric key. Specified by RFC 4556 (L. Zhu and B. Tung, Microsoft and Aerospace, June 2006) [@rfc-4556]. The certificate&apos;s UPN SAN (or its dNSHostName for computer accounts) maps the certificate to the principal whose TGT the KDC will issue. PKINIT is the protocol surface most commonly exercised by Pass-the-Certificate against domain controllers that support certificate-based authentication.

The Windows TLS implementation. Supports TLS client-certificate authentication, which authenticated LDAPS uses. When a domain controller does not support PKINIT (Schroeder + Christensen documented this case in the original catalog; AlmondOffSec built tooling for it), an attacker can authenticate to LDAPS over Schannel with a stolen client certificate and perform high-privilege LDAP operations without traversing the KDC.

The technique of authenticating to Active Directory with a stolen X.509 certificate&apos;s private key, via PKINIT to the KDC or via Schannel client-certificate authentication to LDAPS. Named in this form by Yannick Méheut&apos;s PassTheCert tool and blog post (May 2022) [@almondoffsec-passthecert-github] [@almondoffsec-passthecert-blog], though the technique class was catalogued by Schroeder and Christensen eleven months earlier [@specterops-certified-pre-owned]. Tool of record: Certify (C#), Certipy (Python, ESC1-ESC16 [@certipy-wiki-privesc]), and Rubeus PKINIT mode.

sequenceDiagram
    participant Atk as Attacker (user)
    participant CA as Enterprise CA
    participant KDC
    Atk-&amp;gt;&amp;gt;CA: Enrol for template ESC1, SAN field set to Domain Administrator
    CA--&amp;gt;&amp;gt;Atk: X.509 certificate plus private key
    Note over Atk: Now holds a certificate naming the victim principal
    Atk-&amp;gt;&amp;gt;KDC: AS-REQ with PKINIT pre-auth using the stolen private key
    KDC-&amp;gt;&amp;gt;KDC: Validate certificate, map SAN to victim principal
    KDC--&amp;gt;&amp;gt;Atk: AS-REP with TGT for victim principal
    Atk-&amp;gt;&amp;gt;KDC: TGS-REQ for any service
    KDC--&amp;gt;&amp;gt;Atk: TGS-REP service ticket
&lt;p&gt;The CVE-class case lands on May 10, 2022. Oliver Lyak of IFCR discloses Certifried, CVE-2022-26923, an Active Directory Domain Services elevation-of-privilege vulnerability in which the combination of three Microsoft defaults -- &lt;code&gt;ms-DS-MachineAccountQuota = 10&lt;/code&gt; (any authenticated user can add up to 10 computer accounts to the domain), the default Machine template (which a computer account can enroll for), and the KDC&apos;s permissive &lt;code&gt;dNSHostName&lt;/code&gt;-to-SAN binding logic -- lets any authenticated user obtain a certificate for any computer account in the forest, including domain controllers.&lt;/p&gt;
&lt;p&gt;PKINIT-authenticate as a domain controller, and the KDC issues you a TGT for the DC; from there, DCSync extracts the krbtgt key and the domain is yours. Domain escalation from any authenticated user, with the only required misconfiguration being &lt;em&gt;Microsoft&apos;s defaults&lt;/em&gt; [@nvd-cve-2022-26923] [@semperis-cve-2022-26923].&lt;/p&gt;
&lt;p&gt;The defensive response shipped the same day. Microsoft published KB5014754 on May 10, 2022 -- coordinated disclosure, with the patch shipping in the same window as the CVE -- introducing a new X.509 extension &lt;code&gt;szOID_NTDS_CA_SECURITY_EXT&lt;/code&gt; (OID &lt;code&gt;1.3.6.1.4.1.311.25.2&lt;/code&gt;) that carries the requesting principal&apos;s SID at certificate issuance.&lt;/p&gt;
&lt;p&gt;The KDC&apos;s new strong-mapping logic refuses certificates that fail one of four conditions: the SID extension is present and matches; an issuer-serial mapping is present; a Subject Key Identifier mapping is present; or a SHA1-public-key mapping is present. The KB&apos;s load-bearing sentence: &quot;In Full Enforcement mode, if a certificate fails the strong (secure) mapping criteria (see Certificate mappings), authentication will be denied.&quot; [@ms-kb5014754]&lt;/p&gt;
&lt;p&gt;The KB5014754 change-log preserves a forensic artefact of the coordinated-disclosure timeline that is easy to miss. The current change-log row reads, verbatim: &quot;9/10/2025 - Corrected the Enforcement mode date from September 10, 2025, to September 9, 2025.&quot; [@ms-kb5014754] An off-by-one date correction, captured in the public KB. The kind of detail that only shows up when a small team has had to ship a date repeatedly against a multi-year audit-to-enforcement schedule.&lt;/p&gt;
&lt;p&gt;The enforcement timeline tells you how long even a CVE-class fix took to drive through deployment. Audit mode (May 10, 2022). Enforcement mode with a registry escape that admins could use to revert to compatibility (February 11, 2025). Final cutover with no escape (September 9, 2025) [@ms-kb5014754]. Three years and four months between the patch and the day Microsoft stopped accepting non-strong certificate mappings. Faster than the Credential Guard default-enablement window, but still measured in years.&lt;/p&gt;
&lt;p&gt;The naming history deserves a disambiguation. The &lt;em&gt;catalog&lt;/em&gt; -- ESC1 through ESC8, the full taxonomy of AD CS misconfigurations -- is Schroeder and Christensen, June 2021 [@specterops-certified-pre-owned]. The &lt;em&gt;wire-level technique name&lt;/em&gt; &quot;Pass-the-Certificate&quot; is popularised by AlmondOffSec&apos;s PassTheCert PoC (Yannick Méheut, May 4, 2022), which targets LDAP/S via Schannel client-cert authentication when PKINIT is unavailable, as a fallback path for environments where domain controllers do not support certificate-based Kerberos pre-authentication [@almondoffsec-passthecert-github] [@almondoffsec-passthecert-blog]. The blog post documents the &lt;code&gt;KDC_ERR_PADATA_TYPE_NOSUPP&lt;/code&gt; error path that diverts the PKINIT-blocked attacker into Schannel.&lt;/p&gt;
&lt;p&gt;The AlmondOffSec blog post acknowledges the social attribution of the term: &quot;Note for Googlers: this tool extends the notion of Pass the Certificate, thus dubbed by @_nwodtuhs in his Twitter thread on AD CS and PKINIT.&quot; [@almondoffsec-passthecert-blog] The technique name is socially attributed; the catalog framing is editorial.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A common shorthand says that KB5014754 bound NTOWFs to Kerberos, and that this is what forced attackers to shift to certificates. That arrow runs backwards in time. KB5014754 is the &lt;em&gt;response&lt;/em&gt; to Certifried, not the cause of Pass-the-Certificate. The technique class was catalogued by Schroeder and Christensen in June 2021, eleven months before KB5014754 shipped, and the PassTheCert tool that gave the technique its wire-level name appeared six days before Certifried&apos;s disclosure. The shift to certificates happened because certificates were the next long-term credential type Credential Guard did not isolate.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What does KB5014754 actually close? Three specific CVEs in the Certifried family: CVE-2022-26923 (the original SID-spoof Certifried disclosure), CVE-2022-26931 (UPN / sAMAccountName collision spoof), and CVE-2022-34691 (the certificate-pre-dating-account-creation case) [@ms-kb5014754]. What does it &lt;em&gt;not&lt;/em&gt; close? The broader ESC2 through ESC8 catalog, which is administrative hardening rather than CVE-class control. And it does not close ESC9 through ESC16, which were enumerated &lt;em&gt;after&lt;/em&gt; KB5014754 shipped and include cases like the &lt;code&gt;CT_FLAG_NO_SECURITY_EXTENSION&lt;/code&gt; template flag that &lt;em&gt;exempts&lt;/em&gt; a template from the very SID extension the patch introduced [@specterops-certs-patches-2022] [@certipy-wiki-privesc].&lt;/p&gt;
&lt;p&gt;The current state of the catalog: as of the 2025 Certipy 5.x documentation, ESC1 through ESC16 is the practitioner enumeration, with each technique characterised by a template-level, ACL-level, CA-administrator-level, NTLM-relay-level, SID-extension-level, or mapping-level abuse primitive [@certipy-wiki-privesc]. Microsoft Defender for Identity&apos;s certificates posture assessment tracks nine distinct ESC numbers as of the 2025 documentation -- ten posture assessments, because ESC4 owner and ESC4 ACL are tracked as separate sub-cases (ESC1, ESC2, ESC3, ESC4 owner, ESC4 ACL, ESC6 preview, ESC7, ESC8, ESC11, ESC15) [@ms-defender-id-certs]. Same pattern as Pass-the-Hash in 2012-2014: documentation tells administrators what to do; the structural exposure is downstream of how each enterprise built its templates years earlier.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ESC ID&lt;/th&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;th&gt;Closed by KB5014754&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;ESC1&lt;/td&gt;
&lt;td&gt;Template -- enrollee supplies SAN, client-auth EKU, permissive enrollment&lt;/td&gt;
&lt;td&gt;Partial: SID extension binds requester at issuance; ESC1 still works if the SID extension is absent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC2&lt;/td&gt;
&lt;td&gt;Template -- enrollee supplies SAN, Any-Purpose or no EKU&lt;/td&gt;
&lt;td&gt;No -- administrative hardening&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC3&lt;/td&gt;
&lt;td&gt;Template -- Certificate Request Agent enrollment-agent abuse&lt;/td&gt;
&lt;td&gt;No -- administrative hardening&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC4&lt;/td&gt;
&lt;td&gt;ACL -- writeable template configuration&lt;/td&gt;
&lt;td&gt;No -- administrative hardening&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC6&lt;/td&gt;
&lt;td&gt;CA -- &lt;code&gt;EDITF_ATTRIBUTESUBJECTALTNAME2&lt;/code&gt; flag set on the CA&lt;/td&gt;
&lt;td&gt;No -- CA-level hardening (was MS22-23, separately patched)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC8&lt;/td&gt;
&lt;td&gt;NTLM relay -- HTTP enrolment endpoints reachable from low-privilege contexts&lt;/td&gt;
&lt;td&gt;No -- relay-defence hardening&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC9&lt;/td&gt;
&lt;td&gt;Template -- &lt;code&gt;CT_FLAG_NO_SECURITY_EXTENSION&lt;/code&gt; exempts template from the SID extension&lt;/td&gt;
&lt;td&gt;No -- by design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC11&lt;/td&gt;
&lt;td&gt;NTLM relay -- ICPR RPC endpoint without sign / seal&lt;/td&gt;
&lt;td&gt;No -- relay-defence hardening&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC16&lt;/td&gt;
&lt;td&gt;CA -- security-extension disabled at the CA level&lt;/td&gt;
&lt;td&gt;No -- CA-level hardening&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;em&gt;Table 1. A representative slice of the ESC1-ESC16 catalog showing what KB5014754 closes and what remains administrative hardening [@specterops-certify-wiki] [@certipy-wiki-privesc] [@specterops-certs-patches-2022].&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;KB5014754 is a CVE-class fix for one sub-case. The broader ADCS catalog is administrative hardening. And the &lt;em&gt;next&lt;/em&gt; credential type -- the one that defeats Credential Guard, Protected Users, and KB5014754 simultaneously -- was already shipping in commodity Mimikatz code by August 2020.&lt;/p&gt;
&lt;h2&gt;8. Pass-the-PRT: The CloudAP Frontier&lt;/h2&gt;
&lt;p&gt;By August 2020, Microsoft had two architectural defenses against credential replay that the security industry actually trusted: Credential Guard for local Active Directory credentials, and (eighteen months later) KB5014754 for the certificate-replay class. Then a Dutch security researcher named Dirk-jan Mollema published a 21-minute read that broke both, in the same paragraph, by stealing a different credential type.&lt;/p&gt;
&lt;p&gt;The credential is the &lt;a href=&quot;https://paragmali.com/blog/inside-the-primary-refresh-token-the-cryptographic-seam-betw/&quot; rel=&quot;noopener&quot;&gt;Primary Refresh Token&lt;/a&gt;. The two foundational write-ups are Mollema&apos;s &quot;Abusing Azure AD SSO with the Primary Refresh Token&quot; [@mollema-prt-abusing] and its follow-on &quot;Digging further into the Primary Refresh Token&quot; [@mollema-prt-digging], both posted in August 2020. The second post is the single most-cited primary source in the fifth generation of the family. Read it once and you understand why Pass-the-PRT is structurally different from everything that came before.&lt;/p&gt;
&lt;p&gt;A PRT is a JSON Web Token refresh token issued by Microsoft Entra ID (formerly Azure AD) to Entra-joined or Hybrid-joined Windows devices, paired with a session key (HMAC-SHA256 secret) and bound to a device key registered at device join.&lt;/p&gt;
&lt;p&gt;The Microsoft Entra documentation describes the artefact precisely: &quot;A Primary Refresh Token (PRT) is a key artifact of Microsoft Entra authentication ... Once issued, a PRT is valid for 90 days and is continuously renewed as long as the user actively uses the device.&quot; [@ms-entra-concept-prt] On Windows the PRT is renewed every four hours during sign-in. The device-key registration binds the PRT to the device that owns it -- and is what an attacker has to work around to use a stolen PRT on a different device.&lt;/p&gt;

The Microsoft Entra-issued long-lived refresh token for SSO on Entra-joined or Hybrid-joined Windows devices. Carries a session key (HMAC-SHA256) used to sign per-request `x-ms-RefreshTokenCredential` cookies, and binds to a device transport key registered at device join. Default lifetime is 90 days with sliding renewal as long as the user actively uses the device; an inactivity timeout governs when an idle PRT must be re-acquired [@ms-entra-concept-prt]. The PRT is the load-bearing artefact for Single Sign-On to every Entra-integrated resource the device&apos;s user can reach.
&lt;p&gt;The PRT default lifetime is 90 days per the Microsoft Entra documentation, with renewal every four hours during Windows sign-in [@ms-entra-concept-prt]. The 14-day figure that sometimes appears in secondary references is the inactivity timeout on certain device states, not the PRT lifetime itself; this article uses the Microsoft Entra documentation&apos;s value to avoid the conflation.&lt;/p&gt;
&lt;p&gt;Where the PRT &lt;em&gt;lives&lt;/em&gt; is what makes the rest of the architecture work -- and what makes it vulnerable. The PRT is &lt;em&gt;hybrid&lt;/em&gt;: issued and revoked cloud-side by Entra ID, stored and used client-side via the &lt;strong&gt;CloudAP&lt;/strong&gt; authentication plug-in, which is loaded into LSASS like any other Windows authentication package.&lt;/p&gt;
&lt;p&gt;The load-bearing structural fact is that CloudAP is &lt;em&gt;in LSASS&lt;/em&gt;, not behind the LSAISO trustlet. Credential Guard&apos;s classical isolation does not extend to the CloudAP plug-in&apos;s working memory, because Credential Guard&apos;s scope is the three credential categories its design predates -- NT hashes, Kerberos TGTs, and &quot;domain credentials&quot; -- and the PRT is none of those [@mollema-prt-abusing].&lt;/p&gt;

The Windows authentication package (`cloudap.dll`, loaded into LSASS) that handles authentication against Microsoft Entra ID for Entra-joined and Hybrid-joined devices. Holds the device&apos;s Primary Refresh Token, its session key, and the derived material used to sign per-request PRT cookies. Sits inside LSASS in VTL0, *not* inside the LSAISO trustlet in VTL1; Credential Guard does not currently extend its isolation to CloudAP&apos;s working memory.
&lt;p&gt;The mechanism, as Mollema and Delpy developed it through the second half of 2020, runs as follows. Mimikatz &lt;code&gt;dpapi::cloudapkd /unprotect&lt;/code&gt; extracts the PRT (the encrypted-by-Entra refresh-token blob) and the session key from CloudAP&apos;s working memory.&lt;/p&gt;
&lt;p&gt;The attacker constructs an &lt;code&gt;x-ms-RefreshTokenCredential&lt;/code&gt; JWT carrying the PRT in the &lt;code&gt;refresh_token&lt;/code&gt; claim, &lt;code&gt;is_primary: true&lt;/code&gt;, and a &lt;code&gt;request_nonce&lt;/code&gt; obtained by an unauthenticated POST against the Entra ID v1 token endpoint at &lt;code&gt;https://login.microsoftonline.com/common/oauth2/token&lt;/code&gt; with form-encoded body &lt;code&gt;grant_type=srv_challenge&lt;/code&gt; (the server-challenge nonce pattern used by the ROADtools &lt;code&gt;roadtx prt&lt;/code&gt; reference implementation; the response is a JSON object with a &lt;code&gt;Nonce&lt;/code&gt; field). The signature is HMAC-SHA256 over the JWT under the session key. The completed cookie is presented to &lt;code&gt;login.microsoftonline.com&lt;/code&gt; from any machine, and Entra ID returns access and refresh tokens for any resource the original user can reach. Mollema&apos;s second post describes the collaboration that built the tooling:&lt;/p&gt;

Around the same time Benjamin Delpy took up my &apos;challenge&apos; of recovering PRT data from `lsass` with mimikatz. We combined forces and ended up with tooling that is not only able to extract the PRT and associated cryptographic keys (such as the session key) from memory, but can also use these keys to create new SSO cookies or modify existing ones. -- Dirk-jan Mollema, *Digging further into the Primary Refresh Token* [@mollema-prt-digging]
&lt;p&gt;The operational tooling closed quickly. Mollema&apos;s &lt;code&gt;roadtx prt&lt;/code&gt; (part of ROADtools [@roadtools-github]) automates the full chain end-to-end -- extract the material, mint the cookie, complete the OAuth dance, hand the attacker an access token. The Mimikatz &lt;code&gt;dpapi::cloudapkd&lt;/code&gt; command landed in the open-source repository the same window. Pass-the-PRT moved from research artefact to commodity tooling in months, not years.&lt;/p&gt;

sequenceDiagram
    participant Victim as Victim device (Entra-joined)
    participant Attacker as Attacker device
    participant Entra as login.microsoftonline.com
    Note over Victim: PRT plus session key held by CloudAP in LSASS
    Attacker-&amp;gt;&amp;gt;Victim: mimikatz dpapi::cloudapkd /unprotect
    Victim--&amp;gt;&amp;gt;Attacker: PRT (encrypted blob) plus session key
    Attacker-&amp;gt;&amp;gt;Entra: POST /common/oauth2/token grant_type=srv_challenge (unauthenticated)
    Entra--&amp;gt;&amp;gt;Attacker: request_nonce
    Note over Attacker: Build x-ms-RefreshTokenCredential JWT
    Note over Attacker: Sign HMAC-SHA256 with extracted session key
    Attacker-&amp;gt;&amp;gt;Entra: POST /token with PRT cookie
    Entra--&amp;gt;&amp;gt;Attacker: Access and refresh tokens
    Attacker-&amp;gt;&amp;gt;Attacker: Authenticate to any Entra resource as victim user
&lt;p&gt;Now the analytical core. Pass-the-PRT defeats three Microsoft defenses &lt;em&gt;simultaneously&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;First, &lt;strong&gt;Credential Guard&lt;/strong&gt; is out of scope. The CloudAP material is not an NT hash, not a Kerberos TGT, and not &quot;credentials stored by applications as domain credentials&quot; in the verbatim sense the Credential Guard documentation uses. Credential Guard&apos;s VBS-based isolation does not extend to CloudAP. The defense was designed in 2015 against the three credential types the family had then; the PRT is a credential type the family had not yet evolved into [@ms-learn-credential-guard].&lt;/p&gt;
&lt;p&gt;Second, &lt;strong&gt;KB5014754&lt;/strong&gt; is out of scope. The PRT cookie does not traverse the KDC&apos;s certificate-mapping logic at all; it is a JWT signed by an HMAC and authenticated at the Entra ID token endpoint. The strong certificate mapping that Microsoft drove through five years of audit-to-enforcement timeline has no relevance to a credential that never touches the KDC [@ms-kb5014754].&lt;/p&gt;
&lt;p&gt;Third, &lt;strong&gt;Protected Users&lt;/strong&gt; is out of scope. Protected Users is an Active-Directory-only construct, enforced on Windows Server domain controllers and on AD-joined member devices. Entra ID is a separate identity provider with separate enforcement; the 240-minute TGT cap, the NTLM ban, and the RC4 ban that Protected Users enforces simply do not apply [@ms-protected-users].&lt;/p&gt;
&lt;p&gt;The TPM-sealing finding is where the architectural pattern becomes most precise. Microsoft began sealing the PRT session key to a &lt;a href=&quot;https://paragmali.com/blog/the-tpm-in-windows-one-primitive-twenty-five-years-and-the-c/&quot; rel=&quot;noopener&quot;&gt;TPM-bound key&lt;/a&gt; on TPM-2.0-eligible hardware -- a defense that, in principle, makes the raw session key cryptographically non-exportable. Mollema&apos;s finding in the August 2020 second post is that the seal does not close the attack, because CloudAP holds &lt;em&gt;derived&lt;/em&gt; PRT-cookie-signing material in its own working memory in LSASS, and the attacker only needs the derived material:&lt;/p&gt;

despite the session key of the PRT is stored in the TPM whenever possible, this doesn&apos;t prevent us from extracting the PRT and the required information to create SSO cookies. The result of this is that regardless of whether the PRT is protected by the TPM or not, with Administrator access it is possible to extract the PRT from LSASS and use the PRT on a different device than it was issued to. -- Dirk-jan Mollema, *Digging further into the Primary Refresh Token* [@mollema-prt-digging]
&lt;p&gt;The structural reason the standard hardware-rooted defense pattern does not transfer: the attacker does not need the raw session key out of the TPM. They need only the in-memory derived material CloudAP itself uses to sign the cookies, and that derived material lives in the same address space Credential Guard does not isolate.&lt;/p&gt;
&lt;p&gt;The TPM seals the key. CloudAP uses the key. Whatever CloudAP can read, an attacker with administrator and a memory-access primitive can also read. The defense pattern that worked for NT hashes (move them out of the address space) has not been applied to CloudAP -- and until it is, the TPM seal is a speed bump rather than a wall.&lt;/p&gt;
&lt;p&gt;{`
// Pedagogical demonstration of the JWT structure used in Pass-the-PRT
// cookie minting. Uses placeholder values throughout; no real PRT material.&lt;/p&gt;
&lt;p&gt;const base64url = (buf) =&amp;gt; Buffer.from(buf).toString(&apos;base64&apos;)
  .replace(/=+$/, &apos;&apos;).replace(/\+/g, &apos;-&apos;).replace(/\//g, &apos;_&apos;);&lt;/p&gt;
&lt;p&gt;const header = { alg: &apos;HS256&apos;, ctx: &apos;AAAAAAAA&apos; };
const payload = {
  // The PRT itself, an opaque refresh-token string Entra issued to the
  // device. In a real attack this comes from mimikatz dpapi::cloudapkd.
  refresh_token: &apos;AQABAAAAAAA...redacted...&apos;,
  // Marks this cookie as a primary refresh token cookie.
  is_primary: &apos;true&apos;,
  // Fresh nonce from an unauthenticated POST against the v1 token endpoint
  // at login.microsoftonline.com/common/oauth2/token with form body
  // grant_type=srv_challenge (returns JSON with Nonce field; the canonical
  // server-challenge pattern used by ROADtools roadtx prt).
  request_nonce: &apos;AwABAAEAAAAC...&apos;,
  iat: Math.floor(Date.now() / 1000),
};&lt;/p&gt;
&lt;p&gt;// HMAC-SHA256 over the JWT under the session key recovered from CloudAP.
// Placeholder key for demonstration only.
const sessionKey = Buffer.alloc(32); // 32 bytes of zeros (fake)
const crypto = require(&apos;crypto&apos;);&lt;/p&gt;
&lt;p&gt;const h = base64url(JSON.stringify(header));
const p = base64url(JSON.stringify(payload));
const sig = base64url(
  crypto.createHmac(&apos;sha256&apos;, sessionKey).update(h + &apos;.&apos; + p).digest()
);&lt;/p&gt;
&lt;p&gt;console.log(&apos;Header segment:    &apos; + h);
console.log(&apos;Payload segment:   &apos; + p);
console.log(&apos;Signature segment: &apos; + sig);
console.log();
console.log(&apos;Full PRT cookie: &apos; + h + &apos;.&apos; + p + &apos;.&apos; + sig);
// In a real attack the attacker would now POST this as the
// x-ms-RefreshTokenCredential cookie to login.microsoftonline.com.
`}&lt;/p&gt;
&lt;p&gt;The current partial mitigations are worth enumerating, because none of them closes the gap.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Token Protection&lt;/strong&gt; (a &lt;a href=&quot;https://paragmali.com/blog/who-decided-this-token-is-good-a-field-guide-to-conditional-/&quot; rel=&quot;noopener&quot;&gt;Conditional Access&lt;/a&gt; session control) attempts to ensure that only device-bound sign-in session tokens are accepted at the Entra ID token endpoint for protected resources. The Microsoft Learn page is explicit about both the design intent and the deployment limits: &quot;Token Protection is a Conditional Access session control that attempts to reduce token replay attacks by ensuring only device bound sign-in session tokens, like Primary Refresh Tokens (PRTs), are accepted by Microsoft Entra ID when applications request access to protected resources.&quot; [@ms-entra-token-protection] As of the current documentation the &lt;em&gt;supported resources&lt;/em&gt; are five named applications: Exchange Online, SharePoint Online, Microsoft Teams, Azure Virtual Desktop, and Windows 365. Browser applications are out of scope; &quot;Token Protection currently supports native applications only. Browser-based applications are not supported.&quot; [@ms-entra-token-protection] Most Entra-integrated SaaS is unbound.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Continuous Access Evaluation&lt;/strong&gt; (CAE) shortens the window during which a stolen PRT is operationally usable, by allowing the token endpoint to revoke tokens within minutes of a triggering signal (password change, risk-based detection, conditional-access policy update) [@ms-entra-cae]. CAE is evaluation-time, not isolation. It shortens the window between extraction and detection-driven revocation; it does not prevent extraction.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hybrid-joined PRT renewal binding&lt;/strong&gt; partially closes the cross-tenant case for hybrid Azure AD Join configurations, but does not address the same-tenant Pass-the-PRT case that Mollema&apos;s original 2020 posts described [@ms-entra-hybrid-join-plan].&lt;/p&gt;
&lt;p&gt;The institutional acknowledgment of the supersession pattern is the verbatim Microsoft Learn sentence already quoted in section 6 [@ms-learn-credential-guard]: written about the 2015 Credential Guard architecture, it accurately predicts the 2020 Pass-the-PRT shift. The credential-replay family has reached the point where &lt;em&gt;every Microsoft defense&lt;/em&gt; in the on-prem stack runs in parallel against an attack the on-prem stack cannot reach.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Pass-the-PRT defeats Credential Guard, KB5014754, and Protected Users simultaneously because each defense was designed around a different long-term artefact, and the PRT is none of them. The architectural property -- a long-term authentication artefact reachable from the using process is replayable -- is unchanged. The artefact moved.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Six years after Mollema&apos;s disclosure, the TPM-resilience finding still holds. The CloudAP plug-in is still in LSASS. Credential Guard still does not extend its boundary. Pass-the-PRT remains the operational frontier in 2026.&lt;/p&gt;
&lt;h2&gt;9. The 5x5 Matrix and the Irregular Cadence&lt;/h2&gt;
&lt;p&gt;Five generations of attack. Five generations of defense. They map onto each other unevenly; the gaps are not five years.&lt;/p&gt;
&lt;p&gt;The matrix below consolidates the lineage at a glance. Rows are the attack generations (in the order they entered the practitioner literature). Columns are the defense generations (in the order they shipped). Each cell records whether that defense closes that attack on a fully-deployed hardware-eligible 2026 Windows 11 endpoint with the control turned on. &quot;Closed&quot; means the attack returns empty buffers or fails authentication; &quot;Partial&quot; means the defense increases attacker cost or closes one sub-case; &quot;Open&quot; means the defense&apos;s design scope does not include that attack.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attack \ Defense&lt;/th&gt;
&lt;th&gt;Mitigating-PtH whitepapers (2012/2014)&lt;/th&gt;
&lt;th&gt;Protected Users + RunAsPPL + Restricted Admin (2013-2014)&lt;/th&gt;
&lt;th&gt;Credential Guard / LSAISO (2015)&lt;/th&gt;
&lt;th&gt;KB5014754 strong mapping (2022)&lt;/th&gt;
&lt;th&gt;Token Protection + CAE (2023-2025)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Pass-the-Hash (Ashton 1997, Ochoa 2008)&lt;/td&gt;
&lt;td&gt;Open (documentation)&lt;/td&gt;
&lt;td&gt;Partial (Protected Users members)&lt;/td&gt;
&lt;td&gt;Closed (on enabled endpoints)&lt;/td&gt;
&lt;td&gt;Open (not in scope)&lt;/td&gt;
&lt;td&gt;Open (not in scope)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pass-the-Ticket (Delpy 2011, Duckwall+Delpy 2014)&lt;/td&gt;
&lt;td&gt;Open (documentation)&lt;/td&gt;
&lt;td&gt;Partial (4-hour TGT cap for Protected Users)&lt;/td&gt;
&lt;td&gt;Closed (TGT session key in LSAISO)&lt;/td&gt;
&lt;td&gt;Open (not in scope)&lt;/td&gt;
&lt;td&gt;Open (not in scope)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Overpass-the-Hash (Delpy / Metcalf 2014)&lt;/td&gt;
&lt;td&gt;Open (documentation)&lt;/td&gt;
&lt;td&gt;Partial (RC4 banned for Protected Users)&lt;/td&gt;
&lt;td&gt;Closed (NT hash in LSAISO)&lt;/td&gt;
&lt;td&gt;Open (not in scope)&lt;/td&gt;
&lt;td&gt;Open (not in scope)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pass-the-Certificate (Schroeder + Christensen 2021, Méheut 2022)&lt;/td&gt;
&lt;td&gt;Open (documentation)&lt;/td&gt;
&lt;td&gt;Open (cert keys outside scope)&lt;/td&gt;
&lt;td&gt;Open (cert keys outside scope)&lt;/td&gt;
&lt;td&gt;Partial (closes Certifried sub-case; ESC2-ESC16 remain)&lt;/td&gt;
&lt;td&gt;Open (not in scope)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pass-the-PRT (Mollema + Delpy 2020)&lt;/td&gt;
&lt;td&gt;Open (Entra ID is separate IDP)&lt;/td&gt;
&lt;td&gt;Open (Entra ID is separate IDP)&lt;/td&gt;
&lt;td&gt;Open (CloudAP not in LSAISO)&lt;/td&gt;
&lt;td&gt;Open (not in scope)&lt;/td&gt;
&lt;td&gt;Partial (5 named resources; browser apps out of scope)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;em&gt;Table 2. The 5x5 attack/defense matrix. The union of every cell in the rightmost column of &quot;Closed&quot; entries is the set of attacks Microsoft&apos;s published 2026 defenses close on hardware-eligible non-DC endpoints with every control turned on; that set is precisely the first three rows.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The matrix makes the structure visible. No single defense closes all attacks, and no single attack is closed by all defenses. The union of every defense closes Pass-the-Hash, Pass-the-Ticket, and Overpass-the-Hash on hardware-eligible non-DC Windows 10/11 systems with all controls enabled. It partially closes Pass-the-Certificate (for the Certifried sub-case) and partially closes Pass-the-PRT (for five named resources). Both of the most recent generations remain operationally open against any deployment that does not run those specific controls -- which is most deployments.&lt;/p&gt;
&lt;p&gt;The cadence is just as uneven as the matrix. The original input that prompted this article claimed &quot;every Windows defense against credential replay buys about five years before the attack class evolves to the next credential type.&quot; Memorable. Also wrong. The actual timeline produces gaps from eleven months to eleven years, with one negative interval:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1997 -&amp;gt; 2008&lt;/strong&gt; (eleven years) for the Samba-patch -&amp;gt; Windows-native pivot. Pass-the-Hash existed for over a decade as a Unix-side novelty before Ochoa&apos;s LSASS-injection insight made it Windows-native.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2008 -&amp;gt; 2011&lt;/strong&gt; (three years) for the Mimikatz Pass-the-Ticket extension. The same memory-access primitive that animated &lt;code&gt;IAM.EXE&lt;/code&gt; was retargeted at a different artefact.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2012/2014 -&amp;gt; 2015&lt;/strong&gt; (one to three years) for the Mitigating-PtH whitepapers -&amp;gt; Credential Guard pivot. Documentation took a year and a half to ship; the architectural counter took another.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2021 -&amp;gt; 2022&lt;/strong&gt; (eleven months) for the AD CS catalog -&amp;gt; KB5014754 response. Coordinated disclosure compressed this gap; Certifried&apos;s CVE-class status forced a CVE-class response.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2020 -&amp;gt; 2025+&lt;/strong&gt; (open-ended) for Pass-the-PRT with no Credential-Guard-equivalent shipped. As of the Windows 11 25H2 cycle there is no public roadmap for VBS-class isolation of CloudAP material.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The most striking gap is the 2020/2021 &lt;em&gt;negative&lt;/em&gt; interval. Pass-the-PRT (Mollema, August 2020) and the AD CS catalog (Schroeder + Christensen, June 2021) are siblings rather than sequential; Pass-the-PRT predates Pass-the-Certificate as a &lt;em&gt;named technique&lt;/em&gt; by ten months, even though the article treats them as Generation 4 and Generation 5 in narrative order. The Generation N -&amp;gt; N+1 framing is &lt;em&gt;taxonomic&lt;/em&gt;, not strictly chronological. The reader needs this distinction to read the lineage accurately: the attack class evolves along the architectural property, not along the calendar.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &quot;every Windows defense buys five years&quot; framing is what you see if you select the cleanest pairings (Mitigating-PtH 2012/2014 to Credential Guard 2015 plus an artificial 2020-targeted &quot;next attack&quot;). When you look at the actual intervals, you see eleven years (1997-2008), three years (2008-2011), eleven months (2021-2022), and an open-ended interval (2020 onwards). The pattern is the architectural property persisting across artefact changes, not a calendar drumbeat.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The storage-class progression is the cleanest way to see the property hold across the lineage. Each row names the long-term artefact, where it lives, and which defense moved or shielded that storage class.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Generation&lt;/th&gt;
&lt;th&gt;Long-term artefact&lt;/th&gt;
&lt;th&gt;Storage location&lt;/th&gt;
&lt;th&gt;Defense that isolated it&lt;/th&gt;
&lt;th&gt;Status 2026&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;1A (1997 Samba)&lt;/td&gt;
&lt;td&gt;NT hash (and LM hash)&lt;/td&gt;
&lt;td&gt;Local SAM file on disk&lt;/td&gt;
&lt;td&gt;&quot;Do not store LAN Manager hash&quot; policy (Vista default-on); SAM hash extraction still works&lt;/td&gt;
&lt;td&gt;LM hash retired; NT hash extraction still works&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1B (2008 Windows-native)&lt;/td&gt;
&lt;td&gt;NT hash&lt;/td&gt;
&lt;td&gt;LSASS credential cache&lt;/td&gt;
&lt;td&gt;Credential Guard relocates to LSAISO&lt;/td&gt;
&lt;td&gt;Closed on Credential-Guard-enabled endpoints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2 (2011 Mimikatz)&lt;/td&gt;
&lt;td&gt;Kerberos TGT plus session key&lt;/td&gt;
&lt;td&gt;LSASS Kerberos package&lt;/td&gt;
&lt;td&gt;Credential Guard relocates to LSAISO&lt;/td&gt;
&lt;td&gt;Closed on Credential-Guard-enabled endpoints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3 (2014)&lt;/td&gt;
&lt;td&gt;NT hash promoted to RC4-HMAC Kerberos key&lt;/td&gt;
&lt;td&gt;LSASS, same buffer as Pass-the-Hash&lt;/td&gt;
&lt;td&gt;Credential Guard relocates to LSAISO; KB5021131 makes AES the default&lt;/td&gt;
&lt;td&gt;Closed on Credential-Guard-enabled endpoints; RC4 deprecated in favour of AES [@ms-kb5021131]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4 (2021 AD CS catalog)&lt;/td&gt;
&lt;td&gt;X.509 certificate private key&lt;/td&gt;
&lt;td&gt;CryptoAPI key container, TPM, or smart card&lt;/td&gt;
&lt;td&gt;TPM-resident or VSC-resident keys are cryptographically non-exportable; KB5014754 binds certificates to SIDs at issuance&lt;/td&gt;
&lt;td&gt;Partial; ESC2-ESC16 misconfigurations remain administrative hardening&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5 (2020 Pass-the-PRT)&lt;/td&gt;
&lt;td&gt;PRT session key plus derived signing material&lt;/td&gt;
&lt;td&gt;CloudAP plug-in in LSASS (session key optionally TPM-sealed)&lt;/td&gt;
&lt;td&gt;None deployed; Token Protection partially shields five resources&lt;/td&gt;
&lt;td&gt;Open&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;em&gt;Table 3. Storage-class progression. Each attack generation targets the next long-term artefact whose storage location is not isolated by the previous generation&apos;s defense.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The matrix and the storage-class table jointly produce the structural prediction: each generation shifts to the next available long-term artefact whose storage class the latest defense does not isolate. The graph-based formalisation of these storage-class transitions is the BloodHound edge catalog -- the &lt;code&gt;HasSession&lt;/code&gt;, &lt;code&gt;AdminTo&lt;/code&gt;, and &lt;code&gt;CanRDP&lt;/code&gt; family that operationalises &quot;which principal can reach which credential from where&quot; as a queryable property of an enterprise&apos;s directory [@bloodhound-edges]. The pattern predicts a Generation 6 outside whatever isolation scope arrives next.&lt;/p&gt;
&lt;p&gt;The most credible candidate today is &lt;strong&gt;Pass-the-DeviceKey&lt;/strong&gt;: extraction or abuse of the device transport key the PRT binds to, or of the CloudAP-derived material the cookie-signing process produces from it [@mollema-prt-phishing]. Mollema&apos;s 2023-2025 continuation work documents the underlying device-transport-key primitives in detail; the September 2025 Actor-tokens disclosure shows that cross-tenant abuse of related Entra-side material is also operational in the wild [@mollema-actor-tokens] [@mollema-federated-credentials].&lt;/p&gt;

flowchart TD
    A1[Pass-the-Hash 1A Samba&lt;br /&gt;Ashton 1997]
    A2[Pass-the-Hash 1B Windows-native&lt;br /&gt;Ochoa 2008]
    A3[Pass-the-Ticket&lt;br /&gt;Delpy 2011]
    A4[Overpass-the-Hash&lt;br /&gt;Delpy / Metcalf 2014]
    A5[Pass-the-Certificate&lt;br /&gt;Schroeder + Christensen 2021]
    A6[Pass-the-PRT&lt;br /&gt;Mollema + Delpy 2020]
    A7[Pass-the-DeviceKey forecast]
    D1[Mitigating-PtH whitepapers&lt;br /&gt;v1 2012, v2 2014]
    D2[Protected Users + RunAsPPL + Restricted Admin&lt;br /&gt;2013-2014]
    D3[Credential Guard / LSAISO&lt;br /&gt;2015, default 2022]
    D4[KB5014754 strong mapping&lt;br /&gt;2022, enforced 2025]
    D5[Token Protection + CAE&lt;br /&gt;2023-2025]
    D6[CloudAP isolation forecast]
    A1 --&amp;gt; A2
    A2 --&amp;gt; A3
    A3 --&amp;gt; A4
    A4 --&amp;gt; A5
    A4 --&amp;gt; A6
    A6 --&amp;gt; A7
    D1 --&amp;gt; D2
    D2 --&amp;gt; D3
    D3 --&amp;gt; D4
    D4 --&amp;gt; D5
    D5 -.- D6
    A2 -.- D1
    A2 -.- D2
    A3 -.- D3
    A4 -.- D3
    A5 -.- D4
    A6 -.- D5
    A7 -.- D6
&lt;p&gt;If the pattern holds, Generation 6 is already in research literature. Mollema&apos;s 2023-2025 continuation work [@mollema-prt-phishing] [@mollema-federated-credentials] [@mollema-actor-tokens] documents the device-transport-key extraction primitives. The only things missing are the name and the commodity tool. The historical pattern says we probably get both before VBS-class CloudAP isolation ships.&lt;/p&gt;
&lt;h2&gt;10. Open Problems and the 2026-2030 Forecast&lt;/h2&gt;
&lt;p&gt;The credential-replay family has six load-bearing open problems in 2026. Each is structural rather than mathematical; the cryptographic primitives that would close them already exist.&lt;/p&gt;
&lt;p&gt;The architectural lower bound -- the only configuration that closes the family in principle -- is the union of three things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Universal hardware-rooted non-extractable keys&lt;/strong&gt;: every long-term authentication artefact lives in a TPM, secure enclave, FIDO2 authenticator, or smart card, with key attestation, and is never released to software memory. &lt;strong&gt;Universal protocol-layer token binding&lt;/strong&gt;: every issued token (Kerberos service ticket, OAuth refresh token, OIDC ID token, SAML assertion) is cryptographically bound to the device that requested it, and a verifier rejects any presentation from a non-bound device. &lt;strong&gt;Universal continuous evaluation&lt;/strong&gt;: every protected resource queries the issuer in near-real-time and revokes within minutes of a triggering signal. Each component is deployed &lt;em&gt;somewhere&lt;/em&gt;; none is deployed &lt;em&gt;everywhere&lt;/em&gt;; no single vendor controls all three layers.&lt;/p&gt;
&lt;p&gt;The five concrete open problems flow from the lower bound.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The CloudAP isolation problem.&lt;/strong&gt; When does Microsoft extend VBS-class isolation to the CloudAP plug-in&apos;s working memory in LSASS? No public roadmap as of 2026. Until it ships, Pass-the-PRT remains operationally open against every Entra-joined Windows endpoint.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The token-binding adoption problem.&lt;/strong&gt; Token Protection&apos;s verbatim 2026 scope is the five named resources enumerated in section 8 [@ms-entra-token-protection], which covers approximately five percent of typical Entra-integrated SaaS surface area; every other Entra-integrated resource accepts unbound tokens. The OAuth working group&apos;s RFC 9449 (DPoP, September 2023) standardises proof-of-possession at the OAuth layer [@rfc-9449], but adoption across SaaS providers and enterprise applications is uneven.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Pass-the-DeviceKey forecast.&lt;/strong&gt; Mollema&apos;s 2023-2025 continuation work exercises device-transport-key extraction primitives, federated-credential persistence on Entra applications, and cross-tenant Actor-token abuse [@mollema-prt-phishing] [@mollema-federated-credentials] [@mollema-actor-tokens]. The pattern of every previous generation predicts that whichever of these primitives commoditises first will be the next named &quot;Pass-the-X&quot; technique.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The ESC9-ESC16 hardening problem.&lt;/strong&gt; The AD CS catalog has grown from 8 entries (June 2021) to 16 (current Certipy and Certify wikis [@certipy-wiki-privesc] [@specterops-certify-wiki]); most additions are misconfiguration-class rather than CVE-class. ESC9 specifically describes the &lt;code&gt;CT_FLAG_NO_SECURITY_EXTENSION&lt;/code&gt; template flag that &lt;em&gt;exempts&lt;/em&gt; a template from the very SID extension KB5014754 introduced -- so administrators who turn that flag on for legacy compatibility reasons silently re-enable the Certifried-class abuse path on those templates.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hardware-backed identity ubiquity.&lt;/strong&gt; When does the union of Pluton + FIDO2 + virtual smart cards + TPM key attestation eliminate the long-term software-extractable artefact class? Human interactive sign-in to Entra ID can already be fully passwordless on supported hardware. The long tail of service accounts, scheduled tasks, on-prem AD workflows, and legacy applications resists migration; the migration is a years-long enterprise project, not a feature flag.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The non-Microsoft sibling lineages.&lt;/strong&gt; The credential-replay family is not Windows-specific. Okta session-cookie theft, Google IDP refresh-token reuse, Apple ASWebAuthSession token replay, and AWS STS session-token theft all face the same architectural property. An enterprise running Microsoft plus Okta plus Google inherits the union of every vendor&apos;s residual replay surface. The family generalises beyond Microsoft because the architectural property generalises beyond Microsoft.&lt;/p&gt;

Okta&apos;s `sessionToken` and OAuth `refresh_token` artefacts live on the device that requested them, and have been used in commodity offensive tooling since at least 2022. Google&apos;s IDP refresh tokens face the same exposure surface on managed Chromebooks. Apple&apos;s ASWebAuthSession tokens are device-bound at the platform level, which closes the cross-device replay case but not the same-device extraction case. AWS STS session tokens are not device-bound at all. The credential-replay family is a property of long-term software-extractable authentication artefacts in general; this article is Windows-specific only because Windows has the longest documented lineage.
&lt;p&gt;The institutional position is that the protocol-level fix is unavailable -- Microsoft&apos;s framing of Pass-the-Hash as a structural property of NTLM generalises directly to every later generation. A universal fix would require replacing every long-term software-extractable artefact globally with hardware-bound primitives, with mandatory token binding at every issuer and every resource server, with continuous evaluation everywhere. Each step is incrementally closable; the union has not yet closed for any deployment.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Universal hardware-rooted non-extractable keys, universal protocol-layer token binding, universal continuous evaluation. Each component is deployed somewhere; none is deployed everywhere. No single vendor controls all three layers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The architectural property the family shares has held for twenty-nine years; the defensive lineage will not close it without making &lt;em&gt;every&lt;/em&gt; long-term artefact live in hardware-rooted isolation that exceeds the host&apos;s privilege. Whether that happens in the next five years, the next ten, or the next twenty-five, is the open question the next chapter of this lineage will answer.&lt;/p&gt;
&lt;h2&gt;11. The 2026 Defender Playbook&lt;/h2&gt;
&lt;p&gt;Architectural humility does not mean defensive passivity. The 2026 estate is defensible against generations 1 through 3 and partially against generation 4; the playbook is to deploy every available control while reading Mollema&apos;s 2025 posts to know what&apos;s coming for generation 5 and beyond.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Credential Guard everywhere it can run.&lt;/strong&gt; Hardware-eligible non-DC Windows 10/11 endpoints, with the four-residual disclosure (AD database, DCs, certificate keys, CloudAP) documented for the SOC so that detection engineering does not assume Credential Guard covers categories it explicitly excludes [@ms-learn-credential-guard].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LSA Protection (RunAsPPL), UEFI-anchored&lt;/strong&gt; stacked underneath, per itm4n&apos;s &quot;complementary&quot; framing [@itm4n-lsass-runasppl]. The UEFI-anchored variant resists the registry-based bypass that a kernel-mode attacker can otherwise apply at boot.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Authentication Silos and Protected Users for Tier-0 accounts.&lt;/strong&gt; Expect to encounter unconstrained-delegation breakage on legacy services and budget remediation; the 240-minute TGT cap is the lever that prevents long-lived Tier-0 ticket reuse [@ms-protected-users].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;KB5014754 strong-mapping enforcement&lt;/strong&gt; -- fully on by the September 9, 2025 cutover -- plus an annual certificate-template audit cycle against the ESC1-ESC16 catalog using Certipy or PSPKIAudit [@ms-kb5014754] [@certipy-wiki-privesc]. The audit is the load-bearing control because the strong-mapping fix only closes Certifried-class abuses; the template misconfigurations Schroeder and Christensen catalogued are still administrative responsibility.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Conditional Access with Token Protection where supported&lt;/strong&gt; -- the five resources Microsoft Learn enumerates [@ms-entra-token-protection]. Device-bound sign-ins for privileged accounts; FIDO2 for human interactive sign-in. Know that the long tail of Entra-integrated SaaS does not enforce binding, and that a stolen PRT used against an unbound resource will still authenticate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PRT-extraction telemetry.&lt;/strong&gt; Detect CloudAP-plug-in token access from non-CloudAP processes; tie to Endpoint DLP; alert on out-of-band access to &lt;code&gt;cloudap.dll&lt;/code&gt;-owned regions of LSASS memory. Mollema&apos;s &lt;code&gt;roadtx&lt;/code&gt; and BARK produce signal patterns worth modelling.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mental model: assume the PRT is the next NT hash.&lt;/strong&gt; Architect today as if Credential Guard for CloudAP shipped tomorrow -- which means TPM-attested device joins as standard, FIDO2 for every human sign-in, hardware-backed identity for service accounts wherever the vendor supports it, and conditional access policies that treat unmanaged or non-attested devices as untrusted by default.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

Open PowerShell as administrator and run:&lt;p&gt;&lt;code&gt;Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard | Format-List&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The result of interest is &lt;code&gt;SecurityServicesRunning&lt;/code&gt;. A value of &lt;code&gt;1&lt;/code&gt; in that list means Credential Guard is actively running (per the Win32_DeviceGuard documentation: &lt;code&gt;1 = Credential Guard&lt;/code&gt;, &lt;code&gt;2 = HVCI&lt;/code&gt;, &lt;code&gt;3 = System Guard secure launch&lt;/code&gt;, etc.). &lt;code&gt;SecurityServicesConfigured&lt;/code&gt; tells you what the policy intends; &lt;code&gt;SecurityServicesRunning&lt;/code&gt; tells you what the hypervisor is actually enforcing right now. The two values disagree more often than you would expect, usually because the hardware did not meet a prerequisite at boot.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The minimum-viable layer: Credential Guard on every hardware-eligible non-DC endpoint, KB5014754 enforcement-mode certificate strong mapping with an annual ESC catalog audit, and PRT-extraction telemetry tied to a real detection workflow. The first two are commodity Microsoft features that close real attack classes today; the third is the only meaningful signal you can get on the attack class that none of the published defenses currently closes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;None of this closes Pass-the-PRT. All of it shortens the dwell time.&lt;/p&gt;
&lt;h2&gt;12. Frequently Asked Questions&lt;/h2&gt;


No. The Primary Refresh Token sits in the CloudAP plug-in, which is outside Credential Guard&apos;s verbatim three-credential scope -- see section 6 (&quot;What does Credential Guard isolate?&quot;) and section 8 (&quot;Pass-the-PRT defeats three Microsoft defenses simultaneously&quot;) for the full mechanism.

No. The 1997 Ashton patch and the 2008 Ochoa Windows-native pivot are both pre-Mimikatz; see section 1 and section 3 for the full origin story. Mimikatz is the dominant *tool* (May 2011 first release) but it is not the *origin* of Pass-the-Hash.

No. The PRT is *hybrid* -- issued and revoked cloud-side by Entra ID, but stored and used client-side via the CloudAP plug-in inside LSASS. See section 8 (&quot;Where the PRT *lives*&quot;) for why this hybrid architecture is what makes Pass-the-PRT operationally tractable today.

No. It closed the three Certifried-class CVEs (CVE-2022-26923, CVE-2022-26931, CVE-2022-34691) but not the broader ESC2 through ESC16 catalog. See section 7 (&quot;What does KB5014754 actually close?&quot;) and Table 1 for the per-template breakdown.

For human interactive sign-in to Entra ID, mostly, if the entire enterprise migrates -- the FIDO2 authenticator holds a non-extractable private key in hardware, and the resulting authentication is bound to that key. For service accounts, scheduled tasks, on-prem Kerberos workflows, hybrid identity scenarios, and the long tail of legacy applications, no -- those paths still rely on long-term software-extractable artefacts (passwords, hashes, keys) by construction. The architectural counter is universal hardware-rooted non-extractable keys plus universal token binding plus universal continuous evaluation; the operational reality is partial coverage.

No public v3. See section 5 (&quot;The Mitigating-PtH v3 that never shipped&quot;) for the source-by-source disambiguation against Microsoft Download Center ID 36036.

&lt;h2&gt;13. The Pattern That Outlived Six Defenses&lt;/h2&gt;
&lt;p&gt;The 1997 patch and the 2026 attack are the same attack because the architectural property the family shares is unchanged. The artefact moved; the property did not.&lt;/p&gt;
&lt;p&gt;A long-term authentication artefact reachable by the using process is replayable. The NT hash sat in LSASS on Windows NT 4.0 and replayed against SMB. The Kerberos TGT sat in LSASS on Windows Server 2003 and replayed against Kerberos services. The NT hash sat in LSASS on Windows Server 2008 and replayed against the KDC&apos;s RC4-HMAC authentication path as a real Kerberos client.&lt;/p&gt;
&lt;p&gt;The X.509 certificate private key sat in a CryptoAPI key container on Windows Server 2012 R2 and replayed against PKINIT-supporting domain controllers as the principal in the SAN. The Primary Refresh Token sits in the CloudAP plug-in inside LSASS on Windows 11 23H2 today, and replays against Entra ID as the device&apos;s user from any machine that holds the extracted session key.&lt;/p&gt;
&lt;p&gt;Each defense relocated the artefact to a harder-to-reach storage class. The &quot;Do not store LAN Manager hash&quot; policy retired LM. RunAsPPL marked LSASS as a Protected Process Light. Credential Guard moved NT hashes and TGT session keys out of LSASS in VTL0 into the LSAISO trustlet in VTL1. KB5014754 bound certificates to SIDs at issuance, so that a certificate without the SID extension fails strong mapping at the KDC. Token Protection bound PRTs to devices, so that a stolen PRT used against a supported resource from a non-bound device fails.&lt;/p&gt;
&lt;p&gt;Each defense was real. Each closed a generation. The family did not close.&lt;/p&gt;
&lt;p&gt;The reason the family does not close is structural. Every generation finds the next long-term artefact whose storage class the latest defense did not isolate. Pass-the-Hash worked because the NT hash was reachable. Pass-the-Ticket worked because the TGT was reachable. Overpass-the-Hash worked because the NT hash was reachable &lt;em&gt;and&lt;/em&gt; the KDC accepted RC4-HMAC. Pass-the-Certificate worked because certificate templates were misconfigured and the SID extension did not exist. Pass-the-PRT works because CloudAP is in LSASS in VTL0 and Token Protection covers five resources.&lt;/p&gt;
&lt;p&gt;The architectural lower bound -- universal hardware-rooted non-extractable keys plus universal token binding plus universal continuous evaluation -- is the only configuration that closes the family, and it is not deployed anywhere as a complete stack.&lt;/p&gt;
&lt;p&gt;The playbook in the previous section is what to do today. The forecast in section 10 is what to architect for next. The closing observation is the one this article exists to register: when you read about the next named &quot;Pass-the-X&quot; technique, you already know what it will look like. A long-term authentication artefact, reachable from the process that holds it, replayed from a different machine, defeating the latest defense because that defense was designed for a different artefact.&lt;/p&gt;
&lt;p&gt;Generation 6 is already in research literature. The only thing missing is the name.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;pass-the-hash-to-pass-the-prt&quot; keyTerms={[
  { term: &quot;NT hash&quot;, definition: &quot;16-byte MD4 of the user&apos;s password as UTF-16 little-endian; the long-term Windows authentication secret since the early NT releases, unsalted by design.&quot; },
  { term: &quot;NTLM challenge-response&quot;, definition: &quot;Family of Windows authentication protocols (NTLMv1 and NTLMv2) in which the server sends a random challenge and the client returns a keyed cryptographic response computed under a key derived from the user&apos;s password; the password is never transmitted.&quot; },
  { term: &quot;Pass-the-Hash&quot;, definition: &quot;Authenticating with a stolen NT hash by feeding it directly to the protocol&apos;s response-construction function instead of typing a password; Paul Ashton, NTBugtraq, April 1997.&quot; },
  { term: &quot;LSASS&quot;, definition: &quot;Local Security Authority Subsystem Service; the user-mode Windows process that caches in-memory credential material (hashes, tickets, certificate handles, PRT material) for the duration of each logon session.&quot; },
  { term: &quot;Kerberos TGT&quot;, definition: &quot;Ticket Granting Ticket: the long-lived Kerberos credential issued by the KDC&apos;s Authentication Service, encrypted under the krbtgt long-term key, carrying a session key for subsequent service-ticket requests.&quot; },
  { term: &quot;Pass-the-Ticket&quot;, definition: &quot;Extracting a Kerberos TGT (and its session key) from one machine&apos;s LSASS-resident Kerberos cache and injecting it into another machine&apos;s cache.&quot; },
  { term: &quot;Overpass-the-Hash&quot;, definition: &quot;Presenting a stolen NT hash to the KDC as the user&apos;s long-term RC4-HMAC Kerberos key (per RFC 4757) to obtain a real TGT signed by the real krbtgt.&quot; },
  { term: &quot;Credential Guard&quot;, definition: &quot;Windows feature that relocates NT hashes, Kerberos TGT session keys, and &apos;credentials stored by applications as domain credentials&apos; from LSASS in VTL0 to the LSAISO trustlet in VTL1, isolated by the Windows hypervisor.&quot; },
  { term: &quot;LSAISO trustlet&quot;, definition: &quot;The isolated-user-mode LSA process (lsaiso.exe) that holds Credential Guard&apos;s protected credential material in VTL1; unreadable from any VTL0 process or driver.&quot; },
  { term: &quot;PKINIT&quot;, definition: &quot;Kerberos pre-authentication using a certificate&apos;s private key in place of a long-term symmetric key (RFC 4556); the SAN of the certificate maps to the principal whose TGT the KDC will issue.&quot; },
  { term: &quot;Pass-the-Certificate&quot;, definition: &quot;Authenticating to Active Directory with a stolen X.509 certificate&apos;s private key via PKINIT to the KDC or Schannel client-cert authentication to LDAPS.&quot; },
  { term: &quot;szOID_NTDS_CA_SECURITY_EXT&quot;, definition: &quot;X.509 extension introduced by KB5014754 (OID 1.3.6.1.4.1.311.25.2) that carries the requesting principal&apos;s SID at certificate issuance; the basis of KDC strong certificate mapping.&quot; },
  { term: &quot;Primary Refresh Token (PRT)&quot;, definition: &quot;Microsoft Entra-issued long-lived refresh token for SSO on Entra-joined or Hybrid-joined Windows devices; carries a session key (HMAC-SHA256) and binds to a device transport key; default 90-day lifetime with sliding renewal.&quot; },
  { term: &quot;CloudAP&quot;, definition: &quot;Cloud Authentication Provider; the Windows authentication package (cloudap.dll) loaded into LSASS that holds Microsoft Entra credential material including the PRT; not currently inside Credential Guard&apos;s isolation scope.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>active-directory</category><category>kerberos</category><category>credential-theft</category><category>credential-guard</category><category>entra-id</category><category>pass-the-hash</category><category>pass-the-prt</category><category>windows-security</category><author>noreply@paragmali.com (Parag Mali)</author></item><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>The Card That Wasn&apos;t a Card: How Windows Authentication Outgrew the Smart Card Metaphor</title><link>https://paragmali.com/blog/the-card-that-wasnt-a-card-how-windows-authentication-outgre/</link><guid isPermaLink="true">https://paragmali.com/blog/the-card-that-wasnt-a-card-how-windows-authentication-outgre/</guid><description>Smart cards, virtual smart cards, and Windows authentication 1996-2026: from PC/SC and PIV through the 2014 NTLM-secondary defect to WHfB and FIDO2.</description><pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate><content:encoded>
**The Windows smart card story is the story of a metaphor.** Roland Moreno&apos;s 1974 &quot;card with a secret&quot; became Windows 2000&apos;s `SCardSvr.exe`, then Windows 8&apos;s TPM Virtual Smart Card (a software card with the same PC/SC interface), then Windows Hello for Business (which threw the card edge away and talks to the TPM directly), then FIDO2 (which added the origin binding the card was never designed for). The cryptographic primitive -- a non-exportable asymmetric key under a local gesture -- survives every transition. The 2014 disclosure that smart-card-required accounts still mint a harvestable NTLM hash is closed not by any change to the card but by Microsoft&apos;s 2024-2026 NTLM removal plan. The card was always cryptographically sound; the protection terminated at the act of signing.
&lt;h2&gt;1. A Smart Card Login That Mints an NTLM Hash&lt;/h2&gt;
&lt;p&gt;Picture May 2014. A Department of Defense contractor pushes her Common Access Card into a Windows 7 workstation, types a six-digit PIN, and watches the lock screen melt into her desktop. The RSA-2048 private key that just signed her &lt;a href=&quot;https://paragmali.com/blog/kerberos-in-windows-the-other-half-of-ntlmless/&quot; rel=&quot;noopener&quot;&gt;Kerberos&lt;/a&gt; pre-authentication blob lives inside a tamper-resistant secure element she cannot extract from the card. The cryptography is excellent. Three hours later, an attacker on the same network owns her domain account without ever touching the card [@dirteam-aorato] [@kb-2871997].&lt;/p&gt;
&lt;p&gt;How is that even possible? Hold that question. The answer is the spine of this article.&lt;/p&gt;
&lt;p&gt;The contractor here is a composite figure, not a documented incident. The mechanism (CAC + Windows 7, RSA-2048 signing inside the card, an NT hash recoverable from LSASS three hours later) is the one Aorato disclosed in 2014 [@dirteam-aorato] and Microsoft documented in KB 2871997 [@kb-2871997]. The scenario is faithful to the published attack chain; the person and the office park are illustrative.&lt;/p&gt;
&lt;p&gt;The protocol that ran when she logged in is PKINIT, defined by &lt;a href=&quot;#&quot; rel=&quot;noopener&quot;&gt;RFC 4556&lt;/a&gt; [@rfc-4556] and profiled for Windows in &lt;code&gt;[MS-PKCA]&lt;/code&gt; [@ms-pkca]. PKINIT lets a Kerberos client present an X.509 certificate as pre-authentication for the Authentication Service Request (AS-REQ), with a digital signature proving possession of the matching private key. In a Windows smart card logon the signing happens inside the card. The Microsoft Smart Card Key Storage Provider hands the card a hash; the card returns a signed &lt;code&gt;AuthPack&lt;/code&gt; containing a &lt;code&gt;PKAuthenticator&lt;/code&gt; (timestamp, nonce, paChecksum) and Diffie-Hellman parameters; that signed &lt;code&gt;AuthPack&lt;/code&gt; rides in the &lt;code&gt;PA-PK-AS-REQ&lt;/code&gt; pre-authentication data of the AS-REQ [@rfc-4556] [@ms-pkca].&lt;/p&gt;
&lt;p&gt;So far, so good. The Key Distribution Center (KDC) verifies the signature, validates the certificate chain, mints a Ticket-Granting Ticket (TGT), and returns it. Our contractor sees her desktop.&lt;/p&gt;
&lt;p&gt;But the KDC has a second job she does not know about. Her account is flagged &quot;smart card required for interactive logon,&quot; so she has no password. Windows must still authenticate her to a legacy SMB1 server or any network application that speaks only NTLM. The clean answer would be &quot;it cannot.&quot; The answer Microsoft shipped in Windows 2000 is: the KDC silently maintains an NTLM-equivalent secondary credential for every smart-card-only user, rotating it at logon, so legacy services keep working [@kb-2871997] [@msrc-kb-2871997].&lt;/p&gt;
&lt;p&gt;That secondary credential is an NT hash. Once her session is live, an NT hash sits in the Local Security Authority Subsystem (LSASS) memory of every machine she touches. The smart card never sees it. The card cannot police it. It is sixteen bytes of MD4 output that the OS minted around the cryptographic operation the card refused to delegate.&lt;/p&gt;

A non-NTLM-derived NT hash that Windows maintains for accounts configured to log on with a smart card or other non-password credential, so that legacy NTLM-accepting services (SMB1, pre-Windows-2000 applications, some printers) continue to authenticate the user. The hash is computed from a random secret, not the card key, and is rotated by the KDC. From a pass-the-hash attacker&apos;s perspective, it is indistinguishable from a password-derived hash and equally replayable.
&lt;p&gt;Three hours later, an attacker who has phished a privileged helpdesk account runs &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; from a copy of &lt;code&gt;mimikatz&lt;/code&gt; [@mimikatz-gh] against the LSASS process on a server the contractor logged into earlier that day. The output looks like &lt;code&gt;NTLM : a1b2c3...&lt;/code&gt;. The attacker pipes that NT hash into a &lt;code&gt;pass-the-hash&lt;/code&gt; against any NTLM-accepting service in the forest. Because &lt;a href=&quot;#&quot; rel=&quot;noopener&quot;&gt;RFC 4757&lt;/a&gt; [@rfc-4757] makes the RC4-HMAC Kerberos long-term key identical to the NT hash, the attacker can also forge Kerberos pre-authentication for the smart-card-required account and request its TGT. The card sat in a reader the attacker never touched. None of that mattered.&lt;/p&gt;
&lt;p&gt;This is the inversion the article exists to explain. The card protected the key. The card did not, and could not, protect the identity. Microsoft documented the gap on May 13, 2014 as KB 2871997, &quot;Update to improve credentials protection and management&quot; [@kb-2871997]; the Microsoft Security Response Center followed with a blog overview of the threat model and the defence-in-depth response [@msrc-kb-2871997]. The disclosure came from Tal Be&apos;ery and his team at Aorato, a Tel Aviv security startup Microsoft would acquire six months later. The period-accurate operator analysis lives in Sander Berkouwer&apos;s July 15, 2014 writeup, cited here because the original Aorato post is offline [@dirteam-aorato].&lt;/p&gt;
&lt;p&gt;How did Windows arrive at an architecture where a tamper-resistant cryptographic token could leave the user&apos;s identity wide open? To answer that we go back to a 1974 patent in Paris.&lt;/p&gt;
&lt;h2&gt;2. How Cards Got a Chip&lt;/h2&gt;
&lt;p&gt;Roland Moreno was twenty-nine when he filed his first smart-card patent family in 1974. A self-taught Parisian, a former pinball-machine fixer and humorist who had washed out of the Sorbonne, he wired an off-the-shelf microchip to a ring of contacts on a small plastic substrate and walked the result over to INPI, the French patent office. The patent family -- known in the secondary literature as &lt;code&gt;carte a memoire&lt;/code&gt; -- did not invent the integrated circuit, the credit-card form factor, or even the idea of embedding silicon in plastic. What Moreno added was a property: the card holds a secret the cardholder cannot extract [@wp-moreno] [@wp-smart-card].&lt;/p&gt;
&lt;p&gt;That property is the entire story.&lt;/p&gt;
&lt;p&gt;Helmut Groettrup, a West German engineer, got there first. He filed German patents DE1574074 and DE1574075 in February 1967 for a tamper-proof identification switch based on a semiconductor device, and added a joint Austrian filing with Juergen Dethloff in September 1968 [@bmpos-history] [@wp-smart-card]. The standard French historiography credits Moreno with the secured-memory refinement rather than the form factor. The inventor question depends on which property you treat as load-bearing.&lt;/p&gt;
&lt;p&gt;Three other people belong in this section. In 1977 Michel Ugon, an engineer at Honeywell Bull&apos;s CP8 division in France, built the first microprocessor smart card -- a card with a CPU on it, not just memory. In 1978 Bull filed the SPOM patent that collapsed CPU and EEPROM onto one chip, the architectural change that made mass production tractable [@bmpos-history] [@cnam-pdf]. And from 1987 to 1995 the International Organization for Standardization froze the card edge into a vendor-neutral wire format with the four parts of ISO/IEC 7816 [@wp-smart-card]: physical characteristics, electrical and transmission protocols, and -- the part that would matter most for Windows -- the command set.&lt;/p&gt;

The international standard for contact smart cards, in four parts that interest software architects: Part 1 covers physical characteristics, Part 3 covers electrical interface and the T=0 and T=1 transmission protocols, and Part 4 covers the organisation, security, and command set for interchange. ISO/IEC 7816-4:2020 is the current edition of Part 4.

Application Protocol Data Unit. The request/response unit a host application exchanges with a smart card. The command APDU starts with a four-byte header `CLA INS P1 P2` (class, instruction, two parameter bytes), followed by an optional length byte `Lc` and `Lc` bytes of data, and an optional expected-response-length byte `Le`. The response APDU is `[data] SW1 SW2`, where the two status word bytes encode success or a card-side error.
&lt;p&gt;A worked APDU example makes this concrete. To select the PIV application on a smart card, a host sends &lt;code&gt;00 A4 04 00 0B A0 00 00 03 08 00 00 10 00 01 00&lt;/code&gt;. The first byte is &lt;code&gt;CLA = 00&lt;/code&gt; (interindustry class). The second is &lt;code&gt;INS = A4&lt;/code&gt; (SELECT). &lt;code&gt;P1 = 04&lt;/code&gt; indicates that the parameter is an application identifier. &lt;code&gt;P2 = 00&lt;/code&gt; selects the first occurrence. &lt;code&gt;Lc = 0B&lt;/code&gt; says eleven data bytes follow, and those eleven bytes are the full PIV AID per NIST SP 800-73-4 [@sp-800-73-4-upd1]: nine bytes for the registered application identifier (&lt;code&gt;A0 00 00 03 08 00 00 10 00&lt;/code&gt;) followed by the two-byte PIV application version identifier (the PIX, &lt;code&gt;01 00&lt;/code&gt;, per SP 800-73-4 Part 1 §2.2). The card replies with optional file control information and the status word &lt;code&gt;90 00&lt;/code&gt;, which means success. Every operation the Windows smart card stack performs decomposes, eventually, into a sequence of these short frames.&lt;/p&gt;

timeline
    title Card-as-authenticator timeline
    1967-1968 : Groettrup and Dethloff file IC-on-card patent
    1974 : Moreno files carte a memoire family
    1977-1978 : Ugon and Bull build CPU smart card and SPOM
    1987-1995 : ISO/IEC 7816 parts 1, 3, 4 published
    1996 : PC/SC Workgroup founded
    2000 : Windows 2000 ships SCardSvr.exe
    2007 : Microsoft Base Smart Card CSP and minidriver model
    2011 : Windows 7 SP1 inbox PIV/GIDS minidriver
    2012 : Windows 8 ships Virtual Smart Card
    2015 : Windows Hello announced
    2024 : NTLMv1 removed in Windows 11 24H2
&lt;p&gt;By 1996 the card edge was settled. Three thousand-odd APDU specifications and proprietary applets later, the only remaining question was: how does a personal computer talk to a card reader? Smart card readers lived in two operationally incompatible worlds, the bank-teller world and the workstation world, and the workstation world was held back by a vendor-driver swamp. So in 1996 a consortium called the PC/SC Workgroup formed. The contemporary record names Microsoft, IBM, Hewlett-Packard, Sun Microsystems, Siemens Nixdorf, and Bull as founders, with Schlumberger and other card vendors joining shortly after [@wp-pcsc] [@sc-architecture].&lt;/p&gt;
&lt;p&gt;The PC/SC specification series (&quot;Interoperability Specification for ICCs and Personal Computer Systems&quot;) names exactly the right abstractions: a Smart Card Resource Manager that brokers access to attached readers, an Interface Device Handler that abstracts reader hardware, and a Service Provider that exposes a uniform programming surface to applications [@sc-architecture]. A personal computer talks to a smart card by speaking PC/SC, in user-mode, through whatever service the OS provides.&lt;/p&gt;

Personal Computer/Smart Card. The 1996 industry consortium and its specification series that define how a smart card reader is exposed to a desktop operating system. PC/SC factors the stack into reader hardware (Interface Device), an Interface Device Handler driver, a Smart Card Resource Manager (a system service brokering access), and a Service Provider exposing a uniform API to applications.
&lt;p&gt;Microsoft answered the implementation question in February 2000 with &lt;code&gt;SCardSvr.exe&lt;/code&gt;, the Smart Cards for Windows service that shipped in Windows 2000 [@sc-architecture]. And immediately created a new problem: every card vendor still wanted to own the cryptographic provider.&lt;/p&gt;
&lt;h2&gt;3. From SCardSvr to Base CSP: Eleven Years to a Vendor-Neutral Stack&lt;/h2&gt;
&lt;p&gt;Windows 2000 shipped smart card logon as a vendor-neutral primitive. Within months, the operational reality bit. Every card vendor shipped a different CryptoAPI plug-in, every plug-in needed installing per machine, per card, sometimes per user.&lt;/p&gt;
&lt;p&gt;Walk down the stack. At the bottom is the reader, attached over USB or, in early-2000s deployments, an internal serial port. Above the reader is the Interface Device Handler driver supplied by the reader vendor. Above the driver is &lt;code&gt;SCardSvr&lt;/code&gt;, Microsoft&apos;s Smart Card Resource Manager service. &lt;code&gt;SCardSvr&lt;/code&gt; exposes a user-mode API called WinSCard: &lt;code&gt;SCardEstablishContext&lt;/code&gt;, &lt;code&gt;SCardConnect&lt;/code&gt;, &lt;code&gt;SCardTransmit&lt;/code&gt;, &lt;code&gt;SCardDisconnect&lt;/code&gt; [@winscard-api]. WinSCard is the C-level entry into PC/SC; an application that wants to send raw APDUs to a card uses WinSCard directly [@sc-architecture].&lt;/p&gt;

The Windows user-mode API surface for PC/SC. Canonical entry points include `SCardEstablishContext`, `SCardListReaders`, `SCardConnect`, `SCardTransmit`, and `SCardDisconnect`. An application sending raw APDUs to a smart card uses WinSCard; higher-level Windows components (Kerberos client, certificate enrolment, the lock-screen credential provider) reach the card indirectly through the Cryptographic Service Provider or Key Storage Provider layers.
&lt;p&gt;Cryptographic clients do not want to write APDU sequences. They want to call &lt;code&gt;CryptSignHash&lt;/code&gt; or &lt;code&gt;NCryptSignHash&lt;/code&gt; and have a signature appear. Translating those API calls into the card&apos;s APDU command set is the job of a Cryptographic Service Provider in the CryptoAPI 1.0 world and a Key Storage Provider in the &lt;a href=&quot;https://paragmali.com/blog/cng-architecture-bcrypt-ncrypt-ksps/&quot; rel=&quot;noopener&quot;&gt;CNG (Cryptography Next Generation)&lt;/a&gt; world. From 1996 to 2007, almost every card vendor wrote its own CSP. The Schlumberger CSP. The Gemalto CSP. The Axalto CSP. The ActivIdentity CSP. Each was an in-process DLL that talked to the card through WinSCard, applied vendor-specific quirks, and exposed a CSP interface to Windows.&lt;/p&gt;

A plug-in for CryptoAPI 1.0 that provides cryptographic services (key generation, signing, hashing, key storage) to applications. CryptoAPI loads a CSP in-process. For smart cards, the CSP translates CryptoAPI calls into card-specific APDUs through WinSCard. Microsoft Base Smart Card CSP, shipped in 2007, replaced the per-vendor CSP with a single CSP that delegated card-specific behaviour to a much smaller minidriver.

The CNG-era plug-in that provides key storage and asymmetric cryptographic operations. CNG separates algorithm providers (BCrypt: hashing, symmetric, signature primitives) from key storage providers (NCrypt: key lifecycle, key-protected operations). The Microsoft Smart Card Key Storage Provider is the CNG-side path for smart card and Virtual Smart Card keys; the Microsoft Platform Crypto Provider is its sibling that talks to the TPM directly.
&lt;p&gt;The architecture had two problems by 2003. First, an N x M combinatorial. Every new card vendor multiplied integration cost for every cryptographic application, and vice versa. Large enterprises ran two or three CSPs per workstation; subtle bugs in signature padding or PIN caching only surfaced when an application built for vendor A&apos;s CSP met a card configured for vendor B&apos;s. Second, a security problem: each CSP ran in-process with every CryptoAPI client, so a buggy or compromised third-party CSP could reach critical OS components.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s answer was the Smart Card Minidriver Specification, finalised around the Vista launch in 2006-2007. Microsoft would ship one CSP -- the Microsoft Base Smart Card CSP -- containing the cryptographic state machine common to all PIV-style cards. Per-card behaviour would live in a much smaller DLL called a minidriver, loaded by the Base CSP when it recognised the card. The specification, &lt;code&gt;dn631754&lt;/code&gt;, currently maintained at v7.07, says exactly this: &quot;The Microsoft Smart Card Base CSP and KSP is a refinement of the architecture that separates commonly needed CAPI-based CSP and CNG-based KSP functionality, respectively, from the implementation details that must change for every card vendor&quot; [@sc-minidrivers] [@sc-minidriver-spec].&lt;/p&gt;
&lt;p&gt;The CNG-side sibling, the Microsoft Smart Card Key Storage Provider, plugs into the same minidriver layer. CNG is the post-Vista cryptographic platform: BCrypt for algorithm primitives, NCrypt for key lifecycle and storage [@cng-storage]. The Smart Card KSP supports DH 512-4096, ECDH P256/P384/P521, ECDSA P256/P384/P521, and RSA 512-16384 [@cng-ksp-list]. Both the legacy Base CSP and the modern KSP route through the same minidriver, so a card vendor writes one DLL and gets compatibility with both CryptoAPI 1.0 and CNG applications.&lt;/p&gt;

flowchart TD
    A[Reader hardware] --&amp;gt; B[IFD driver]
    B --&amp;gt; C[SCardSvr Smart Card Resource Manager]
    C --&amp;gt; D[WinSCard user-mode API]
    D --&amp;gt; E[Microsoft Base Smart Card CSP and Smart Card KSP]
    E --&amp;gt; F[Card minidriver DLL]
    F --&amp;gt; G[ISO 7816-4 APDU on the card]
    H[CryptoAPI 1.0 client] --&amp;gt; E
    I[CNG NCrypt client] --&amp;gt; E
&lt;p&gt;CryptoAPI&apos;s &lt;code&gt;CryptSignHash&lt;/code&gt; walks the Base CSP; CNG&apos;s &lt;code&gt;NCryptSignHash&lt;/code&gt; walks the Smart Card KSP; both end up issuing the same APDU sequence through the same minidriver to the same card.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;CryptoAPI Base CSP&lt;/th&gt;
&lt;th&gt;CNG Smart Card KSP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Era&lt;/td&gt;
&lt;td&gt;CryptoAPI 1.0, pre-Vista to present (legacy support)&lt;/td&gt;
&lt;td&gt;CNG, Vista onward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entry point&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CryptAcquireContext&lt;/code&gt;, &lt;code&gt;CryptSignHash&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NCryptOpenStorageProvider&lt;/code&gt;, &lt;code&gt;NCryptSignHash&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Implementation DLL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;basecsp.dll&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;microsoft smart card key storage provider&lt;/code&gt; registered through &lt;code&gt;ncrypt.dll&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-card extension&lt;/td&gt;
&lt;td&gt;Smart card minidriver&lt;/td&gt;
&lt;td&gt;Same smart card minidriver&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Algorithm range&lt;/td&gt;
&lt;td&gt;RSA, basic ECC&lt;/td&gt;
&lt;td&gt;RSA, full Suite B ECC, large key ranges&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;By 2008 the architecture was elegant. But every PIV card still needed a minidriver acquired from somewhere -- a CD, a vendor ftp site, an enterprise distribution share. And in 2004 the US federal government was about to make the smart card mandatory for several million people who could not wait for a vendor disk.&lt;/p&gt;
&lt;h2&gt;4. PIV, GIDS, CAC, and the Inbox Driver That Removed the Last Install Step&lt;/h2&gt;
&lt;p&gt;On August 27, 2004, President George W. Bush signed Homeland Security Presidential Directive 12, a one-page policy with one operational sentence: there shall be &quot;a mandatory, government-wide standard for secure and reliable forms of identification issued by the federal government to its employees and contractors&quot; [@hspd-12]. HSPD-12 did not specify how. It pointed at the National Institute of Standards and Technology and said &quot;make it so.&quot;&lt;/p&gt;
&lt;p&gt;NIST&apos;s response was FIPS 201, the Personal Identity Verification standard, first published in February 2005. The current revision, FIPS 201-3, was published in January 2022, superseding FIPS 201-2 from 2013 [@fips-201-3] [@fips-201-3-pdf]. Where FIPS 201 specifies the credential -- what a PIV card is, biometrically, biographically, visually -- the companion NIST SP 800-73 specifies the card-edge interface: file system, data objects, APDU command set [@sp-800-73-4-upd1].&lt;/p&gt;

The US federal smart card identity credential defined by FIPS 201 and its companion NIST Special Publications. FIPS 201 defines what a PIV credential is; NIST SP 800-73 defines the card-edge interface (file structure, data objects, APDU command set) so any host can talk to any PIV-compliant card; SP 800-78 covers cryptographic algorithms; SP 800-76 covers biometrics; SP 800-79 covers card issuer accreditation.
&lt;p&gt;The numbers are striking. NIST reports &quot;close to five million PIV Cards today provide multifactor authentication to federal IT resources and facilities&quot; [@nist-piv-home]. The largest single cohort is the DoD Common Access Card (CAC), which by 2002 numbers had reached more than one million card readers across more than 1,000 issuance sites in more than 25 countries [@wp-cac].&lt;/p&gt;
&lt;p&gt;Microsoft, watching from Redmond, faced two choices: negotiate a separate minidriver for the GSC-IS card-edge applet some federal agencies were using, or ship an inbox class minidriver that auto-discovered PIV-compliant cards out of the box -- and for completeness, supported a Microsoft-defined alternative called the Generic Identity Device Specification.&lt;/p&gt;
&lt;p&gt;GIDS, Microsoft&apos;s complementary card-edge profile, shipped v1.0 in April 2010 and v2.0 in October 2012 [@gids-spec]. It was a profile for card vendors and TPM integrators who wanted a Microsoft-blessed alternative to PIV, and it would become important to Windows 8&apos;s Virtual Smart Card design.&lt;/p&gt;

The Generic Identity Device Specification, a Microsoft-published smart card profile for identity credentials. GIDS v1.0 published April 2010; v2.0 published October 2012. GIDS coexists with PIV at the inbox minidriver layer: Windows&apos; inbox `msclmd.dll` recognises both, allowing zero-install integration for any card that implements either applet.
&lt;p&gt;The inbox driver shipped in Windows 7 SP1 in February 2011. Microsoft Learn is direct: &quot;Windows provides an inbox generic class minidriver that supports Personal Identity Verification (PIV)-compliant smart cards and cards that implement the Generic Identity Device Specification (GIDS) card edge&quot; [@inbox-minidriver]. The auto-discovery sequence is sequential: &lt;code&gt;msclmd.dll&lt;/code&gt; issues a &lt;code&gt;SELECT&lt;/code&gt; for the PIV AID; if the card returns &lt;code&gt;90 00&lt;/code&gt;, Windows treats it as PIV. If the PIV select fails, the driver tries the GIDS AID; if that succeeds, Windows treats the card as GIDS. If both selects return a &quot;neither-AID-exists&quot; status, Windows still proceeds as if the card were GIDS, and the inbox driver continues to handle it. Only an unknown SELECT error makes the inbox driver decline and Windows fall back to a vendor minidriver [@inbox-minidriver]. The effect: any PIV-compliant card (CAC, Yubico YubiKey 5 [@yubico-piv], any FIPS 201-compliant federal credential) worked on a stock Windows 7 SP1 install with zero additional software.&lt;/p&gt;

Before Windows 7 SP1, deploying a CAC to a workstation required an out-of-band CSP install: a vendor disk, an enterprise distribution share, or a manual download. Some classified networks could not reach the vendor distribution channels at all. The inbox `msclmd.dll` removed that friction. A workstation that had never been online could authenticate a CAC user on first boot, provided it was joined to a domain whose KDC chain it could reach for PKINIT validation. Many DoD operational deployments lived inside the airgap, and many of them only became deployable at scale once the inbox minidriver had landed.
&lt;p&gt;With the card-edge problem solved and the install problem closed, what remained was the protocol Windows logon would use. That protocol is PKINIT.&lt;/p&gt;

Public Key Cryptography for Initial Authentication in Kerberos. Specified by [RFC 4556](#) [@rfc-4556] and profiled for Windows by `[MS-PKCA]` [@ms-pkca]. PKINIT lets a Kerberos client present an X.509 certificate, and prove possession of the private key, as pre-authentication for the Authentication Service Request (AS-REQ), instead of a password-derived shared secret. The Windows AS Exchange remains otherwise unchanged: the client receives a TGT encrypted with a session key established under the public-key exchange.

The PKINIT structure that carries the client&apos;s proof of possession. It contains a `PKAuthenticator` (cusec, ctime, nonce, paChecksum) and Diffie-Hellman parameters. The client signs the `AuthPack` with the private key corresponding to its certificate, then embeds the signed structure in the `PA-PK-AS-REQ` pre-authentication data of the Kerberos AS-REQ. The granularity matters: the signature covers the `AuthPack`, not the AS-REQ as a whole.
&lt;p&gt;In a Windows smart card logon the path from PIN to TGT runs through eight named components. Walk it once and the rest of the article becomes legible.&lt;/p&gt;

sequenceDiagram
    participant U as User at lock screen
    participant CP as Credential Provider
    participant LSA as LSASS Kerberos client
    participant KSP as Microsoft Smart Card KSP
    participant MD as Minidriver
    participant CARD as Smart card
    participant KDC as Domain Controller KDC&lt;pre&gt;&lt;code&gt;U-&amp;gt;&amp;gt;CP: Insert card, type PIN
CP-&amp;gt;&amp;gt;LSA: Logon attempt with PIV credential
LSA-&amp;gt;&amp;gt;KSP: NCryptSignHash on AuthPack hash
KSP-&amp;gt;&amp;gt;MD: Card-specific sign request
MD-&amp;gt;&amp;gt;CARD: VERIFY PIN, then SIGN APDU
CARD--&amp;gt;&amp;gt;MD: Signed AuthPack bytes, SW=9000
MD--&amp;gt;&amp;gt;KSP: Signed AuthPack
KSP--&amp;gt;&amp;gt;LSA: Signed AuthPack
LSA-&amp;gt;&amp;gt;KDC: AS-REQ with PA-PK-AS-REQ pre-auth
KDC-&amp;gt;&amp;gt;KDC: Verify signature, cert chain, freshness
KDC--&amp;gt;&amp;gt;LSA: AS-REP with TGT
LSA--&amp;gt;&amp;gt;CP: Logon success, session keys cached
CP--&amp;gt;&amp;gt;U: Desktop
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice what the card sees and what it does not. It sees a hash to sign and a PIN to verify. It does not see &quot;I am authenticating to KDC &lt;code&gt;DC01.contoso.local&lt;/code&gt; for user &lt;code&gt;jdoe&lt;/code&gt;.&quot; A PIV card is a signing oracle. The relying party identity, the freshness, the replay window, the binding of signature to context: all of that lives in the protocol above the card, not in the card itself. We come back to this in section 8.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The cryptographic primitive at the centre of the smart card metaphor -- a non-exportable asymmetric key, bound to a tamper-resistant element, gated by a local gesture -- is the longest-lived object in this lineage. The interface around the primitive (PC/SC, CryptoAPI, CNG, NCrypt-direct, WebAuthn) is what changes every generation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;By 2013 the cryptographic story was excellent. PKINIT was a clean Kerberos AS exchange. The card protected the key. The KDC issued a TGT. Then, in a few months in 2014, one researcher in Tel Aviv showed that the protection ended at the very moment of signing.&lt;/p&gt;
&lt;h2&gt;5. KB2871997 and the NTLM Secondary Credential&lt;/h2&gt;
&lt;p&gt;Tal Be&apos;ery, then Vice President of Research at Aorato, sat down in early 2014 with a question that should have had a boring answer. If an Active Directory account is flagged &quot;smart card required for interactive logon,&quot; and the user has no password, is the account immune to pass-the-hash?&lt;/p&gt;
&lt;p&gt;The answer is no. Aorato&apos;s original disclosure post is offline; Microsoft acquired Aorato in November 2014 and the research became the foundation of what is now Microsoft Defender for Identity. The period-accurate operator analysis that survives in public is Sander Berkouwer&apos;s July 15, 2014 dirteam.com writeup, cited here in lieu of the dead original [@dirteam-aorato].&lt;/p&gt;
&lt;p&gt;The attack is built from three off-the-shelf parts. The first is the NTLM secondary credential we met in section 1: every smart-card-only account in Active Directory has a usable NT hash on the KDC, maintained for legacy compatibility. The second is the harvesting tool. Benjamin Delpy&apos;s &lt;code&gt;mimikatz&lt;/code&gt; had reached its 2.0-alpha milestone in April 2014; the README documents &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; extracting NT hashes from LSASS, plus &lt;code&gt;sekurlsa::pth&lt;/code&gt; and golden-ticket forgery for replay [@mimikatz-gh]. The third is the cryptographic identity that makes hashes Kerberos-relevant. &lt;a href=&quot;#&quot; rel=&quot;noopener&quot;&gt;RFC 4757&lt;/a&gt; section 2 establishes that the RC4-HMAC long-term key in Kerberos is the NT hash itself, &quot;for compatibility reasons&quot; [@rfc-4757] [@dirteam-aorato].&lt;/p&gt;
&lt;p&gt;Compose those three parts. An attacker with administrative footing on any machine the user has touched runs &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; against LSASS and gets the NT hash. By RFC 4757 the hash is a usable Kerberos RC4-HMAC pre-authentication key for the user; pre-auth is a function of the long-term key, so the attacker can request a TGT. Or they replay the hash directly via SMB. The card sits, intact, in the user&apos;s reader. Nothing about it has changed.&lt;/p&gt;

The smart card&apos;s tamper-resistance was real. But the cryptographic guarantee terminated at the act of signing -- not at the authentication outcome.
&lt;p&gt;This is the article&apos;s central inversion. The card was right. The system was wrong. The card protected the &lt;em&gt;key&lt;/em&gt;; the OS minted &lt;em&gt;credentials around&lt;/em&gt; that key the card could not police; the protection terminated at the signing operation; the identity did not.&lt;/p&gt;

Given an interactive shell as Local System or a debug-privileged user, the harvest is two commands:&lt;pre&gt;&lt;code&gt;privilege::debug
sekurlsa::logonpasswords
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; walks LSASS sessions and prints any cached NT hashes, including the rotated secondary credential for smart-card-required users. The pass-the-hash replay is one more:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sekurlsa::pth /user:JaneDoe /domain:CONTOSO /ntlm:a1b2c3...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This launches a process whose Kerberos ticket cache accepts the supplied NT hash as the RC4-HMAC pre-auth key for the named principal. Any tool spawned from that process can request service tickets for the user. The smart card need not be in any reader on any machine on the network. KB 2871997 and the Pass-the-Hash mitigations (KB 2984972, 2984976, 2984981) addressed this defence-in-depth; NTLM removal addresses it structurally.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s response shipped on May 13, 2014 as Security Advisory KB 2871997, &quot;Update to improve credentials protection and management.&quot; It is mostly a registry change and a recommended Group Policy: set &lt;code&gt;HKLM\SYSTEM\CurrentControlSet\Control\Lsa\TokenLeakDetectDelaySecs&lt;/code&gt; to 30 seconds [@kb-2871997]. The June 2014 MSRC blog added more context, especially around a new security group called &lt;a href=&quot;https://paragmali.com/blog/who-is-allowed-to-log-in-where-the-kdc-side-answer-to-creden/&quot; rel=&quot;noopener&quot;&gt;Protected Users&lt;/a&gt; [@msrc-kb-2871997].&lt;/p&gt;
&lt;p&gt;Protected Users, added to Windows Server 2012 R2 domains and Windows 8.1 clients, blocks NTLM, blocks DES and RC4 in Kerberos pre-authentication, blocks both forms of delegation, and prevents offline sign-in caching [@protected-users]. Add a privileged account to Protected Users and you force it off the RC4-HMAC code path. An attacker who steals the NT hash no longer has a usable Kerberos pre-auth key, even though the hash itself is still recoverable.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s later response was &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;, which isolates credential material in a Virtualization-Based Security (VBS) container called LSAISO, separated from LSASS by a Hyper-V trust boundary. On Windows 11 22H2 and Server 2025, Credential Guard is enabled by default on domain-joined, non-DC systems that meet hardware requirements, protecting NTLM hashes, Kerberos TGTs, and stored domain credentials [@credential-guard].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The KB 2871997 family (TokenLeakDetectDelaySecs, Protected Users, LSA Protection / RunAsPPL, Credential Guard later) is defence-in-depth. It makes hash theft harder, the harvested hash less universally useful, and lateral movement more visible. None of those measures removes the secondary NT hash itself. The structural fix is to &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;remove NTLM&lt;/a&gt;. That work began in earnest with the 2023 &quot;evolution of Windows authentication&quot; announcement and reached its first hard milestone with the NTLMv1 removal in Windows 11 24H2 and Windows Server 2025 [@evolution-windows-auth] [@ntlmv1-removal].&lt;/p&gt;
&lt;/blockquote&gt;

Two sentences look identical but mean very different things: &quot;the card protected the key&quot; and &quot;the system protected the user.&quot; The first is a statement about a piece of hardware and the cryptographic discipline of its operation; it was true in 1996, true in 2014, true today. The second is a statement about the authentication subsystem that uses the card. In 2014 it was false, and the falsehood had been present for fourteen years, hidden under the assumption that strong cryptography at the card edge guaranteed a corresponding strength of identity assertion. The 2014 disclosure was a forcing function for distinguishing the two. Every subsequent design (VSC, WHfB, FIDO2) can be evaluated by where it draws that line.
&lt;p&gt;If the card alone could not deliver the protection, perhaps the right move was to throw away the &lt;em&gt;physical&lt;/em&gt; card entirely. Microsoft had shipped exactly that experiment eighteen months earlier.&lt;/p&gt;
&lt;h2&gt;6. Virtual Smart Cards in Windows 8&lt;/h2&gt;
&lt;p&gt;On October 26, 2012, Microsoft shipped Windows 8. Buried in the new features, alongside the Start screen redesign and the Hyper-V client, was a command-line tool named &lt;code&gt;tpmvscmgr.exe&lt;/code&gt; that created a smart card without any plastic. The tool is still there. Open an elevated prompt on a current Windows installation and type &lt;code&gt;tpmvscmgr create /name vsc1 /AdminKey DEFAULT /PIN PROMPT&lt;/code&gt;, and the system manufactures a new entry under &lt;code&gt;ROOT\SMARTCARDREADER\&lt;/code&gt; that any PC/SC client sees as a freshly inserted card [@tpmvscmgr].&lt;/p&gt;
&lt;p&gt;The pitch is mechanical. Every Windows 8+ device with a &lt;a href=&quot;https://paragmali.com/blog/the-tpm-in-windows-one-primitive-twenty-five-years-and-the-c/&quot; rel=&quot;noopener&quot;&gt;Trusted Platform Module&lt;/a&gt; already has the cryptographic substrate of a smart card on the motherboard: a tamper-resistant chip, a non-exportable key store, dictionary-attack resistance, an isolated execution environment for crypto. Why not implement the smart card abstraction in software, with the TPM as the backing chip [@vsc-overview] [@vsc-understanding]?&lt;/p&gt;
&lt;p&gt;The Microsoft Learn &quot;Virtual Smart Card Overview&quot; makes the framing crisp. The three core properties of a smart card -- non-exportability, isolated cryptography, anti-hammering -- map directly onto TPM capabilities. Non-exportability becomes TPM key wrapping. Isolated cryptography becomes signing inside the TPM. Anti-hammering becomes the TPM&apos;s dictionary-attack counter [@vsc-overview] [@vsc-understanding].&lt;/p&gt;

A TPM-backed software smart card introduced in Windows 8 (October 2012). A VSC exposes the same PC/SC card edge as a physical card -- the same WinSCard API, the same Base CSP, the same Microsoft Smart Card KSP, the same minidriver model. The chip backing the card is the TPM, soldered to the motherboard, rather than a removable IC on a plastic substrate. From the perspective of any application using the WinSCard API, a VSC is indistinguishable from a permanently-inserted physical smart card.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Windows 8 shipped Virtual Smart Cards in October 2012. The Trusted Computing Group did not ratify TPM 2.0 until 2014. VSCs are therefore a &lt;em&gt;TPM-binding policy&lt;/em&gt; technology, not a TPM-2.0-bound technology; Microsoft Learn lists TPM 1.2 as the documented minimum. TPM 2.0 works and is the practical choice on modern Windows 11 installations, but the architecture predates it [@vsc-overview] [@vsc-understanding].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The beauty of the design is that nothing above the chip changed. Applications still call &lt;code&gt;CryptSignHash&lt;/code&gt; or &lt;code&gt;NCryptSignHash&lt;/code&gt;. The Base CSP and Smart Card KSP still route through a minidriver. The minidriver still sends APDUs through WinSCard to a reader. The only differences: the reader is a software pseudo-device named &lt;code&gt;Microsoft Virtual Smart Card&lt;/code&gt;, and the card behind it is the TPM dressed up as an ISO 7816-4 applet.&lt;/p&gt;

flowchart LR
    subgraph Physical [Physical smart card]
        A1[Application] --&amp;gt; B1[CSP/KSP]
        B1 --&amp;gt; C1[Minidriver]
        C1 --&amp;gt; D1[WinSCard]
        D1 --&amp;gt; E1[USB reader]
        E1 --&amp;gt; F1[Plastic card IC]
    end
    subgraph Virtual [Virtual smart card]
        A2[Application] --&amp;gt; B2[CSP/KSP]
        B2 --&amp;gt; C2[Minidriver]
        C2 --&amp;gt; D2[WinSCard]
        D2 --&amp;gt; E2[Virtual reader]
        E2 --&amp;gt; F2[TPM on motherboard]
    end
&lt;p&gt;The cryptographic substrate underneath the abstraction is the TPM, and the binding policy is per-device. The Microsoft Learn &quot;Understanding and Evaluating Virtual Smart Cards&quot; article is precise: &quot;Non-exportability: Because all private information on the virtual smart card is encrypted by using the TPM on the host computer, it can&apos;t be used on a different computer with a different TPM&quot; [@vsc-understanding]. The property that makes a VSC tamper-resistant also makes it un-migratable. A TPM clear destroys the keys irrecoverably. We return to that in section 8.&lt;/p&gt;
&lt;p&gt;The canonical primary source for the architecture is the &quot;Understanding and Evaluating Virtual Smart Cards&quot; whitepaper on the Microsoft Download Center. The download page reports &lt;code&gt;Version: July 2014, Date Published: 7/15/2024&lt;/code&gt; [@vsc-whitepaper]. The 2014 revision is canonical.&lt;/p&gt;

The card was a metaphor. Microsoft kept the byte-for-byte PC/SC interface and put the TPM behind it.
&lt;p&gt;A worked provisioning example brings the design to ground. The &lt;code&gt;tpmvscmgr create&lt;/code&gt; command takes four arguments that matter for security policy: the administrative key (&lt;code&gt;/AdminKey {DEFAULT | PROMPT | RANDOM}&lt;/code&gt;), the PIN policy (&lt;code&gt;/PIN PROMPT&lt;/code&gt; or &lt;code&gt;/PIN DEFAULT&lt;/code&gt;), the attestation mode (&lt;code&gt;/attestation {AIK_AND_CERT | AIK_ONLY}&lt;/code&gt;), and the card&apos;s reader instance, surfaced under &lt;code&gt;ROOT\SMARTCARDREADER\000n&lt;/code&gt; in Device Manager [@tpmvscmgr].&lt;/p&gt;
&lt;p&gt;{`
function provisionVSC(opts) {
  const adminKeyMap = {
    DEFAULT: &apos;0102030405060708&apos; + &apos;0102030405060708&apos; + &apos;0102030405060708&apos;,
    PROMPT: &apos;[user-supplied 48 hex chars]&apos;,
    RANDOM: &apos;[random 24-byte key the admin must record]&apos;,
  };
  const attestationNote = {
    AIK_ONLY: &apos;Identity-binding only; no platform certificate chain stored on the card.&apos;,
    AIK_AND_CERT: &apos;Full AIK-and-EK-cert chain stored; supports federated re-enrolment.&apos;,
    NONE: &apos;No attestation; the card is identity-only.&apos;,
  };
  return {
    cardName: opts.name,
    adminKey: adminKeyMap[opts.adminKey] || &apos;invalid&apos;,
    pin: opts.pin === &apos;PROMPT&apos; ? &apos;[user-typed PIN, min 8 chars, alphanumeric+special allowed]&apos; : &apos;12345678&apos;,
    attestation: attestationNote[opts.attestation || &apos;NONE&apos;],
    advice: opts.adminKey === &apos;DEFAULT&apos;
      ? &apos;WARN: default admin key is documented; treat as factory-default.&apos;
      : &apos;OK: admin key not factory-default.&apos;,
  };
}&lt;/p&gt;
&lt;p&gt;console.log(provisionVSC({
  name: &apos;vsc-jdoe&apos;,
  adminKey: &apos;RANDOM&apos;,
  pin: &apos;PROMPT&apos;,
  attestation: &apos;AIK_AND_CERT&apos;,
}));
`}&lt;/p&gt;
&lt;p&gt;The default administrative key &lt;code&gt;010203040506070801020304050607080102030405060708&lt;/code&gt; is documented in the public &lt;code&gt;tpmvscmgr&lt;/code&gt; page [@tpmvscmgr]. Any VSC provisioned with &lt;code&gt;/AdminKey DEFAULT&lt;/code&gt; should be treated as factory-default; in production, supply (&lt;code&gt;PROMPT&lt;/code&gt;) or randomise (&lt;code&gt;RANDOM&lt;/code&gt;) the admin key and store it separately.&lt;/p&gt;
&lt;p&gt;The provisioning chain has four hard-to-script steps: run &lt;code&gt;tpmvscmgr create&lt;/code&gt; as administrator; request and install an authentication certificate from a PKI the domain trusts (typically Microsoft Certificate Services with an enterprise CA and a smart card auto-enrolment template); set the user PIN; log the user out and back in. Each step is a place an enterprise rollout can stall.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Microsoft kept the PC/SC card edge byte-for-byte and put the TPM behind it. The Virtual Smart Card was, technically, exactly that: a software smart card whose chip happened to be soldered to the board. The cryptographic primitive at the centre did not change; only the form factor of the chip carrying it did.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;VSCs solved the physical-distribution problem. They did not solve the user-experience problem -- and they introduced a new one no Windows feature had ever produced quite this way: a credential a hardware reset could permanently destroy.&lt;/p&gt;
&lt;h2&gt;7. WHfB, FIDO2, and the Card Edge That Got Discarded&lt;/h2&gt;
&lt;p&gt;On March 17, 2015, Joe Belfiore announced &lt;a href=&quot;https://paragmali.com/blog/your-face-is-not-your-password-inside-windows-hellos-hardwar/&quot; rel=&quot;noopener&quot;&gt;Windows Hello&lt;/a&gt; on the Windows Experience Blog: &quot;I&apos;d like to introduce you to Windows Hello -- biometric authentication which can provide instant access to your Windows 10 devices&quot; [@windows-hello-blog]. The consumer pitch was face and fingerprint. The mechanism underneath, in the enterprise variant called Windows Hello for Business (WHfB), was the same TPM-bound asymmetric key the Virtual Smart Card had used -- except there was no virtual reader, no virtual minidriver, and no virtual APDU.&lt;/p&gt;
&lt;p&gt;WHfB talks to the TPM directly through the Microsoft Platform Crypto Provider, a CNG Key Storage Provider that calls into the TPM rather than into a smart card minidriver [@whfb-overview] [@whfb-how-it-works]. The PC/SC card edge had been removed from the path entirely. The cryptographic primitive (non-exportable TPM-bound asymmetric key, gated by a local gesture, used to sign an authentication request) survived; the interface around the primitive simplified.&lt;/p&gt;
&lt;p&gt;Microsoft Learn describes WHfB in five phases: device registration, provisioning, key synchronisation, certificate enrolment (cert-trust only), authentication. The public key is registered with the identity provider and mapped to the user account; the private key never leaves the device [@whfb-how-it-works]. WHfB ships in three deployment models -- cloud-only, hybrid, on-premises -- and two trust types: key-trust and cert-trust [@whfb-deploy].&lt;/p&gt;
&lt;p&gt;Key-trust is cloud-first. The TPM-bound public key is registered with Microsoft Entra ID; authentication is a public-key proof of possession to Entra, which mints whatever downstream artifacts a federated service needs (PRT, refresh token, optional Kerberos TGT via the cloud Kerberos service). No X.509 certificate sits in the user&apos;s path. Cert-trust adds an X.509 wrapper for downstream services that require one: an enterprise PKI issues a smart-card-logon-style certificate bound to the TPM key, and the WHfB authentication produces a Kerberos PKINIT exchange against an on-premises DC, just as a physical smart card would. The certificate is the adapter to brownfield infrastructure that still expects a smart-card-shaped credential [@whfb-deploy].&lt;/p&gt;
&lt;p&gt;So far the lineage has been Windows-specific. &lt;a href=&quot;https://paragmali.com/blog/webauthn-and-passkeys-on-windows-from-ctap-to-the-credential/&quot; rel=&quot;noopener&quot;&gt;FIDO2&lt;/a&gt; is not. WebAuthn 2 is a W3C Recommendation; CTAP 2.1 is a FIDO Alliance specification [@webauthn-2] [@ctap-2-1]. Together they specify a cross-vendor protocol for public-key authentication to web relying parties, with one load-bearing property the smart card lineage never had: origin binding.&lt;/p&gt;

The property that a WebAuthn credential is scoped to a specific relying party identifier (the RP ID, typically a domain name) and the authenticator will refuse to sign an assertion for any other RP ID. The W3C WebAuthn 2 specification states: &quot;the public key credential can only be accessed by origins belonging to that Relying Party. This scoping is enforced jointly by conforming User Agents and authenticators&quot; [@webauthn-2]. A PIV smart card has no equivalent property; it will sign whatever the host hands it.
&lt;p&gt;Origin binding is the structural fix to a class of relay attacks. A PIV smart card cannot tell whether it is signing a Kerberos AuthPack for the legitimate KDC or a maliciously crafted blob for an attacker-controlled relay; the card has no notion of &quot;what is this signature for.&quot; A WebAuthn authenticator does. It hashes the RP ID into the signed assertion, the relying party verifies the RP ID matches its own origin, and a phishing site cannot trick the authenticator into producing a signature it will accept.&lt;/p&gt;
&lt;p&gt;Microsoft Entra ID supports FIDO2 in two flavours. &lt;em&gt;Device-bound passkeys&lt;/em&gt; live on a FIDO2 security key (a YubiKey 5 [@yubico-piv]) or in Microsoft Authenticator and cannot be extracted. &lt;em&gt;Synced passkeys&lt;/em&gt; are credentials a platform synchronises across the user&apos;s devices through a cloud passkey provider [@entra-passkeys-howto] [@entra-passwordless]. The trade-off is sharp: device-bound passkeys support attestation (the relying party can verify authenticator hardware at registration); synced passkeys do not.&lt;/p&gt;
&lt;p&gt;For workforce identity, Microsoft&apos;s passwordless strategy describes a four-step journey: deploy a password-replacement option, reduce user-visible password surface, transition to passwordless, eliminate passwords [@passwordless-strategy]. WHfB and FIDO2 are the two recommended replacements.&lt;/p&gt;
&lt;p&gt;What about smart cards? The Microsoft Learn Virtual Smart Card Overview now opens with a Warning box that reads, in full: &quot;Windows Hello for Business and FIDO2 security keys are modern, two-factor authentication methods for Windows. Customers using virtual smart cards are encouraged to move to Windows Hello for Business or FIDO2. For new Windows installations, we recommend Windows Hello for Business or FIDO2 security keys&quot; [@vsc-overview]. The deprecation signal could not be more explicit. Physical PIV and CAC cards are not deprecated -- the federal government is not switching off PIV -- but the structural recommendation for greenfield is now WHfB or FIDO2.&lt;/p&gt;
&lt;p&gt;Why did Virtual Smart Cards not survive into the WHfB era? Three reasons.&lt;/p&gt;
&lt;p&gt;The first is provisioning UX. A VSC requires four steps (&lt;code&gt;tpmvscmgr create&lt;/code&gt;, certificate enrolment, PIN set, logon round-trip) where WHfB requires one (a setup wizard the user runs at first sign-in). Each VSC step can fail in idiosyncratic ways: the enterprise CA template not configured for VSCs, the user&apos;s certificate request rejected, the PIN policy mismatched between the GPO and the card. Even when every step succeeds, the user sees a &quot;smart card&quot; UI -- card reader prompts, PIN entries -- that does not match the device they are holding.&lt;/p&gt;
&lt;p&gt;The second is recovery. A TPM clear destroys VSC keys irrecoverably. Microsoft Learn states the constraint plainly [@vsc-understanding]: &quot;all private information on the virtual smart card is encrypted by using the TPM on the host computer.&quot; Recovery would have to be re-enrolment under a federated attestation chain. The AIK-and-EK-cert attestation mode in &lt;code&gt;tpmvscmgr&lt;/code&gt; exists [@tpmvscmgr], but it never grew into a productised re-enrolment story; the practical answer was always &quot;issue a new card.&quot;&lt;/p&gt;
&lt;p&gt;The third is the multi-device world. VSCs bind one credential to one device. By 2017 most enterprise users had at least two devices: a laptop and a phone. By 2022 most had three. A credential metaphor borrowed from the era of one workstation per user could not stretch.&lt;/p&gt;
&lt;p&gt;Where do physical smart cards still belong in 2026? Three places. First, federal PIV / DoD CAC: the badge IS the credential, the issuance lifecycle is owned by an external organisation, and the cards have to work cross-platform and cross-application in a way a Windows-only credential cannot. Second, high-assurance regulated industries (banking, healthcare imaging, court systems) where existing PKI investment and signed-document workflows make the card the institutional artifact, not just an authentication factor. Third, &quot;smart card removal locks workstation&quot; cases (operating-room PCs, trading-floor terminals) where the physical act of pulling the card out of the reader is the security control.&lt;/p&gt;
&lt;p&gt;Where does Entra Certificate-Based Authentication fit? Entra CBA is the cloud-native PIV/CAC path. A federal user logs into Entra ID directly with their PIV/CAC card, bypassing the on-premises ADFS infrastructure that was the traditional cloud-bridge for federal organisations. Entra CBA preserves the PIV credential while replacing the on-premises STS, and is the practical answer to &quot;we have to keep PIV, but also we are migrating to cloud.&quot;&lt;/p&gt;
&lt;p&gt;The table below condenses the comparison.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Where the key lives&lt;/th&gt;
&lt;th&gt;Origin binding&lt;/th&gt;
&lt;th&gt;NTLM secondary&lt;/th&gt;
&lt;th&gt;Provisioning steps&lt;/th&gt;
&lt;th&gt;Multi-device&lt;/th&gt;
&lt;th&gt;Phishing resistance&lt;/th&gt;
&lt;th&gt;Recovery&lt;/th&gt;
&lt;th&gt;Suitable for new deployments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Physical PIV / CAC&lt;/td&gt;
&lt;td&gt;Removable IC&lt;/td&gt;
&lt;td&gt;No (relay possible)&lt;/td&gt;
&lt;td&gt;Yes (until NTLM removed)&lt;/td&gt;
&lt;td&gt;High (PKI + issuance)&lt;/td&gt;
&lt;td&gt;Yes (cross-device by physical movement)&lt;/td&gt;
&lt;td&gt;Conditional&lt;/td&gt;
&lt;td&gt;Re-issue card&lt;/td&gt;
&lt;td&gt;Federal/DoD only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TPM Virtual Smart Card&lt;/td&gt;
&lt;td&gt;On-device TPM&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (until NTLM removed)&lt;/td&gt;
&lt;td&gt;High (4-step)&lt;/td&gt;
&lt;td&gt;No (bound to one TPM)&lt;/td&gt;
&lt;td&gt;Conditional&lt;/td&gt;
&lt;td&gt;Re-enrol&lt;/td&gt;
&lt;td&gt;Not recommended (deprecation Warning)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WHfB key-trust&lt;/td&gt;
&lt;td&gt;On-device TPM&lt;/td&gt;
&lt;td&gt;Limited (RP=Entra)&lt;/td&gt;
&lt;td&gt;Reduced (cloud Kerberos)&lt;/td&gt;
&lt;td&gt;Low (in-OS wizard)&lt;/td&gt;
&lt;td&gt;Per-device enrolment&lt;/td&gt;
&lt;td&gt;Yes (relative)&lt;/td&gt;
&lt;td&gt;Re-enrol via device registration&lt;/td&gt;
&lt;td&gt;Yes (cloud/hybrid)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WHfB cert-trust&lt;/td&gt;
&lt;td&gt;On-device TPM&lt;/td&gt;
&lt;td&gt;Limited (RP=AD)&lt;/td&gt;
&lt;td&gt;Yes (until NTLM removed)&lt;/td&gt;
&lt;td&gt;Medium (PKI required)&lt;/td&gt;
&lt;td&gt;Per-device enrolment&lt;/td&gt;
&lt;td&gt;Conditional&lt;/td&gt;
&lt;td&gt;Re-enrol; CA-issued cert&lt;/td&gt;
&lt;td&gt;Yes (brownfield PKI)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FIDO2 security key&lt;/td&gt;
&lt;td&gt;External authenticator (e.g., YubiKey)&lt;/td&gt;
&lt;td&gt;Yes (WebAuthn RP ID)&lt;/td&gt;
&lt;td&gt;Not applicable (no Kerberos)&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Yes (key is portable)&lt;/td&gt;
&lt;td&gt;Yes (origin-bound)&lt;/td&gt;
&lt;td&gt;Spare key or backup credential&lt;/td&gt;
&lt;td&gt;Yes (high-assurance)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entra device-bound passkey&lt;/td&gt;
&lt;td&gt;TPM or external authenticator&lt;/td&gt;
&lt;td&gt;Yes (WebAuthn RP ID)&lt;/td&gt;
&lt;td&gt;Not applicable&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Per-device&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Re-enrol&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entra synced passkey&lt;/td&gt;
&lt;td&gt;Cloud-synced (no attestation)&lt;/td&gt;
&lt;td&gt;Yes (WebAuthn RP ID)&lt;/td&gt;
&lt;td&gt;Not applicable&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Yes (cloud-synced)&lt;/td&gt;
&lt;td&gt;Yes (origin-bound)&lt;/td&gt;
&lt;td&gt;Cloud provider recovery&lt;/td&gt;
&lt;td&gt;Yes (consumer, low-friction)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The architecture is now mature. But the lineage has a hard ceiling no architecture can cross: a signing oracle cannot tell you what it signed &lt;em&gt;for&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;8. What a Card Edge Can and Cannot Mediate&lt;/h2&gt;
&lt;p&gt;Set aside provisioning UX. Set aside NTLM legacy. Set aside everything Windows-specific. What are the &lt;em&gt;structural&lt;/em&gt; limits any card-edge-or-equivalent design must accept? Six, by my count, and each one is anchored to a primary source.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The card edge is a signing oracle, not a transcript witness.&lt;/strong&gt; A PIV card receives a hash and returns a signature. It does not know what protocol the signature is for, what relying party requested it, or whether the same hash has been requested two minutes ago by an attacker on a wireless network. PKINIT&apos;s vulnerability to relay was open from 2006 (RFC 4556) until 2017 (RFC 8070, which added a freshness token to the AS exchange) [@rfc-4556] [@rfc-8070]. The fix had to live in the &lt;em&gt;protocol&lt;/em&gt;, not in the card. The card cannot prove what it signed &lt;em&gt;for&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The card has no notion of relying-party identity.&lt;/strong&gt; This is the structural defect WebAuthn fixes. A WebAuthn authenticator includes the RP ID in the signed assertion and refuses to release a signature for the wrong RP. The W3C specification states this property explicitly [@webauthn-2]. A PIV card does not. To add an equivalent property to the smart card lineage would have meant changing the SP 800-73 command set; it was easier to throw the PC/SC card edge away and start over with FIDO2.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cryptographic protection at the card edge cannot reach downstream OS-minted credentials.&lt;/strong&gt; This is the 2014 NTLM-secondary lesson at its most general. The card protects a key; the OS may mint credentials around that key the card cannot police. Microsoft KB 2871997 closed the leak with defence-in-depth retrofits (TokenLeakDetectDelaySecs, Protected Users, RunAsPPL, eventually Credential Guard) [@kb-2871997] [@msrc-kb-2871997] [@protected-users] [@credential-guard]; the structural close had to wait for the 2024-2026 NTLM removal programme [@ntlmv1-removal]. Any future credential the OS mints around the card&apos;s key is, by construction, outside the card&apos;s authority.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Revocation must be reachable, and the card cannot tell you when it is not.&lt;/strong&gt; A PIV card&apos;s certificate is a relying-party-side concept; revocation status is a property of the issuing PKI, not the card. CRL distribution points and OCSP responders are the relying party&apos;s problem to reach. When a domain controller cannot reach the CRL, the policy choice is to fail open or fail closed; either policy carries risk. The &lt;code&gt;[MS-PKCA]&lt;/code&gt; Windows profile specifies server-side certificate-validation processing -- including revocation checking -- as a property of the KDC, not the credential the card presented [@ms-pkca]. The card signed correctly either way.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Certificate-to-user mapping must be strongly bound, and again the card cannot help.&lt;/strong&gt; When a domain controller receives a PKINIT request, it must map the presented certificate to an Active Directory account. The Certifried CVE class disclosed in May 2022 (CVE-2022-26923, CVE-2022-26931, CVE-2022-34691) showed that weak mapping -- by Subject Alternative Name UPN without a strong identifier bound into the certificate -- lets an attacker who can enrol against an over-permissive template impersonate any account [@kb-5014754]. The card signed exactly what it was asked to sign; the structural defect was at the KDC&apos;s mapping step. Microsoft KB 5014754 closed the mapping defect by requiring strong certificate-to-account binding; we return to its multi-year deployment timeline in §9 [@kb-5014754].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hardware-bound keys cannot be teleported -- and this is both feature and limit.&lt;/strong&gt; Non-exportability is the central promise of the entire lineage. It is also the bound. A TPM clear or a hardware replacement destroys the key. The recovery story has to be re-enrolment, not restore. Microsoft Learn states the constraint for VSCs and the same constraint applies, structurally, to every TPM-bound or external-authenticator credential -- including FIDO2 device-bound passkeys [@vsc-understanding]. Synced passkeys recover this property by giving up attestation; you cannot have both.&lt;/p&gt;

Non-exportability is the property. It is also the bound.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; An ideal card-lineage authenticator refuses to sign without RP-issued freshness, refuses to release a signature outside its RP scope, leaves no downstream-cacheable credential material, attests to its hardware at registration, and supports identity portability via re-enrolment-under-attestation rather than key portability. No shipping authenticator delivers all five of these authenticator-side properties in a workforce-grade product today; the two RP-side limits (revocation reachability, certificate-to-user mapping) are necessarily closed at the relying party, not the authenticator. The combination is the work of the next decade.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Limit&lt;/th&gt;
&lt;th&gt;What it forbids&lt;/th&gt;
&lt;th&gt;Primary source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Signing oracle, not transcript witness&lt;/td&gt;
&lt;td&gt;Card cannot prove signature was for the intended protocol context&lt;/td&gt;
&lt;td&gt;RFC 4556 / RFC 8070 [@rfc-4556] [@rfc-8070]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No RP identity&lt;/td&gt;
&lt;td&gt;Card cannot refuse a relay; relay window must close in protocol&lt;/td&gt;
&lt;td&gt;WebAuthn 2 [@webauthn-2]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No reach to downstream OS credentials&lt;/td&gt;
&lt;td&gt;Card protects key, not identity around the key&lt;/td&gt;
&lt;td&gt;KB 2871997, MSRC [@kb-2871997] [@msrc-kb-2871997]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Revocation is not self-asserting&lt;/td&gt;
&lt;td&gt;Card cannot vouch for its own validity; KDC must reach the PKI&lt;/td&gt;
&lt;td&gt;[MS-PKCA] [@ms-pkca]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong cert-to-user mapping is not card-asserted&lt;/td&gt;
&lt;td&gt;Relying party must bind certificate to AD account; card has no view of the mapping&lt;/td&gt;
&lt;td&gt;KB 5014754 [@kb-5014754]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Non-exportability bounds portability&lt;/td&gt;
&lt;td&gt;Key dies with the chip; recovery must be re-enrolment&lt;/td&gt;
&lt;td&gt;VSC Understanding [@vsc-understanding]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Some limits are being closed. The signing-oracle limit is mitigated by RFC 8070 freshness tokens; the RP-identity limit is closed for new credentials by WebAuthn; the downstream-credential limit is being closed by NTLM removal; the strong-mapping limit was closed by KB 5014754 on shipping AD infrastructure between February and September 2025. Others are inherent: a non-exportable key is, by definition, not portable. The next decade of smart-card-lineage work is being shaped by which is which.&lt;/p&gt;
&lt;h2&gt;9. Open Problems for the Next Decade&lt;/h2&gt;
&lt;p&gt;Five problems are still open in 2026. Each has a candidate fix in flight; none has shipped to general availability for the workforce case.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PIV / CAC in a post-NTLM Windows estate.&lt;/strong&gt; NTLMv1 was removed from Windows 11 24H2 and Windows Server 2025 [@ntlmv1-removal]; NTLMv2 is on the deprecation track [@deprecated-features]. What does &quot;smart card required for interactive logon&quot; &lt;em&gt;mean&lt;/em&gt; in a forest with no NTLMv1 secondary credential? The historical answer was &quot;the KDC mints an NT hash so legacy services keep working.&quot; The new answer must be either &quot;no NT hash; legacy services break&quot; or &quot;an NT hash for NTLMv2 only, restricted by SCRIL rotation and Protected Users membership.&quot; Microsoft has not yet published a complete blueprint for what federal PIV deployments look like after NTLMv2 also retires. Credential Guard&apos;s role in the transition is to make any residual secondary credential harder to harvest [@credential-guard] [@protected-users].&lt;/p&gt;

Three concrete questions a federal IT shop should be asking. First: does our forest have any domain controllers still serving NTLMv1 to legacy clients? After 24H2 / Server 2025, the answer should be no [@ntlmv1-removal]. Second: are our privileged accounts in Protected Users? The group blocks NTLM, DES, RC4 pre-auth, and constrained or unconstrained delegation [@protected-users]; for a smart-card-required account, membership effectively removes the RC4-HMAC-via-NTLM-hash attack surface even before NTLMv2 retirement. Third: is Credential Guard enabled on every member system? On Windows 11 22H2 and Server 2025, it is on by default for hardware-eligible domain-joined non-DC systems [@credential-guard]. These three measures are the practical answer to &quot;what does smart-card-required mean today.&quot; The full structural answer waits on NTLMv2 retirement.
&lt;p&gt;&lt;strong&gt;The recovery primitive that never shipped.&lt;/strong&gt; TPM-clear or device replacement destroys TPM-bound keys; this is the cost of non-exportability. AIK-and-EK-cert attestation in &lt;code&gt;tpmvscmgr&lt;/code&gt; could in principle support federated re-enrolment with strong proof of platform identity [@tpmvscmgr], and the Entra passkey enrolment flow supports attestation-required policies [@entra-passkeys-howto], but neither path matured into a &quot;your VSC died; here is how the help desk restores you in fifteen seconds&quot; story. Synced passkeys recover this property by giving up attestation. Workforce-grade attestation &lt;em&gt;and&lt;/em&gt; easy recovery, together, is still not shipping.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The certificate-based-authentication hardening lag.&lt;/strong&gt; Microsoft&apos;s KB 5014754 hardens certificate-based authentication on Windows domain controllers against the Certifried CVE class (CVE-2022-26923, CVE-2022-26931, CVE-2022-34691) by requiring strong certificate-to-user mapping at the KDC. The CVE class was disclosed on May 10, 2022. The mitigation moved DCs to Enforcement mode by default on February 11, 2025, with a fallback to Compatibility mode still available; the override was finally retired on September 9, 2025 [@kb-5014754]. The KB&apos;s own change log records several intermediate slips of the Full-Enforcement target (the original commitment was a 2023 milestone, slipping to February 2025 and then to September 2025) [@kb-5014754]. That is roughly three years from CVE disclosure to default Enforcement and a further seven months to end-of-override on shipping infrastructure -- and the gap from the &lt;em&gt;first published&lt;/em&gt; Full-Enforcement target to the actual end-of-override stretches the slip to a multi-year story in its own right. The lesson is sobering: in a brownfield estate, the time from &quot;CVE disclosed&quot; to &quot;hardening fully enforced on every domain controller&quot; is measured in &lt;em&gt;years&lt;/em&gt;, not weeks. Separately, RFC 8070 PKINIT freshness tokens (February 2017) are a &lt;em&gt;different&lt;/em&gt; hardening programme [@rfc-8070]; Windows has not deployed RFC 8070 freshness as the default in the broad estate, and the article&apos;s RunnableCode in §10 illustrates the freshness exchange rather than documenting deployed Windows behaviour. Any protocol-level fix to the smart-card lineage in 2026 will, on the KB 5014754 evidence, take three to four years to land -- and longer if the standards process itself slips, as RFC 8070&apos;s still-undeployed status (over nine years since publication) suggests.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cross-platform card-edge longevity.&lt;/strong&gt; OpenSC and pcsc-lite still implement NIST SP 800-73 on macOS and Linux; the cross-platform PIV story works for basic logon. But the modern features Windows keeps adding -- attestation chains, device-bound credential extensions, integration with the Entra passkey APIs -- lag on the open-source side. Whether PC/SC outlives the platforms that built it is genuinely uncertain. Some federal organisations will keep PIV alive cross-platform as policy; many private-sector deployments will quietly move off.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Post-quantum signature algorithms on smart cards.&lt;/strong&gt; PIV&apos;s current baseline is RSA-2048 and ECDSA P-256 -- not post-quantum resistant. NIST&apos;s post-quantum standardisation selected ML-DSA (Module Lattice DSA, formerly Dilithium) and SLH-DSA (Stateless Hash-Based DSA, formerly SPHINCS+); both have key and signature sizes substantially larger than RSA-2048 or ECDSA P-256, and both will stress the storage and bandwidth budgets of a typical PIV card. SP 800-73-4 has no slots for post-quantum keys today [@sp-800-73-4-upd1] [@fips-201-3]. A future revision will have to accommodate them, and the existing population of $\approx$ five million PIV cards [@nist-piv-home] will not all be PQ-capable at once. The transition runs on a card-issuance cycle: roughly $T_{\text{transition}} \approx T_{\text{issuance}} + T_{\text{rollout}}$, each term in the multi-year range.&lt;/p&gt;
&lt;p&gt;Architecture is a question about which problems your design &lt;em&gt;cannot&lt;/em&gt; solve. The next section is for the architect who has to choose right now, with all five problems still open.&lt;/p&gt;
&lt;h2&gt;10. Choosing Between PIV, VSC, WHfB, and FIDO2 in 2026&lt;/h2&gt;
&lt;p&gt;Four operator-grade callouts. Pick the one that matches your context.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Stay on PIV / CAC for the foreseeable future. FIPS 201-3 is the current standard and SP 800-73 the current card-edge interface; policy mandates are not changing on a tactical timeline [@fips-201-3] [@nist-piv-home]. Add Entra Certificate-Based Authentication for cloud workloads so the same PIV card authenticates to Microsoft 365 and Azure resources without going through on-premises ADFS. For the three operational controls -- Credential Guard, Protected Users membership for privileged accounts, and NTLMv1-removal status -- see the federal-IT checklist in the §9 Aside. Do not rely on the smart card alone to defeat NTLM-secondary-credential abuse until NTLM removal has reached your environment.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Pick WHfB key-trust if you are cloud-first or hybrid, cert-trust if you have an existing on-premises PKI you need to honour [@whfb-deploy] [@whfb-how-it-works]. Add FIDO2 security keys for the populations that need cross-device portability or strict phishing resistance: contractors, executives, IT administrators, anyone whose credential theft would be catastrophic [@webauthn-2] [@passwordless-strategy]. Do not pick Virtual Smart Cards for new deployments; the Microsoft Learn VSC Overview deprecation Warning quoted verbatim in §7 applies [@vsc-overview].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Continue to operate it but plan migration to WHfB. Audit your recovery and re-enrolment process: a TPM clear destroys VSC keys irrecoverably, so any disaster-recovery plan that assumes you can move a credential between devices is wrong [@vsc-understanding]. Do not assume your VSC deployment is &quot;supported&quot; the way it was in 2014; the deprecation Warning quoted in §7 applies here [@vsc-overview]. The cleanest exit path is to enrol the same users into WHfB cert-trust against your existing PKI, then retire the VSC layer once the WHfB credential is operational.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; FIDO2 security keys with attested device-bound credentials [@webauthn-2] [@ctap-2-1], paired with Microsoft Entra ID passkeys. Use attestation-required profiles for high-assurance populations (so the relying party can verify the authenticator hardware) and attestation-optional profiles for less sensitive populations who benefit from synced-passkey recovery [@entra-passkeys-howto] [@entra-passwordless]. The trade-off remains: device-bound passkeys are attestable but not portable; synced passkeys are portable but not attestable. Match the profile to the population, not the population to the profile.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For the architect who wants to see how PKINIT freshness enforcement would work if the RFC 8070 extension were enforced, the JavaScript below simulates the nonce check. The KDC issues a freshness token; the client includes it in the signed &lt;code&gt;PKAuthenticator&lt;/code&gt;; the KDC verifies that the token in the signed structure matches the one it issued. This is illustrative protocol behaviour, not the Windows default today.&lt;/p&gt;
&lt;p&gt;{`
function kdcIssueFreshness() {
  const token = Math.random().toString(16).slice(2, 18);
  return { token, issuedAt: Date.now() };
}&lt;/p&gt;
&lt;p&gt;function clientSignAuthPack({ freshness, cardSign }) {
  const pkAuthenticator = {
    cusec: 0,
    ctime: Date.now(),
    nonce: Math.floor(Math.random() * 1e9),
    freshness: freshness.token,
    paChecksum: &apos;sha256-of-paData&apos;,
  };
  const signature = cardSign(JSON.stringify(pkAuthenticator));
  return { pkAuthenticator, signature };
}&lt;/p&gt;
&lt;p&gt;function kdcVerify({ pkAuthenticator, signature }, issued) {
  const tooOld = Date.now() - issued.issuedAt &amp;gt; 5 * 60 * 1000;
  if (tooOld) return { ok: false, reason: &apos;freshness token too old&apos; };
  if (pkAuthenticator.freshness !== issued.token) {
    return { ok: false, reason: &apos;freshness token does not match&apos; };
  }
  return { ok: true };
}&lt;/p&gt;
&lt;p&gt;const issued = kdcIssueFreshness();
const cardSign = (msg) =&amp;gt; &apos;sig(&apos; + msg.length + &apos;)&apos;;
const signed = clientSignAuthPack({ freshness: issued, cardSign });&lt;/p&gt;
&lt;p&gt;console.log(&apos;Honest client:&apos;, kdcVerify(signed, issued));&lt;/p&gt;
&lt;p&gt;const replayed = { ...signed, pkAuthenticator: { ...signed.pkAuthenticator, freshness: &apos;stale-token-1234&apos; } };
console.log(&apos;Replayed with stale token:&apos;, kdcVerify(replayed, issued));
`}&lt;/p&gt;
&lt;p&gt;Whichever method you choose, no method alone defeats the legacy compatibility surfaces the card was never designed to police. The structural fix lives in the protocol-removal programme finishing through 2026 and beyond.&lt;/p&gt;
&lt;h2&gt;11. Frequently Asked Questions&lt;/h2&gt;

Yes functionally and cryptographically; no physically. A VSC exposes the same PC/SC card edge, Microsoft Smart Card KSP, and minidriver model as a physical card. Above the minidriver layer, every Windows component sees it as a smart card. Tamper-resistance comes from the host TPM rather than a removable IC; Microsoft Learn lists TPM 1.2 as the documented minimum -- VSCs predate TPM 2.0 [@vsc-overview] [@vsc-understanding].

No, by construction. The card signs internally and returns the signature. The only material that leaves during normal operation is the signed output (or, for key exchange, an unwrapped symmetric session key the card has decrypted with the wrapping key). The private key is generated on-card during enrolment and cannot be extracted; that property is the load-bearing security claim of the entire lineage.

Legacy NTLM compatibility. Many pre-Windows-2000 services speak only NTLM, and accounts flagged &quot;smart card required for interactive logon&quot; must still authenticate to them. KB 2871997 (May 13, 2014) added auto-rotation of the secondary credential at logon, reducing but not eliminating the attack surface [@kb-2871997]. The structural fix is NTLM removal: NTLMv1 has now been removed in Windows 11 24H2 and Windows Server 2025 [@ntlmv1-removal].

Yes. The YubiKey 5 series exposes a PIV applet that the inbox `msclmd.dll` minidriver recognises out of the box [@yubico-piv] [@inbox-minidriver]. Insert the YubiKey and Windows treats it as a PIV-compliant smart card; the same enrolment, PKINIT, and lock-screen workflows apply. The YubiKey 5 can act as a FIDO2 authenticator concurrently, which is the practical way to bridge smart-card and origin-bound passkey workflows on the same device.

Conditionally. PKINIT signs an `AuthPack` containing a nonce and a paChecksum; with the RFC 8070 freshness extension and a correctly validated KDC certificate, an attacker cannot trivially replay or relay an `AuthPack` signed by the client&apos;s smart card [@rfc-4556] [@rfc-8070]. But PKINIT is not origin-bound in the WebAuthn sense -- the card has no notion of which KDC the signature is for. If a trust assumption fails (an attacker plants a certificate in the client&apos;s NTAuth store, for example), the card will happily sign for the wrong KDC. WebAuthn&apos;s RP-ID-bound assertion is a stronger guarantee [@webauthn-2].

See the §6 Callout &quot;VSCs predate TPM 2.0&quot; for the full timeline. TPM 1.2 is the documented minimum; TPM 2.0 is the practical choice on Windows 11, which itself requires TPM 2.0 for the OS [@vsc-overview].

Three reasons, all expanded in §7: provisioning UX, TPM-clear recovery, and the multi-device world. Windows Hello for Business delivered the same TPM-bound-key benefits without the PC/SC abstraction cost (no virtual reader, no virtual minidriver, no APDU layer); FIDO2 then added cross-device portability and origin binding, neither of which the VSC architecture could deliver. The Microsoft Learn VSC Overview deprecation Warning quoted verbatim in §7 makes the recommendation explicit [@vsc-overview] [@passwordless-strategy].

Both are CNG Key Storage Providers. The Smart Card KSP routes calls through the minidriver to either a physical card or a TPM VSC; the cryptographic operation is APDU-encoded and sent to the card. The Platform Crypto Provider routes calls directly to the TPM via TPM Base Services; there is no card abstraction in the path. Windows Hello for Business uses the Platform Crypto Provider for TPM-bound key operations [@cng-ksp-list] [@whfb-how-it-works].
&lt;p&gt;The card was always a metaphor. The cryptographic primitive at its centre -- a non-exportable asymmetric key, bound to a tamper-resistant element, gated by a local gesture -- is the longest-lived object in this lineage. Every generation transition (PC/SC -&amp;gt; CryptoAPI/CNG -&amp;gt; inbox PIV/GIDS -&amp;gt; Virtual Smart Card -&amp;gt; WHfB -&amp;gt; FIDO2) was a transition of the &lt;em&gt;interface around&lt;/em&gt; that primitive, not of the primitive itself. The May 2014 contractor whose CAC signed the right blob and lost her account anyway was the canary; the fix she needed was not on her card but in a decade-long programme to remove the OS-minted secondary credentials that lived outside the card&apos;s authority. Windows is most of the way through that programme now. The card that wasn&apos;t a card outgrew its metaphor -- and the protection it always promised is, finally, arriving at the authentication outcome.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;smart-cards-and-virtual-smart-cards-in-windows-the-card-centric-auth-lineage&quot; keyTerms={[
  { term: &quot;APDU&quot;, definition: &quot;Application Protocol Data Unit. The request/response unit a host application exchanges with a smart card; header CLA INS P1 P2, optional Lc/data/Le, response SW1 SW2.&quot; },
  { term: &quot;PC/SC&quot;, definition: &quot;Personal Computer/Smart Card. The 1996 industry consortium and its specification series for how a smart card reader is exposed to a desktop OS.&quot; },
  { term: &quot;PKINIT&quot;, definition: &quot;Public Key Cryptography for Initial Authentication in Kerberos. Lets a client present an X.509 certificate as Kerberos pre-authentication instead of a password-derived shared secret.&quot; },
  { term: &quot;AuthPack&quot;, definition: &quot;The PKINIT structure containing PKAuthenticator and Diffie-Hellman parameters that the client signs and embeds in the PA-PK-AS-REQ pre-authentication data of the Kerberos AS-REQ.&quot; },
  { term: &quot;CSP&quot;, definition: &quot;Cryptographic Service Provider. A CryptoAPI 1.0 plug-in providing cryptographic services to applications, loaded in-process.&quot; },
  { term: &quot;KSP&quot;, definition: &quot;Key Storage Provider. The CNG-era plug-in for key storage and asymmetric cryptographic operations, with Microsoft Smart Card KSP for cards and VSCs and Microsoft Platform Crypto Provider for direct TPM access.&quot; },
  { term: &quot;Minidriver&quot;, definition: &quot;A small per-card DLL loaded by the Microsoft Base Smart Card CSP and Smart Card KSP that contains card-specific behaviour; the inbox msclmd.dll covers PIV and GIDS cards out of the box.&quot; },
  { term: &quot;Virtual Smart Card&quot;, definition: &quot;A TPM-backed software smart card introduced in Windows 8 in October 2012; exposes the same PC/SC card edge as a physical card with the TPM as backing chip.&quot; },
  { term: &quot;NTLM secondary credential&quot;, definition: &quot;The NT hash Windows maintains for smart-card-only accounts so legacy NTLM-accepting services continue to authenticate the user; harvestable from LSASS and replayable in pass-the-hash attacks.&quot; },
  { term: &quot;KB 2871997&quot;, definition: &quot;Microsoft Security Advisory of May 13, 2014; added TokenLeakDetectDelaySecs, the Protected Users group, and LSA Protection / RunAsPPL to mitigate the credential leakage class disclosed in 2014.&quot; },
  { term: &quot;Protected Users&quot;, definition: &quot;A Windows Server 2012 R2 security group whose members cannot use NTLM, DES, or RC4 in Kerberos pre-auth and cannot delegate.&quot; },
  { term: &quot;Credential Guard&quot;, definition: &quot;VBS-based isolation of LSA credential material in the LSAISO container; enabled by default on Windows 11 22H2 and Windows Server 2025 hardware-eligible domain-joined systems.&quot; },
  { term: &quot;RFC 8070&quot;, definition: &quot;PKINIT Freshness Extension, February 2017. Adds a KDC-issued freshness token to the signed PKAuthenticator, closing the relay window present in RFC 4556.&quot; },
  { term: &quot;WHfB key-trust&quot;, definition: &quot;Windows Hello for Business deployment in which the TPM-bound public key is registered directly with the identity provider (Microsoft Entra ID); no X.509 certificate is required.&quot; },
  { term: &quot;WHfB cert-trust&quot;, definition: &quot;Windows Hello for Business deployment in which an X.509 certificate is issued for the TPM-bound key by an enterprise PKI, allowing PKINIT-style authentication to downstream services.&quot; },
  { term: &quot;Microsoft Platform Crypto Provider&quot;, definition: &quot;A CNG KSP that talks directly to the TPM, used by Windows Hello for Business and by other modern Windows components that want TPM-bound keys without the smart card abstraction layer.&quot; },
  { term: &quot;FIDO2&quot;, definition: &quot;The FIDO Alliance and W3C specifications (WebAuthn and CTAP) for public-key authentication to relying parties, with origin binding to the RP ID.&quot; },
  { term: &quot;WebAuthn&quot;, definition: &quot;The W3C Web Authentication API; the relying-party-facing part of FIDO2.&quot; },
  { term: &quot;RP ID&quot;, definition: &quot;Relying Party Identifier. In WebAuthn, the domain name or registrable suffix to which a credential is scoped; the authenticator refuses to sign assertions for any other RP ID.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>smart-cards</category><category>virtual-smart-cards</category><category>pkinit</category><category>kerberos</category><category>windows-security</category><category>tpm</category><category>windows-hello-for-business</category><category>fido2</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>Agentic Identity on Windows: When the Process Acting on Your Behalf Isn&apos;t You</title><link>https://paragmali.com/blog/agentic-identity-on-windows-when-the-process-acting-on-your-/</link><guid isPermaLink="true">https://paragmali.com/blog/agentic-identity-on-windows-when-the-process-acting-on-your-/</guid><description>Every AI agent on Windows in 2026 runs as the logged-on user. The cloud-identity layer has crossed the agent-attribution gap; the OS layer has not. This article maps the FIDO AATWG pillars onto Windows primitives and asks what is missing.</description><pubDate>Mon, 25 May 2026 00:00:00 GMT</pubDate><content:encoded>
Every locally-installed AI agent on Windows in May 2026 -- Claude Desktop, ChatGPT Desktop, Cursor, GitHub Copilot CLI, the MSIX-packaged Microsoft Copilot for Windows -- runs in a process whose primary token traces to the logged-on user. `SeAccessCheck`, ETW, RPC ACLs, Defender, and on-device Conditional Access all collapse &quot;the user asked&quot; and &quot;the agent decided&quot; into one principal. The cloud-identity layer has crossed this gap: Microsoft&apos;s Entra Agent ID has been in public preview since May 19, 2025 [@ms-security-blog-agentid], and the FIDO Alliance&apos;s Agentic Authentication Technical Working Group launched its three-pillar effort on April 28, 2026 with Google&apos;s AP2 and Mastercard&apos;s Verifiable Intent as foundational donations [@fido-aatwg-pr]. The Windows OS-level analog -- a kernel-recognised `AgentPrincipal` distinct from the user SID and the package SID -- does not exist, even though the substrate primitives (AppContainer package SIDs, Kerberos S4U2Proxy, WebAuthn and Windows Hello, the TPM&apos;s Direct Anonymous Attestation, the Administrator-Protection separate-session pattern, WAM, ETW) already ship. This article maps each AATWG pillar onto the Windows primitive that already exists and the glue that does not, and argues that agent identity belongs at both layers, with the OS layer being the missing piece.
&lt;h2&gt;1. Two principals walk into a syscall&lt;/h2&gt;
&lt;p&gt;A Tuesday in May 2026. Windows 11 24H2. Claude Desktop is open. In one terminal, the user types &lt;code&gt;Remove-Item -Recurse -Force .\old-builds&lt;/code&gt;. In another, the agent decides to run the same command against the same path. &lt;code&gt;SeAccessCheck&lt;/code&gt; returns the same answer for both. The Security event log records the same &lt;code&gt;SubjectUserSid&lt;/code&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;ETW&lt;/a&gt; emits the same &lt;code&gt;SubjectUserName&lt;/code&gt;. Microsoft Defender attributes both deletions to the same person -- the human at the keyboard.&lt;/p&gt;
&lt;p&gt;As far as the Windows kernel is concerned, there is exactly one principal in this story, and his name is the user [@ms-learn-sids].&lt;/p&gt;
&lt;p&gt;Nothing is broken. No malware. No zero-day. The kernel is doing exactly what NT 3.1 shipped to do on July 27, 1993 [@wiki-nt31]: read the primary token, hand the access-check engine the user SID, the group SIDs, and the integrity-level overlay [@ms-learn-mic], and decide. The decision is correct. It is also, in 2026, an attribution failure -- because the two actors who issued those two commands are different actors, and the kernel cannot tell.&lt;/p&gt;
&lt;p&gt;The attribution-collapse claim holds for every deployment pattern of every shipping agent today, but the privilege-blast-radius framing is the strong claim for Electron-wrapped agents (full DPAPI user scope, full Kerberos ticket-granting ticket, full network egress) and a more qualified claim for MSIX-packaged agents like Microsoft Copilot for Windows, which inherit a LowBox token and a per-package DPAPI scope under AppContainer [@ms-learn-appcontainer].&lt;/p&gt;

The kernel-resident access token attached to every Windows process at creation. It contains a user SID, a list of group SIDs, an integrity-level SID carried in a `SYSTEM_MANDATORY_LABEL_ACE` inside the token&apos;s SACL [@ms-learn-mic], and a privilege set; every `SeAccessCheck` call reads it as the authoritative statement of &quot;who is running this process&quot; [@ms-learn-sids].
&lt;p&gt;The collapse is structural. Three observations make the shape visible.&lt;/p&gt;
&lt;p&gt;First, the kernel&apos;s access-check pipeline reads the &lt;em&gt;user&lt;/em&gt;. &lt;code&gt;SeAccessCheck&lt;/code&gt; walks the DACL on the target object and matches each ACE against the SIDs in the primary token. The integrity-level overlay, added in Windows Vista, gates writes against the integrity label [@ms-learn-mic]; AppContainer, added in Windows 8, adds a second-principal-shaped SID to the same token group list [@ms-learn-appcontainer]; but the primary SID -- the answer the kernel returns when a downstream consumer asks &quot;whose authority is being exercised here?&quot; -- is the user.&lt;/p&gt;
&lt;p&gt;Second, the cloud-identity layer has just put the dual-principal answer on the wire. On April 28, 2026, the FIDO Alliance announced the Agentic Authentication Technical Working Group [@fido-aatwg-pr]. The three pillars: Verifiable User Instructions, Agent Authentication, and Trusted Delegation for Commerce. Chairs are CVS Health, Google, and OpenAI; vice-chairs are Amazon, Google, and Okta; the parallel Payments Technical Working Group is chaired by Mastercard and Visa. Google&apos;s Agent Payments Protocol (AP2) and Mastercard&apos;s Verifiable Intent framework are the foundational donations [@ap2-blog-google; @mastercard-vi]. Independent coverage from HelpNetSecurity dated April 29, 2026 carries the same governance roster [@helpnetsecurity-aatwg]. The cloud side now has a named, governed wire-format design space for the agent-as-distinct-principal story.&lt;/p&gt;
&lt;p&gt;Third, the OS-side gap is structural. Every layer of Windows from &lt;code&gt;SeAccessCheck&lt;/code&gt; through ETW [@ms-learn-mic] through on-device Conditional Access still answers &quot;the user&quot; because the primary token still has only the user SID. The package SID under AppContainer is the closest signal Windows has to a second principal; the access-check rule is intersection, not addition -- &quot;the permitted access is the intersection of that granted by the user/group SIDs and AppContainer SIDs&quot; [@ms-learn-appcontainer]. That intersection rule is the closest thing the kernel has to a sibling-principal model, and it identifies a &lt;em&gt;package&lt;/em&gt;, not an &lt;em&gt;agent&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; No engineering effort is required to produce this attribution failure. The kernel is functioning as designed. The design is from 1993. The user is the principal. The agent is the user. The audit log is what the audit log has always been.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What would it take, mechanically, for the kernel to know which principal was which -- and why has the answer been &quot;the user&quot; for the thirty-three years since NT 3.1? Both halves of that question have load-bearing histories, and those histories are older than NT itself.&lt;/p&gt;
&lt;h2&gt;2. From Multics to NT 3.1: the user-as-principal genealogy&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;MIT, Bell Labs, and General Electric. Fernando Corbato of MIT and Victor Vyssotsky of Bell Telephone Laboratories present &lt;em&gt;Introduction and Overview of the Multics System&lt;/em&gt; at the AFIPS Fall Joint Computer Conference. Their opening describes a general-purpose programming system intended to scale to thousands of users at a single installation [@multics-fjcc]. Multics, jointly led by MIT&apos;s Project MAC, General Electric, and Bell Laboratories [@multics-wiki], is the first operating system designed from the start around the idea that the kernel must know &lt;em&gt;whose&lt;/em&gt; work each running process is doing.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The Multics inheritance is not stylistic. It is the source of the abstraction Windows NT 3.1 picks up twenty-eight years later: a &lt;em&gt;principal&lt;/em&gt; is a named entity (a user, or in some systems a service account); every process belongs to exactly one principal at creation; the kernel mediates access using that principal. TENEX, BBN&apos;s PDP-10 time-sharing system from 1969 [@tenex-bitsavers], inherits the same model and ports it into the DEC product line; the Multics-to-TENEX-to-Unix lineage [@multics-hist] is the route the article reads as carrying the user-as-principal assumption forward into the design ground from which DEC VMS and later Windows NT 3.1 emerged.&lt;/p&gt;

A variable-length data structure that uniquely identifies a security principal in a Windows access decision. The canonical user-SID form is `S-1-5-21--`; every access token carries a user SID plus a list of group SIDs, and every `SeAccessCheck` call reads them as the authoritative answer to &quot;who is running this thread?&quot; [@ms-learn-sids].
&lt;p&gt;The formal model came in 1971. Butler Lampson, then at Xerox Palo Alto, published &lt;em&gt;Protection&lt;/em&gt; at the 5th Princeton Conference on Information Sciences and Systems, later reprinted in ACM Operating Systems Review 8(1) in January 1974 [@lampson-catalog]. Lampson&apos;s access-matrix model -- subject by object by right -- is the operational mathematics behind every modern access-control system. Read the matrix row by row and you get a capability list (&quot;what each subject can do&quot;); read it column by column and you get an access control list (&quot;who can do what to this object&quot;). Windows picks column-major: every securable object on Windows is described by a DACL, and &lt;code&gt;SeAccessCheck&lt;/code&gt; is the operational realisation of Lampson&apos;s matrix on NT. The DACL is the column; the primary token is the row index; the access-check answer is the cell.&lt;/p&gt;
&lt;p&gt;The bwlampson.site author catalog is the canonical fetchable anchor for the 1971 paper [@lampson-catalog]. The Microsoft Research-hosted PDF that this corpus previously linked is dead (HTTP 404); the catalog page itself names the ACM OSR 8(1) January 1974 reprint as the journal of record.&lt;/p&gt;

timeline
    title Genealogy of the user-as-principal model
    1965 : Multics
         : Corbato and Vyssotsky present at AFIPS FJCC
         : Per-user authentication as a kernel primitive
    1969 : TENEX
         : BBN ports the user-as-principal model to PDP-10
    1971 : Lampson&apos;s access-matrix model
         : Subject x object x right
         : Foundation for SeAccessCheck and the DACL
    1988 : Hardy&apos;s Confused Deputy
         : Authority from two sources, no way to name which
    1993 : NT 3.1 ships
         : One primary token per process, user SID as principal
&lt;p&gt;Seventeen years later, in 1988, Norm Hardy writes &lt;em&gt;The Confused Deputy&lt;/em&gt; at Key Logic (the company formed from the wreckage of Tymshare, where the events Hardy describes had occurred years earlier). Hardy&apos;s compiler is a FORTRAN compiler with a home-files licence; it legitimately holds authority to write into one path (the billing file &lt;code&gt;(SYSX)BILL&lt;/code&gt;) so it can record per-user compilation charges, and it legitimately accepts user-supplied output paths so it can write generated &lt;code&gt;.obj&lt;/code&gt; files where the user requests. A clever user supplies &lt;code&gt;(SYSX)BILL&lt;/code&gt; as the output path. The compiler obediently writes the user&apos;s output over the billing record, because the compiler &quot;had no way of expressing these intents&quot; [@hardy-caplore].&lt;/p&gt;
&lt;p&gt;Hardy&apos;s punchline is structural, and the article will return to it once more. &quot;The fundamental problem is that the compiler runs with authority stemming from two sources. (That&apos;s why the compiler is a confused deputy.) ... The compiler had no way of expressing these intents!&quot; [@hardy-caplore]. The deputy holds authority from two principals (itself, the licensed compiler; and the user it is serving), and the system the deputy talks to has no protocol for the deputy to say &lt;em&gt;which&lt;/em&gt; authority it is exercising for &lt;em&gt;this&lt;/em&gt; action. Any system that grants a deputy ambient authority from multiple sources without giving the deputy a way to name those sources at the syscall is a confused-deputy system by construction. The ACM Digital Library carries the canonical reprint at &lt;code&gt;10.1145/54289.871709&lt;/code&gt; [@hardy-acm], with the cap-lore.com mirror as the fetchable secondary.&lt;/p&gt;

Hardy 1988: a process holding authority delegated from one principal can be tricked into using that authority on behalf of another principal because the process has no way to attribute its actions to the right authorising principal at the syscall [@hardy-caplore]. The structural lower bound on agent attribution.
&lt;p&gt;July 27, 1993 [@wiki-nt31]. Dave Cutler ships NT 3.1. Every process on NT carries exactly one primary token; the token&apos;s user SID is the principal; impersonation is the only way a thread can temporarily speak as a different identity, and impersonation is bounded to the thread, not the process. Microsoft Learn states the consequence verbatim: &quot;Each time a user signs in, the system creates an access token for that user. The access token contains the user&apos;s SID, user rights, and the SIDs for any groups the user belongs to&quot; [@ms-learn-sids]. That description is the Multics inheritance with thirty years of refinement: one principal per process, the principal is a user, the access-check is the operational form of Lampson&apos;s matrix.&lt;/p&gt;
&lt;p&gt;This is the &lt;em&gt;user-identity&lt;/em&gt; milestone, not the code-identity milestone. NT 3.1 made user identity precise. The process that ran an attached binary still had no answer to &quot;who is this &lt;em&gt;code&lt;/em&gt;?&quot; -- and as the late-1990s ActiveX download experience would prove, that gap could not stay open.&lt;/p&gt;
&lt;h2&gt;3. Layering code identity on user identity: 1996 to 2017&lt;/h2&gt;
&lt;p&gt;August 7, 1996. A joint Microsoft and VeriSign press release crosses the wire: &lt;em&gt;Microsoft and VeriSign Provide First Technology For Secure Downloading of Software Over the Internet&lt;/em&gt; [@ms-news-authenticode-1996]. Internet Explorer 3.0 will ship with the new model the same year. The model has a name: Authenticode. The question this section asks: did Authenticode and its successors solve the principal question, or did they only decorate it?&lt;/p&gt;
&lt;p&gt;The pattern that emerges across five generations of &lt;a href=&quot;https://paragmali.com/blog/windows-app-identity-33-year-reinvention/&quot; rel=&quot;noopener&quot;&gt;code-identity layering&lt;/a&gt; deserves a name. Every generation answers a real failure of the one before it. Every generation adds an attribute to the access decision -- a publisher signature on the binary, a policy gate at load time, a second SID in the token, a kernel-mode code-integrity policy. And every generation leaves the runtime principal unchanged. The user is still the user. The token&apos;s primary SID is still the user SID. The downstream consumer (Defender, an ETW provider, a remote RPC server, a file-system DACL) still sees one principal.&lt;/p&gt;
&lt;h3&gt;3.1 Authenticode (1996, NT 4.0 with IE 3.0)&lt;/h3&gt;
&lt;p&gt;Authenticode is a load-time attribute. The publisher signs the PE on disk; the signature is a PKCS #7 blob embedded in a dedicated PE attribute certificate slot [@ms-learn-cryptography]. When the loader maps the binary, Windows can verify the signature, walk the certificate chain to a trusted root, and present the publisher name to the user (in IE 3.0&apos;s case, in the famous ActiveX install dialog). Cross-vendor code-signing history places Authenticode among the earliest widely-deployed commercial schemes to bind a publisher identity to a downloaded executable [@wikipedia-codesign; @ms-news-authenticode-1996].&lt;/p&gt;
&lt;p&gt;Authenticode is a &lt;em&gt;load-time&lt;/em&gt; attribute -- the publisher signs the file on disk, not the running process. After the loader has validated the signature and mapped the image, the running process&apos;s primary token has nothing in it that records &quot;this binary was signed by Microsoft Corporation.&quot; The runtime principal is unchanged from what the user&apos;s logon session created.&lt;/p&gt;
&lt;p&gt;The failure mode that forces the next generation is structural. A signature is descriptive (&quot;this file is from Microsoft&quot;), not authoritative (&quot;this process is acting with Microsoft&apos;s authority&quot;). A binary&apos;s publisher is attached to the file on disk; nothing about it propagates into the access decision the kernel makes when the process opens a network socket, decrypts a DPAPI blob, or impersonates over RPC.&lt;/p&gt;
&lt;h3&gt;3.2 SRP and AppLocker (2001, 2009)&lt;/h3&gt;
&lt;p&gt;Software Restriction Policies arrived first with Windows XP (October 2001) [@wiki-winxp] and shipped again with Windows Server 2003 (April 2003) [@wiki-srv2003]; AppLocker arrived on Windows 7 (October 22, 2009) [@wiki-win7] and Server 2008 R2 as the formal successor. Microsoft Learn says it directly: &quot;AppLocker policies in the GPO are applied and supersede the SRP policies in the GPO and any local AppLocker policies or SRP policies&quot; [@ms-learn-srp-applocker]. Both layers are policy gates: an administrator authors rules naming publishers, hashes, or paths, and the OS enforces the rules at process creation. The runtime token is, again, unchanged.&lt;/p&gt;
&lt;p&gt;The failure mode is one Microsoft itself documents in unusually plain language. The AppLocker overview reads, verbatim: &quot;AppLocker is a defense-in-depth security feature and not considered a defensible Windows security feature&quot; [@ms-learn-applocker]. The same page directs administrators to App Control for Business when the goal is defensible threat protection. Defense-in-depth means the feature raises attacker cost; it does not promise an attacker cannot bypass it. That promise is reserved for documented security boundaries.&lt;/p&gt;
&lt;h3&gt;3.3 AppContainer and the package SID (Windows 8, October 26, 2012 general availability)&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://paragmali.com/blog/appcontainer-and-lowbox-tokens-windowss-capability-sandbox/&quot; rel=&quot;noopener&quot;&gt;AppContainer&lt;/a&gt; is the first time the kernel carries a &lt;em&gt;second&lt;/em&gt; principal-shaped SID in the token&apos;s group list. Windows 8 ships with the new sandbox; every UWP app process runs with an &lt;code&gt;S-1-15-2-...&lt;/code&gt; package SID attached to its primary token, alongside the user SID and the user&apos;s group SIDs. The dual-principal model has a verbatim Microsoft Learn definition: &quot;This dual-principal model ensures that access to sensitive resources is tightly controlled and can be managed independently for different applications ... the permitted access is the intersection of that granted by the user/group SIDs and AppContainer SIDs&quot; [@ms-learn-appcontainer].&lt;/p&gt;

The kernel sandboxing primitive shipped in Windows 8 (October 26, 2012 general availability) [@ms-learn-appcontainer; @wiki-win8]. It attaches a second SID (`S-1-15-2-...`) to a process&apos;s access token; access decisions become the intersection of user/group SIDs and the package SID, gated further by capability SIDs (`S-1-15-3-...`) the app declares in its manifest [@ms-learn-appcontainer]. The kernel-internal name for the structure is the LowBox token, which is why the relevant API is `NtCreateLowBoxToken` [@ms-learn-appcontainer-legacy].
&lt;p&gt;The dual-principal language is real and load-bearing. It is also not what the article needs. The package SID identifies a &lt;em&gt;package&lt;/em&gt; (the UWP manifest, the MSIX bundle), not an &lt;em&gt;agent role&lt;/em&gt;. Nothing upstream tells Defender, ETW, or Conditional Access whether the package SID it sees represents an AI agent, a UWP calculator, or a games launcher. AppContainer also originally targeted UWP only; the legacy-applications variant arrived later as a way to retrofit unpackaged Win32 apps into the same kernel substrate [@ms-learn-appcontainer-legacy], which is the path Win32 App Isolation (June 14, 2023) extends [@ms-blogs-win32appiso].&lt;/p&gt;
&lt;h3&gt;3.4 App Control for Business (2017 onwards)&lt;/h3&gt;
&lt;p&gt;App Control for Business -- the policy formerly known as Windows Defender Application Control (WDAC), which arrived as a named feature in Windows 10 1709 (Fall Creators Update, released October 17, 2017) [@wiki-win10vh] -- is the kernel-mode code-integrity policy enforced by the loader itself [@ms-learn-appcontrol]. Unlike AppLocker, App Control for Business is on the documented security-boundary list when configured per the supported guidance; it can cover DLL loads, driver loads, and script-host loads with a single policy. The runtime principal is, predictably, still the user.&lt;/p&gt;

flowchart TD
    subgraph TokenAtRuntime[&quot;What is in the primary token&quot;]
        US[&quot;User SID (1993)&quot;]
        PSID[&quot;Package SID (2012)&quot;]
        IL[&quot;Integrity level overlay (2006)&quot;]
    end
    subgraph GateBeforeRuntime[&quot;What gates execution before the token exists&quot;]
        AC[&quot;Authenticode signature (1996)&quot;]
        SRP[&quot;SRP and AppLocker (2001 and 2009)&quot;]
        WDAC[&quot;App Control for Business (2017)&quot;]
    end
    AC --&amp;gt; SRP --&amp;gt; WDAC
    US --&amp;gt; PSID --&amp;gt; IL
    GateBeforeRuntime -.-&amp;gt; TokenAtRuntime
    classDef def fill:transparent
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Each generation of Windows code identity pushed the publisher, package, or integrity attribute into the token or into a load-time gate, but the runtime principal stayed the user. The agent-attribution problem is the third instance of this pattern -- the question shifts from &quot;who wrote this code?&quot; to &quot;who instructed this code right now?&quot; but the architectural answer Windows has shipped is the same answer it shipped in 1993.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So a reader who arrived at this article believing Windows must have some way of attributing what an AI agent does, given how much identity machinery has accumulated since 1993, can now see why the belief is wrong. Authenticode signs the file on disk. AppLocker is defense-in-depth. The AppContainer package SID is per-package, not per-role. App Control for Business controls what code runs, not which principal carries the authority once code is loaded. Five generations of layering identity attributes; one user SID at the centre.&lt;/p&gt;
&lt;p&gt;If we take the genealogy seriously and ask what a sixth generation -- a &lt;em&gt;second principal&lt;/em&gt; attached to the process at the kernel layer -- would have to look like, the answer is sitting in an Insider build.&lt;/p&gt;
&lt;h2&gt;4. Six generations, plus the one that hasn&apos;t shipped&lt;/h2&gt;
&lt;p&gt;Read the genealogy as a forcing function and the shape becomes clear. Every generation of Windows app identity was forced by a specific failure of the one before it, and the forced response was never &quot;replace the existing identity model&quot; -- it was always &quot;add an attribute or a sibling principal alongside it.&quot; That conservation rule is what makes Windows identity legible across thirty-three years. It is also what makes the seventh generation visible by its absence.&lt;/p&gt;
&lt;p&gt;The six shipped generations are easy to enumerate.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Generation 1: NT 3.1 primary token (July 27, 1993).&lt;/strong&gt; One primary token per process. The token carries a user SID and a group SID list [@ms-learn-sids; @wiki-nt31]. The runtime principal is the user.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generation 2: Authenticode (August 7, 1996).&lt;/strong&gt; Publisher signature attached to the binary on disk [@ms-news-authenticode-1996]. Runtime token unchanged.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generation 3: SRP, then AppLocker (2001, October 22, 2009).&lt;/strong&gt; Group-Policy execution gates; runtime token unchanged; AppLocker explicitly defense-in-depth, not a defensible boundary [@ms-learn-applocker; @ms-learn-srp-applocker; @wiki-winxp; @wiki-win7].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generation 4: AppContainer and the package SID (October 26, 2012).&lt;/strong&gt; Second principal-shaped SID in the token group list. Access check is the intersection of user and package authority [@ms-learn-appcontainer; @wiki-win8]. Runtime principal is still the user.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generation 5: App Control for Business (2017 onwards).&lt;/strong&gt; Kernel-mode code-integrity policy; defensible boundary; controls what code can run, not which principal carries authority [@ms-learn-appcontrol; @wiki-win10vh].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generation 6: Administrator Protection (late 2025 Insider, iterating through 2026).&lt;/strong&gt; The first shipping Windows feature that mints a true second logon-session principal for a bounded action, gated by a Windows Hello user-verification gesture [@ms-techcomm-adminprot].&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/&quot; rel=&quot;noopener&quot;&gt;Administrator Protection&lt;/a&gt; is the interesting one. The feature surfaced on Windows 11 Insider builds in late 2025; subsequent Insider build iterations have continued through 2026, with a temporary disablement and re-enablement during that window [@ms-techcomm-adminprot]. As of May 2026 it is not yet generally available; the Tech Community announcement page is the canonical reference for the design [@ms-techcomm-adminprot].&lt;/p&gt;
&lt;p&gt;The structural innovation is worth describing precisely. Pre-Administrator-Protection elevation on Windows used split tokens: an administrator user signs in, and the Local Security Authority creates two logon sessions for the same user, one filtered and one full. When the user clicks through the User Account Control prompt, the elevating process swaps its primary token from the filtered to the full session. Both sessions belong to the same user SID; the policy boundary is integrity-level and group-driven, not principal-driven.&lt;/p&gt;
&lt;p&gt;Administrator Protection breaks that. The feature introduces a &lt;em&gt;System-Managed Administrator Account&lt;/em&gt; shadow profile.The internal acronym is SMAA. It does not yet appear in &lt;code&gt;whoami /all&lt;/code&gt; output on shipping builds. When the user authorises an elevation through Windows Hello, the elevated process runs under the separate SMAA logon session, scoped to that elevation [@ms-techcomm-adminprot]. The Hello gesture is the verification step; the separate session is the new principal; the bound is the single elevated action.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Every generation of Windows app identity has been forced by a specific failure of the previous generation, and every forced response added an attribute or a sibling principal alongside the existing one -- but until Administrator Protection (Generation 6, Insider in 2026, not yet generally available), no shipping Windows feature minted a true second principal for a bounded action.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Administrator Protection is the existence proof. Windows &lt;em&gt;can&lt;/em&gt; mint a second logon-session principal for a bounded action under a user-verification gesture. The architectural question this article asks: can the same pattern generalise from elevation to delegation?&lt;/p&gt;

flowchart TD
    G1[&quot;Gen 1: NT 3.1 primary token (1993). User SID only.&quot;]
    G2[&quot;Gen 2: Authenticode (1996). Publisher attached to binary.&quot;]
    G3[&quot;Gen 3: SRP and AppLocker (2001, 2009). Execution gates.&quot;]
    G4[&quot;Gen 4: AppContainer and package SID (2012). Second SID in token.&quot;]
    G5[&quot;Gen 5: App Control for Business (2017+). Kernel-mode CI.&quot;]
    G6[&quot;Gen 6: Administrator Protection (late 2025 Insider). Second logon session for elevation.&quot;]
    G7[&quot;Gen 7 (missing): AgentPrincipal. Second logon session for delegation.&quot;]
    G1 --&amp;gt; G2 --&amp;gt; G3 --&amp;gt; G4 --&amp;gt; G5 --&amp;gt; G6 -.-&amp;gt; G7
&lt;p&gt;The missing seventh generation is what this article is about. It exists at the cloud layer. Microsoft&apos;s Entra Agent ID has been in public preview since May 19, 2025 [@ms-security-blog-agentid] and was the centrepiece of the Ignite 2025 expansion that Microsoft itself called &quot;the largest expansion of Microsoft Entra capabilities to date, extending Zero Trust principles to AI workloads&quot; [@ms-learn-ignite25]. The FIDO Alliance has named the wire-format design space [@fido-aatwg-pr]. The IETF has an individual draft for the OAuth wire format [@ietf-draft-agentoauth]. The OS layer does not have an analog.&lt;/p&gt;
&lt;p&gt;If Generation 6 is the existence proof at the OS layer, what just happened at the cloud layer that finally makes the delegation case unavoidable?&lt;/p&gt;
&lt;h2&gt;5. April 28, 2026: the wire format goes public&lt;/h2&gt;
&lt;p&gt;April 28, 2026. The FIDO Alliance press release crosses the wire. &lt;em&gt;FIDO Alliance to Develop Standards for Trusted AI Agent Interactions&lt;/em&gt; [@fido-aatwg-pr]. The opening sentence is the inflection point: &quot;The FIDO Alliance today announced initiatives to develop interoperable standards for agentic interactions and commerce.&quot; Andrew Shikiar, FIDO Alliance CEO, is the launch spokesperson. The BusinessWire mirror under wire ID &lt;code&gt;20260427506015&lt;/code&gt; carries the same text [@fido-aatwg-bw], and independent press coverage from HelpNetSecurity (April 29, 2026) [@helpnetsecurity-aatwg] and PPC Land [@ppcland-aatwg] corroborate the launch.&lt;/p&gt;
&lt;p&gt;Four interlocking pieces of news land in the same press release.&lt;/p&gt;
&lt;h3&gt;5.1 The three AATWG pillars&lt;/h3&gt;
&lt;p&gt;The Agentic Authentication Technical Working Group is chartered around three pillars [@fido-aatwg-pr]. The press release wording is verbatim because the wording is what every downstream protocol will quote.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Verifiable User Instructions.&lt;/strong&gt; &quot;Enabling users to authorise AI agents through clear, phishing-resistant mechanisms so agents only perform approved actions, including transactions, without exposing credentials&quot; [@fido-aatwg-pr]. The wire-format primitive: a passkey-signed delegation token bound to a specific intent (&quot;approve $50 to vendor X&quot;), with replay protection and a short TTL.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent Authentication.&lt;/strong&gt; &quot;Allowing services to verify that an AI agent is acting on behalf of an authenticated user and within defined parameters, distinguishing legitimate agents from unauthorised actors&quot; [@fido-aatwg-pr]. The wire-format primitive: an attestation binding an agent class (optionally a specific instance) to a verifiable identity assertion.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trusted Delegation for Commerce.&lt;/strong&gt; &quot;Defining how agent-initiated transactions can be executed within user-controlled boundaries, with verifiable authorisation&quot; [@fido-aatwg-pr]. The wire-format primitive: the AP2 mandate or Verifiable Intent SD-JWT chain binding an agent action to a user-approved scope and constraint set.&lt;/li&gt;
&lt;/ul&gt;

The FIDO Alliance today announced initiatives to develop interoperable standards for agentic interactions and commerce ... Verifiable User Instructions ... Agent Authentication ... Trusted Delegation for Commerce. -- FIDO Alliance press release, April 28, 2026 [@fido-aatwg-pr]
&lt;h3&gt;5.2 The governance&lt;/h3&gt;
&lt;p&gt;The taxonomy matters because over-attribution is one of the easier mistakes to make in this story. AATWG chairs are CVS Health, Google, and OpenAI; vice-chairs are Amazon, Google, and Okta; the parallel Payments Technical Working Group is chaired by Mastercard and Visa [@fido-aatwg-pr]. Co-sponsors include OpenAI, Amazon, Okta, CVS Health, Visa, and Proof, plus the donating partners (Google, Mastercard). Proof Inc.&apos;s &lt;em&gt;Know Your Agent&lt;/em&gt; framework is a separate Sponsor-tier contribution to FIDO; it is not an AATWG chair or vice-chair role.&lt;/p&gt;
&lt;h3&gt;5.3 The foundational donations&lt;/h3&gt;
&lt;p&gt;Google&apos;s Agent Payments Protocol (AP2) and Mastercard&apos;s Verifiable Intent framework are the foundational donations [@ap2-blog-google; @mastercard-vi]. AP2 was open-sourced on September 16, 2025 [@ap2-cloud-blog] at &lt;code&gt;github.com/google-agentic-commerce/AP2&lt;/code&gt; under Apache 2.0 [@ap2-github]; v0.2 shipped alongside the FIDO donation, with the v0.2 release notes calling out &quot;Human Not Present&quot; payments [@ap2-blog-google]. Mastercard&apos;s Verifiable Intent specification is hosted at verifiableintent.dev as Draft v0.1, describing a three-layer SD-JWT delegation chain (Identity, Intent, Action) with eight constraint types -- amount bounds, merchant allow-lists, budget caps, recurrence terms -- &quot;cryptographically bound and machine-verifiable&quot; [@vi-dev]. The underlying credential model is the W3C Verifiable Credentials Data Model v2.0 W3C Recommendation [@w3c-vc-2].&lt;/p&gt;
&lt;p&gt;The mandate vocabulary drifted between the September 2025 AP2 launch and the v0.2 release. The launch announcement at cloud.google.com described &quot;Intent / Cart / Payment&quot; mandates [@ap2-cloud-blog]; the current ap2-protocol.org spec describes &quot;Checkout (Open / Closed) + Payment (Open / Closed)&quot; [@ap2-protocol]. Readers diffing the September 2025 blog against the April 2026 spec should expect the vocabulary, not the underlying primitives, to have changed.&lt;/p&gt;
&lt;h3&gt;5.4 The Microsoft parallel&lt;/h3&gt;
&lt;p&gt;Microsoft has been on the same arc for nearly a year. The Build 2025 security blog, dated May 19, 2025, introduced Microsoft Entra Agent ID in public preview: &quot;We are excited to introduce Microsoft Entra Agent ID, which extends identity management and access capabilities to AI agents&quot; [@ms-security-blog-agentid]. The Workday Agent System of Record and ServiceNow AI Platform integrations announced on September 16, 2025 made Entra Agent ID a directory service for agents across two of the largest enterprise SaaS platforms [@prnewswire-workday]. The Ignite 2025 expansion (November 2025) was, in Microsoft&apos;s own framing, &quot;the largest expansion of Microsoft Entra capabilities to date, extending Zero Trust principles to AI workloads&quot; [@ms-learn-ignite25]; the agent OAuth protocol trio shipped at the same time [@ms-learn-agentoauth], and Conditional Access for agent identities followed into preview in early 2026 [@ms-learn-caagent]. WinBuzzer (May 20, 2025) corroborates the public-preview launch [@winbuzzer-agentid].&lt;/p&gt;

flowchart LR
    P1[&quot;Pillar 1: Verifiable User Instructions&quot;]
    P2[&quot;Pillar 2: Agent Authentication&quot;]
    P3[&quot;Pillar 3: Trusted Delegation for Commerce&quot;]
    W1[&quot;Wire: passkey-signed delegation token, intent-bound, short TTL&quot;]
    W2[&quot;Wire: attestation + identity assertion, agent class or instance&quot;]
    W3[&quot;Wire: AP2 mandate or Verifiable Intent SD-JWT chain&quot;]
    P1 --&amp;gt; W1
    P2 --&amp;gt; W2
    P3 --&amp;gt; W3
&lt;p&gt;So the reader&apos;s understanding shifts. Before April 28, 2026 the easy mental model was that AI agents were a product feature, not an identity question. After the FIDO press release the design space is named, governed, and partially specified on the wire. The further shift drives the rest of the article: &lt;em&gt;the cloud layer is no longer the gap&lt;/em&gt;. Entra Agent ID has shipped a directory; OAuth Token Exchange has had the &lt;code&gt;act&lt;/code&gt; and &lt;code&gt;may_act&lt;/code&gt; claims standardised since January 2020 [@ietf-rfc-8693]; the MCP authorisation profile has its 2025-11-25 revision live [@anthropic-mcp-2025-11-25]; AP2 and Verifiable Intent are now under FIDO governance.&lt;/p&gt;
&lt;p&gt;The gap is on the desktop. So if we take the three pillars seriously, which Windows primitive does each pillar already have a substrate for, and which Windows primitive is missing?&lt;/p&gt;
&lt;h2&gt;6. Mapping the three pillars onto Windows primitives&lt;/h2&gt;
&lt;p&gt;One section. Three sub-sections, one per pillar. For each: the existing Windows primitive, the API surface that exposes it, and the missing glue that turns it into a pillar-compatible building block.&lt;/p&gt;
&lt;h3&gt;6.1 Pillar 1: Verifiable User Instructions on Windows&lt;/h3&gt;
&lt;p&gt;The substrate exists in user mode and lives in &lt;code&gt;webauthn.dll&lt;/code&gt;, the &lt;a href=&quot;https://paragmali.com/blog/webauthn-and-passkeys-on-windows-from-ctap-to-the-credential/&quot; rel=&quot;noopener&quot;&gt;Win32 platform-authenticator entry point&lt;/a&gt;. Microsoft Learn describes it verbatim: &quot;Provides Win32 apps with APIs for communicating to Windows Hello and external security keys as part of WebAuthN and CTAP specifications&quot; [@ms-learn-webauthn-api]. Windows Hello provides the TPM-rooted user-verification gesture: &quot;credentials are asymmetric and generated within isolated environments of TPMs&quot; [@ms-learn-hello]. The credential provider model in Winlogon, the passkey provider plug-in model in Windows 11 24H2, and per-relying-party passkey isolation in Windows Hello for Business round out the platform-authenticator surface.&lt;/p&gt;
&lt;p&gt;What is missing is a Windows-native &lt;em&gt;agent action approval&lt;/em&gt; UI surface. Today&apos;s pieces let a relying party in the browser ask the user to authenticate to that relying party; they do not let a locally-installed agent ask the user to authorise a specific action (&quot;approve $50 to vendor X&quot;; &quot;approve &lt;code&gt;rm -rf .\old-builds&lt;/code&gt;&quot;) by minting a per-action, intent-bound delegation token signed by the user&apos;s passkey with replay protection and a TTL measured in seconds. The Pillar 1 wire format AATWG is developing is exactly this kind of token; the Windows-side glue would land it as a system UI surface (analogous to UAC, but minting a passkey assertion rather than escalating an integrity level), wired into the WebAuthn platform authenticator and audited via ETW.&lt;/p&gt;

The Windows-resident OAuth token broker that ships with the operating system. WAM acts as an authentication broker on Windows 10 1703 and later; &quot;WAM ensures that the refresh tokens are device bound and enables apps to acquire device bound access tokens&quot; [@ms-learn-wam]. WAM is the on-device credential broker for Microsoft Entra ID; it does not work with third-party identity providers as of May 2026.
&lt;h3&gt;6.2 Pillar 2: Agent Authentication on Windows&lt;/h3&gt;
&lt;p&gt;The kernel substrate is AppContainer plus the package SID. The verbatim Microsoft Learn dual-principal model is the load-bearing citation: &quot;the permitted access is the intersection of that granted by the user/group SIDs and AppContainer SIDs&quot; [@ms-learn-appcontainer]. The cryptographic binding from binary to package is Authenticode signing the file [@ms-news-authenticode-1996; @wikipedia-codesign] and App Control for Business as the policy gating the loader [@ms-learn-appcontrol]. The privacy-preserving agent-class attestation primitive is &lt;a href=&quot;https://paragmali.com/blog/direct-anonymous-attestation-the-zero-knowledge-proof-alread/&quot; rel=&quot;noopener&quot;&gt;Direct Anonymous Attestation&lt;/a&gt;, defined in the TPM 2.0 Library Specification by the Trusted Computing Group; the corpus&apos;s sibling DAA article describes the protocol in detail, and the verbatim TCG specification language is sourced there.&lt;/p&gt;

A TPM 2.0 protocol that lets a device prove membership in a privacy-preserving group without revealing the specific device identity. In the agent setting, DAA would let an agent vendor prove &quot;this binary is a member of the *signed Claude Desktop* class&quot; without revealing which specific desktop installation is making the call. The protocol&apos;s group-signature mathematics is the load-bearing primitive.
&lt;p&gt;What is missing on Windows is a kernel-recognised &lt;code&gt;AgentPrincipal&lt;/code&gt; that downstream consumers treat as first-class. Today the package SID is the closest signal; it is also category-incorrect, because the package SID represents a package, not an agent role. An &lt;code&gt;AgentPrincipal&lt;/code&gt; would be a third token-resident SID alongside the user SID and the package SID, with its own ACL slot in opt-in DACLs, its own &lt;code&gt;SubjectAgentSid&lt;/code&gt; field in &lt;code&gt;SeAccessCheck&lt;/code&gt; audit events, its own ETW header alongside &lt;code&gt;SubjectUserSid&lt;/code&gt;, its own RPC binding-handle metadata, and its own claim in the access tokens WAM mints. Defender, EDR, on-device Conditional Access -- every consumer that today reads the user SID would gain a sibling field.&lt;/p&gt;

The dominant deployment pattern for AI agents on Windows desktops in May 2026 is Electron plus an NSIS or MSI per-user installer, not MSIX plus the AppContainer kernel substrate. Claude Desktop, ChatGPT Desktop, and Cursor all ship through this Electron path; GitHub Copilot CLI ships as a Node.js CLI via npm (`@github/copilot`), WinGet (`GitHub.Copilot`), or an MSI installer from the github/copilot-cli GitHub Releases page, which is a different non-MSIX-packaged path but is structurally equivalent for the purposes of this article -- no package SID, no AppContainer kernel substrate, primary token traces to the user. Each of them runs under the user&apos;s primary token without a package SID; the WebAuthn platform authenticator is available to them via `webauthn.dll`, but the kernel-substrate dual-principal model under AppContainer is not.&lt;p&gt;Win32 App Isolation, announced in public preview on June 14, 2023, is the in-flight retrofit. The launch blog describes it directly: &quot;We are thrilled to announce the public preview launch of Win32 app isolation ... Win32 app isolation is built on the foundation of AppContainers ... AppContainer, which is recognized as a security boundary by Microsoft&quot; [@ms-blogs-win32appiso]. Adoption among agent vendors three years later is minimal; the Pillar 2 substrate exists, but the deployment substrate that would carry it does not.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;6.3 Pillar 3: Trusted Delegation for Commerce on Windows&lt;/h3&gt;
&lt;p&gt;The act-on-behalf-of primitive on Windows is &lt;a href=&quot;https://paragmali.com/blog/kerberos-in-windows-the-other-half-of-ntlmless/&quot; rel=&quot;noopener&quot;&gt;Kerberos S4U2Self and S4U2Proxy&lt;/a&gt;, formally specified in Microsoft&apos;s MS-SFU Kerberos Protocol Extensions [@ms-learn-mssfu]. S4U2Self lets a service obtain a service ticket for a user without that user&apos;s password (the &quot;for&quot; half); S4U2Proxy lets the service then present that ticket to a back-end service on the user&apos;s behalf (the &quot;proxy&quot; half). Resource-Based Constrained Delegation is the modern policy form: the back-end service authors which front-end services may delegate to it. Protected Users, Authentication Policies, and Authentication Silos are the policy plumbing. WAM is the on-device token broker for Entra-side delegation [@ms-learn-wam]; Microsoft&apos;s OAuth 2.0 On-Behalf-Of flow [@ms-learn-obo-flow] is the cloud analog.&lt;/p&gt;

Microsoft&apos;s Kerberos Protocol Extensions, formalised in MS-SFU, that let a server obtain a service ticket on behalf of a user without that user&apos;s password (S4U2Self) and then present that ticket to a back-end service (S4U2Proxy). They are the act-on-behalf-of primitive on Windows [@ms-learn-mssfu]. Resource-Based Constrained Delegation refines the policy: the back-end resource names the front-end services it accepts delegation from.
&lt;p&gt;What is missing is a Macaroons-style mintable, attenuable, revocable capability-token format scoped to a per-tool allow-list. Macaroons were introduced by Birgisson, Politz, Erlingsson, Taly, Vrable, and Lentczner at NDSS 2014 (February 22, 2014) [@macaroons-ndss; @macaroons-gr]. The verbatim positioning from the Google Research abstract is the load-bearing description: &quot;macaroons are bearer credentials, like Web cookies, macaroons embed caveats that attenuate and contextually confine when, where, by who, and for what purpose a target service should authorize requests&quot; [@macaroons-gr]. The construction is a chained HMAC: a fresh HMAC of the previous HMAC plus a caveat. Any holder can append a caveat, derive a strictly weaker macaroon, and present it to a verifier; the verifier walks the chain, checks each caveat against its policy, and verifies the final HMAC against the issuer&apos;s secret.&lt;/p&gt;

Birgisson, Politz, Erlingsson, Taly, Vrable, and Lentczner at NDSS 2014 [@macaroons-ndss]. A bearer credential constructed as a chained HMAC over caveats; any holder can derive a strictly weaker credential by appending a caveat without round-tripping the issuer, but cannot derive a stronger one. The attenuation property is what makes macaroons the natural format for per-tool agent capabilities [@macaroons-gr].
&lt;p&gt;In a Windows-shipping Pillar 3 implementation, the agent would not present the user&apos;s TGT to a downstream tool. The agent would present a macaroon issued at agent-install time -- attenuated to the specific tools the user authorised through a Pillar 1 Verifiable User Instructions flow -- and the tool would verify the macaroon plus an ETW emission carrying both &lt;code&gt;SubjectUserSid&lt;/code&gt; and &lt;code&gt;SubjectAgentSid&lt;/code&gt;. Revocation would land at the issuer (the WAM-resident macaroon authority), with a Continuous Access Evaluation analog fanning out to local token caches without logging the user out.&lt;/p&gt;

flowchart LR
    subgraph P1G[&quot;Pillar 1: Verifiable User Instructions&quot;]
        P1S[&quot;Substrate: webauthn.dll, Windows Hello, passkey provider&quot;]
        P1M[&quot;Missing: agent-action approval UI minting intent-bound delegation tokens&quot;]
        P1S --&amp;gt; P1M
    end
    subgraph P2G[&quot;Pillar 2: Agent Authentication&quot;]
        P2S[&quot;Substrate: AppContainer package SID, Authenticode, App Control, TPM 2.0 DAA, Pluton&quot;]
        P2M[&quot;Missing: kernel-recognised AgentPrincipal across SeAccessCheck, ETW, RPC, Defender, CA&quot;]
        P2S --&amp;gt; P2M
    end
    subgraph P3G[&quot;Pillar 3: Trusted Delegation for Commerce&quot;]
        P3S[&quot;Substrate: Kerberos S4U2Proxy, RBCD, WAM, OBO flow, ETW&quot;]
        P3M[&quot;Missing: Macaroons-style attenuable capability tokens plus AgentPrincipalSid in ETW&quot;]
        P3S --&amp;gt; P3M
    end
&lt;p&gt;The proposed access-check sequence is the second load-bearing diagram. Picture an agent in its own AppContainer, with its own package SID, holding a macaroon scoped to one tool. The agent calls the tool; WAM intercepts; if the action requires fresh user verification, Hello mints a passkey assertion; &lt;code&gt;SeAccessCheck&lt;/code&gt; evaluates user SID, package SID, and the proposed agent SID; ETW emits the dual-principal record.&lt;/p&gt;

sequenceDiagram
    participant Agent as Agent process
    participant WAM as WAM broker
    participant Hello as Windows Hello
    participant Kernel as SeAccessCheck
    participant ETW as ETW provider
    Agent-&amp;gt;&amp;gt;WAM: request tool access with macaroon
    WAM-&amp;gt;&amp;gt;WAM: verify macaroon chain
    WAM-&amp;gt;&amp;gt;Hello: if intent required, mint fresh assertion
    Hello--&amp;gt;&amp;gt;WAM: passkey assertion
    WAM-&amp;gt;&amp;gt;Kernel: assemble token (user SID, package SID, agent SID)
    Kernel-&amp;gt;&amp;gt;Kernel: access check with three principals
    Kernel--&amp;gt;&amp;gt;Agent: granted or denied
    Kernel-&amp;gt;&amp;gt;ETW: emit dual-principal record
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pillar&lt;/th&gt;
&lt;th&gt;Windows substrate that already ships&lt;/th&gt;
&lt;th&gt;API surface&lt;/th&gt;
&lt;th&gt;Missing glue&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;1: Verifiable User Instructions&lt;/td&gt;
&lt;td&gt;&lt;code&gt;webauthn.dll&lt;/code&gt;, Windows Hello, passkey provider&lt;/td&gt;
&lt;td&gt;Win32 WebAuthn API; Hello credential provider&lt;/td&gt;
&lt;td&gt;Agent-action approval UI; intent-bound passkey delegation tokens with short TTL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2: Agent Authentication&lt;/td&gt;
&lt;td&gt;AppContainer + package SID, Authenticode + App Control, TPM 2.0 DAA, Pluton attestation&lt;/td&gt;
&lt;td&gt;NtCreateLowBoxToken; LSASS package-SID assignment; TPM attestation&lt;/td&gt;
&lt;td&gt;Kernel-recognised &lt;code&gt;AgentPrincipal&lt;/code&gt; across &lt;code&gt;SeAccessCheck&lt;/code&gt;, ETW, RPC, Defender, on-device CA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3: Trusted Delegation for Commerce&lt;/td&gt;
&lt;td&gt;Kerberos S4U2Self/S4U2Proxy, RBCD, WAM, OBO flow, ETW&lt;/td&gt;
&lt;td&gt;MS-SFU; MSAL WAM broker; Entra OBO token endpoint&lt;/td&gt;
&lt;td&gt;Macaroons-style per-tool capability tokens; &lt;code&gt;AgentPrincipalSid&lt;/code&gt; ETW field; CAE-style fan-out for revocation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Deployment pattern&lt;/th&gt;
&lt;th&gt;Token at runtime&lt;/th&gt;
&lt;th&gt;Where DPAPI lives&lt;/th&gt;
&lt;th&gt;Network privilege&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Non-MSIX user-mode (Claude Desktop / Cursor / ChatGPT Desktop: Electron + NSIS; Copilot CLI: Node.js + npm / WinGet / MSI)&lt;/td&gt;
&lt;td&gt;User primary token; no package SID&lt;/td&gt;
&lt;td&gt;User DPAPI scope (decryptable by any process under the same user)&lt;/td&gt;
&lt;td&gt;Full user network privilege; user TGT available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MSIX-packaged AppContainer (Microsoft Copilot for Windows)&lt;/td&gt;
&lt;td&gt;LowBox token with package SID; integrity level usually Low&lt;/td&gt;
&lt;td&gt;Per-package DPAPI scope (isolated from other packages)&lt;/td&gt;
&lt;td&gt;Capability-gated network egress per app manifest&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;So the substrate is largely on the box. The glue is not. What competing approaches already ship -- and which one wins?&lt;/p&gt;
&lt;h2&gt;7. Where the principal lives: three positions&lt;/h2&gt;
&lt;p&gt;Three architectural positions are already shipping enough code that &quot;which one wins&quot; is a real question. Each picks a different layer to host the agent principal: the cloud, the operating system, or the on-device token broker.&lt;/p&gt;
&lt;h3&gt;7.1 Cloud-only&lt;/h3&gt;
&lt;p&gt;Agent identity lives in the identity provider. Microsoft&apos;s Entra Agent ID is the reference design: agents are first-class directory objects, with their own client credentials, sign-in logs, Conditional Access policies, and audit trail in Purview [@ms-learn-agentid]. When an agent needs to call a back-end API on a user&apos;s behalf, it uses RFC 8693 Token Exchange [@ietf-rfc-8693] or Microsoft&apos;s OAuth 2.0 On-Behalf-Of flow [@ms-learn-obo-flow] to exchange the user&apos;s token for an actor-claim-carrying access token; the back-end API consumes the &lt;code&gt;act&lt;/code&gt; and &lt;code&gt;may_act&lt;/code&gt; claims to attribute the call.&lt;/p&gt;
&lt;p&gt;Pros: works today, no kernel change, no Windows update required. The plumbing is fully specified at IETF [@ietf-rfc-8693; @ietf-rfc-9728; @ietf-oauth-v2-1], the Microsoft documentation is live [@ms-learn-agentoauth; @ms-learn-agentobo], and the directory exists [@ms-learn-agentid]. Cons: the OS never sees an agent principal. Every local file action, every DPAPI decrypt, every Kerberos ticket use, every RPC call inside the device collapses to the user identity. On-device endpoint detection cannot attribute. Continuous Access Evaluation knows the agent has been revoked in the cloud but cannot purge the user&apos;s local Kerberos cache or local DPAPI-protected secrets without logging the user out.&lt;/p&gt;
&lt;p&gt;Microsoft Learn makes the cloud-only constraint explicit: &quot;Agents aren&apos;t supported for OBO (&lt;code&gt;/authorize&lt;/code&gt;) flows. Supported grant types are &lt;code&gt;client_credential&lt;/code&gt;, &lt;code&gt;jwt-bearer&lt;/code&gt;, and &lt;code&gt;refresh_token&lt;/code&gt;&quot; [@ms-learn-agentobo]. Agent identities are confidential clients only [@ms-learn-agentoauth]; the interactive-flow path used by browser-based delegation is not available to agent entities. Cloud-only works precisely because the agent never tries to participate in a desktop user-verification gesture. AzureFeeds (January 28, 2026) records the practical consequences for Conditional Access: agent authentication is &quot;purely machine-driven&quot; with no MFA prompt, no device check, and no authentication-strength evaluation [@azurefeeds-caagent].&lt;/p&gt;
&lt;h3&gt;7.2 OS-only&lt;/h3&gt;
&lt;p&gt;Hypothetical, not shipping. The kernel access-check, ETW, and RPC ACLs all carry an agent SID distinct from the user SID. Every event the kernel emits gets a &lt;code&gt;SubjectAgentSid&lt;/code&gt; field next to the existing &lt;code&gt;SubjectUserSid&lt;/code&gt;. The access check is a three-way intersection: user SID, package SID, agent SID. Capability SIDs gate per-resource consent the way they do today for UWP apps.&lt;/p&gt;
&lt;p&gt;Pros: native attribution at every layer. EDR products read the agent SID directly from the kernel-supplied event header. File-system DACLs gain an explicit &quot;deny the agent, allow the user&quot; expression. On-device Conditional Access can refuse to release a DPAPI-protected secret if the requesting process carries an agent SID that has been revoked in Entra. Cons: requires a kernel-level change and a packaging story for non-MSIX agents (Electron in particular, the dominant deployment pattern). Without the packaging story, the kernel substrate exists but the deployment substrate does not.&lt;/p&gt;
&lt;h3&gt;7.3 Token broker&lt;/h3&gt;
&lt;p&gt;WAM extended with an agent-scoped token cache. The OS holds agent-scoped, attenuable tokens that any local agent process must mint from before calling a downstream API. The principal in the OS is still the user, but the &lt;em&gt;token&lt;/em&gt; the agent presents to each downstream consumer is scoped to the agent.&lt;/p&gt;
&lt;p&gt;Pros: reuses existing WAM plumbing [@ms-learn-wam]. WAM already binds refresh tokens to the device&apos;s TPM. Adding an agent-scope cache is plumbing, not architecture. Cons: cooperative. A malicious or buggy agent can bypass the broker and fall back to the user&apos;s TGT in the local Kerberos cache, the user&apos;s DPAPI master keys, or the user&apos;s network privileges. The broker can only attribute the agents that choose to be attributed.&lt;/p&gt;

A bearer OAuth access token, in OAuth 2.0 and OAuth 2.1, is a credential the bearer presents to a resource server; the server consults the issuer (via introspection or JWT signature verification) and accepts or rejects. Adding a new constraint means going back to the authorisation server and asking for a new token with the new constraint applied. Round-trip required.&lt;p&gt;A macaroon attenuates without a round-trip. The holder appends a caveat (&quot;only for tool X&quot;, &quot;only until 2026-05-25T15:00:00Z&quot;, &quot;only with body hash matching &lt;code&gt;sha256:...&lt;/code&gt;&quot;) and a fresh HMAC of the previous HMAC plus the caveat text. The verifier walks the chain, checks each caveat against its policy, and verifies the final HMAC against the issuer&apos;s secret. The holder cannot un-attenuate; the issuer does not have to be online. That property -- attenuation without a round-trip, by any party in the chain -- is what makes macaroons the natural format for per-tool agent capabilities [@macaroons-ndss; @macaroons-gr].
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;7.4 Three live spec families that complicate the picture&lt;/h3&gt;
&lt;p&gt;Three protocol families are racing in parallel and the article will not pretend any one is the obvious winner.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Anthropic&apos;s Model Context Protocol authorisation profile.&lt;/strong&gt; Revision 2025-11-25 is the current authoritative profile [@anthropic-mcp-2025-11-25], and the MCP specification index confirms 2025-11-25 as the latest pointer [@anthropic-mcp-index]. The opening sentence makes the design choice explicit: &quot;Authorization is OPTIONAL for MCP implementations. When supported: Implementations using an HTTP-based transport SHOULD conform to this specification. Implementations using an STDIO transport SHOULD NOT follow this specification, and instead retrieve credentials from the environment&quot; [@anthropic-mcp-2025-11-25]. The HTTP profile is OAuth 2.1 [@ietf-oauth-v2-1] plus RFC 9728 [@ietf-rfc-9728] for resource metadata, with PKCE mandatory and dynamic client registration optional.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google AP2 plus Mastercard Verifiable Intent.&lt;/strong&gt; The W3C Verifiable Credential-shaped mandate ladder for agent-initiated commerce [@ap2-protocol; @ap2-github; @ap2-cloud-blog; @vi-dev; @w3c-vc-2]. The September 2025 launch vocabulary used Intent / Cart / Payment mandates [@ap2-cloud-blog]; the current v0.2 spec uses Checkout (Open / Closed) and Payment (Open / Closed) [@ap2-protocol]. The April 28, 2026 FIDO donation moves the spec to multi-vendor governance [@ap2-blog-google].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The IETF individual draft for agents on behalf of users.&lt;/strong&gt; &lt;code&gt;draft-oauth-ai-agents-on-behalf-of-user&lt;/code&gt; by Thilina Senarath and Ayesha Dissanayaka [@ietf-draft-agentoauth]. The current revision introduces the &lt;code&gt;requested_actor&lt;/code&gt; parameter in authorisation requests and the &lt;code&gt;actor_token&lt;/code&gt; parameter in token requests to authenticate the agent during code-to-token exchange [@ietf-draft-agentoauth]. The original -00 revision used &lt;code&gt;requested_agent&lt;/code&gt; and defined an explicit grant type &lt;code&gt;urn:ietf:params:oauth:grant-type:agent-authorization_code&lt;/code&gt; [@ietf-draft-agentoauth-00]; the parameter rename is documented and recent. The draft is an individual submission, not yet a working-group document.&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Position&lt;/th&gt;
&lt;th&gt;Principal lives in&lt;/th&gt;
&lt;th&gt;Token format&lt;/th&gt;
&lt;th&gt;Revocation surface&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Cloud-only (Entra Agent ID + RFC 8693)&lt;/td&gt;
&lt;td&gt;Entra directory&lt;/td&gt;
&lt;td&gt;JWT with &lt;code&gt;act&lt;/code&gt; claim&lt;/td&gt;
&lt;td&gt;Sign-in policy + CAE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OS-only (hypothetical AgentPrincipal)&lt;/td&gt;
&lt;td&gt;Kernel access token&lt;/td&gt;
&lt;td&gt;Token-resident SID&lt;/td&gt;
&lt;td&gt;Local SID purge + Defender&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Token broker (WAM extended)&lt;/td&gt;
&lt;td&gt;WAM cache (TPM-bound)&lt;/td&gt;
&lt;td&gt;Macaroon or signed capability&lt;/td&gt;
&lt;td&gt;WAM eviction + macaroon allow-list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP authorisation profile&lt;/td&gt;
&lt;td&gt;MCP server&apos;s IdP&lt;/td&gt;
&lt;td&gt;OAuth 2.1 bearer&lt;/td&gt;
&lt;td&gt;OAuth introspection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AP2 plus Verifiable Intent&lt;/td&gt;
&lt;td&gt;Mandate issuer&lt;/td&gt;
&lt;td&gt;SD-JWT VC chain&lt;/td&gt;
&lt;td&gt;Mandate revocation registry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IETF agent-OBO draft&lt;/td&gt;
&lt;td&gt;Authorisation server&lt;/td&gt;
&lt;td&gt;JWT with &lt;code&gt;actor_token&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OAuth introspection&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Most of the primitives exist on Windows today: AppContainer package SIDs, Kerberos S4U2Proxy, WebAuthn and Windows Hello, TPM 2.0 Direct Anonymous Attestation, the Administrator-Protection separate-session pattern, WAM, ETW. What does not exist is the coherent glue -- a kernel-recognised &lt;code&gt;AgentPrincipal&lt;/code&gt; that downstream consumers treat as first-class. The article&apos;s position is that agent identity belongs at both the cloud layer and the OS layer, with the OS layer being the missing piece in May 2026. The cloud layer makes Conditional Access work; the OS layer makes endpoint detection work; both are necessary; neither is sufficient.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Even the union of all three positions has structural ceilings. What are the limits no engineering can buy?&lt;/p&gt;
&lt;h2&gt;8. Three ceilings no engineering can buy&lt;/h2&gt;
&lt;p&gt;Three structural ceilings constrain every agent-attribution architecture, regardless of which of the three positions wins.&lt;/p&gt;
&lt;h3&gt;8.1 The semantic-intent ceiling&lt;/h3&gt;
&lt;p&gt;No cryptographic primitive can distinguish &quot;the user wanted the agent to delete this file&quot; from &quot;the user wanted to delete this file&quot; once both calls go through the same syscall. The OS sees bytes, not intent. The strongest architecture binds each intent to a fresh user-verification gesture (passkey plus Hello); at the limit, this requires one gesture per syscall, which is operationally unusable. The practical optimum is &lt;em&gt;batched intent&lt;/em&gt; traded off against &lt;em&gt;granularity of audit&lt;/em&gt;: the user authorises a session-scoped delegation (&quot;for the next 20 minutes, this agent may modify files under &lt;code&gt;.\old-builds&lt;/code&gt;&quot;), the system mints a macaroon attenuated to that scope, and the audit log records the macaroon issuance plus every syscall it gates. The intent is bounded by the scope of the gesture; the audit reconstructs intent after the fact from scope plus action.&lt;/p&gt;
&lt;h3&gt;8.2 The Confused-Deputy ceiling&lt;/h3&gt;
&lt;p&gt;Hardy 1988, in the verbatim formulation that began the genealogy. &quot;The fundamental problem is that the compiler runs with authority stemming from two sources. (That&apos;s why the compiler is a confused deputy.) ... The compiler had no way of expressing these intents!&quot; [@hardy-caplore]. Any system that grants a deputy ambient authority -- authority derived from multiple sources without the deputy being able to name &lt;em&gt;which&lt;/em&gt; authority it intends to exercise for a given action -- is structurally susceptible to confused-deputy attacks. Capability-style attenuation (macaroons, capability SIDs in AppContainer) mitigates by forcing the deputy to name the authority on every call; it does not eliminate, because a deputy that holds two authorities can be tricked into presenting the wrong one if the protocol does not require the relying party to verify the intent.&lt;/p&gt;
&lt;h3&gt;8.3 The &quot;running as the user&quot; ceiling and the MSRC servicing-criteria rule&lt;/h3&gt;
&lt;p&gt;As long as the agent process runs under the user&apos;s primary token, the agent inherits the user&apos;s TGT, the user&apos;s DPAPI master keys, and the user&apos;s network privileges by construction. That inheritance is what makes attribution collapse. The proposed remedy in Section 6 is an &lt;code&gt;AgentPrincipal&lt;/code&gt; that lives next to the user SID in the same token. The remedy depends on whether the Windows Security Response Center treats user-versus-agent as a defended security boundary.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://paragmali.com/blog/windows-security-boundaries-the-document-that-decides-what-g/&quot; rel=&quot;noopener&quot;&gt;MSRC servicing criteria document&lt;/a&gt; defines the boundary taxonomy. The verbatim opening: &quot;Does the vulnerability violate the goal or intent of a security boundary or a security feature? ... A security boundary provides a logical separation between the code and data of security domains with different levels of trust&quot; [@ms-msrc-servicing]. The same document gives the kernel-mode-versus-user-mode separation as the canonical example of a security boundary, and that example is the article&apos;s anchor for what counts as a security boundary under current MSRC policy. By inference from the boundary taxonomy table, &lt;em&gt;within the same logon session and the same primary token&lt;/em&gt;, a defect that requires the attacker to already be running as the user does not, by default, constitute a violation of a security boundary -- it is, under the criteria, a defense-in-depth concern rather than a CVE-eligible servicing event.&lt;/p&gt;

The MSRC document is the governance object that fixes the rule. For an OS-level `AgentPrincipal` to be a defensible boundary -- and therefore for an agent-bypass to qualify as a CVE-eligible servicing event -- the document itself would have to be amended to add the user-versus-agent split to the boundary taxonomy.&lt;p&gt;That is not an engineering ask. It is a governance ask. Microsoft has amended the document before (AppContainer was added to the security-boundary list during the Windows 10 era; Win32 App Isolation is built on the foundation of AppContainers, &quot;which is recognized as a security boundary by Microsoft&quot; [@ms-blogs-win32appiso]). The amendment is possible. It is not obviously imminent. As of May 2026 the MSRC document does not contain agent-related boundary language.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;That third ceiling lands the shift. The deepest part of the gap is not engineering -- it is &lt;em&gt;policy&lt;/em&gt;. The engineering substrate is more or less in place; the governance posture is not. An OS-level &lt;code&gt;AgentPrincipal&lt;/code&gt; either becomes a new defended boundary (a major policy shift) or ships as a feature without boundary semantics (no CVE eligibility for agent-bypass). The Confused-Deputy ceiling is the structural mirror of the same observation: the only mitigation a deputy can perform is to &lt;em&gt;name&lt;/em&gt; the two authorities at the access-check, which is what &lt;code&gt;AgentPrincipal&lt;/code&gt; would do.&lt;/p&gt;
&lt;p&gt;Given the structural ceilings, what specifically is still open in May 2026?&lt;/p&gt;
&lt;h2&gt;9. Seven open problems&lt;/h2&gt;
&lt;p&gt;Seven numbered, unsolved problems as of May 2026. None of them are blocked by physics; all of them are blocked by some combination of plumbing, packaging convention, and policy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The state-of-the-art inventory this article rests on names seven open problems; an earlier pass listed six and missed the methodological one (no shared cross-method benchmark). The seventh is restored at the end of this section, and three of the existing problems (cross-process delegation, signed-binary harvesting, and the DAA deployment chain) are walked through in worked-example form using kernel and TPM primitives the prior sections have named.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;9.1 The Electron and Win32 packaging gap&lt;/h3&gt;
&lt;p&gt;Claude Desktop, ChatGPT Desktop, and Cursor are Electron and NSIS-installed apps; GitHub Copilot CLI is a Node.js CLI distributed via npm, WinGet, or MSI. None of them ships as MSIX. The package SID surface from AppContainer does not reach them; nothing in their primary token marks them as an agent class. Win32 App Isolation [@ms-blogs-win32appiso] is the in-flight retrofit -- adoption among agent vendors three years after the public preview is minimal. Until the dominant agent vendors ship under MSIX or Win32 App Isolation, the only kernel-level identifier the Pillar 2 substrate can grab onto does not exist for the agents readers actually have installed.&lt;/p&gt;
&lt;h3&gt;9.2 Cross-process delegation: a worked example&lt;/h3&gt;
&lt;p&gt;The failure mode lives at the kernel layer and is invisible from the source code of the agent. Claude Desktop on Windows 11 24H2 is a non-MSIX, NSIS-installed Electron binary whose primary process runs under the user&apos;s primary token. When that process calls &lt;code&gt;CreateProcessW(L&quot;powershell.exe&quot;, L&quot;-NoProfile -Command \&quot;Remove-Item ...\&quot;&quot;, ...)&lt;/code&gt; to shell out, the kernel side of &lt;code&gt;NtCreateUserProcess&lt;/code&gt; calls &lt;code&gt;PspAllocateProcess&lt;/code&gt;, which calls into the security reference monitor to assign a primary token to the child. By default -- when the caller passes neither a replacement token through &lt;code&gt;CreateProcessAsUserW&lt;/code&gt; nor a &lt;code&gt;PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES&lt;/code&gt; entry in &lt;code&gt;STARTUPINFOEX::lpAttributeList&lt;/code&gt; -- the kernel duplicates the parent&apos;s primary token verbatim. Microsoft Learn is explicit: &quot;The new process runs in the security context of the calling process&quot; [@ms-learn-createproc]. The child inherits the user&apos;s SID, the user&apos;s group SID list, the user&apos;s privileges, the medium integrity level, and the per-session logon SID. No &lt;code&gt;TokenAppContainerSid&lt;/code&gt; is present (&lt;code&gt;GetTokenInformation(..., TokenIsAppContainer, ...)&lt;/code&gt; returns zero); no &lt;code&gt;TokenPackageClaims&lt;/code&gt; field is present. There is no field anywhere in the child&apos;s primary token that distinguishes &quot;this PowerShell child was launched by Claude Desktop&quot; from &quot;this PowerShell child was launched by Notepad.&quot;&lt;/p&gt;
&lt;p&gt;The rule that does work for packaged parents -- and the cliff at the unpackaged boundary -- are both in Microsoft Learn for legacy-application AppContainer behaviour: &quot;When an unpackaged process running in an app container calls CreateProcess, the child process typically inherits the parent&apos;s token. That token includes the integrity level (IL) and app container info&quot; [@ms-learn-appcontainer-legacy]. For an MSIX-packaged parent like Microsoft Copilot for Windows, the kernel propagates the &lt;code&gt;TokenAppContainerSid&lt;/code&gt; and capability list to the child [@ms-learn-msix-container]. For an unpackaged Electron parent, the rule does not fire because there is nothing to propagate; even for the packaged parent, the package SID identifies the package, not an agent role. The semantics the article calls for -- &quot;this child is acting on behalf of the user, and the agent making that decision is X&quot; -- has no kernel-layer encoding today.&lt;/p&gt;
&lt;p&gt;A hypothetical &lt;code&gt;AgentPrincipal&lt;/code&gt;-preserving inheritance rule would extend the existing AppContainer rule. The pseudocode below is illustrative of an unshipped kernel routine; it cannot be executed.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// PspAssignPrimaryTokenWithAgentInheritance (kernel-mode, called by
// NtCreateUserProcess via PspAllocateProcess for the SRM token path).

NTSTATUS PspAssignPrimaryTokenWithAgentInheritance(
    PEPROCESS  ChildProcess,
    PEPROCESS  ParentProcess,
    PTOKEN     ParentToken,
    PSECURITY_CAPABILITIES Caps,
    PIMAGE_SECTION_OBJECT  ChildImage)
{
    PTOKEN ChildToken;
    NTSTATUS s = SeSubProcessToken(ParentToken, &amp;amp;ChildToken);
    if (!NT_SUCCESS(s)) return s;

    // Existing rule (today&apos;s kernel): propagate AppContainer SID + caps
    // when the parent token is in an AppContainer.
    if (SeTokenIsAppContainer(ParentToken)) {
        SePropagateAppContainerSids(ParentToken, ChildToken);
    }

    // New rule: AgentPrincipal inheritance with refusal path.
    PTOKEN_AGENT_PRINCIPAL_INFORMATION AgentInfo =
        SeQueryAgentPrincipalInformation(ParentToken);
    if (AgentInfo != NULL) {
        // Child image must be Authenticode-signed and on the
        // AgentSID&apos;s per-tool allowlist authored at agent-install
        // time via the FIDO AATWG Pillar 1 ceremony.
        if (!SeImageIsAuthenticodeSigned(ChildImage) ||
            !SeAgentAllowlistContains(AgentInfo-&amp;gt;AgentSid,
                                      ChildImage-&amp;gt;SignerCertHash)) {
            ObDereferenceObject(ChildToken);
            return STATUS_AGENT_TOOL_NOT_ALLOWED;
        }
        SePropagateAgentPrincipal(AgentInfo, ChildToken);
        EtwWriteAgentChildProcessCreated(
            ParentProcess, ChildProcess, AgentInfo-&amp;gt;AgentSid);
    }
    return PsAssignPrimaryToken(ChildProcess, ChildToken);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The refusal path is the load-bearing part. Today, &lt;code&gt;CreateProcess&lt;/code&gt; from an agent process to any binary the user can execute succeeds. Under the proposed rule, the agent&apos;s per-tool allowlist is the access-check boundary: a child image not on the allowlist -- for example, an attacker-dropped &lt;code&gt;payload.exe&lt;/code&gt; masquerading as PowerShell -- is refused at the syscall layer, with the refusal landing in ETW as an &lt;code&gt;AgentToolDenied&lt;/code&gt; event correlated to the agent SID. Win32 App Isolation already ships an analogous inheritance-with-refusal shape for unpackaged Win32 binaries: the Application Capability Profiler produces a developer-supplied capability profile that the kernel enforces at child-process creation, with unprofiled syscalls failing the same way AppContainer fails capability-bounded calls today [@ms-learn-win32appiso-overview]. The missing piece for the agent case is the &lt;em&gt;agent&lt;/em&gt; dimension on the token, not the mechanism.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Even if Windows ships an &lt;code&gt;AgentPrincipal&lt;/code&gt;, every agent that shells out to PowerShell, Node, or Python today loses agent-attribution at the child-process boundary, because non-packaged children inherit the user&apos;s primary token unmodified. Agent vendors should assume that &quot;shell out to a language runtime&quot; is the default attack path; readers writing agent tools should keep operations inside the agent process where possible.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;9.3 Revocation latency&lt;/h3&gt;
&lt;p&gt;Revoking an agent&apos;s Entra Agent ID in the cloud should fan out to a Kerberos TGT purge plus local token-cache invalidation plus a WAM cache flush, without logging the user out. The plumbing does not exist on Windows. Continuous Access Evaluation is the closest cloud-side analog -- it can short-circuit access-token reuse against a remote API on the cloud side, but it cannot reach the user&apos;s local Kerberos cache or the user&apos;s local DPAPI scope.&lt;/p&gt;
&lt;h3&gt;9.4 MCP authorisation alignment&lt;/h3&gt;
&lt;p&gt;Every MCP server today runs its own OAuth 2.1 plus RFC 9728 PRM dance [@anthropic-mcp-2025-11-25]. The OS-side agent principal has no role; per-tool authorisation lives above the OS and is invisible to ETW and Defender. An MCP-aware &lt;code&gt;AgentPrincipal&lt;/code&gt; would let the OS surface the per-tool grant chain as part of the access-check audit record, so EDR can correlate an MCP grant to a downstream syscall.&lt;/p&gt;
&lt;h3&gt;9.5 DAA-for-agent-class deployment: end-to-end&lt;/h3&gt;
&lt;p&gt;TPM 2.0 Direct Anonymous Attestation can, in principle, prove &quot;this binary is &lt;em&gt;some&lt;/em&gt; Claude Desktop&quot; without identifying the specific instance. As of May 2026 no agent vendor uses DAA as an attestation issuer for itself; the deployment glue between Pluton, Azure Attestation Service, and an AATWG Pillar 2 verifier does not exist. The cryptographic substrate is in the TPM; the deployment pipeline that would carry it is not. Working the chain end-to-end clarifies what would have to ship.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Leg 1: the agent vendor as DAA issuer.&lt;/strong&gt; Anthropic, Microsoft, or Cursor plays the role of &lt;em&gt;DAA Issuer&lt;/em&gt; in the canonical three-entity formulation: &quot;The entities are the DAA Member (TPM platform or EPID-enabled microprocessor), the DAA Issuer and the DAA Verifier. The issuer is charged to verify the TPM platform during the Join step and to issue DAA credential to the platform&quot; [@wiki-daa]. The vendor maintains a long-term issuer key pair; the public half is the basename a verifier consults. Discovery is conventionally JSON Web Key Set under OpenID Connect Discovery 1.0, the same mechanism Azure Attestation Service itself exposes for relying parties [@ms-learn-aas-concepts]. No agent vendor publishes such an endpoint today.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Leg 2: the Join step at first run.&lt;/strong&gt; On first agent launch, a Windows-side broker (a proposed extension to WAM) mediates the Join with the vendor&apos;s issuer endpoint. Conceptually, the local Pluton or TPM runs &lt;code&gt;TPM2_CreatePrimary(hierarchy = TPM_RH_ENDORSEMENT, inPublic.type = TPM_ALG_ECDAA, ...)&lt;/code&gt; to mint the member key, then &lt;code&gt;TPM2_Commit&lt;/code&gt; to produce the ECDAA ephemeral commitments. The vendor issues an ECDAA membership credential -- not a per-device cert; the credential is unlinkable across signatures by construction -- and Pluton stores it in non-volatile memory [@ms-learn-pluton-tpm]. The user&apos;s WebAuthn-bound consent (the Pillar 1 evidence) is recorded in the vendor&apos;s audit log. The WAM broker has no agent-scoped DAA Join extension as of May 2026.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Leg 3: the Sign step on each agent action.&lt;/strong&gt; Per-action, Pluton runs &lt;code&gt;TPM2_Commit&lt;/code&gt; with the verifier&apos;s nonce, then &lt;code&gt;TPM2_Sign(daaMemberKey, message_digest, scheme = TPM_ALG_ECDAA)&lt;/code&gt;. The WAM broker bundles the ECDAA signature into an Azure-Attestation-Service-style JWT envelope and submits it to the AATWG Pillar 2 verifier endpoint [@ms-learn-aas-overview; @ms-learn-aas-concepts]. The verifier de-serialises the JWT, runs the four-step check from Problem 6 (Authenticode chain plus Pluton EK chain plus measured-boot PCRs plus application-load PCR) plus the ECDAA verification. The verifier learns &quot;some Anthropic Claude Desktop is making this request&quot; but not &lt;em&gt;which&lt;/em&gt; device; two consecutive actions from the same agent on the same device are cryptographically indistinguishable from two actions on different devices. The Azure Attestation Service policy engine does not carry an &quot;agent-class membership&quot; claim type that downstream Conditional Access can consume as a signal today.&lt;/p&gt;
&lt;p&gt;The deployment gap, taken together, is integration rather than algorithm. Every primitive exists in the TCG TPM 2.0 specification, in the Azure Attestation Service engine, and in the WAM broker. Nobody has glued vendor-issuer plus Pluton-member plus WAM-broker plus AAS-verifier into a shipping pipeline. The corpus&apos;s sibling DAA article carries the verbatim TCG protocol detail; this section anchors the deployment chain to the Windows-side primitives Microsoft documents.&lt;/p&gt;
&lt;h3&gt;9.6 Signed-binary harvesting: a worked example&lt;/h3&gt;
&lt;p&gt;An attacker who steals a legitimately signed agent binary inherits any &lt;code&gt;AgentPrincipal&lt;/code&gt; that would otherwise be granted to that binary -- unless attestation is bound to runtime state, which DAA alone cannot provide. The attack is the Stuxnet-class supply-chain pattern, generalised to the agent case.&lt;/p&gt;
&lt;p&gt;The attacker compromises Anthropic&apos;s signing infrastructure -- the private-key custodian for the EV code-signing certificate, or the build pipeline that calls the custodian. The historical precedent for this exact attack shape is the 2010 Stuxnet incident, in which two distinct Authenticode driver-signing certificates were exfiltrated from JMicron Technology Corp and Realtek Semiconductor Corp (both VeriSign-issued) and used to produce kernel drivers Windows accepted as legitimate [@wiki-stuxnet]. The attacker now produces &lt;code&gt;claude-desktop-evil.exe&lt;/code&gt; with the Anthropic Subject Name signed by the legitimate private key; &lt;code&gt;wintrust.dll!WinVerifyTrust&lt;/code&gt; returns &lt;code&gt;S_OK&lt;/code&gt;. To every existing Authenticode consumer -- App Control for Business publisher rules, AppLocker publisher conditions, Defender signer-based exclusions -- the malicious binary is indistinguishable from the legitimate Claude Desktop. If a hypothetical &lt;code&gt;AgentPrincipal&lt;/code&gt; is bound to the install-time Authenticode signature alone, Windows mints the same &lt;code&gt;AgentSid&lt;/code&gt; for the malicious binary; the audit trail still reads &quot;Claude Desktop did X&quot; because the binary cryptographically &lt;em&gt;is&lt;/em&gt; Claude Desktop as far as the load-time check can tell.&lt;/p&gt;
&lt;p&gt;The remediation runs through Pluton&apos;s measured-boot chain plus Azure Attestation Service. Microsoft Pluton &quot;provides hardware-based root of trust, secure identity, secure attestation, and cryptographic services&quot; [@ms-learn-pluton]; secure attestation is exactly the role this attack requires. Pluton-rooted attestation is a TPM 2.0 &lt;code&gt;TPM2_Quote&lt;/code&gt; over a selected set of Platform Configuration Registers signed by an Attestation Identity Key whose endorsement chain terminates at Pluton&apos;s manufacturer-burned Endorsement Key [@ms-learn-pluton-tpm]. The PCRs that matter for distinguishing the legitimate Claude Desktop from &lt;code&gt;claude-desktop-evil.exe&lt;/code&gt; are PCRs 0 through 7 (UEFI firmware, Option ROMs, boot manager, Secure Boot policy -- the pre-OS measured-boot range per the TCG PC Client Platform Firmware Profile), PCR 11 (BitLocker and the OS loader application code path, into which ELAM and kernel-mode driver measurements extend on Windows), and an application-extend PCR (PCR 12 in many shipping configurations, sometimes a virtual PCR via the TPM Base Services or VBS) carrying the SHA-256 of the on-disk agent image plus the cumulative hash of in-process module loads. The wire format the verifier evaluates is the Azure-Attestation-Service JWT envelope [@ms-learn-aas-overview; @ms-learn-aas-concepts].&lt;/p&gt;
&lt;p&gt;The AATWG Pillar 2 verifier performs four cascaded checks in order. (1) Authenticode chain valid -- the agent binary&apos;s image hash is covered by an Authenticode signature whose chain terminates in a trusted root; this is the only check today. (2) Pluton EK chain valid -- the AAS-issued JWT was signed by an AIK whose endorsement chain terminates at a Microsoft-issued Pluton EK certificate, proving the quote came from real hardware. (3) Measured-boot PCRs in known-good set -- PCRs 0 through 11 match a reference value for the user&apos;s claimed device class and OS build (Windows 11 24H2, Secure Boot on, VBS on). (4) Application-load PCR matches the published-by-vendor measurement -- PCR 12 matches the hash the agent vendor published in a verifier-discoverable channel for the legitimate release. Step (4) is the runtime-state binding. The attacker now needs either to compromise the vendor&apos;s published-hashes channel &lt;em&gt;in addition to&lt;/em&gt; the signing key, or to compromise the user&apos;s Pluton-rooted measured-boot chain &lt;em&gt;in addition to&lt;/em&gt; the signing key. Both are strictly stronger compromises; both raise the attacker&apos;s cost by a hardware-vs-software factor. No agent vendor publishes the application-load-PCR reference channel today; the AATWG Pillar 2 verifier reference implementation does not exist.&lt;/p&gt;
&lt;h3&gt;9.7 Agent-identity benchmark gap&lt;/h3&gt;
&lt;p&gt;No published peer-reviewed benchmark suite compares the cloud, OS, and broker positions on a common agent-attribution workload as of May 2026. The closest available empirical results are vendor-internal: AP2 v0.2 demo measurements published with the September 2025 cloud.google.com launch and the subsequent ap2-protocol.org release notes [@ap2-cloud-blog; @ap2-protocol]; Microsoft Build 2025 session telemetry for WAM Token Protection latency [@ms-learn-wam]; RFC 8693 OAuth Token Exchange implementations measured in IEEE / ACM / USENIX venues since 2019 [@ietf-rfc-8693] but in non-agent configurations. None of these is a comparison; all are baselines.&lt;/p&gt;
&lt;p&gt;The absence matters at two levels. Practitioners deploying an agent stack in 2026 cannot make principled latency, scale, or audit-completeness tradeoffs across the seven methods catalogued in Section 7 without a shared harness; a cloud-managed enterprise running Entra Agent ID plus RFC 8693 plus MCP cannot compare its per-action token-mint latency against a competing WAM-extended deployment without rerunning both stacks under the same workload. At the literature level, the field has named its primitives, sketched its composition rules, and assembled its wire formats but has not yet produced shared evaluation workloads.&lt;/p&gt;
&lt;p&gt;A public AATWG-blessed benchmark would have to measure four axes matching the four distinct architectural moves the article catalogues: per-action token-mint latency from agent decision to capability-token presentation; ETW event volume per agent action and per agent session; attestation chain length (Pluton AIK to AAS JWT to vendor ECDAA to relying-party verify) in the Pillar 2 path; and cross-process-delegation propagation success rate (the §9.2 property -- the fraction of agent-spawned child processes that retain agent attribution end-to-end). The four axes are necessary because the seven methods make incomparable tradeoffs across them, and the only honest cross-method statement today is the negative one: no shared benchmark exists.&lt;/p&gt;
&lt;h2&gt;10. What to ship today&lt;/h2&gt;
&lt;p&gt;Six things a Windows engineer or agent vendor can do in May 2026 using only primitives that already ship.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ship the agent as an MSIX-packaged app to get a stable package SID.&lt;/strong&gt; The package SID is not an agent principal, but it is the only kernel-level identifier you can rely on today [@ms-learn-appcontainer; @ms-learn-appcontainer-legacy]. Packaging is the precondition for per-package DPAPI scope, capability-gated network egress under Windows Filtering Platform, and any future &lt;code&gt;AgentPrincipal&lt;/code&gt; retrofit -- a non-packaged Electron app gets none of these.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mint agent-scoped tokens from Entra Agent ID&lt;/strong&gt; rather than letting the agent act under the user&apos;s delegated token [@ms-learn-agentid; @ms-learn-agentoauth]. You get Conditional Access on the agent identity, Purview agent-interaction audit fields, and a sign-in log entry distinct from the user&apos;s. Available grant types are &lt;code&gt;client_credentials&lt;/code&gt;, &lt;code&gt;jwt-bearer&lt;/code&gt;, and &lt;code&gt;refresh_token&lt;/code&gt;; interactive flows are not supported for agent entities [@ms-learn-agentobo].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Kerberos Resource-Based Constrained Delegation rather than unconstrained delegation.&lt;/strong&gt; Scope the allowed-to-delegate-to list to the specific back-end services the agent legitimately calls [@ms-learn-mssfu]. RBCD inverts the authoring point: the back-end resource names the front-end services it accepts delegation from, which is the right authoring point when the agent population changes faster than the back-end population.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Route agent tool invocations through an MCP server with the 2025-11-25 OAuth 2.1 plus RFC 9728 PRM authorisation profile enabled&lt;/strong&gt; [@anthropic-mcp-2025-11-25; @ietf-rfc-9728; @ietf-oauth-v2-1]. Do not rely on the user&apos;s logon credentials at the tool layer. Each tool grant is then explicit, scoped, and revocable independently of the user&apos;s session.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The cost of MSIX packaging is paid once, at install-time, and the cost of leaving the Electron user-DPAPI scope alone is paid forever. Every future agent-attribution retrofit -- per-package DPAPI scope, capability-gated network egress, an &lt;code&gt;AgentPrincipal&lt;/code&gt; token field -- depends on the package SID being there to attach to. Pay the install-time cost.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Treat every locally stored agent secret as a user-DPAPI-scope liability for Electron-wrapped agents.&lt;/strong&gt; Any other process under the same user can decrypt it. If isolation matters, store the secret in a Virtualisation-Based Security trustlet behind Credential Guard, in an AppContainer per-package DPAPI scope, or in a Pluton-backed key. The substrate exists; the decision is whether to use it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Subscribe to the FIDO Alliance AATWG and Payments TWG mailing lists&lt;/strong&gt; [@fido-aatwg-pr; @fido-aatwg-landing]. Wire formats are in flight; deployment characteristics will not be settled until at least H2 2026. The mailing-list traffic is the cheapest signal you can get on what the agent-protocol wire format will look like in 2027.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

Open an elevated PowerShell prompt and run `whoami /all`. You will see the primary user SID, the group SIDs, the integrity-level overlay, and the enabled privileges that your shell process is currently running with -- the exact data structure the kernel reads on every `SeAccessCheck` call.&lt;p&gt;If you have an MSIX-packaged AppContainer process available (the Microsoft Store apps are the easiest source), run &lt;code&gt;Get-AppxPackage | Select Name, PackageFamilyName, SignatureKind&lt;/code&gt; and then &lt;code&gt;Get-AppxPackage &amp;lt;Name&amp;gt; | Get-AppxPackageManifest&lt;/code&gt; to see the capability list. The capability SIDs that show up in the manifest are the per-resource gates that AppContainer adds on top of the package SID. There is, today, no analogous &lt;code&gt;whoami /agent&lt;/code&gt; command. That absence is the gap.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The first RunnableCode block gives a hands-on feel for the shape of a primary token&apos;s principal set and what the proposed &lt;code&gt;AgentPrincipal&lt;/code&gt; would add. The second demonstrates macaroon attenuation so the chained-HMAC construction stops being abstract.&lt;/p&gt;
&lt;p&gt;{`
// Conceptual model of a Windows access token, as whoami /all would print it.
// On a non-AppContainer process today there are user/group SIDs but no
// package SID and no proposed AgentPrincipalSid.
const tokenToday = {
  primaryUserSid: &apos;S-1-5-21-3623811015-3361044348-30300820-1013&apos;,
  groupSids: [
    &apos;S-1-5-21-3623811015-3361044348-30300820-513&apos;, // Domain Users
    &apos;S-1-5-32-545&apos;,                                // BUILTIN\\Users
    &apos;S-1-5-11&apos;,                                    // Authenticated Users
  ],
  packageSid: null,        // not in an AppContainer
  agentPrincipalSid: null, // proposed in this article; not in any shipping build
  integrityLevel: &apos;Medium&apos;,
};&lt;/p&gt;
&lt;p&gt;// Same agent process under the proposed seventh-generation token shape.
const tokenWithAgentPrincipal = Object.assign({}, tokenToday, {
  packageSid: &apos;S-1-15-2-2756086904-3023256918-1882200006-3954548928-2786400166-3567463568-3801030027&apos;,
  agentPrincipalSid: &apos;S-1-15-7-1001-AGENT-CLAUDE-DESKTOP&apos;,
  integrityLevel: &apos;Low&apos;,
});&lt;/p&gt;
&lt;p&gt;function summarise(label, t) {
  console.log(&apos;--- &apos; + label + &apos; ---&apos;);
  console.log(&apos;Primary user SID: &apos; + t.primaryUserSid);
  console.log(&apos;Package SID:      &apos; + (t.packageSid || &apos;(none)&apos;));
  console.log(&apos;Agent SID:        &apos; + (t.agentPrincipalSid || &apos;(none)&apos;));
  console.log(&apos;Integrity:        &apos; + t.integrityLevel);
}&lt;/p&gt;
&lt;p&gt;summarise(&apos;Token today (Electron Claude Desktop under user logon)&apos;, tokenToday);
summarise(&apos;Token after the seventh generation&apos;, tokenWithAgentPrincipal);
`}&lt;/p&gt;
&lt;p&gt;{`
// Conceptual macaroon: each caveat is bound by a fresh HMAC over the prior
// HMAC plus the caveat text. The holder can only attenuate; never expand.
const crypto = {
  hmac(key, msg) {
    // Toy mixing function, not cryptographic. Real macaroons use HMAC-SHA256.
    let h = 2166136261;
    const data = String(key) + &apos;|&apos; + String(msg);
    for (let i = 0; i &amp;lt; data.length; i++) {
      h = Math.imul(h ^ data.charCodeAt(i), 16777619);
    }
    return (&apos;00000000&apos; + (h &amp;gt;&amp;gt;&amp;gt; 0).toString(16)).slice(-8);
  },
};&lt;/p&gt;
&lt;p&gt;function mint(rootKey, identifier) {
  const sig = crypto.hmac(rootKey, identifier);
  return { id: identifier, caveats: [], sig };
}&lt;/p&gt;
&lt;p&gt;function attenuate(macaroon, caveat) {
  const nextSig = crypto.hmac(macaroon.sig, caveat);
  return {
    id: macaroon.id,
    caveats: macaroon.caveats.concat([caveat]),
    sig: nextSig,
  };
}&lt;/p&gt;
&lt;p&gt;function verify(rootKey, macaroon) {
  let sig = crypto.hmac(rootKey, macaroon.id);
  for (const c of macaroon.caveats) {
    sig = crypto.hmac(sig, c);
  }
  return sig === macaroon.sig;
}&lt;/p&gt;
&lt;p&gt;const ROOT = &apos;agent-issuer-root-secret-123&apos;;
const m0 = mint(ROOT, &apos;agent-claude-desktop-session-42&apos;);
const m1 = attenuate(m0, &apos;tool = filesystem.read&apos;);
const m2 = attenuate(m1, &apos;path-prefix = C:\\Users\\parag\\projects&apos;);
const m3 = attenuate(m2, &apos;expires-at = 2026-05-25T15:00:00Z&apos;);&lt;/p&gt;
&lt;p&gt;console.log(&apos;Base verified:       &apos; + verify(ROOT, m0));
console.log(&apos;Three-caveat chain:  &apos; + verify(ROOT, m3));&lt;/p&gt;
&lt;p&gt;// Holder cannot un-attenuate. A holder who tries to drop a caveat would
// have to compute the prior signature, which requires the issuer&apos;s secret.
const tampered = { id: m3.id, caveats: m3.caveats.slice(0, 2), sig: m3.sig };
console.log(&apos;Tampered (verify):   &apos; + verify(ROOT, tampered));
`}&lt;/p&gt;
&lt;p&gt;Six things you can do today; eight misconceptions you can stop carrying.&lt;/p&gt;
&lt;h2&gt;11. Misconceptions and practical concerns&lt;/h2&gt;

Entra Agent ID solves the cloud-side half. It gives an agent a directory entry, a sign-in log, a Conditional Access surface, and a token-exchange path under `client_credentials`, `jwt-bearer`, and `refresh_token` grants [@ms-learn-agentid; @ms-learn-agentoauth]. What it does not do is reach inside the operating system. A locally-installed agent with an Entra Agent ID still calls the Windows file-system API under the user&apos;s primary token, decrypts user-DPAPI blobs as the user, and impersonates over RPC as the user. The OS-side attribution stays collapsed even when the cloud-side attribution is clean. Both layers are necessary; neither is sufficient.

The Microsoft On-Behalf-Of flow [@ms-learn-obo-flow] and RFC 8693 Token Exchange [@ietf-rfc-8693] solve the *back-end-to-back-end* delegation problem: a web API can call another web API as the user. They do not address desktop attribution. When the user&apos;s Microsoft 365 Copilot client (running on the user&apos;s desktop as the user) calls a downstream API, the cloud-side token carries the actor claims; the desktop-side process still runs under the user&apos;s primary token, and the OS-side audit trail still records the user as the syscall principal. OBO is the cloud answer to a different question.

The package SID is part of the agent attribution story, but it does not by itself constitute agent attribution. The verbatim Microsoft Learn rule is that &quot;the permitted access is the intersection of that granted by the user/group SIDs and AppContainer SIDs&quot; [@ms-learn-appcontainer]. That gives the access-check a way to restrict the package&apos;s authority below the user&apos;s; it does not give downstream consumers a way to distinguish &quot;this package is an AI agent acting on a separable principal&quot; from &quot;this package is a UWP weather app.&quot; Treating the package SID as the agent principal also fails at the boundary every Electron-wrapped agent crosses today: those agents are not packaged, so they do not get a package SID at all.

NT 3.1 solved *user* attribution. The primary token model, the user SID structure, impersonation, `SeAccessCheck` -- all of these are about distinguishing one user from another and about a thread temporarily speaking as a different identity [@ms-learn-sids]. None of them solved *code* identity (which took until 1996 with Authenticode and was still being refined in 2017 with App Control for Business) and none of them solved *agent* identity (the open problem this article is about). The article must not conflate the three. The 1993 milestone is the foundation; it is also incomplete by design for the question that arrived in 2025.

Putting the agent in AppContainer gets you a package SID, a per-package DPAPI scope, capability-gated network egress, and a LowBox token; do this regardless of whether you call it an agent. What AppContainer does not give you is a kernel-level signal that distinguishes agent semantics from app semantics. Defender, ETW, and Conditional Access read package SIDs as package identifiers, not as agent role markers. A full agent-principal answer needs both the AppContainer-style sandbox and a sibling-principal SID that downstream consumers explicitly understand to be an agent identity, separately governed and separately revocable.

Administrator Protection is the existence proof that Windows can mint a second logon-session principal for a bounded action under a Hello user-verification gesture. As of May 2026 it is in Insider preview, not generally available; the feature surfaced on Insider builds in late 2025 and subsequent Insider build iterations have continued through 2026 [@ms-techcomm-adminprot]. The architectural pattern -- separate logon session, Hello gesture, scoped to one action -- is exactly the shape the seventh-generation agent principal would take. What it does not do today is generalise to delegation. The System-Managed Administrator Account is scoped to elevation. The agent-principal version would be scoped to &quot;this agent for the duration of this delegated session&quot;; the policy machinery does not yet exist.

No. Macaroons attenuate offline: the holder appends a caveat and a fresh HMAC, derives a strictly weaker macaroon, and presents it; the verifier walks the chain. OAuth bearer tokens cannot attenuate without round-tripping the authorisation server, which makes them structurally unfit for an agent that talks to many tools with many different scope shapes [@macaroons-ndss; @macaroons-gr]. See §7.3 for the worked construction.

The Windows framing is specific because the article is specifically about Windows. The underlying problem is platform-general. iOS App Attest (`DCAppAttestService`) and the Android per-app UID model are the cross-platform analogs of an OS-level application principal; neither has a published agent-identity story as of May 2026. macOS has its own per-app code-signing and entitlement substrate; it also has no shipping agent-principal model. Linux distributions vary. The fact that Windows ships the AppContainer dual-principal substrate already, plus the Administrator Protection bounded-second-principal existence proof, plus the Pluton-rooted attestation chain, makes Windows the operating system where the seventh-generation answer is most legibly close. It is not a Windows-only problem; it is a problem where Windows is unusually well-equipped to solve it next.
&lt;p&gt;The position the article ends on is the one each prior section pushed toward. As of May 2026 the cloud-identity layer has crossed the agentic-identity gap. The OS layer has not. The substrate primitives are largely in place: AppContainer package SIDs and the LowBox token, Kerberos S4U2Self and S4U2Proxy, WAM with TPM-bound refresh tokens, WebAuthn and Windows Hello with TPM-rooted user verification, TPM 2.0 Direct Anonymous Attestation, the Administrator-Protection separate-logon-session pattern, ETW as an audit channel. The missing piece is a kernel-recognised &lt;code&gt;AgentPrincipal&lt;/code&gt; extended from the package-SID substrate, gated by Hello-mediated Verifiable User Instructions, scoped via a macaroon-style per-tool capability layer, audited via an ETW &lt;code&gt;SubjectAgentSid&lt;/code&gt; field, and revocable via a CAE-style fan-out that does not require logging the user out. The MSRC servicing criteria document is the governance object that determines whether the seventh generation is a defensible security boundary or a defense-in-depth feature; that document has not been amended.&lt;/p&gt;
&lt;p&gt;The question is when, not whether, Windows ships the seventh generation.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;agentic-identity-on-windows-when-the-process-acting-on-your-behalf-isnt-you&quot; keyTerms={[
  { term: &quot;Primary token&quot;, definition: &quot;The kernel-resident access token attached to every Windows process at creation; carries the user SID, group SIDs, an integrity-level SID in a SYSTEM_MANDATORY_LABEL_ACE inside the token&apos;s SACL, and a privilege set.&quot; },
  { term: &quot;SID&quot;, definition: &quot;Security Identifier; the variable-length structure that uniquely identifies a security principal in a Windows access decision.&quot; },
  { term: &quot;AppContainer&quot;, definition: &quot;The kernel sandbox shipped in Windows 8 (October 26, 2012); attaches an S-1-15-2 package SID to the access token and gates access through the intersection of user and package authority.&quot; },
  { term: &quot;S4U2Self / S4U2Proxy&quot;, definition: &quot;Microsoft&apos;s Kerberos Protocol Extensions that let a server obtain a service ticket on behalf of a user without that user&apos;s password; the act-on-behalf-of primitive on Windows.&quot; },
  { term: &quot;Confused Deputy&quot;, definition: &quot;Hardy 1988: a process holding authority from multiple sources cannot express which authority it is exercising for a given action; the structural lower bound on agent attribution.&quot; },
  { term: &quot;Macaroon&quot;, definition: &quot;A bearer credential constructed as a chained HMAC over caveats; any holder can derive a strictly weaker credential by appending a caveat without round-tripping the issuer.&quot; },
  { term: &quot;DAA&quot;, definition: &quot;Direct Anonymous Attestation; a TPM 2.0 protocol that lets a device prove membership in a privacy-preserving group without revealing the specific device identity.&quot; },
  { term: &quot;WAM&quot;, definition: &quot;Web Account Manager; the on-device OAuth token broker that ships with Windows and binds refresh tokens to the TPM.&quot; },
  { term: &quot;Administrator Protection&quot;, definition: &quot;The Windows 11 Insider feature (late 2025 onwards, not yet GA) that mints a separate logon session under a System-Managed Administrator Account for an elevation, gated by a Windows Hello gesture.&quot; },
  { term: &quot;AATWG&quot;, definition: &quot;FIDO Alliance Agentic Authentication Technical Working Group; launched April 28, 2026 with three pillars: Verifiable User Instructions, Agent Authentication, Trusted Delegation for Commerce.&quot; }
]} questions={[
  { q: &quot;What is the primary structural reason a locally-installed AI agent on Windows in 2026 cannot be attributed separately from the logged-on user?&quot;, a: &quot;Every process on Windows carries one primary token; the token&apos;s user SID is the runtime principal; the agent process inherits the user&apos;s primary token; SeAccessCheck, ETW, RPC ACLs, Defender, and on-device Conditional Access all read the user SID as the principal.&quot; },
  { q: &quot;Name the six shipped generations of Windows app identity and the generation that has not yet shipped.&quot;, a: &quot;Gen 1 NT 3.1 primary token (1993); Gen 2 Authenticode (1996); Gen 3 SRP then AppLocker (2001, 2009); Gen 4 AppContainer + package SID (2012); Gen 5 App Control for Business (2017+); Gen 6 Administrator Protection (late 2025 Insider, not yet GA); Gen 7 AgentPrincipal (missing).&quot; },
  { q: &quot;Why does the AppContainer package SID not, by itself, constitute an agent principal?&quot;, a: &quot;The package SID identifies a package, not an agent role; downstream consumers cannot distinguish &apos;this package SID is an AI agent on a separable principal&apos; from &apos;this package SID is a UWP calculator&apos;; Electron-wrapped agents do not get a package SID at all.&quot; },
  { q: &quot;What are the three pillars of the FIDO AATWG and what wire-format primitive does each carry?&quot;, a: &quot;Pillar 1 Verifiable User Instructions: passkey-signed delegation token bound to a specific intent with short TTL. Pillar 2 Agent Authentication: attestation plus identity assertion. Pillar 3 Trusted Delegation for Commerce: AP2 mandate or Verifiable Intent SD-JWT chain.&quot; },
  { q: &quot;Why is attenuation without a round-trip the load-bearing property of macaroons in an agent setting?&quot;, a: &quot;An agent talks to many tools with many scope shapes; the holder can derive a weaker per-tool macaroon by appending a caveat and a fresh HMAC without round-tripping the issuer; the holder cannot un-attenuate; the issuer does not have to be online.&quot; },
  { q: &quot;What is the MSRC servicing-criteria policy ceiling and why does it matter for an AgentPrincipal?&quot;, a: &quot;Under the MSRC document, within the same logon session and the same primary token, a defect that requires the attacker to already be running as the user is treated as defense-in-depth rather than a CVE-eligible servicing event; for an OS-level AgentPrincipal to be a defensible security boundary the MSRC document itself would have to be amended to add the user-versus-agent split to the boundary taxonomy.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows-security</category><category>identity</category><category>ai-agents</category><category>fido-aatwg</category><category>kerberos</category><category>appcontainer</category><category>entra-agent-id</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>Certified Pre-Owned: AD CS and Active Directory&apos;s Second Trust Root</title><link>https://paragmali.com/blog/certified-pre-owned-ad-cs-and-active-directorys-second-trust/</link><guid isPermaLink="true">https://paragmali.com/blog/certified-pre-owned-ad-cs-and-active-directorys-second-trust/</guid><description>AD CS ESC1-ESC16: how Microsoft shipped Certificate Services in 2000, what SpecterOps named in 2021, and why the catalog grows faster than the patches.</description><pubDate>Mon, 25 May 2026 00:00:00 GMT</pubDate><content:encoded>
**Microsoft Certificate Services shipped in Windows 2000 Server on February 17, 2000 and was renamed Active Directory Certificate Services in Windows Server 2008.** Its misconfigurations remained admin-tunable knobs without numbered names for twenty-one years. In June 2021, Will Schroeder and Lee Christensen at SpecterOps published *Certified Pre-Owned* and named eight of them ESC1 through ESC8. Through 2025 the community extended the catalog to ESC16 across IFCR, Compass Security, SpecterOps, TrustedSec, and independent researchers, each one abusing one of six primitives: the template, the issuing authority, the transport, the mapping, the authentication step, or the persistence substrate. Two ESCs have cleanly received CVE-class Microsoft patches (EKUwu / ESC15 -&amp;gt; CVE-2024-49019; ESC8 received KB5005413 *hardening guidance* rather than a CVE, and the adjacent Certifried CVE-2022-26923 patches the dNSHostName impersonation chain on the Machine template rather than a numbered ESC); the rest are administrative hardening matters per Microsoft&apos;s Windows Security Servicing Criteria. The KB5014754 strong-mapping rollout closed ESC9 and ESC10 but is bypassed by ESC16. The architectural property -- that every CA in NTAuth is a key parallel to krbtgt that can mint a Domain Admin authenticator -- is not closable by any patch. The operational playbook is to run Locksmith, BloodHound CE, MDI, PSPKIAudit, and Certipy in parallel, ingest CA logs, and prepare a Lane-3 CA rebuild before you need it.
&lt;h2&gt;1. Two Hours, No KRBTGT, No Touch on Tier Zero&lt;/h2&gt;
&lt;p&gt;The operator&apos;s stopwatch reads two hours and seven minutes when the SOCKS proxy lights up with a Ticket-Granting Ticket for the Domain Administrator account. No service was crashed. No LSASS process was touched. No Tier-Zero principal had its password reset. 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 hash&lt;/a&gt; from last quarter&apos;s rotation is still good. The certificate that minted the ticket was issued, signed, and logged by the enterprise&apos;s own Certificate Authority -- the one the IT director&apos;s slide deck calls &quot;internal PKI&quot; -- against a template the help desk uses to enroll Wi-Fi clients.&lt;/p&gt;
&lt;p&gt;Walk the chain backwards. The operator joined &lt;code&gt;Domain Users&lt;/code&gt; four hours ago via a phishing payload that never escalated past medium integrity. They ran one tool. Certipy &lt;code&gt;find&lt;/code&gt; enumerated every certificate template the foothold account was permitted to enroll in [@certipy-gh]. One of those templates -- call it &lt;code&gt;WiFi-Auth&lt;/code&gt; -- had three properties: low-privilege enrollment open to &lt;code&gt;Authenticated Users&lt;/code&gt;, the Client Authentication Extended Key Usage attached, and the &lt;code&gt;CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT&lt;/code&gt; bit flipped on. Certipy &lt;code&gt;req&lt;/code&gt; produced a Certificate Signing Request that supplied &lt;code&gt;DOMAIN\Administrator&lt;/code&gt; as the Subject Alternative Name. The Enterprise CA, doing exactly what its template configured it to do, issued the certificate. Certipy &lt;code&gt;auth -pfx&lt;/code&gt; exchanged the certificate for a TGT via the Public Key Cryptography for Initial Authentication extension to Kerberos. Mimikatz &lt;code&gt;ptt&lt;/code&gt; loaded the TGT into the operator&apos;s session. Domain Admin.&lt;/p&gt;
&lt;p&gt;What did not fire is the part that frustrates the incident response team. There was no Windows Event 4624 for the Administrator account anywhere on the domain. Microsoft Defender for Identity raised no lateral-movement alert. No Pass-the-Ticket detection triggered, because the ticket was minted as fresh PKINIT authentication, not replayed. The only artifact in the entire chain was a single Event ID 4886 in the CA&apos;s issuance log -- the event the SOC&apos;s SIEM does not ingest, because the SOC&apos;s SIEM was built to follow &lt;code&gt;krbtgt&lt;/code&gt; and not to follow PKI.&lt;/p&gt;

RFC 4556&apos;s Public Key Cryptography for Initial Authentication in Kerberos. The protocol extension that lets a Kerberos client present a certificate to a Key Distribution Center and receive a Ticket-Granting Ticket in return. Authored by L. Zhu (Microsoft) and B. Tung (Aerospace), published in June 2006 [@rfc4556]. PKINIT is the authentication step that converts an issued certificate into a TGT, and therefore the step every ESC must cross to convert a misconfigured template into Domain Admin.
&lt;p&gt;The TGT in this scenario is produced by Active Directory&apos;s Key Distribution Center after it validates the certificate against its trusted certificate stores. The KDC does not call back to the CA -- it trusts any certificate signed by a CA published into the forest&apos;s &lt;code&gt;NTAuthCertificates&lt;/code&gt; container. That trust relationship is the load-bearing detail; we will return to it in section eight.&lt;/p&gt;
&lt;p&gt;So how is any of this possible? The operator&apos;s organization rotated krbtgt twice last quarter, runs a top-quartile EDR product, and bought Microsoft Defender for Identity with the AD CS sensor add-on. The simple answer is: rotating krbtgt closes one of the keys that can mint a Domain Admin authenticator in this forest. It does not close the others. The forest has more than one such key, and nobody told the IR plan.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Every domain whose CA can issue authentication certificates has two trust roots that can mint a Domain Admin authenticator, not one. The first is the &lt;code&gt;krbtgt&lt;/code&gt; account hash. The second is the private key of any Certificate Authority published into the forest&apos;s &lt;code&gt;NTAuthCertificates&lt;/code&gt; container. Rotating one does not touch the other. The catalog this article walks through is the community&apos;s attempt to enumerate the misconfigurations that turn the second trust root into a path low-privilege users can walk.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The vocabulary for this surface -- the named techniques, the numbered identifiers, the tool that enumerates them in eleven seconds -- did not exist until June 2021. The misconfigurations did. They had been shipping as customer-tunable knobs in Microsoft&apos;s identity stack since Windows Server 2003. If this surface has been available for twenty-one years, why did it take twenty-one years for someone to give the misconfigurations names?&lt;/p&gt;
&lt;h2&gt;2. Twenty-One Years of Unnamed Knobs&lt;/h2&gt;
&lt;p&gt;February 17, 2000. Windows 2000 Server reaches general availability. Microsoft Certificate Services -- the AD-integrated CA role -- ships as an optional server component on day one [@wikipedia-w2k]. The role is &lt;em&gt;not yet&lt;/em&gt; called Active Directory Certificate Services; that rename arrives with Windows Server 2008. The shipping defaults that the operator in section one just exploited were already buildable on the 2000 release.&lt;/p&gt;

You will see both anchor dates in the literature. Semperis&apos;s CVE-2022-26923 retrospective writes that &quot;In Windows Server 2008, Microsoft introduced AD CS&quot; [@semperis-cve]. The Microsoft Learn current overview describes AD CS as a &quot;Windows Server role for issuing and managing public key infrastructure (PKI) certificates&quot; [@msl-adcs-current] without distinguishing the ship date from the rename date. This article uses the dual anchor: the role *shipped* in 2000 as Microsoft Certificate Services, and was *renamed* Active Directory Certificate Services in 2008. The misconfigurations the ESC catalog enumerates were enabled by Windows Server 2003&apos;s V2 templates and have not been default-off since.
&lt;p&gt;The misconfigurations the catalog later attacks did not all arrive at once. Three Microsoft releases between 2000 and 2008 built the surface piece by piece.&lt;/p&gt;
&lt;p&gt;Windows Server 2003 (general availability April 24, 2003 [@wikipedia-ws2003]) shipped Version 2 (V2) certificate templates, user and computer autoenrollment over the V2 schema, and the AD-stored template store [@msl-ws2003-ca]. Most of the surface ESC1 and ESC4 later attack first appears in this release: &lt;code&gt;msPKI-Certificate-Name-Flag&lt;/code&gt;, the &lt;code&gt;CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT&lt;/code&gt; bit, per-template DACLs editable in Active Directory Sites and Services, and the modifiable Extended Key Usage list. The Enrollee-Supplies-Subject flag, in particular, is a customer-tunable bit; it ships off by default on the stock templates but is a one-click enable in &lt;code&gt;certtmpl.msc&lt;/code&gt; [@msl-adcs-2012r2]. Microsoft&apos;s documentation warned against it on sensitive templates. It did not warn against it as a numbered identifier.&lt;/p&gt;
&lt;p&gt;Certificate templates have version numbers tied to the Active Directory schema. V1 templates ship with Windows 2000 and are non-modifiable from the GUI. V2 templates ship with Windows Server 2003 and are fully modifiable; they introduce the per-template DACL and the editable &lt;code&gt;msPKI-Certificate-Name-Flag&lt;/code&gt; properties the catalog attacks. V3 templates ship with Windows Server 2008 and add Suite B cryptography support. The catalog mostly attacks V2 templates; ESC15 specifically attacks the residual V1 templates that ship pre-installed and cannot be removed.&lt;/p&gt;
&lt;p&gt;Windows Server 2008 (general availability February 27, 2008 [@wikipedia-ws2008]) renamed the role to Active Directory Certificate Services and added new role services: Online Certificate Status Protocol Responder, Network Device Enrollment Service, Certificate Enrollment Web Service, and Certificate Enrollment Policy Web Service. These role services expanded the transport surface that ESC8 and ESC11 later attack. The Windows Server 2012 R2 documentation page &lt;code&gt;hh831740&lt;/code&gt; became the canonical reference SpecterOps later linked from the 2021 paper [@msl-adcs-2012r2].&lt;/p&gt;
&lt;p&gt;Between 2008 and 2021 Microsoft published hardening guidance for AD CS in several places -- Test Lab Guides, PKI design pages, role-service deployment docs [@msl-pki-design]. The guidance covered template ACLs, manager approval, least-privilege enrollment, and the Enrollee-Supplies-Subject bit. It did not assign numbered identifiers to specific dangerous combinations. It did not appear in MSRC&apos;s vulnerability pipeline. It did not get a Common Vulnerabilities and Exposures registration. The configurations were &lt;em&gt;documented but unnamed&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In 2019, two seeds for the named class appeared. Géraud de Drouas at the French ANSSI published a brief GitHub note that the Active Directory &lt;code&gt;Public-Information&lt;/code&gt; property set includes &lt;code&gt;altSecurityIdentities&lt;/code&gt;, which lets an attacker with that permission map their own certificate onto a privileged user [@dedrouas-altsec]. The note ends with a striking line: &quot;This issue has been responsibly disclosed to MSRC and received a &apos;won&apos;t fix&apos; response.&quot; The same year Microsoft began documenting the &lt;code&gt;szOID_NTDS_CA_SECURITY_EXT&lt;/code&gt; extension in certificate-related KBs, though without making it default-on. The substrate for what would become ESC9, ESC10, and ESC14 was already in place; nobody had named it yet.&lt;/p&gt;
&lt;p&gt;Twenty-one years from the role&apos;s ship date, then. Twenty-one years of admin-tunable knobs. No numbered identifiers, no patch cadence, no scanner enumeration, no MSRC pipeline. Microsoft documented every one of these settings individually, often well; what was missing was the &lt;em&gt;catalog&lt;/em&gt;. Hardening guidance without numbered identifiers produces no defensive prioritization in real enterprises, because enterprise security programs prioritize against catalogs, not against documentation pages [@bollinger-ekuwu]. So what happened in June 2021 that turned a documentation pattern into a catalog?&lt;/p&gt;

flowchart LR
    A[2000&lt;br /&gt;Microsoft Certificate Services&lt;br /&gt;ships in Windows 2000 Server] --&amp;gt; B[2003&lt;br /&gt;V2 templates&lt;br /&gt;and autoenrollment]
    B --&amp;gt; C[2008&lt;br /&gt;Role renamed&lt;br /&gt;Active Directory&lt;br /&gt;Certificate Services]
    C --&amp;gt; D[2019&lt;br /&gt;de Drouas notes&lt;br /&gt;altSecurityIdentities abuse]
    D --&amp;gt; E[June 2021&lt;br /&gt;SpecterOps catalog&lt;br /&gt;ESC1 through ESC8]
    E --&amp;gt; F[2021 to 2022&lt;br /&gt;KB5005413&lt;br /&gt;CVE-2022-26923&lt;br /&gt;KB5014754]
    F --&amp;gt; G[2022 to 2023&lt;br /&gt;ESC9 to ESC12&lt;br /&gt;from Lyak Heiniger Knobloch]
    G --&amp;gt; H[2024&lt;br /&gt;ESC13 to ESC15&lt;br /&gt;Knudsen and Bollinger&lt;br /&gt;CVE-2024-49019]
    H --&amp;gt; I[2025&lt;br /&gt;ESC16&lt;br /&gt;strong-mapping full enforcement]
&lt;h2&gt;3. Six Primitives Every ESC Abuses&lt;/h2&gt;
&lt;p&gt;Before opening the catalog, install the vocabulary. Every ESC -- without exception -- abuses one of six primitives: the template, the issuing authority, the enrollment transport, the certificate mapping, the authentication bridge, and the persistence substrate. Once you have these six names in your head, the sixteen ESCs compose into a small grid.&lt;/p&gt;
&lt;h3&gt;The Template&lt;/h3&gt;
&lt;p&gt;A certificate template is an Active Directory object stored in the &lt;code&gt;CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration&lt;/code&gt; partition that tells an Enterprise CA what kind of certificate to issue and to whom. Templates carry their own DACL controlling who can enroll, who can write, and who can autoenroll. They carry a &lt;code&gt;msPKI-Certificate-Name-Flag&lt;/code&gt; attribute whose bits control how the Subject and Subject Alternative Name fields are populated. They carry an Extended Key Usage list that names what the certificate is permitted to do. And they carry a Manager Approval bit that gates whether issuance is automatic or whether a CA officer must approve each request [@msl-adcs-2012r2].&lt;/p&gt;

The Active Directory-stored object specifying who can request what kind of certificate from an Enterprise CA. Templates carry per-object DACLs (enrollment, autoenrollment, write), a `msPKI-Certificate-Name-Flag` controlling Subject and SAN behavior, an Extended Key Usage list, and a Manager Approval bit. V1 templates (Windows 2000) are non-modifiable; V2 templates (Windows Server 2003) are fully modifiable; V3 templates (Windows Server 2008) add Suite B cryptography.
&lt;p&gt;ESC1, ESC2, ESC3, ESC4, and ESC15 all attack the template. They differ only in which template property is misconfigured. (ESC9 also begins on a template flag, &lt;code&gt;CT_FLAG_NO_SECURITY_EXTENSION&lt;/code&gt;, but its effect lives in the mapping layer; we file it under mapping below, matching SpecterOps&apos;s own Certify taxonomy [@specterops-certify-docs-index].)&lt;/p&gt;
&lt;h3&gt;The Issuing Authority&lt;/h3&gt;
&lt;p&gt;An Enterprise CA is a Windows Server role service that signs certificate requests against published templates. To be trusted for authentication, the CA must be published into the forest&apos;s &lt;code&gt;NTAuthCertificates&lt;/code&gt; container. That container is the single list of CA certificates the Key Distribution Center trusts for PKINIT. The CA carries its own security descriptor controlling who can enroll, who can manage certificates, and who can manage the CA itself. It carries two registry flags that change its issuance behavior: &lt;code&gt;EDITF_ATTRIBUTESUBJECTALTNAME2&lt;/code&gt;, which permits requesters to specify arbitrary Subject Alternative Names, and &lt;code&gt;IF_ENFORCEENCRYPTICERTREQUEST&lt;/code&gt;, which controls whether RPC enrollment requires packet privacy [@compass-esc11]. The 2022 KB5014754 patch introduced &lt;code&gt;szOID_NTDS_CA_SECURITY_EXT&lt;/code&gt;, a Microsoft-specific extension carrying the requester&apos;s Security Identifier; that extension is the load-bearing artifact of the strong-mapping enforcement track [@kb5014754].&lt;/p&gt;

The AD-integrated certificate authority role in AD CS. Publishes certificate templates into Active Directory, processes certificate requests against those templates, and signs issued certificates with its private key. To be trusted for Windows authentication, the CA&apos;s certificate must be present in the forest-wide `NTAuthCertificates` container.

The AD-published container `CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration` listing CA certificates trusted by the Key Distribution Center for client authentication. Any certificate signed by a CA in this container can, given a valid mapping, mint a Kerberos Ticket-Granting Ticket. Publishing a CA into NTAuth is the moment that CA&apos;s private key becomes a trust root parallel to krbtgt.
&lt;p&gt;ESC5, ESC6, ESC7, and ESC16 attack the issuing authority itself -- its DACL, its registry flags, its extension policy. (ESC11&apos;s RPC packet-privacy gap is a CA-side configuration, but its abuse is an NTLM relay; we group it with ESC8 under transport, matching the §5 diagram.)&lt;/p&gt;
&lt;h3&gt;The Enrollment Transport&lt;/h3&gt;
&lt;p&gt;A certificate is requested over a network protocol. The default transport is DCOM/MS-WCCE -- the Windows Client Certificate Enrollment protocol, an RPC-based interface that ships enabled on every Enterprise CA [@ms-icpr-spec]. Additional transports ship as separate role services: HTTP Web Enrollment (IIS-based, with NTLM auth by default), the Certificate Enrollment Web Service (web service, supports basic and Kerberos), the Network Device Enrollment Service (the SCEP gateway), and the Certificate Enrollment Policy Web Service. Each transport is a network attack surface for relay primitives that route a coerced NTLM authentication into a certificate request.&lt;/p&gt;
&lt;p&gt;ESC8 attacks the HTTP Web Enrollment transport. ESC11 attacks the RPC transport. Both are &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;NTLM-relay attacks&lt;/a&gt;; they differ only in which transport the relayed authentication targets.&lt;/p&gt;
&lt;p&gt;The CA&apos;s security model distinguishes two rights that look similar but differ in scope. &lt;em&gt;Issue and Manage Certificates&lt;/em&gt; permits the holder to approve pending requests, revoke issued certificates, and read the request store. &lt;em&gt;Manage CA&lt;/em&gt; permits the holder to edit the CA&apos;s own configuration -- including its registry-controlled extension policy and its DACL. ESC7 attacks the latter. The escalation chain that follows ESC7 typically pivots to ESC4 (edit a template) or to issuing a certificate directly via a CA officer&apos;s request-approval right.&lt;/p&gt;
&lt;h3&gt;The Certificate Mapping&lt;/h3&gt;
&lt;p&gt;When a CA issues an authentication certificate, the certificate identifies a principal -- a user or a computer. The Key Distribution Center has to decide which Active Directory principal that certificate represents. Two mappings exist. &lt;em&gt;Implicit mapping&lt;/em&gt; reads the Subject Alternative Name (or the Subject, on older templates) and looks up the principal by User Principal Name. &lt;em&gt;Explicit mapping&lt;/em&gt; reads the AD principal&apos;s own &lt;code&gt;altSecurityIdentities&lt;/code&gt; attribute, which holds one or more X.509 issuer/serial expressions [@dedrouas-altsec]. The May 2022 KB5014754 patch redefined which mappings the KDC accepts: explicit mappings using &lt;code&gt;X509IssuerSerialNumber&lt;/code&gt;, &lt;code&gt;X509SKI&lt;/code&gt;, or &lt;code&gt;X509SHA1PublicKey&lt;/code&gt; are &lt;em&gt;strong&lt;/em&gt;; everything else is &lt;em&gt;weak&lt;/em&gt; and will be rejected once Full Enforcement is active [@kb5014754].&lt;/p&gt;

OID 1.3.6.1.4.1.311.25.2. The Microsoft certificate extension introduced by KB5014754 that embeds the SID of the requesting Active Directory principal directly into the issued certificate. When present, the KDC matches the certificate against the principal whose SID is embedded, defeating SAN-supply attacks like ESC1. The extension is the load-bearing mechanism of strong mapping enforcement.

Per KB5014754, explicit `altSecurityIdentities` entries using the `X509IssuerSerialNumber`, `X509SKI`, or `X509SHA1PublicKey` formats are *strong*. All other formats -- including implicit UPN and SAN matching -- are *weak* and rejected once Full Enforcement mode is active (February 11, 2025 default; legacy-mapping registry override removed September 9, 2025) [@kb5014754]. The strong-mapping track was the single largest Microsoft mitigation of the ESC era.
&lt;p&gt;ESC9, ESC10, ESC13, and ESC14 all attack the mapping. They abuse the gap between what a certificate asserts and which AD principal the KDC binds it to.&lt;/p&gt;
&lt;h3&gt;The Authentication Step&lt;/h3&gt;
&lt;p&gt;This component is the part of Windows that turns a certificate into an authenticator. For &lt;a href=&quot;https://paragmali.com/blog/kerberos-in-windows-the-other-half-of-ntlmless/&quot; rel=&quot;noopener&quot;&gt;Kerberos&lt;/a&gt;, the protocol is PKINIT (RFC 4556 [@rfc4556]): client presents a cert, KDC validates the cert and the mapping, KDC issues a TGT. For TLS-based services -- LDAPS, RDP with smart card, IIS with client cert -- the protocol is Schannel. For the legacy smart-card pipeline, the path is the combination of the Smart Card Resource Manager and PKINIT.&lt;/p&gt;
&lt;p&gt;No ESC attacks this step directly. Every ESC must &lt;em&gt;cross&lt;/em&gt; it to convert a misconfigured template, ACL, or mapping into a usable authenticator. The authentication step is the choke point; it is also the point Microsoft has reshaped most heavily with KB5014754.&lt;/p&gt;
&lt;h3&gt;The Persistence Substrate&lt;/h3&gt;
&lt;p&gt;An issued certificate is not a transient credential. It is a signed authenticator with a configurable validity period (one year is common, ten years is permitted). The certificate authenticates the embedded principal as long as the certificate is valid and not revoked. That property is what the SpecterOps paper&apos;s &lt;code&gt;DPERSIST&lt;/code&gt; and &lt;code&gt;THEFT&lt;/code&gt; classes attack [@cpo-blog]. UnPAC-the-Hash recovers the NTLM hash from a PKINIT-issued TGT, giving the attacker a password-equivalent credential they did not previously have. The Golden Certificate attack steals the CA&apos;s own private key, granting forever-issuance against the entire forest.&lt;/p&gt;
&lt;p&gt;This article scopes those attacks to a sidebar; the body walks the ESC1 to ESC16 escalation catalog. But every ESC ends in the persistence substrate: the certificate the attacker walks out with is the receipt that survives password rotation.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A &lt;em&gt;primitive&lt;/em&gt; is a Microsoft-shipped knob, flag, ACL, or protocol that, when misconfigured, becomes part of an escalation. An &lt;em&gt;exploitation chain&lt;/em&gt; is the specific sequence of operator actions that turns one or more misconfigured primitives into a Domain Admin authenticator. ESCs are exploitation chains, not primitives. ESC1, for example, abuses the &lt;em&gt;template&lt;/em&gt; primitive&apos;s &lt;code&gt;CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT&lt;/code&gt; bit, combined with the &lt;em&gt;bridge&lt;/em&gt; primitive (PKINIT), to produce the authenticator. The catalog enumerates chains; the six categories above enumerate the substrate.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now that the vocabulary is in place, sixteen named attacks compose neatly onto a 6 by 16 grid. Here is the moment they did.&lt;/p&gt;

flowchart TD
    T[Template&lt;br /&gt;per-template DACL&lt;br /&gt;Name-Flag bits&lt;br /&gt;EKU list&lt;br /&gt;Manager Approval]
    A[Issuing Authority&lt;br /&gt;NTAuth membership&lt;br /&gt;CA security descriptor&lt;br /&gt;EDITF flags&lt;br /&gt;extension policy]
    X[Enrollment Transport&lt;br /&gt;RPC/MS-WCCE&lt;br /&gt;HTTP Web Enrollment&lt;br /&gt;CES/CEP&lt;br /&gt;NDES/SCEP]
    M[Certificate Mapping&lt;br /&gt;implicit UPN/SAN&lt;br /&gt;explicit altSecurityIdentities&lt;br /&gt;strong vs weak&lt;br /&gt;SID extension]
    B[Authentication Bridge&lt;br /&gt;PKINIT for Kerberos&lt;br /&gt;Schannel for TLS&lt;br /&gt;smart-card pipeline]
    P[Persistence Substrate&lt;br /&gt;validity period&lt;br /&gt;UnPAC-the-Hash&lt;br /&gt;Golden Certificate&lt;br /&gt;CRL bypass]
    T --&amp;gt; A
    A --&amp;gt; X
    X --&amp;gt; B
    A --&amp;gt; M
    M --&amp;gt; B
    B --&amp;gt; P
&lt;h2&gt;4. Certified Pre-Owned&lt;/h2&gt;
&lt;p&gt;Will Schroeder pushes the SpecterOps Medium post live on June 17, 2021. (A revision tagged &lt;code&gt;[EDIT 06/22/21]&lt;/code&gt; follows the next week; the literature settles on &quot;June 2021&quot; as the canonical date [@cpo-blog].) The whitepaper PDF drops in the same window and is rehosted on the SpecterOps domain the following year [@cpo-whitepaper]. Seven weeks later, on August 5, Schroeder and Christensen present &lt;em&gt;Certified Pre-Owned: Abusing Active Directory Certificate Services&lt;/em&gt; at Black Hat USA 2021. Three GhostPack tools ship to GitHub on schedule: PSPKIAudit for defense [@pspkiaudit-gh], Certify for offense [@certify-gh], and ForgeCert for Golden Certificate work.&lt;/p&gt;
&lt;p&gt;The paper names eight escalation paths and three persistence and theft prefixes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ESC1 through ESC8&lt;/strong&gt; -- &lt;em&gt;escalation&lt;/em&gt; paths from a low-privilege foothold to Domain Admin&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DPERSIST&lt;/strong&gt; -- &lt;em&gt;domain persistence&lt;/em&gt; via forged certificates after CA private-key compromise&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;THEFT&lt;/strong&gt; -- &lt;em&gt;certificate and credential theft&lt;/em&gt; primitives, including the UnPAC-the-Hash technique&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DETECT&lt;/strong&gt; -- &lt;em&gt;defensive detection&lt;/em&gt; primitives the team mapped to each abuse&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The contribution was not the &lt;em&gt;discovery&lt;/em&gt; of new individual primitives. Most of the individual misconfigurations had appeared in Microsoft&apos;s hardening guidance or in scattered community posts well before the paper. ENROLLEE_SUPPLIES_SUBJECT had been a documented warning for a decade. NTLM relay to IIS had been a known attack class since at least 2008. The &lt;code&gt;EDITF_ATTRIBUTESUBJECTALTNAME2&lt;/code&gt; flag was a documented option in &lt;code&gt;certutil&lt;/code&gt; since Windows Server 2008 R2. What the paper contributed was the &lt;em&gt;unified catalog&lt;/em&gt; -- numbered identifiers, reproducible exploitation, a tool that enumerated each path, and a single document tying every abuse to its primitive and its mitigation.&lt;/p&gt;

While AD CS is not installed by default for Active Directory environments, from our experience in enterprise environments it is widely deployed, and the security ramifications of misconfigured certificate service instances are enormous. -- Will Schroeder and Lee Christensen, *Certified Pre-Owned* (June 2021) [@cpo-blog]
&lt;p&gt;Microsoft&apos;s response was uncharacteristically fast. KB5005413 published in late July 2021 -- roughly six weeks after the blog -- recommending Extended Protection for Authentication and &quot;Require SSL&quot; on the AD CS Web Enrollment and Certificate Enrollment Web Service role services [@kb5005413]. The KB closes ESC8 over HTTPS when EPA is enabled. It does not close ESC1 through ESC7, and it does not close ESC11 (which had not yet been named).&lt;/p&gt;
&lt;p&gt;The &quot;ESC&quot; prefix is an acronym for &lt;em&gt;escalation&lt;/em&gt;. The catalog uses three sibling prefixes from the same paper: &lt;code&gt;DPERSIST&lt;/code&gt; for &lt;em&gt;domain persistence&lt;/em&gt;, &lt;code&gt;THEFT&lt;/code&gt; for credential and certificate theft, and &lt;code&gt;DETECT&lt;/code&gt; for defensive detection identifiers. ESC numbering is consecutive but not contiguous in time -- ESC12 (a hardware substrate attack) was disclosed by Knobloch in October 2023 [@knobloch-esc12] [@knobloch-esc12-archive], four months before Knudsen disclosed ESC13 and ESC14 from SpecterOps. The numbering tracks the order of community disclosure, not a planned roadmap.&lt;/p&gt;
&lt;p&gt;Here is the observation that this article will load-bear: the breakthrough was &lt;em&gt;naming&lt;/em&gt;, not discovery. Until SpecterOps named the eight configurations, every one of them had been documented somewhere in Microsoft Learn or in a community blog. The hardening documentation had existed for years and had produced essentially no defensive prioritization in real enterprises. Microsoft Defender for Identity did not flag ESC1 templates. BloodHound did not graph ESC4-shaped DACLs. SIEMs did not ingest CA Event ID 4886. No commercial scanner shipped a rule for the Enrollee-Supplies-Subject bit. The reason was not that the information was inaccessible. The reason was that the &lt;em&gt;configurations had no names&lt;/em&gt; -- and an enterprise security program cannot prioritize against an unnamed configuration.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Naming is itself a defensive primitive. The 2021 SpecterOps catalog converted twenty-one years of unnamed admin-tunable knobs into a numbered backlog that scanners could enumerate, BloodHound could path-find, MSRC could patch, and operators could prioritize. Every subsequent mitigation generation -- KB5005413, CVE-2022-26923, KB5014754, CVE-2024-49019, BloodHound CE ADCS edges, Locksmith, Microsoft Defender for Identity&apos;s posture assessments -- builds on the catalog rather than on the underlying hardening documentation. The catalog is the security primitive; the patches are downstream of the catalog.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Eight ESCs in 2021. Within fifteen months, two researchers extended the catalog past the original boundary: Oliver Lyak at the Institute For Cyber Risk added ESC9 and ESC10 in August 2022 [@lyak-certipy-4-archive]; Sylvain Heiniger at Compass Security added ESC11 in November 2022 [@compass-esc11]. Hans-Joachim Knobloch added ESC12 in October 2023 [@knobloch-esc12]. SpecterOps&apos;s Jonas Bülow Knudsen added ESC13 in February 2024 [@knudsen-esc13] and ESC14 two weeks later [@knudsen-esc14]. Justin Bollinger at TrustedSec added ESC15 in October 2024 [@bollinger-ekuwu]. Lyak named ESC16 in 2025 against a workaround Schroeder himself had documented in 2022 [@specterops-esc16-docs]. Sixteen ESCs by the time you read this. Here is what each one does.&lt;/p&gt;
&lt;h2&gt;5. The Catalog: ESC-1 through ESC-16&lt;/h2&gt;
&lt;p&gt;Of the sixteen named ESCs, the original eight name the surface; ESC9 through ESC16 name the residual after every Microsoft mitigation shipped to date. We walk them in primitive-grouped order, following the same taxonomy the SpecterOps Certify documentation uses: template misconfigurations, access-control vulnerabilities, CA configuration issues, certificate mapping issues, and one hardware-substrate sidebar [@specterops-certify-docs-index].&lt;/p&gt;
&lt;h3&gt;Template misconfigurations: ESC1, ESC2, ESC3&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;ESC1 -- Misconfigured Certificate Template.&lt;/strong&gt; A V2 template that lets a low-privilege principal enroll, has Client Authentication in its Extended Key Usage list, has &lt;code&gt;CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT&lt;/code&gt; set, and does &lt;em&gt;not&lt;/em&gt; require Manager Approval. The attacker requests a certificate naming the target principal in the Subject Alternative Name; the CA issues; the certificate maps via UPN to the target; PKINIT produces a TGT as the target. One operator chain: &lt;code&gt;certipy req -u user -p pass -ca CA -template VulnTemplate -upn administrator@domain.local&lt;/code&gt;. First disclosed by SpecterOps in June 2021 [@cpo-blog]. BloodHound CE edge: &lt;code&gt;ADCSESC1&lt;/code&gt; [@bh-esc1-edge].&lt;/p&gt;

The `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` bit in `msPKI-Certificate-Name-Flag`. When set, the requester is allowed to supply the Subject or Subject Alternative Name in the CSR rather than having the CA build the Subject from the requester&apos;s own AD attributes. This is the load-bearing primitive of ESC1.

```powershell
Get-ADObject -SearchBase &quot;CN=Certificate Templates,CN=Public Key Services,CN=Services,$((Get-ADRootDSE).configurationNamingContext)&quot; -Filter * -Properties msPKI-Certificate-Name-Flag, pKIExtendedKeyUsage, msPKI-Enrollment-Flag |
  Where-Object {
    ($_.&apos;msPKI-Certificate-Name-Flag&apos; -band 0x1) -ne 0 -and
    ($_.&apos;msPKI-Enrollment-Flag&apos; -band 0x2) -eq 0 -and
    ($_.pKIExtendedKeyUsage -contains &apos;1.3.6.1.5.5.7.3.2&apos;)
  } | Select-Object Name
```
The query lists templates with ESS set, no manager approval, and Client Authentication EKU. Locksmith, PSPKIAudit, and Certipy all run a logically equivalent check; this is the smallest reproducible form for an audit script that does not depend on a vendor tool.
&lt;p&gt;&lt;strong&gt;ESC2 -- Any-Purpose or Subordinate CA EKU.&lt;/strong&gt; A template that grants the Any-Purpose EKU (&lt;code&gt;2.5.29.37.0&lt;/code&gt;) or the Subordinate CA EKU permits the certificate to be used for arbitrary purposes, including subordinate CA work. The attacker enrolls and then forges new certificates against the issued certificate&apos;s keypair. First disclosed by SpecterOps, June 2021 [@cpo-blog]. No BloodHound CE edge; the abuse pattern lives in Certify and Certipy [@certipy-wiki-priv].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ESC3 -- Enrollment Agent Template.&lt;/strong&gt; A template with the &lt;em&gt;Certificate Request Agent&lt;/em&gt; EKU lets the holder enroll certificates &lt;em&gt;on behalf of other users&lt;/em&gt;. Combined with a second template flagged &quot;Enrollment Agent&quot; the attacker can request a certificate naming any principal. The chain is two requests rather than one. SpecterOps, June 2021 [@cpo-blog]. BloodHound CE edge: &lt;code&gt;ADCSESC3&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Access-control vulnerabilities: ESC4, ESC5, ESC7&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;ESC4 -- Vulnerable Certificate Template ACL.&lt;/strong&gt; Any principal with &lt;code&gt;GenericAll&lt;/code&gt;, &lt;code&gt;GenericWrite&lt;/code&gt;, &lt;code&gt;WriteOwner&lt;/code&gt;, or &lt;code&gt;WriteDacl&lt;/code&gt; on a template can modify the template into an ESC1-shaped configuration and then enroll. This converts a write right on a template object into Domain Admin. SpecterOps, June 2021 [@cpo-blog]. BloodHound CE edge: &lt;code&gt;ADCSESC4&lt;/code&gt;.The ADCSESC4 edge composes with BloodHound&apos;s general DACL graph, so a &lt;code&gt;Domain Users&lt;/code&gt; principal that holds &lt;code&gt;WriteDacl&lt;/code&gt; on a sensitive template inherits the path automatically without a hand-written query. The edge composes naturally with the rest of BloodHound&apos;s principal-DACL graph -- a &lt;code&gt;Domain Users&lt;/code&gt; principal with &lt;code&gt;WriteDacl&lt;/code&gt; on the template inherits the path.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ESC5 -- Vulnerable PKI Object ACL.&lt;/strong&gt; The same class of write rights on the CA computer object, the &lt;code&gt;NTAuthCertificates&lt;/code&gt; container, or the AIA container. Compromising any of these gates the entire AD CS substrate. SpecterOps, June 2021 [@cpo-blog]. No BloodHound CE edge today; the surface is wide and the operator chain depends on the specific object compromised.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ESC7 -- Vulnerable CA ACL.&lt;/strong&gt; A principal with the &lt;em&gt;Manage CA&lt;/em&gt; right on the Enterprise CA can edit its registry-controlled configuration (including the &lt;code&gt;EDITF_ATTRIBUTESUBJECTALTNAME2&lt;/code&gt; flag, which converts the CA into a global ESC6 condition). A principal with &lt;em&gt;Issue and Manage Certificates&lt;/em&gt; can approve their own otherwise-blocked certificate requests. SpecterOps, June 2021 [@cpo-blog]. No BloodHound CE edge; the abuse is a CA-side write rather than an AD principal-graph relationship.&lt;/p&gt;
&lt;h3&gt;CA configuration issues: ESC6, ESC8, ESC11&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;ESC6 -- &lt;code&gt;EDITF_ATTRIBUTESUBJECTALTNAME2&lt;/code&gt; on the CA.&lt;/strong&gt; When this CA-wide flag is set, &lt;em&gt;every&lt;/em&gt; certificate request can specify an arbitrary Subject Alternative Name regardless of the template&apos;s Name-Flag bits. The CA becomes globally ESC1-shaped against any template the attacker can enroll into. SpecterOps, June 2021 [@cpo-blog]. BloodHound CE edges: &lt;code&gt;ADCSESC6a&lt;/code&gt; and &lt;code&gt;ADCSESC6b&lt;/code&gt; (the latter for cases where the CA also disables the SID extension).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ESC8 -- NTLM Relay to AD CS HTTP Web Enrollment.&lt;/strong&gt; The AD CS Web Enrollment role service ships with NTLM authentication enabled and, by default, no Extended Protection for Authentication. An attacker who can coerce a target computer to authenticate (PetitPotam, PrinterBug, DFSCoerce) can relay that authentication to the CA&apos;s &lt;code&gt;/certsrv/&lt;/code&gt; endpoint, request a certificate naming the relayed principal, and walk away with a certificate impersonating the coerced computer -- including Domain Controllers. SpecterOps, June 2021 [@cpo-blog]. BloodHound CE graphs this as the &lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt; edge [@bh-coerce-adcs-edge]: a Group-to-Computer edge whose source is &lt;code&gt;Authenticated Users&lt;/code&gt; and whose destination is the coerced target computer, with the edge&apos;s evaluation conditioned on at least one ESC8-vulnerable Web Enrollment endpoint being reachable on the network.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; ESC8 needs no template misconfiguration. It needs a CA with HTTP Web Enrollment role service installed -- common in environments that ever provisioned smart cards or did web-based renewal -- and at least one computer account the attacker can coerce. Microsoft mitigated it with KB5005413 in July 2021 [@kb5005413], but the mitigation is configuration guidance (EPA on, &quot;Require SSL&quot; on, Web Enrollment disabled if unused), not a binary patch. Environments that never enabled EPA on /certsrv/ remain exploitable today. The &quot;Domain Users to Domain Admin in eight minutes&quot; demos that pepper conference talks are usually ESC8 demos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;ESC11 -- NTLM Relay to ICPR/RPC.&lt;/strong&gt; The ICertPassage RPC interface (the default enrollment transport on every Enterprise CA) enforces packet privacy when the &lt;code&gt;IF_ENFORCEENCRYPTICERTREQUEST&lt;/code&gt; flag is set; that flag has been on by default since Windows Server 2012. However, because the flag breaks certificate enrollment for legacy Windows XP clients, Compass Security observed real-world environments where administrators had explicitly &lt;em&gt;removed&lt;/em&gt; the flag for compatibility, leaving the RPC enrollment surface unencrypted. When packet privacy is not enforced, an attacker can relay a coerced NTLM authentication into the CA&apos;s RPC interface and obtain a certificate impersonating the coerced principal. Disclosed by Sylvain Heiniger at Compass Security, November 2022 [@compass-esc11]. The SpecterOps Certify documentation describes the misconfiguration as &quot;an insufficiently protected certificate authority RPC interface&quot; [@specterops-esc11-docs]. No BloodHound CE edge; the RPC transport is below the principal-graph model.&lt;/p&gt;
&lt;h3&gt;Certificate mapping issues: ESC9, ESC10, ESC13, ESC14, ESC15, ESC16&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;ESC9 -- No Security Extension.&lt;/strong&gt; A template flagged &lt;code&gt;CT_FLAG_NO_SECURITY_EXTENSION&lt;/code&gt; instructs the CA to issue certificates &lt;em&gt;without&lt;/em&gt; the &lt;code&gt;szOID_NTDS_CA_SECURITY_EXT&lt;/code&gt; SID embedding. KB5014754&apos;s strong-mapping enforcement then falls back to weak UPN mapping, and the attacker can rename a controlled user account to match a privileged user&apos;s UPN, enroll, and authenticate as that privileged user. Disclosed by Oliver Lyak at IFCR on August 4, 2022, twelve weeks after KB5014754 [@lyak-certipy-4-archive]. BloodHound CE edges: &lt;code&gt;ADCSESC9a&lt;/code&gt; and &lt;code&gt;ADCSESC9b&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ESC10 -- Weak Certificate Mapping.&lt;/strong&gt; The registry values &lt;code&gt;StrongCertificateBindingEnforcement&lt;/code&gt; (on KDCs) and &lt;code&gt;CertificateMappingMethods&lt;/code&gt; (on Schannel servers) control whether weak mappings are accepted. In Compatibility mode (the KB5014754 staged-rollout default through February 11, 2025), weak mappings still pass. An attacker who can write &lt;code&gt;altSecurityIdentities&lt;/code&gt; on a target, or who can engineer a weak UPN match, authenticates as the target. Same disclosure: Lyak, August 4, 2022 [@lyak-certipy-4-archive]. BloodHound CE edges: &lt;code&gt;ADCSESC10a&lt;/code&gt; and &lt;code&gt;ADCSESC10b&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ESC13 -- Issuance Policy linked to AD Group via msDS-OIDToGroupLink.&lt;/strong&gt; Active Directory issuance-policy OIDs can be linked to a security group via the &lt;code&gt;msDS-OIDToGroupLink&lt;/code&gt; attribute. When a certificate carries that issuance-policy OID, the issued PAC includes the linked group. A template configured with such an issuance policy effectively grants its enrollees membership in the linked group at authentication time. Disclosed by Jonas Bülow Knudsen at SpecterOps on February 14, 2024; discovery credit goes to Adam Burford, who brought the technique to Knudsen and Stephen Hinck [@knudsen-esc13]. BloodHound CE edge: &lt;code&gt;ADCSESC13&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ESC14 -- Explicit altSecurityIdentities Write.&lt;/strong&gt; A principal with write access to a privileged user&apos;s &lt;code&gt;altSecurityIdentities&lt;/code&gt; attribute can add their own certificate&apos;s X.509 expression to that attribute, then authenticate as the privileged user. The prior art goes back to Géraud de Drouas in 2019 [@dedrouas-altsec] and Jean Marsault at Wavestone in June 2021 [@marsault-wavestone]; Knudsen catalogued it as ESC14 in February 2024 [@knudsen-esc14]. No BloodHound CE edge today; the abuse traces through a write right on a single AD attribute and is in scope for future BloodHound coverage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ESC15 -- V1 Template Application Policies Override (EKUwu).&lt;/strong&gt; The pre-installed V1 &lt;code&gt;WebServer&lt;/code&gt; template -- which ships on every CA, cannot be deleted, and is enrollable by &lt;code&gt;Authenticated Users&lt;/code&gt; by default -- accepts &lt;code&gt;Application Policies&lt;/code&gt; extensions in the request. Application Policies, a Microsoft extension parallel to standard EKU, are honored by the KDC. An attacker submits a CSR adding the Client Authentication Application Policy to a WebServer certificate, gets it signed, and authenticates as the requester. Disclosed by Justin Bollinger at TrustedSec on October 8, 2024 [@bollinger-ekuwu]. Microsoft assigned CVE-2024-49019 and patched it on November 12, 2024 [@cve-2024-49019-msrc]. No BloodHound CE edge.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ESC16 -- CA-wide SID Extension Disabled.&lt;/strong&gt; The CA&apos;s &lt;code&gt;DisableExtensionList&lt;/code&gt; registry value can list OIDs the CA will &lt;em&gt;omit&lt;/em&gt; from issued certificates. If &lt;code&gt;szOID_NTDS_CA_SECURITY_EXT&lt;/code&gt; (1.3.6.1.4.1.311.25.2) is on that list, the CA stops embedding the SID extension globally, and the strong-mapping enforcement of KB5014754 collapses into weak mapping for every certificate the CA issues. The SpecterOps Certify documentation records the punchline: &quot;The configuration was first described in 2022 by Will Schroeder in this blogpost as a temporary workaround for the interaction between ESC7 and ESC6, but was later tagged ESC16 by Oliver Lyak&quot; [@specterops-esc16-docs]. No BloodHound CE edge.&lt;/p&gt;

ESC12 lives in a different primitive category from every other ESC: it attacks the CA&apos;s HSM, not its software configuration. Hans-Joachim Knobloch&apos;s October 2023 disclosure (earliest Wayback snapshot dated October 24, 2023) observes that the YubiHSM2 Key Storage Provider on AD CS stores the HSM authentication key in cleartext under `HKEY_LOCAL_MACHINE\SOFTWARE\Yubico\YubiHSM\AuthKeysetPassword` [@knobloch-esc12] [@knobloch-esc12-archive]. A non-administrative user with shell access to the CA and read on that registry key can recover the HSM password and forge certificates against the HSM-backed CA key. Out of body scope for this article; readers running YubiHSM-backed CAs should read Knobloch&apos;s primary source.
&lt;p&gt;By the time you reach ESC10 here, a pattern is visible without anyone naming it: every Microsoft mitigation in this class is followed by a new ESC that side-steps it. KB5005413 closes ESC8 over HTTPS; ESC11 routes around it via RPC. KB5014754 closes ESC9 and ESC10 under Full Enforcement; ESC16 disables the underlying SID extension. CVE-2024-49019 closes ESC15 on V1 templates; the V1 templates themselves remain on every CA. The catalog grows faster than the patches.&lt;/p&gt;
&lt;p&gt;Of the sixteen entries above, BloodHound CE ships eleven principal-graph edges covering eight distinct ESCs: &lt;code&gt;ADCSESC1&lt;/code&gt;, &lt;code&gt;ADCSESC3&lt;/code&gt;, &lt;code&gt;ADCSESC4&lt;/code&gt;, &lt;code&gt;ADCSESC6a/b&lt;/code&gt;, &lt;code&gt;ADCSESC9a/b&lt;/code&gt;, &lt;code&gt;ADCSESC10a/b&lt;/code&gt;, &lt;code&gt;ADCSESC13&lt;/code&gt;, plus the &lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt; edge that graphs ESC8 [@bh-llms]. The remaining eight ESCs (ESC2, ESC5, ESC7, ESC11, ESC12, ESC14, ESC15, ESC16) are out of edge coverage today -- some because their primitive lives below the principal graph (ESC11&apos;s RPC transport), some because their abuse is a CA-side write rather than a domain principal relationship (ESC7, ESC5), and some because they are too new to have been edge-modeled (ESC14, ESC15, ESC16). The gap is structural and operationally significant; section eight explores why.&lt;/p&gt;

flowchart TD
    subgraph TEMPLATE[Template]
        E1[ESC1 ESS+ClientAuth+LowPriv&lt;br /&gt;SpecterOps 2021]
        E2[ESC2 AnyPurpose/SubCA&lt;br /&gt;SpecterOps 2021]
        E3[ESC3 Enrollment Agent&lt;br /&gt;SpecterOps 2021]
        E15[ESC15 V1 AppPolicy&lt;br /&gt;TrustedSec 2024]
    end
    subgraph ACL[Access Control]
        E4[ESC4 Template DACL&lt;br /&gt;SpecterOps 2021]
        E5[ESC5 PKI Object DACL&lt;br /&gt;SpecterOps 2021]
        E7[ESC7 CA DACL&lt;br /&gt;SpecterOps 2021]
    end
    subgraph CA[CA Configuration]
        E6[ESC6 EDITF SAN2&lt;br /&gt;SpecterOps 2021]
        E16[ESC16 Disable SID Ext&lt;br /&gt;tagged Lyak 2025]
    end
    subgraph TRANSPORT[Transport]
        E8[ESC8 Relay to HTTP&lt;br /&gt;SpecterOps 2021]
        E11[ESC11 Relay to RPC&lt;br /&gt;Compass 2022]
    end
    subgraph MAP[Mapping]
        E9[ESC9 No SID Ext&lt;br /&gt;IFCR 2022]
        E10[ESC10 Weak Mapping&lt;br /&gt;IFCR 2022]
        E13[ESC13 OIDToGroupLink&lt;br /&gt;SpecterOps 2024]
        E14[ESC14 altSecurityIdentities&lt;br /&gt;SpecterOps 2024]
    end
    subgraph HW[Hardware]
        E12[ESC12 YubiHSM Substrate&lt;br /&gt;Knobloch 2023]
    end
&lt;p&gt;The static rules that Certipy, Certify, Locksmith, and PSPKIAudit all run to decide whether a template is ESC1-shaped are simpler than the catalog above might suggest. Three boolean inputs, three conjunctive conditions, one output label.&lt;/p&gt;
&lt;p&gt;{`
function classifyTemplate(t) {
  const ess = t.flags.includes(&apos;CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT&apos;);
  const clientAuth = t.eku.includes(&apos;1.3.6.1.5.5.7.3.2&apos;);
  const lowPriv = t.enroll.some(p =&amp;gt; [&apos;Authenticated Users&apos;, &apos;Domain Users&apos;].includes(p));
  const noApproval = !t.flags.includes(&apos;CT_FLAG_PEND_ALL_REQUESTS&apos;);
  if (ess &amp;amp;&amp;amp; clientAuth &amp;amp;&amp;amp; lowPriv &amp;amp;&amp;amp; noApproval) return &apos;ESC1&apos;;
  return &apos;safe-for-now&apos;;
}&lt;/p&gt;
&lt;p&gt;const wifi = {
  flags: [&apos;CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT&apos;],
  eku:   [&apos;1.3.6.1.5.5.7.3.2&apos;],
  enroll:[&apos;Authenticated Users&apos;]
};
console.log(classifyTemplate(wifi));
`}&lt;/p&gt;
&lt;h2&gt;6. The 2026 Toolchain&lt;/h2&gt;
&lt;p&gt;Sixteen ESCs is too many for one tool. The 2026 state of the art is a stack: defenders run Locksmith, PSPKIAudit, BloodHound CE, and Microsoft Defender for Identity in parallel; offense runs Certipy and Certify. No single tool covers every ESC, prioritizes its findings, &lt;em&gt;and&lt;/em&gt; produces forensic primitives for response. Coverage gaps are structural, not accidental.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Certify&lt;/strong&gt; is the original offense-side tool from the SpecterOps team that wrote &lt;em&gt;Certified Pre-Owned&lt;/em&gt;. A C# Windows binary that enumerates and abuses AD CS misconfigurations using the operator&apos;s in-process credentials [@certify-gh]. Released at Black Hat 2021, built against .NET 4.7.2. Certify covers the ESC1 through ESC16 enumeration surface via its documentation pages [@specterops-certify-docs-index]; abuse implementations exist for the catalog&apos;s most operator-friendly entries, with ESC11 documented as enumeration-only at the most recent docs revision [@specterops-esc11-docs].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Certipy&lt;/strong&gt; is the Linux-side sibling, written in Python by Oliver Lyak at IFCR (now an independent project) [@certipy-gh]. The README carries the strongest coverage claim in the tool community: &quot;full support for identifying and exploiting all known ESC1-ESC16 attack paths.&quot; Certipy ships its own NTLM relay (&lt;code&gt;certipy relay&lt;/code&gt;), embedded BloodHound output, certificate forging, and PKINIT-to-TGT exchange. The Certipy wiki&apos;s privilege-escalation page is the best walking reference for the entire catalog [@certipy-wiki-priv].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BloodHound Community Edition&lt;/strong&gt; is the only tool in the stack that integrates AD CS findings into the broader Active Directory attack graph. SharpHound CE collects AD CS objects -- CAs, templates, NTAuth membership, per-template DACLs -- and the BloodHound server computes ten &lt;code&gt;ADCSESC*N*&lt;/code&gt; edges (ESC1, ESC3, ESC4, ESC6a/b, ESC9a/b, ESC10a/b, ESC13) plus the &lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt; edge that graphs ESC8 via coercion [@bh-llms]. BloodHound CE 7.x added Privilege Zones, which let defenders tag NTAuth CAs and their templates as Tier-Zero objects and surface paths to them in the analysis UI.&lt;/p&gt;

The principal-graph model treats each AD object as a node and each access right or trust as an edge. The graph then path-finds from a starting principal to a Tier-Zero target. This model works elegantly for template DACLs (ESC4) and CA DACLs (ESC7) and for issuance-policy group linkage (ESC13). It struggles with attacks where the abuse is a transport-level interaction rather than a principal-to-principal relationship.&lt;p&gt;ESC8 used to be considered uncatchable in this model. The &lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt; edge solved that: BloodHound CE now models the SMB-coercion-plus-NTLM-relay-to-ESC8 chain as a Group-to-Computer edge whose source is &lt;code&gt;Authenticated Users&lt;/code&gt; and whose destination is the coerced target computer; the relay target CA and the template are encoded in the edge&apos;s metadata, not as graph nodes [@bh-coerce-adcs-edge]. The edge exists because coercion has a stable shape -- an unauthenticated principal class, a target computer, and an ESC8-vulnerable CA endpoint reachable on the network -- that the graph can express.&lt;/p&gt;
&lt;p&gt;ESC11 remains harder. The RPC enrollment transport does not have a stable coercion model (the trigger is &lt;code&gt;ICertPassage&lt;/code&gt; packet privacy not being enforced, not a coercion gadget like &lt;code&gt;MS-EFSR&lt;/code&gt;), and the BloodHound graph today does not ship an &lt;code&gt;ADCSESC11&lt;/code&gt; edge. The model limit is partial, not total. The conventional &quot;BloodHound cannot graph transport attacks&quot; framing -- which was the prevailing folklore through 2024 -- is wrong; ESC8 is in the graph. ESC11 is the open structural case.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Locksmith&lt;/strong&gt; is a PowerShell defender tool by Jake Hildreth (with Spencer Alessi) [@locksmith-gh]. It runs locally on a domain-joined host and reports template, CA, and NTAuth-container findings against the catalog. Modes 0 through 4: identify-and-report, auto-remediate where safe, produce a CSV, and so on. The lowest-friction defender tool in the stack -- a single &lt;code&gt;Invoke-Locksmith&lt;/code&gt; cmdlet returns a triage list against the published ESC range.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PSPKIAudit&lt;/strong&gt; is the SpecterOps team&apos;s own defender baseline, built on top of PKI Solutions&apos; PSPKI module [@pspkiaudit-gh]. Its &lt;code&gt;Invoke-PKIAudit&lt;/code&gt; and &lt;code&gt;Get-CertRequest&lt;/code&gt; cmdlets cover ESC1 through ESC8 plus the &quot;Explicit Mappings&quot; surface for ESC14. The README is marked beta; PSPKIAudit predates Locksmith and ships fewer remediation primitives, but it is the canonical reference for what the original SpecterOps team thinks the defensive audit should do.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Microsoft Defender for Identity&lt;/strong&gt; ships the ADCS posture assessment suite when the MDI sensor is installed on the CA itself [@mdi-certs]. The current product surface assesses nine ESCs by name: ESC1 (Preview), ESC2, ESC3, ESC4 (split across two separate assessments -- template owner and template ACL), ESC6 (Preview), ESC7, ESC8, ESC11, and ESC15. The product page is explicit: &quot;This assessment is available only to customers who have installed a sensor on an AD CS server.&quot; MDI&apos;s coverage is &lt;em&gt;broad and operationally integrated&lt;/em&gt; -- the same SOC console that surfaces Pass-the-Hash detections now surfaces the largest named-ESC posture-assessment suite of any non-Certipy tool in the stack, with the ESC1 and ESC6 assessments shipped in Preview state.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The KB5014754 strong-mapping track&lt;/strong&gt; is Microsoft&apos;s runtime mitigation rather than a tool, but operationally it belongs in the stack discussion because it is the largest single thing Microsoft has shipped for this class [@kb5014754]. Strong mapping closes ESC9 and ESC10 (plus Certifried CVE-2022-26923) under Full Enforcement, defaults to Compatibility through February 11, 2025, and removes the legacy-mapping registry override on September 9, 2025. Operationally this is a deployment decision more than a &quot;tool to run&quot;, but every defender stack has to plan for it; the Microsoft Tech Community Intune blog is the cross-reference for environments using SCEP or PKCS [@ms-tc-intune].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Hacker Recipes AD CS chapter&lt;/strong&gt; is a community reference catalog rather than a runnable tool; it serves as the canonical operator-facing summary of every ESC and is worth bookmarking. (Network reachability of the canonical URL has been inconsistent in late 2025 / 2026.)&lt;/p&gt;
&lt;p&gt;Here is a single-table comparison of the practical stack. The right answer for a real enterprise is roughly &quot;all of them in parallel&quot;; the table makes the coverage gaps explicit.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool / track&lt;/th&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;ESC enumeration coverage&lt;/th&gt;
&lt;th&gt;Abuse capable&lt;/th&gt;
&lt;th&gt;Graph capable&lt;/th&gt;
&lt;th&gt;Best deployed for&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Certify&lt;/td&gt;
&lt;td&gt;C# (Windows)&lt;/td&gt;
&lt;td&gt;ESC1 to ESC16 (per docs)&lt;/td&gt;
&lt;td&gt;Yes (most)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Operator chains, Windows offense&lt;/td&gt;
&lt;td&gt;[@certify-gh]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Certipy&lt;/td&gt;
&lt;td&gt;Python (Linux)&lt;/td&gt;
&lt;td&gt;ESC1 to ESC16 (README claim)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Embedded&lt;/td&gt;
&lt;td&gt;Operator chains, Linux offense&lt;/td&gt;
&lt;td&gt;[@certipy-gh]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BloodHound CE ADCS edges&lt;/td&gt;
&lt;td&gt;Cypher&lt;/td&gt;
&lt;td&gt;8 of 16 ESCs (11 edges: ten ADCSESC&lt;em&gt;N&lt;/em&gt; + CoerceAndRelayNTLMToADCS)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Prioritization, attack-path analysis&lt;/td&gt;
&lt;td&gt;[@bh-llms]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Locksmith&lt;/td&gt;
&lt;td&gt;PowerShell&lt;/td&gt;
&lt;td&gt;Published ESC catalog&lt;/td&gt;
&lt;td&gt;Identify and fix&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Operational scans on each CA&lt;/td&gt;
&lt;td&gt;[@locksmith-gh]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PSPKIAudit&lt;/td&gt;
&lt;td&gt;PowerShell&lt;/td&gt;
&lt;td&gt;ESC1 to ESC8 plus Explicit Mappings&lt;/td&gt;
&lt;td&gt;No (read-only)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Defender baseline, audit&lt;/td&gt;
&lt;td&gt;[@pspkiaudit-gh]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MDI ADCS posture&lt;/td&gt;
&lt;td&gt;SaaS&lt;/td&gt;
&lt;td&gt;ESC1 (Preview), ESC2, ESC3, ESC4, ESC6 (Preview), ESC7, ESC8, ESC11, ESC15&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Inside MDI console&lt;/td&gt;
&lt;td&gt;SOC integration, posture scoring&lt;/td&gt;
&lt;td&gt;[@mdi-certs]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KB5014754 strong mapping&lt;/td&gt;
&lt;td&gt;Windows runtime&lt;/td&gt;
&lt;td&gt;ESC9, ESC10, Certifried (mitigation)&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;Domain Controllers (deploy)&lt;/td&gt;
&lt;td&gt;[@kb5014754]&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 most enterprises the realistic configuration is: Locksmith scheduled monthly on every CA; BloodHound CE with the ADCS collector enabled in SharpHound CE; Microsoft Defender for Identity sensor on every AD CS server (for the nine-ESC SOC visibility surface that now includes ESC1 and ESC6 in Preview); PSPKIAudit run once a quarter as the SpecterOps-blessed baseline; Certipy in the red-team or purple-team kit; and the KB5014754 rollout staged to land at Full Enforcement before February 11, 2025 (legacy-mapping removal September 9, 2025). The remaining gap items -- ESC5, ESC12, ESC14, and ESC16 (neither in BloodHound&apos;s principal graph nor in MDI&apos;s posture-assessment surface) -- are caught by Locksmith plus PSPKIAudit plus Certipy plus careful template review.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If no single tool covers everything, what is Microsoft actually doing about it?&lt;/p&gt;
&lt;h2&gt;7. What Microsoft Has Actually Shipped&lt;/h2&gt;
&lt;p&gt;Of sixteen named ESCs, Microsoft has shipped three CVE-class patches. The rest are hardening guidance. The asymmetry is not accidental; it tracks the boundary Microsoft draws in its &lt;a href=&quot;https://paragmali.com/blog/windows-security-boundaries-the-document-that-decides-what-g/&quot; rel=&quot;noopener&quot;&gt;Windows Security Servicing Criteria&lt;/a&gt; between &lt;em&gt;default-state vulnerabilities&lt;/em&gt; (which receive CVEs and binary patches) and &lt;em&gt;admin-configurable misconfigurations&lt;/em&gt; (which receive documentation). Most ESCs sit on the configurable side of that boundary.&lt;/p&gt;
&lt;p&gt;Four Microsoft mitigation tracks define the response, in order of when they shipped.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KB5005413 (late July 2021) -- NTLM Web Enrollment hardening.&lt;/strong&gt; Published roughly six weeks after &lt;em&gt;Certified Pre-Owned&lt;/em&gt; in response to PetitPotam plus the SpecterOps ESC8 disclosure [@kb5005413]. Recommends enabling Extended Protection for Authentication, requiring SSL on the &lt;code&gt;/certsrv/&lt;/code&gt; virtual directories of AD CS Web Enrollment and the Certificate Enrollment Web Service, and disabling NTLM where Kerberos is available. Crucially: KB5005413 is &lt;em&gt;guidance&lt;/em&gt;, not a binary patch. Environments that never enabled EPA on &lt;code&gt;/certsrv/&lt;/code&gt; remain exploitable today. The KB closes ESC8 over HTTPS when fully applied; it does not affect ESC11 (RPC), ESC1 through ESC7, or anything in the ESC9-plus range.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CVE-2022-26923 (May 10, 2022) -- Certifried.&lt;/strong&gt; The single MSRC-acknowledged CVE in the original ESC1 through ESC8 design space [@cve-2022-26923-nvd] [@cve-2022-26923-msrc]. Disclosed by Oliver Lyak at IFCR [@lyak-certifried], the vulnerability lets any Authenticated User (because the default &lt;code&gt;ms-DS-MachineAccountQuota&lt;/code&gt; is 10 [@semperis-cve]) create a computer account, write its &lt;code&gt;dNSHostName&lt;/code&gt; to match a Domain Controller, request a certificate from the default Machine template, and PKINIT as the DC. Microsoft patched it on the May 10, 2022 Patch Tuesday. Semperis&apos;s retrospective documents the chain in detail [@semperis-cve]. The patch closes &lt;em&gt;that specific path&lt;/em&gt; -- the &lt;code&gt;dNSHostName&lt;/code&gt; impersonation race -- and is part of the same Patch Tuesday that shipped KB5014754. It does not close any other ESC.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KB5014754 (May 10, 2022 -- present) -- the strong-mapping rollout.&lt;/strong&gt; The largest single Microsoft mitigation in the entire class [@kb5014754]. SpecterOps&apos;s own analysis -- &quot;Certificates and Pwnage and Patches, Oh My!&quot; -- remains the canonical walkthrough of how the new behavior interacts with the existing catalog [@specterops-pwnage].&lt;/p&gt;
&lt;p&gt;The mechanics: KB5014754 introduces the &lt;code&gt;szOID_NTDS_CA_SECURITY_EXT&lt;/code&gt; extension (OID 1.3.6.1.4.1.311.25.2), embeds the requester&apos;s SID into every issued certificate by default, and redefines which &lt;code&gt;altSecurityIdentities&lt;/code&gt; mappings the KDC will accept. Deployment is staged across three modes -- Disabled, Compatibility, and Full Enforcement -- with the Full Enforcement transition originally planned for November 2023, then repeatedly delayed in response to customer compatibility issues with SCEP, Intune PKCS, and non-Microsoft PKIs. The KB&apos;s current text states that Full Enforcement becomes the default on February 11, 2025, and the legacy compatibility-mode registry override is removed by the September 9, 2025 Windows security update [@kb5014754].&lt;/p&gt;
&lt;p&gt;What it closes: ESC9 (because Full Enforcement rejects certificates lacking the SID extension), ESC10 (because weak mappings are rejected), and Certifried even on unpatched templates. It is &lt;em&gt;bypassed&lt;/em&gt; by ESC16, which disables the SID extension at the CA level.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CVE-2024-49019 (EKUwu / ESC15) -- November 12, 2024.&lt;/strong&gt; Patched thirty-five days after Bollinger&apos;s October 8, 2024 disclosure [@bollinger-ekuwu]. The November 12, 2024 Patch Tuesday addressed the V1 WebServer template Application-Policies override [@cve-2024-49019-nvd] [@cve-2024-49019-msrc]. The patch hardens the KDC&apos;s interpretation of Application Policies in V1 certificates; it does not close ESC16, ESC11, or anything in the template DACL space.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Microsoft&apos;s Windows Security Servicing Criteria reserves CVEs for vulnerabilities in default product state [@msrc-servicing-criteria]. Misconfigurations that require administrator action to introduce are treated as hardening matters and receive documentation rather than CVEs. The 2019 ANSSI altSecurityIdentities report received a &quot;won&apos;t fix&quot; response on exactly these grounds [@dedrouas-altsec]. The boundary explains the catalog&apos;s CVE asymmetry: ESC1 (template flag) is configuration; Certifried (a default-template behavior on an account-creation-default-permission interaction) is a CVE. ESC15 sat on the boundary -- the affected template is shipped pre-installed and cannot be uninstalled, so its default-state could be argued either way -- and Microsoft chose to issue a CVE. The boundary is operational policy, not technical bound; it can move.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The single most useful table in this article is the cross-reference of which Microsoft mitigation closes which ESC. Read row by row to understand which ESCs are runtime-closed in a hardened environment and which remain dependent on the customer&apos;s administrative hardening discipline.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ESC&lt;/th&gt;
&lt;th&gt;KB5005413 (2021)&lt;/th&gt;
&lt;th&gt;CVE-2022-26923 (2022)&lt;/th&gt;
&lt;th&gt;KB5014754 (2022-2025)&lt;/th&gt;
&lt;th&gt;CVE-2024-49019 (2024)&lt;/th&gt;
&lt;th&gt;Hardening only&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;ESC1&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Partial (SID ext defeats SAN supply for cert-authn)&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Primary mitigation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC2&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC3&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Partial (SID ext binds the cert to the agent)&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC4&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC5&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC6&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Partial (SID ext defeats requested SAN)&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC7&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC8 (HTTP)&lt;/td&gt;
&lt;td&gt;Closed when EPA + SSL deployed&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Continues if EPA off&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC9&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Closed at Full Enforcement&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Until Feb 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC10&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Closed at Full Enforcement&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Until Feb 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC11 (RPC)&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Primary (&lt;code&gt;IF_ENFORCEENCRYPTICERTREQUEST&lt;/code&gt; flag)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC12&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Primary (HSM hardening)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC13&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC14&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC15&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Closed (Nov 12, 2024)&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESC16&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Bypassed (this attack disables the extension)&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Of sixteen ESCs, three have CVE-class binary patches (Certifried, EKUwu, and -- if you count it -- the KB5005413 NTLM-relay hardening track), two are runtime-closed under KB5014754 Full Enforcement, and the remaining eleven are administrative hardening matters. If only three of sixteen have CVEs, what stops the catalog from growing forever?&lt;/p&gt;
&lt;h2&gt;8. The Two-Trust-Roots Problem&lt;/h2&gt;
&lt;p&gt;What stops the catalog from growing forever is the architectural property the catalog enumerates around but cannot eliminate. The catalog grows because the property is structural, not because the engineering is sloppy. Four pieces of theory anchor the limit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Two trust roots.&lt;/strong&gt; Active Directory&apos;s Kerberos KDC will mint a Domain Admin Ticket-Granting Ticket on presentation of any valid certificate signed by a CA in the forest&apos;s &lt;code&gt;NTAuthCertificates&lt;/code&gt; container, provided the certificate maps to the Administrator principal. The &lt;code&gt;krbtgt&lt;/code&gt; key is the symmetric root of trust for password and TGS authentication; an NTAuth CA&apos;s private key is an asymmetric root of trust for PKINIT. There is no architectural relationship between the two. Rotating the &lt;code&gt;krbtgt&lt;/code&gt; key does not invalidate any certificate. Revoking a CA does not invalidate &lt;code&gt;krbtgt&lt;/code&gt;-issued tickets. They are &lt;em&gt;independent authenticator-minting keys&lt;/em&gt;. For a forest with $n$ NTAuth-published CAs, the count of independent keys that can mint a Domain Admin authenticator is $n + 1$.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; For an Active Directory forest with $n$ Certificate Authorities published into &lt;code&gt;NTAuthCertificates&lt;/code&gt;, there are exactly $n + 1$ independent keys that can mint a Domain Admin authenticator: the krbtgt account hash, and the private key of every published CA. Rotating krbtgt closes one root. Revoking one CA closes another. The other $n - 1$ remain. The ESC catalog enumerates &lt;em&gt;how&lt;/em&gt; an attacker can make those keys issue a Domain Admin authenticator with low-privilege materials; the architectural property -- that there are $n + 1$ such keys at all -- is a design property of PKINIT and is not closable by any patch [@rfc4556] [@cpo-whitepaper].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;PKINIT&apos;s binding gap.&lt;/strong&gt; RFC 4556 specifies how a Kerberos client presents a certificate and receives a TGT [@rfc4556]. The RFC does not bind the certificate to a Microsoft SID; the mapping from certificate to AD principal is a Microsoft extension. The KB5014754 strong-mapping track closes the &lt;em&gt;mapping ambiguity&lt;/em&gt; by embedding the requester&apos;s SID into the certificate and matching the SID on the KDC side [@kb5014754]. It does not close the underlying primitive: a certificate is an alternate identity assertion that the KDC honors as long as the signing CA is trusted. Different ESCs find different ways to get a useful certificate; the authentication step is identical across the catalog.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The transport-versus-principal split.&lt;/strong&gt; The §6 BloodHound Aside develops this in full: BloodHound&apos;s principal-graph model now expresses ESC8 as the &lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt; edge, but ESC11 remains the open structural case because the RPC transport has no equivalent coercion gadget [@bh-coerce-adcs-edge]. The model limit is partial, not total -- it applies to RPC, not to all transport attacks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The configuration-versus-CVE boundary.&lt;/strong&gt; The §7 Callout develops this in full. The catalog has accumulated CVEs only when Microsoft judged the configuration was default-state -- Certifried&apos;s machine-account-quota path and ESC15&apos;s pre-installed V1 templates. The architectural property is policy-driven and movable.&lt;/p&gt;

Active Directory has two trust roots that can mint a Domain Admin authenticator: the krbtgt key, and any CA published into NTAuth. Rotating one does not touch the other.
&lt;p&gt;The architectural property reshapes how operators should think about the catalog. The catalog is not an arms race that ends; the catalog is the community mapping the surface of a design property of PKINIT. Each new ESC narrows the description of &lt;em&gt;what surface remains exposed&lt;/em&gt;; no plausible patch removes the underlying $n + 1$ key count. Until PKINIT itself is replaced -- until PKINIT is deprecated, until the KDC stops accepting certificate-based authentication, until NTAuth-published CAs lose their KDC trust -- every NTAuth-published CA in the forest is a key parallel to krbtgt.&lt;/p&gt;
&lt;p&gt;If the architectural limit cannot be closed, what are the open questions in 2026?&lt;/p&gt;

flowchart LR
    K[krbtgt account hash&lt;br /&gt;symmetric KDC key]
    CA1[CA #1 private key&lt;br /&gt;published in NTAuth]
    CA2[CA #2 private key&lt;br /&gt;published in NTAuth]
    CAN[CA #n private key&lt;br /&gt;published in NTAuth]
    KDC[Kerberos KDC&lt;br /&gt;and PKINIT]
    AUTH[Domain Admin&lt;br /&gt;authenticator TGT]
    K --&amp;gt; KDC
    CA1 --&amp;gt; KDC
    CA2 --&amp;gt; KDC
    CAN --&amp;gt; KDC
    KDC --&amp;gt; AUTH
&lt;h2&gt;9. Open Problems and the Catalog&apos;s Closure&lt;/h2&gt;
&lt;p&gt;The catalog has no published closure principle. Here are the five open frontiers in 2026.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No closure principle.&lt;/strong&gt; The catalog has grown every year since 2021: ESC1 through ESC8 in June 2021; ESC9 and ESC10 in August 2022; ESC11 in November 2022; ESC12 in October 2023 [@knobloch-esc12] [@knobloch-esc12-archive]; ESC13 and ESC14 in February 2024; ESC15 in October 2024; ESC16 named in 2025 against a workaround from 2022 [@specterops-esc16-docs]. ESC15 revealed a twenty-four-year-old default behavior on V1 templates -- behavior that had been quietly present since the role&apos;s 2000 shipping date [@bollinger-ekuwu]. The Certify documentation conjectures an upper bound (the six primitive categories times the misconfigurable bits per primitive) but no formal upper bound is published. ESC15 is itself an existence proof that &lt;em&gt;new categories&lt;/em&gt; still emerge: Application Policies as a parallel to standard EKU was not in the original 2021 catalog at all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Detection asymmetry.&lt;/strong&gt; Most ESCs leave artifacts on the CA -- specifically Event ID 4886 (certificate request submitted) and Event ID 4887 (certificate issued) -- and no artifact in the standard Active Directory event stream. Most SIEMs do not ingest CA logs, because CA logs were never on the standard Tier-Zero ingest checklist. The result is that the CA&apos;s own audit log carries the only reliable forensic primitive for the entire catalog, and that log is in a place the SOC does not look. Locksmith and PSPKIAudit can identify the &lt;em&gt;misconfigurations&lt;/em&gt; but cannot tell you whether they have been &lt;em&gt;exploited&lt;/em&gt;; that signal lives in the CA&apos;s audit log alone.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Strong-mapping migration risk.&lt;/strong&gt; The KB5014754 staged rollout enters Full Enforcement on February 11, 2025 and removes the legacy compatibility-mode registry override on September 9, 2025 [@kb5014754]. Environments with legacy SCEP gateways, third-party PKI vendors, Intune PKCS profiles without strong mapping, or smart cards issued by non-Microsoft CAs face a real risk that &lt;em&gt;legitimate&lt;/em&gt; authentication breaks at Full Enforcement. The Microsoft Tech Community Intune guidance is the operational reference for the SCEP/PKCS path [@ms-tc-intune]. The migration is a security upgrade and a deployment minefield in the same package; environments that defer the rollout past September 9, 2025 lose the legacy override and are forced into Full Enforcement by an OS update they did not opt into.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Per the live KB5014754 text on Microsoft Support: &quot;By February 2025, if the StrongCertificateBindingEnforcement registry key is not configured, domain controllers will move to Full Enforcement mode&quot; and &quot;the option to move back to Compatibility mode will remain until the September 9, 2025, Windows security update is installed&quot; [@kb5014754]. Environments that have not finished the strong-mapping rollout by those dates -- particularly those with non-Microsoft PKI in the chain, including legacy SCEP / Intune PKCS / smart-card vendors -- should plan for breakage and have a rollback plan ready.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Cloud PKI.&lt;/strong&gt; Entra-managed Cloud PKI changes the substrate: the issuing CA is Microsoft-operated, the template surface is partially exposed to administrators, and the trust relationship between Cloud PKI and on-premises Active Directory is itself a configurable bridge. The community has not yet published an ESC catalog for Cloud PKI; the on-premises catalog is on-prem-specific and does not transfer directly. The open question is whether the Cloud PKI substrate has its own equivalent primitives (a CA-side &quot;this template is configured with ESS-equivalent behavior&quot;) that just have not yet been named.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The NTLM dependency in ESC8 and ESC11.&lt;/strong&gt; Both ESC8 and ESC11 depend on NTLM authentication being available between the coerced computer and the CA host. Microsoft&apos;s stated direction is to disable NTLM by default in future Windows releases (the &quot;NTLM disablement&quot; track) [@ms-ntlm-evolution]. If that direction completes, ESC8 and ESC11&apos;s relay primitives lose their substrate -- not because the AD CS transport hardens, but because there is no NTLM authentication to relay. The rest of the catalog -- the template, ACL, mapping, and CA-configuration ESCs -- does not depend on NTLM and is unaffected by NTLM disablement.&lt;/p&gt;
&lt;p&gt;Taken together, these results suggest the catalog&apos;s growth trajectory is structural. The reason ESC15 surfaced a twenty-four-year-old default is not that the SpecterOps team was lazy in 2021; it is that the surface is so large that systematic enumeration of every cross-product (six primitives multiplied by the configurable bits per primitive) is itself a research program. Knowing the architectural limits and the open problems, here is the operational playbook.&lt;/p&gt;
&lt;h2&gt;10. The Four-Lane Playbook&lt;/h2&gt;
&lt;p&gt;Here is what an enterprise security program actually does, in four lanes. Lane discipline matters because the catalog rewards parallel work: a single quarter spent only on Lane 1 leaves you detection-blind, and a single quarter spent only on Lane 2 leaves you remediation-paralyzed.&lt;/p&gt;
&lt;h3&gt;Lane 1: Preventive hygiene&lt;/h3&gt;
&lt;p&gt;Run Locksmith and PSPKIAudit on every Enterprise CA at least monthly [@locksmith-gh] [@pspkiaudit-gh]. Both tools enumerate the published catalog and produce a triage list. The defender baseline these tools encode is roughly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Template ACL audit. Confirm that no non-Tier-Zero principal holds &lt;code&gt;WriteDacl&lt;/code&gt;, &lt;code&gt;WriteOwner&lt;/code&gt;, &lt;code&gt;WriteProperty&lt;/code&gt;, or &lt;code&gt;GenericAll&lt;/code&gt; on any V2 template.&lt;/li&gt;
&lt;li&gt;CA security descriptor audit. Confirm that &lt;code&gt;Manage CA&lt;/code&gt; and &lt;code&gt;Issue and Manage Certificates&lt;/code&gt; are held only by Tier-Zero principals.&lt;/li&gt;
&lt;li&gt;ESS audit. Confirm that no template enrollable by &lt;code&gt;Authenticated Users&lt;/code&gt; or &lt;code&gt;Domain Users&lt;/code&gt; has &lt;code&gt;CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT&lt;/code&gt; set with Client Authentication EKU and no Manager Approval.&lt;/li&gt;
&lt;li&gt;CA registry audit. Confirm that &lt;code&gt;EDITF_ATTRIBUTESUBJECTALTNAME2&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; set, and &lt;code&gt;IF_ENFORCEENCRYPTICERTREQUEST&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; set.&lt;/li&gt;
&lt;li&gt;SID extension audit. Confirm that &lt;code&gt;szOID_NTDS_CA_SECURITY_EXT&lt;/code&gt; (OID 1.3.6.1.4.1.311.25.2) is &lt;em&gt;not&lt;/em&gt; present in any CA&apos;s &lt;code&gt;DisableExtensionList&lt;/code&gt; registry value -- closing the ESC16 path.&lt;/li&gt;
&lt;li&gt;Manager Approval on sensitive templates. Confirm that any template with privileged EKU sets has Manager Approval.&lt;/li&gt;
&lt;li&gt;Least-privilege Enroll. Confirm that Domain Users-equivalent groups do not hold Enroll or Autoenroll on sensitive templates.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Lane 2: Detection deployment&lt;/h3&gt;
&lt;p&gt;Ingest the CA&apos;s own Security event log into the SIEM. The two load-bearing events are 4886 (&quot;Certificate Services received a certificate request&quot;) and 4887 (&quot;Certificate Services approved a certificate request and issued a certificate&quot;). These events are what fire when an operator chain like the cold-open in section one executes. They are the only AD CS event stream the SOC needs to detect the entire issuance side of the catalog.&lt;/p&gt;
&lt;p&gt;Enable Microsoft Defender for Identity sensors on every AD CS server. MDI now ships nine named ESC posture assessments -- ESC1 (Preview), ESC2, ESC3, ESC4 (template owner and template ACL as two separate assessments), ESC6 (Preview), ESC7, ESC8, ESC11, and ESC15 -- and surfaces them in the same console the SOC uses for the rest of Active Directory [@mdi-certs]. The ADCS-resident sensor is the only MDI sensor that produces these particular assessments; environments running MDI on Domain Controllers only do not get the AD CS surface.&lt;/p&gt;
&lt;p&gt;Run SharpHound CE with the AD CS collection options enabled and ingest the resulting graph into BloodHound CE. Tag NTAuth-published CAs and their pre-installed sensitive templates as Tier Zero in BloodHound&apos;s Privilege Zones. Run the analysis layer&apos;s &lt;code&gt;Shortest Paths to Tier Zero&lt;/code&gt; query weekly; ESC1, ESC3, ESC4, ESC6a/b, ESC9a/b, ESC10a/b, and ESC13 will surface as edges, along with &lt;code&gt;CoerceAndRelayNTLMToADCS&lt;/code&gt; paths for any ESC8-vulnerable HTTP enrollment endpoint [@bh-llms] [@bh-coerce-adcs-edge].&lt;/p&gt;
&lt;p&gt;Schedule Locksmith on a recurring cadence with output to a triage queue. Locksmith is the lowest-friction defender tool; it identifies and (with mode 1) optionally fixes published-catalog findings with a single cmdlet.&lt;/p&gt;
&lt;h3&gt;Lane 3: Confirmed-compromise response&lt;/h3&gt;
&lt;p&gt;This lane carries the article&apos;s load-bearing operational claim. If a CA&apos;s private key is suspected compromised -- whether through ESC12 hardware-substrate compromise, through &lt;code&gt;ntdsutil&lt;/code&gt;-equivalent CA export, or through a vendor compromise of the HSM -- the recovery path is &lt;em&gt;not&lt;/em&gt; &quot;rotate krbtgt&quot; and &lt;em&gt;not&lt;/em&gt; &quot;revoke the affected certificates&quot;. The recovery path is multi-week:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Revoke the CA&apos;s published certificate chain.&lt;/li&gt;
&lt;li&gt;Decommission the CA (remove the role service, delete the CA private key store, retire the host).&lt;/li&gt;
&lt;li&gt;Build a replacement CA on new hardware with a new key.&lt;/li&gt;
&lt;li&gt;Publish the new CA into &lt;code&gt;NTAuthCertificates&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Distrust the old CA&apos;s certificates throughout the forest (CRL update, certificate revocation lists pushed via Group Policy, decommissioning all certificates issued by the compromised CA).&lt;/li&gt;
&lt;li&gt;Re-issue every credential that depended on the compromised CA.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This operation is analogous in scale and duration to a forest rebuild for &lt;code&gt;krbtgt&lt;/code&gt; compromise -- a multi-week IR project, not a one-day patch. The reason is the two-trust-roots property: revoking the CA closes only one of the $n + 1$ keys; if the operator already minted Golden Certificates against the CA&apos;s private key, those certificates outlive the revocation unless every issued serial is on the CRL and every relying party has a fresh CRL fetch policy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Lane-3 CA rebuild operation is the single most important &lt;em&gt;preparatory&lt;/em&gt; deliverable in this entire playbook. Run a tabletop exercise: &quot;the CA private key is compromised; what are the steps to a clean state?&quot; If the answer is unclear in the absence of an incident, the answer will be improvised during one -- typically poorly. Build the runbook, identify the operational owners, pre-stage the replacement CA&apos;s hardware, and document the certificate inventory you will need to re-issue. The two-week recovery becomes a one-week recovery if the prep is done; the two-week recovery becomes a four-week recovery if it is not.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Lane 4: What does not work&lt;/h3&gt;
&lt;p&gt;Five operator myths that the catalog refutes by construction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&quot;Rotating krbtgt closes AD CS.&quot;&lt;/strong&gt; Wrong. Rotating krbtgt closes the symmetric KDC key; it does not touch the asymmetric CA private keys in &lt;code&gt;NTAuthCertificates&lt;/code&gt;. An ESC1 certificate issued against the new krbtgt mints a Domain Admin TGT the same way it would have against the old one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&quot;Credential Guard protects against ESC.&quot;&lt;/strong&gt; Wrong. &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&apos;s LSAISO&lt;/a&gt; isolates LSASS-resident credentials from the rest of the OS. AD CS abuse does not touch LSAISO; the certificate is issued by the CA against a request submitted over a network protocol. The credential never leaves the attacker&apos;s machine in a form Credential Guard could isolate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&quot;Disabling Web Enrollment closes AD CS.&quot;&lt;/strong&gt; Partial. Disabling the AD CS Web Enrollment role service closes ESC8 (the HTTP relay primitive). It does not affect ESC1 through ESC7 (template, ACL, and CA-config attacks), ESC11 (RPC relay), or any of the mapping ESCs. The default RPC enrollment transport on every Enterprise CA is unaffected.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&quot;If we patch CVE-2022-26923 we&apos;re done.&quot;&lt;/strong&gt; Wrong. CVE-2022-26923 closes the specific &lt;code&gt;dNSHostName&lt;/code&gt; machine-account-impersonation chain. It does not close ESC1, ESC4, or any of the configuration ESCs that the same operator chain could have taken.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&quot;Reset krbtgt twice and we have evicted the attacker.&quot;&lt;/strong&gt; Wrong. The double-krbtgt-reset playbook is well-suited for Golden Ticket eviction. It is not effective against an attacker who has issued a long-validity authentication certificate from a CA the attacker controls or has compromised. The issued certificate authenticates against the new krbtgt the same way it did against the old one, because PKINIT does not bind the certificate&apos;s authority to the symmetric krbtgt key.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Run Locksmith this week. Tag NTAuth CAs as Tier Zero in BloodHound. Schedule the Lane 3 rebuild playbook before you need it. The catalog grew faster than the patches; the defender&apos;s only working strategy is parallel work in all four lanes.&lt;/p&gt;
&lt;h2&gt;11. Frequently Asked Questions&lt;/h2&gt;

The SID extension is on by default for any CA running an OS that has installed KB5014754 or later. The catch is what the *KDC* does with that extension. Switching the KDC to Full Enforcement breaks every certificate that lacks the SID extension, which is why Microsoft built the three-mode staged rollout: the §7 timeline anchors the compatibility window (mechanics and the Feb 11, 2025 / Sep 9, 2025 milestones), and the §9 Callout carries the verbatim KB5014754 dates and the customer compatibility-friction set (legacy SCEP, Intune PKCS, non-Microsoft PKI, third-party smart cards). ESC16 closes the loop in the other direction: an admin (or a compromised admin) can re-disable the extension at the CA level, recreating the weak-mapping condition KB5014754 was designed to close.

Partially. The on-premises ESC catalog enumerates misconfigurations of the on-premises AD CS role. Entra Cloud PKI is a Microsoft-operated SaaS CA whose substrate is not the on-premises AD CS Windows role at all -- so ESCs that abuse on-premises CA registry flags (ESC6, ESC16), on-premises CA DACLs (ESC5, ESC7), or the on-premises transport (ESC8, ESC11) do not transfer directly. But Cloud PKI still issues authentication certificates, still has a template-equivalent administrative surface, and still maps certificates onto AD or Entra principals. The community has not yet published a Cloud PKI ESC catalog; the open question is whether the cross-product of Cloud PKI&apos;s primitive surface and its mapping behavior has its own equivalent class of named misconfigurations.

No. A two-tier hierarchy improves protection of the *root* CA&apos;s private key (the root signs only the subordinate&apos;s certificate and stays offline) but does nothing for the subordinate. The ESC catalog attacks the issuing subordinate, not the root. The misconfigured Enrollee-Supplies-Subject template, the editable `EDITF_ATTRIBUTESUBJECTALTNAME2` registry flag, the per-template DACL, the NTLM-relayable Web Enrollment endpoint -- all live on the subordinate CA. A two-tier hierarchy is the right architecture and is essentially orthogonal to the ESC discussion.

No. Smart cards are *consumers* of certificates issued by AD CS; the smart-card pipeline reads a certificate off the card, presents it to PKINIT, and receives a TGT. AD CS is the *issuing* substrate. Every ESC attacks the issuance side. A smart-card deployment depends on AD CS being correctly configured; it adds no defense against ESC1 through ESC16 and may add complexity in the strong-mapping migration (smart-card-issued certificates may use legacy mappings that break under Full Enforcement).

No. BloodHound CE does not ship a numbered `ADCSESC8` edge. It ships `CoerceAndRelayNTLMToADCS`, an edge representing &quot;a computer can be SMB-coerced to authenticate to an attacker host, and the attacker host can relay that authentication to an ESC8-vulnerable Web Enrollment endpoint on a CA&quot; [@bh-coerce-adcs-edge]. Look for that edge, not for a numbered ESC8 edge. If `CoerceAndRelayNTLMToADCS` paths exist anywhere in the graph, your Web Enrollment endpoint is ESC8-exposed and the operator chain from any coercible computer to a Domain Admin authenticator runs in eight minutes.

ESC12 is treated in the §5 Aside: Knobloch&apos;s October 2023 YubiHSM hardware-substrate disclosure (earliest Wayback snapshot dated October 24, 2023), scoped out of the body because the abuse depends on the specific HSM vendor and on shell access to the CA host [@knobloch-esc12] [@knobloch-esc12-archive]. ESC0 does not exist in the SpecterOps catalog; some operator blogs use &quot;ESC0&quot; informally to describe naive enumeration (no abuse, just &quot;the CA is reachable and the template store is readable&quot;) but it is not a community-named technique.
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;ad-cs-esc-catalog&quot; keyTerms={[
  { term: &quot;PKINIT&quot;, definition: &quot;RFC 4556 protocol extension that lets a client authenticate to Kerberos with a certificate and receive a TGT.&quot; },
  { term: &quot;NTAuthCertificates&quot;, definition: &quot;Forest-wide AD container listing CA certificates trusted by the KDC for client authentication. Publication here makes a CA&apos;s key a trust root parallel to krbtgt.&quot; },
  { term: &quot;ENROLLEE_SUPPLIES_SUBJECT&quot;, definition: &quot;msPKI-Certificate-Name-Flag bit (CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT) that lets the requester specify the certificate Subject or SAN; primary primitive of ESC1.&quot; },
  { term: &quot;EDITF_ATTRIBUTESUBJECTALTNAME2&quot;, definition: &quot;CA-side registry flag that lets any request include a SAN of choice; primary primitive of ESC6.&quot; },
  { term: &quot;szOID_NTDS_CA_SECURITY_EXT&quot;, definition: &quot;OID 1.3.6.1.4.1.311.25.2; certificate extension carrying the requester SID. Introduced in KB5014754; load-bearing element of strong mapping.&quot; },
  { term: &quot;Strong vs Weak Mapping&quot;, definition: &quot;Per KB5014754: X509IssuerSerialNumber, X509SKI, X509SHA1PublicKey are strong; UPN, SAN, and other formats are weak and rejected under Full Enforcement.&quot; },
  { term: &quot;ADCSESC1&quot;, definition: &quot;BloodHound CE edge representing an ESC1 path: low-priv principal can enroll into a template with ESS + Client Authentication EKU.&quot; },
  { term: &quot;CoerceAndRelayNTLMToADCS&quot;, definition: &quot;BloodHound CE edge representing the ESC8 chain: SMB-coerce a computer, relay NTLM auth to the CA&apos;s Web Enrollment endpoint, get a certificate impersonating the coerced computer.&quot; }
]} questions={[
  { q: &quot;Why does rotating krbtgt not close the AD CS escalation paths?&quot;, a: &quot;Because every NTAuth-published CA&apos;s private key is a separate authenticator-minting trust root parallel to krbtgt. PKINIT honors any valid certificate signed by an NTAuth CA. Rotating krbtgt does not touch those private keys.&quot; },
  { q: &quot;Of the sixteen named ESCs, how many have received CVE-class Microsoft patches and which ones?&quot;, a: &quot;Three: CVE-2022-26923 (Certifried, the dNSHostName impersonation chain, May 2022), CVE-2024-49019 (EKUwu / ESC15, V1 template Application Policies override, November 2024), and the KB5005413 NTLM-relay hardening track for ESC8 (July 2021, configuration guidance rather than a binary patch).&quot; },
  { q: &quot;What is the difference between ESC8 and ESC11, and why does BloodHound CE graph one but not the other?&quot;, a: &quot;Both are NTLM relay attacks against AD CS. ESC8 relays to the HTTP Web Enrollment role service (/certsrv/). ESC11 relays to the default RPC enrollment transport (ICertPassage). BloodHound graphs ESC8 as the CoerceAndRelayNTLMToADCS edge because SMB coercion plus HTTP relay has a stable principal-graph shape; ESC11&apos;s RPC trigger (IF_ENFORCEENCRYPTICERTREQUEST not set) does not have an equivalent coercion gadget that the principal-graph model can express.&quot; },
  { q: &quot;Which ESC bypasses KB5014754&apos;s strong-mapping enforcement?&quot;, a: &quot;ESC16. The CA&apos;s DisableExtensionList registry value can list the szOID_NTDS_CA_SECURITY_EXT OID, instructing the CA to omit the SID extension from every certificate it issues. The KDC then falls back to weak mapping for those certificates, defeating the strong-mapping enforcement.&quot; },
  { q: &quot;What is the recommended Lane 3 response if a CA&apos;s private key is suspected compromised?&quot;, a: &quot;Revoke the CA&apos;s chain, decommission the CA, build a replacement on new hardware, publish the new CA into NTAuthCertificates, distrust the old CA&apos;s certificates throughout the forest, and re-issue every credential that depended on the compromised CA. A multi-week IR operation analogous in scale to a forest rebuild for krbtgt compromise.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>active-directory</category><category>ad-cs</category><category>pkinit</category><category>kerberos</category><category>red-team</category><category>security</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>KRBTGT: The Account That Owns Active Directory</title><link>https://paragmali.com/blog/krbtgt-the-account-that-owns-active-directory/</link><guid isPermaLink="true">https://paragmali.com/blog/krbtgt-the-account-that-owns-active-directory/</guid><description>Active Directory ships with one cryptographic key whose disclosure forges valid TGTs for every principal -- and why rotating it is necessary but not sufficient.</description><pubDate>Sat, 23 May 2026 00:00:00 GMT</pubDate><content:encoded>
Active Directory&apos;s `krbtgt` account is the one secret in any Windows domain whose disclosure forges valid Ticket-Granting Tickets for every principal -- including ones that do not exist. Twelve years of attacks (Golden, Diamond, Sapphire) and Microsoft&apos;s responses (the MS14-068 patch, KrbtgtFullPacSignature, the two-reset rotation procedure) converge on one fact: krbtgt rotation invalidates forged TGTs but does not recover the systemic compromise that produced them. That distinction is why confirmed krbtgt compromise is a forest-rebuild event in modern incident-response playbooks, not a key-rotation event.
&lt;h2&gt;1. Ninety Seconds to Domain Admin&lt;/h2&gt;
&lt;p&gt;A single &lt;code&gt;mimikatz kerberos::golden&lt;/code&gt; command, with the krbtgt account&apos;s AES-256 long-term key in hand, walks the attacker onto any resource in the domain as Administrator. No Domain Admin password was reset. No Domain Admin account was created. No SACL on a sensitive object fired. No LSASS on any host was dumped. No signature-based IDS rule triggered. The attacker holds exactly one cryptographic key -- the long-term key of the RID-502 service account named &lt;code&gt;krbtgt&lt;/code&gt; -- and the entire Kerberos trust hierarchy of the domain now accepts whatever they sign [@mitre-t1558001]. The section title&apos;s &quot;ninety seconds&quot; is an illustration of how fast the attack is on the wall clock, not a measured demonstration from a published primary.&lt;/p&gt;
&lt;p&gt;The operator sequence is short enough to quote. Earlier in the engagement, the attacker ran &lt;code&gt;lsadump::dcsync /user:contoso\krbtgt&lt;/code&gt; from a member-server foothold and walked off with the krbtgt long-term key material [@mimikatz]. Then they switched tools to forge a ticket from scratch:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mimikatz # kerberos::golden /domain:contoso.local
                            /sid:S-1-5-21-1004336348-1177238915-682003330
                            /aes256:&amp;lt;key&amp;gt;
                            /user:Administrator /id:500
                            /groups:512,513,518,519,520 /ptt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That single command, documented by Sean Metcalf for operators in 2015 [@adsec-1640], does the forgery in process memory, injects the ticket into the local Kerberos cache (&lt;code&gt;/ptt&lt;/code&gt; = pass-the-ticket), and lets the next &lt;code&gt;dir \\dc01\admin&lt;/code&gt; succeed.&lt;/p&gt;
&lt;p&gt;Count the controls that did not fire while the forged ticket was being minted and presented. No Domain Admin password reset, because the attacker never used a Domain Admin password. No new privileged account, because the attacker impersonated an existing one (RID 500). No SACL on a sensitive object, because the ticket was already approved by the Kerberos trust root before any object was touched. No LSASS dump on a writeable DC, because &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; is a replication API call, not a memory scrape [@mitre-t1003006]. No IDS hit on a known-malicious payload, because Mimikatz lives in attacker process memory and the wire traffic is, structurally, a TGS-REQ. No anomalous logon time, MFA prompt, or Conditional Access decision, because Kerberos pre-authentication is satisfied by holding a valid TGT and the TGT was minted offline.&lt;/p&gt;
&lt;p&gt;The article&apos;s load-bearing thesis: within the Kerberos trust root of a single domain, the krbtgt key is the unique secret whose disclosure yields valid TGTs for every principal -- including ones that do not exist. The technical recovery (two-reset rotation) is well-documented [@ms-forest-recovery] and does cryptographically invalidate forged tickets. But the operational recovery from a confirmed krbtgt compromise is a forest-rebuild event for reasons that have nothing to do with the krbtgt key itself.&lt;/p&gt;
&lt;p&gt;This produces an apparent contradiction. Microsoft documents a clean two-reset rotation procedure with a ten-hour interval [@ms-forest-recovery]; Mandiant- and SpecterOps-style incident-response playbooks treat confirmed krbtgt compromise as a forest-rebuild event [@specterops-dot2]. Both statements are simultaneously true. The job of the next ten thousand words is to explain why -- starting with what krbtgt actually is. Not the key. Not the protocol. The account itself: RID 502, disabled, indelible.&lt;/p&gt;
&lt;h2&gt;2. The Account: RID 502, Disabled, Indelible&lt;/h2&gt;
&lt;p&gt;Open Active Directory Users and Computers on a fresh Windows Server 2022 domain promoted ten seconds ago. In the &lt;code&gt;Users&lt;/code&gt; container there is an account called &lt;code&gt;krbtgt&lt;/code&gt;. It has no password visible to the admin. It is disabled. Try to enable it -- the checkbox accepts the click, but the next replication cycle puts the account right back into the disabled state. Try to rename it -- the operation appears to succeed, but the &lt;code&gt;objectSID&lt;/code&gt; does not change. Try to delete it -- the operation fails outright. You cannot log in as it; the disabled-for-interactive-logon property is enforced inside the Security Accounts Manager. The account exists exactly because the domain exists; the lifetime of the account and the lifetime of the domain are the same lifetime [@ms-default-accounts].&lt;/p&gt;
&lt;p&gt;Why does Active Directory ship with an account that no admin can use, no attacker can authenticate as interactively, and no operator can remove?&lt;/p&gt;

The Kerberos Ticket-Granting Ticket service account that exists, exactly once per Active Directory domain, to hold the long-term cryptographic key the domain controllers use to encrypt and sign every TGT issued in the domain. The account name itself is the Kerberos principal name (`krbtgt/DOMAIN@DOMAIN`) inherited from MIT&apos;s 1988 Kerberos v4 design.
&lt;p&gt;&lt;strong&gt;Creation.&lt;/strong&gt; The account is created automatically when the first writeable domain controller is promoted in a new domain. The Microsoft Learn default-accounts page lists it alongside &lt;code&gt;Administrator&lt;/code&gt; and &lt;code&gt;Guest&lt;/code&gt; as one of the three default local accounts in the &lt;code&gt;Users&lt;/code&gt; container, with the verbatim note that &quot;the KRBTGT account can&apos;t be enabled in Active Directory&quot; [@ms-default-accounts]. The account&apos;s lifecycle is bound to the domain&apos;s lifecycle; there is no operator-controllable provisioning of a krbtgt account, and no de-provisioning short of demoting the domain.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RID 502.&lt;/strong&gt; The relative identifier at the tail of the account&apos;s SID (&lt;code&gt;S-1-5-21-&amp;lt;domain&amp;gt;-502&lt;/code&gt;) is fixed by the well-known SID specification [@ms-sids]. Sean Metcalf&apos;s operator primer confirms the RID-502 binding directly: &quot;Each Active Directory domain has an associated KRBTGT account ... The SID for the KRBTGT account is &lt;code&gt;S-1-5-&amp;lt;domain&amp;gt;-502&lt;/code&gt;&quot; [@adsec-483].RIDs 500 through 1000 are reserved for built-in security principals; 500 is Administrator, 501 is Guest, 502 is krbtgt. Renaming the &lt;code&gt;sAMAccountName&lt;/code&gt; cannot move the RID. The KDC service derives its key lookups from the principal name, which binds to the RID, not from the friendly name shown in ADUC. Renaming krbtgt as a defensive measure is a fallacy that the next section will sharpen further.&lt;/p&gt;
&lt;p&gt;Each Read-Only Domain Controller has its own &lt;code&gt;krbtgt_&amp;lt;rid&amp;gt;&lt;/code&gt; account whose key signs only that RODC&apos;s tickets. The full-domain krbtgt account is read-only from the RODC&apos;s perspective -- the design property that lets RODCs participate in Kerberos without holding the full-domain trust root [@adsec-483].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Container.&lt;/strong&gt; &lt;code&gt;CN=Users,DC=&amp;lt;domain&amp;gt;&lt;/code&gt;. The standard Users container, not a Tier-0 OU or a Protected Users group. The account is privileged by virtue of its RID, not by virtue of its containership. Moving it into a different container does not change its semantic role to the KDC.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disabled for interactive logon.&lt;/strong&gt; Documented verbatim on the Microsoft Learn default-accounts page: &quot;The KRBTGT account can&apos;t be enabled in Active Directory&quot; [@ms-default-accounts]. The account is reserved for the KDC service. There is no interactive logon surface attached, no LSA logon-rights grant, no Kerberos pre-authentication path that produces a TGT &lt;em&gt;for&lt;/em&gt; the krbtgt account itself. The account exists to provide a key, not to authenticate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Indelible and unrenamable.&lt;/strong&gt; Also from the same Microsoft Learn page: &quot;This account can&apos;t be deleted, and the account name can&apos;t be changed&quot; [@ms-default-accounts]. ADUC will show a renamed display, but the underlying object identity (the RID, the principal name) is fixed by the directory schema and by &lt;code&gt;LsaSrv&lt;/code&gt; enforcement on the writeable DCs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Password.&lt;/strong&gt; System-generated, unknown to operators by design. Resetting it via ADUC produces a value Active Directory immediately replaces with a fresh system-generated value. The mechanism that produces the current key is therefore not operator-controllable; rotation is the only primitive operators have over the key value [@ms-forest-recovery].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Password history equals 2.&lt;/strong&gt; Documented verbatim on the AD Forest Recovery page: &quot;The password history value for the krbtgt account is 2, meaning it includes the two most recent passwords&quot; [@ms-forest-recovery]. This is the mechanical foundation for the two-reset procedure Section 7 will dissect. The KDC keeps both a &lt;em&gt;current&lt;/em&gt; and a &lt;em&gt;previous&lt;/em&gt; key in the krbtgt account; in-flight TGT validation tries both during the brief window after a rotation; one reset retires only the older of the two; a second reset, separated by at least the maximum ticket lifetime, evicts the key the attacker held.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where the key lives.&lt;/strong&gt; The KDC service (&lt;code&gt;kdcsvc.dll&lt;/code&gt;) on every writeable DC reads the krbtgt long-term key from &lt;code&gt;ntds.dit&lt;/code&gt; at startup and holds it in process memory for ticket signing and validation. &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;&apos;s VBS trustlet -- LSAISO -- does not isolate this read on writeable DCs by design: a DC &lt;em&gt;must&lt;/em&gt; read the key to issue tickets [@ms-credential-guard] (see also §10 Aside on why Credential Guard skips the DC). This is the structural asymmetry that makes the krbtgt key reachable to any attacker who can compromise a writeable DC (or invoke its replication API remotely), even on a system where Credential Guard is otherwise enforced everywhere else.&lt;/p&gt;
&lt;p&gt;We know what the account is now: a non-interactive, indelible, RID-502 service principal with a system-generated, two-slot password history. But the account is just the container. The rest of the article cares about the &lt;em&gt;long-term cryptographic key&lt;/em&gt; it holds.&lt;/p&gt;
&lt;h2&gt;3. The Key: What RFC 4120 and [MS-KILE] Specify&lt;/h2&gt;
&lt;p&gt;Hand a network capture of a Kerberos AS-REP to a Wireshark dissector. The dissector shows the TGT as a sequence of ASN.1 fields. One field is named &lt;code&gt;enc-part&lt;/code&gt; and its content is opaque. The dissector knows the format of what is &lt;em&gt;inside&lt;/em&gt; that opaque blob -- an &lt;code&gt;EncTicketPart&lt;/code&gt; -- but it cannot show the field values because the blob is encrypted [@rfc4120]. Encrypted under what? Under one key: the long-term key of the principal named &lt;code&gt;krbtgt/CONTOSO.LOCAL@CONTOSO.LOCAL&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The Microsoft specification puts it as plainly as is possible to put it. [MS-KILE] specifies that the KDC encrypts every ticket using the long-term cryptographic key of the krbtgt principal, citing RFC 4120 §5.2.2 [@mskile]. That sentence, more than any other in the Microsoft Open Specifications corpus, is the cryptographic foundation of Active Directory authentication. Every TGT issued by every writeable DC in the domain is encrypted under one key. There is no per-account key, no per-DC key, no rolling subkey. One key, one trust scope.&lt;/p&gt;

The credential the Kerberos Key Distribution Center issues at logon, encrypted under the KDC&apos;s own service key (in Windows, the krbtgt account&apos;s long-term key), that the client subsequently presents to request service tickets without re-authenticating with a password. RFC 4120 §5.3 defines its fields; [MS-KILE] specifies the Windows wire profile [@rfc4120][@mskile].

The Kerberos service that issues TGTs (the Authentication Service) and exchanges TGTs for service tickets (the Ticket-Granting Service). In Active Directory the KDC runs as `kdcsvc.dll` on every writeable domain controller; it holds the krbtgt long-term key in process memory for the lifetime of the service [@rfc4120].
&lt;h3&gt;Inside the encrypted blob&lt;/h3&gt;
&lt;p&gt;RFC 4120 §5.3 specifies the fields of the &lt;code&gt;EncTicketPart&lt;/code&gt;: a session key the KDC generates for this TGT, the client&apos;s name, the cross-domain transit path, the timestamps (&lt;code&gt;authtime&lt;/code&gt;, &lt;code&gt;starttime&lt;/code&gt;, &lt;code&gt;endtime&lt;/code&gt;, &lt;code&gt;renew-till&lt;/code&gt;), the optional client-address list, and a final field of &lt;code&gt;authorization-data&lt;/code&gt; that Windows uses to carry the Privilege Attribute Certificate [@rfc4120].&lt;/p&gt;

The Windows-specific data structure embedded inside the `authorization-data` field of every Kerberos ticket. The PAC carries the user&apos;s SID, the SIDs of every group the user belongs to, account restrictions, profile path, logon server, and a small set of cryptographic signatures the KDC computes to bind the structure to the ticket. Defined in [MS-PAC] [@mspac].
&lt;p&gt;The PAC is where the load-bearing security claim of Windows Kerberos lives. RFC 4120 itself does not care about groups; it cares about whether the client can prove identity to a server. The PAC carries the &lt;em&gt;authorization&lt;/em&gt; layer Windows needs on top of authentication: which security principal the ticket represents, which groups confer which permissions, which restrictions apply [@mspac]. The first thing a Windows file server does when it receives a service ticket is decode the PAC, read the SIDs, and run the access-check algorithm.&lt;/p&gt;
&lt;h3&gt;The three signatures inside every PAC&lt;/h3&gt;
&lt;p&gt;The PAC is integrity-protected by a small set of signatures the KDC computes when it issues the ticket. As of the [MS-PAC] revision 26.0 dated June 10, 2024 [@mspac], a TGT-resident PAC carries three of them:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The PAC server signature.&lt;/strong&gt; A keyed HMAC computed under the &lt;em&gt;service&lt;/em&gt; key. For a TGT the service is &lt;code&gt;krbtgt/DOMAIN&lt;/code&gt;, so the server signature is computed under the krbtgt long-term key. For a service ticket the server signature is computed under the service account&apos;s long-term key (the file server&apos;s machine-account key, for example) [@mspac].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The PAC KDC signature.&lt;/strong&gt; A keyed HMAC computed under the krbtgt long-term key, signing the bytes of the server signature. This is the pre-2022 anchor of PAC integrity: even if a service holding only its own key could verify the server signature, only the KDC (or anyone holding the krbtgt key) could compute the matching KDC signature. The &quot;pre-2022&quot; framing tracks the deployment of KB5020805&apos;s Full PAC Signature, documented in §5 Generation 6 [@kb5020805].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Full PAC Signature.&lt;/strong&gt; Added by Microsoft&apos;s response to CVE-2022-37967, deployed via KB5020805 starting November 8, 2022 and enforced by default since July 11, 2023 [@kb5020805][@cve-2022-37967]. Computed by the KDC over the &lt;em&gt;entire&lt;/em&gt; PAC -- including the older two signatures -- and stored alongside them. Also computed under the krbtgt long-term key.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

flowchart TD
    PAC[PAC contents: SIDs, groups, restrictions] --&amp;gt; SSig[Server Signature]
    PAC --&amp;gt; KSig[KDC Signature]
    PAC --&amp;gt; FSig[Full PAC Signature]
    SSig --&amp;gt; KEY[&quot;krbtgt long-term key (TGT)&quot;]
    KSig --&amp;gt; KEY
    FSig --&amp;gt; KEY
    KEY --&amp;gt; TGT[EncTicketPart for TGT]
    TGT --&amp;gt; WIRE[AS-REP / TGS-REP on the wire]
&lt;p&gt;This is the architectural fact the rest of the article will refer back to. The addition of the Full PAC Signature did not relocate the trust to a different key. All three PAC signatures on a TGT terminate at the krbtgt long-term key. An attacker who holds the krbtgt key computes all three correctly in the same step. This is the precise technical observation that motivates the Section 5 attack cascade and the Section 7 rotation analysis.&lt;/p&gt;
&lt;h3&gt;The enctype matrix&lt;/h3&gt;
&lt;p&gt;The krbtgt account does not hold a single key; it holds a set of keys, one per Kerberos encryption type advertised in &lt;code&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; on the account object. RFC 4120 §5.2.9 defines the enctype numbers; common Windows values are AES-256-CTS-HMAC-SHA1-96 (enctype 18), AES-128 (enctype 17), and the legacy RC4-HMAC (enctype 23) [@rfc4120]. AES-256 has been the recommended default for newly-provisioned krbtgt accounts since the Windows Server 2008 R2 / Windows Server 2012 functional levels, though early Windows Server 2008 deployments often required a krbtgt password reset to materialise the AES keys. The post-2017 AES-SHA2 family (enctypes 19 and 20) is defined by IETF but not deployed in mainline Windows production as of [MS-KILE] revision 47.0 dated April 27, 2026 [@mskile].&lt;/p&gt;

A numeric identifier for the cryptographic algorithm and key length used to encrypt a Kerberos message. RFC 4120 §5.2.9 enumerates them; common Windows values are 17 (AES-128), 18 (AES-256), and 23 (the legacy RC4-HMAC). Each principal&apos;s long-term key is derived per enctype, so the krbtgt account stores multiple key derivations side by side [@rfc4120].
&lt;p&gt;Each derivation is stored in both &lt;em&gt;current&lt;/em&gt; and &lt;em&gt;previous&lt;/em&gt; slots; rotating the krbtgt password rederives the entire set for the new password and shifts the previous derivations into the previous slot.&lt;/p&gt;
&lt;h3&gt;FAST armoring sits next to, not above, the krbtgt key&lt;/h3&gt;
&lt;p&gt;RFC 6113 / [MS-KILE] Flexible Authentication Secure Tunneling adds a second key layer for the client-facing pre-authentication exchange, armoring the AS-REQ under a separate channel key derived from a TGT the client already holds. FAST hardens pre-authentication against offline brute-force. It does not change the fact that the TGT&apos;s &lt;code&gt;enc-part&lt;/code&gt; is encrypted under the krbtgt key on its way back to the client [@mskile]. No Kerberos extension shipped through 2026 moves the TGT&apos;s trust anchor anywhere other than the krbtgt long-term key.&lt;/p&gt;

Within a Kerberos domain, every TGT reduces to the same key, and that key has a name: krbtgt.
&lt;p&gt;That sentence is the load-bearing claim the rest of the article rests on. The next section explains how a 1988 academic design decision became the cryptographic foundation of every Windows domain alive today.&lt;/p&gt;
&lt;p&gt;{`
// Simplified model of the three PAC signatures on a TGT.
// Each signature is a keyed HMAC computed under the krbtgt long-term key.
const pacContents = &quot;SIDs, groups, restrictions&quot;;
const krbtgtKey = &quot;&amp;lt;32-byte AES-256 long-term key&amp;gt;&quot;;&lt;/p&gt;
&lt;p&gt;function hmac(key, data) {
  return key === krbtgtKey
    ? &quot;SIG(&quot; + data + &quot;)&quot;           // attacker-with-key computes valid sigs
    : &quot;INVALID&quot;;                    // attacker-without-key cannot forge them
}&lt;/p&gt;
&lt;p&gt;function buildPACBlock(attackerKey) {
  const serverSig = hmac(attackerKey, pacContents);
  const kdcSig    = hmac(attackerKey, serverSig);
  const fullPAC   = hmac(attackerKey, pacContents + serverSig + kdcSig);
  const validates = [serverSig, kdcSig, fullPAC].every(s =&amp;gt; s !== &quot;INVALID&quot;);
  return { serverSig, kdcSig, fullPAC, validates };
}&lt;/p&gt;
&lt;p&gt;console.log(&quot;with krbtgt key   :&quot;, buildPACBlock(krbtgtKey).validates);
console.log(&quot;without krbtgt key:&quot;, buildPACBlock(&quot;guess-key&quot;).validates);
`}&lt;/p&gt;
&lt;h2&gt;4. Origins: 1988 Athena, RFC 4120, [MS-KILE]&lt;/h2&gt;
&lt;p&gt;Open the bibliography of RFC 4120 and find an entry tagged &lt;code&gt;[Ste88]&lt;/code&gt;: &quot;Steiner, J., Neuman, C., and J. Schiller, &apos;Kerberos: An Authentication Service for Open Network Systems,&apos; USENIX Conference Proceedings, February 1988&quot; [@rfc4120]. The principal name &lt;code&gt;krbtgt&lt;/code&gt; is in that paper. It has been carried forward unchanged through RFC 1510 (1993) [@rfc1510], through Active Directory&apos;s February 2000 release, through RFC 4120 (2005) [@rfc4120], through the first [MS-KILE] revision (2007), and into the current [MS-KILE] revision 47.0 dated April 27, 2026 [@mskile]. Thirty-eight years.&lt;/p&gt;
&lt;p&gt;What did the 1988 design decision look like, and what has changed about its security properties since?&lt;/p&gt;
&lt;h3&gt;MIT Project Athena, 1983-1991&lt;/h3&gt;
&lt;p&gt;Project Athena ran at MIT from 1983 to 1991 as a campus-scale distributed-computing experiment funded primarily by IBM and DEC [@project-athena]. The authentication problem Athena needed to solve was the one every multi-user network has needed to solve since: how do you let thousands of workstations talk to thousands of services without broadcasting cleartext passwords on every connection? Steiner, Neuman, and Schiller presented their answer at the Winter USENIX conference in Dallas in February 1988. Their design introduced the &lt;code&gt;krbtgt&lt;/code&gt; principal name and the trust property that one key encrypts every TGT in the Kerberos domain [@athena1988].&lt;/p&gt;
&lt;p&gt;The principal name &lt;code&gt;krbtgt&lt;/code&gt; predates Active Directory by twelve years. MIT&apos;s 1988 USENIX paper used the name, RFC 1510 standardised it in 1993 [@rfc1510], and Windows 2000 inherited it unchanged. There is no Microsoft-specific Kerberos principal naming convention; the convention is IETF.&lt;/p&gt;
&lt;p&gt;The design property that one key encrypts every TGT was not framed in 1988 as a security risk. It was framed as a &lt;em&gt;simplification&lt;/em&gt;: by giving the TGS one stable identity that issues every TGT, the protocol does not need to negotiate per-session KDC identities or per-server validation paths. The protocol reduces, mathematically, to two questions: did the KDC issue this TGT, and did the TGT permit the subsequent TGS-REQ for this service? Both reduce to &quot;does this signature validate under the krbtgt key?&quot;&lt;/p&gt;
&lt;h3&gt;From RFC 1510 to [MS-KILE]&lt;/h3&gt;
&lt;p&gt;John Kohl and Clifford Neuman published RFC 1510 in September 1993, standardising Kerberos version 5 [@rfc1510]. The &lt;code&gt;krbtgt/DOMAIN@DOMAIN&lt;/code&gt; principal-name convention carried forward unchanged from Athena. RFC 1510 is the document Microsoft engineers read when they chose Kerberos v5 as the Windows 2000 default authentication protocol; the krbtgt account became part of the AD schema at the Windows 2000 ship date (RTM December 15, 1999; general availability February 17, 2000) [@windows-2000]. The Microsoft Learn default-accounts page binds the two specifications to the same account: &quot;KRBTGT is also the security principal name used by the KDC for a Windows Server domain, as specified by RFC 4120&quot; [@ms-default-accounts].&lt;/p&gt;
&lt;p&gt;RFC 4120, published in July 2005 by Neuman, Yu, Hartman, and Raeburn, obsoleted RFC 1510 [@rfc4120]. The principal name carried forward unchanged again. Section 5.3 defines the wire format of a ticket; §6.2 defines the principal-name convention. Microsoft Open Specifications then published the first [MS-KILE] revision in March 2007, documenting the Windows wire profile on top of RFC 4120. The current revision -- 47.0, dated April 27, 2026 -- still says the same thing: the krbtgt long-term key encrypts every TGT [@mskile]. The Microsoft overlay on top of the IETF specification is the AD-account-management surface: RID 502 fixed, password system-generated, password-history-of-2, disabled-for-interactive-logon, automatic provisioning at first-DC promotion [@ms-default-accounts][@ms-forest-recovery].&lt;/p&gt;
&lt;p&gt;Every Kerberos domain on the public Internet today has a &lt;code&gt;krbtgt&lt;/code&gt; principal in it. The name has not moved in thirty-eight years. Only the AD-specific overlay is what gives this article its Windows-specific subject; the protocol substrate is older than the attack surface by twenty-six years.&lt;/p&gt;
&lt;p&gt;The principal name and the trust property are nearly forty years old. The exploit chain that targets them is twelve. The interesting question is what happened in the twelve years that turned an academic design decision into the most consequential single key in enterprise computing. That story has a beginning at Black Hat USA on August 7, 2014.&lt;/p&gt;
&lt;h2&gt;5. The Attack Cascade, 2014 to 2024&lt;/h2&gt;
&lt;p&gt;Six generations of attack span ten years. None of them found a way to forge a TGT &lt;em&gt;without&lt;/em&gt; the krbtgt key; the search space is mathematically closed in that direction. What they did instead is get progressively better at hiding the forgery inside genuine-looking wire traffic. By 2022, the forgery and the legitimate TGT are wire-indistinguishable. Here is how that arc unfolded.&lt;/p&gt;

gantt
    title Attack and defence generations
    dateFormat YYYY-MM-DD
    axisFormat %Y
    section Attack
    Gen 0 Academic baseline       :done, g0, 2000-02-01, 2014-08-05
    Gen 1 MS14-068 PAC forgery    :crit, g1, 2014-11-18, 90d
    Gen 2 Golden Ticket           :crit, g2, 2014-08-07, 2920d
    Gen 3 Silver Ticket           :       g3, 2015-01-01, 4000d
    Gen 4 Diamond Ticket          :crit, g4, 2022-06-21, 1700d
    Gen 5 Sapphire Ticket         :crit, g5, 2022-10-15, 1300d
    section Defence
    MS14-068 patch                :done, d1, 2014-11-18, 30d
    MDI alert family              :done, d2, 2016-01-01, 800d
    Full PAC Signature audit      :done, d3, 2022-12-13, 210d
    Full PAC Signature enforce    :done, d4, 2023-07-11, 90d
    Compatibility removed         :done, d5, 2023-10-10, 30d
&lt;h3&gt;Generation 0 (pre-November 2014): the academic baseline&lt;/h3&gt;
&lt;p&gt;Two assumptions held for fourteen years between Windows 2000 RTM and Black Hat USA 2014. First, the PAC&apos;s two signatures -- the Server Signature and the KDC Signature -- were treated as adequate; the [MS-PAC] specification required the KDC Signature to be a keyed HMAC under the krbtgt key, but Windows KDCs in practice accepted weaker non-keyed checksums on it (CRC32, RSA-MD5) [@mspac][@ms14068]. Second, the long-term krbtgt key was held only on writeable DCs and was considered unreachable to remote attackers because no remote primitive existed to extract it. Both assumptions failed within months of each other. The MS14-068 disclosure broke the first; the productionised DCSync primitive in Mimikatz broke the second.&lt;/p&gt;
&lt;h3&gt;Generation 1 (November 18, 2014): MS14-068 and CVE-2014-6324&lt;/h3&gt;
&lt;p&gt;On November 18, 2014, Microsoft published security bulletin MS14-068, &quot;Vulnerability in Kerberos Could Allow Elevation of Privilege (3011780)&quot; [@ms14068]. The disclosure: the KDC validated PACs using a checksum algorithm that did not actually depend on the krbtgt key. Any authenticated domain user could forge a PAC asserting Domain Admin group membership, attach it to an otherwise-valid AS-REQ exchange, and the KDC would accept the forgery. The NVD entry for CVE-2014-6324 records that the bug &quot;allows remote authenticated domain users to obtain domain administrator privileges via a forged signature in a ticket, as exploited in the wild in November 2014, aka &apos;Kerberos Checksum Vulnerability&apos;&quot; [@cve-2014-6324]. CVSS 9.0. Critical for every supported Windows Server SKU. Exploited in the wild within hours of the bulletin.&lt;/p&gt;
&lt;p&gt;Discovery credit for MS14-068 appears across Metasploit module authorship, AttackerKB, and several practitioner write-ups as Tom Maddock. The MSRC bulletin verbatim says only &quot;privately reported&quot; and does not name the reporter publicly [@ms14068]. The Maddock attribution is folk knowledge; the MSRC primary does not confirm it.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s patch replaced the weak checksum with a real keyed HMAC under the krbtgt key, the same construction the [MS-PAC] document specifies today. The patch was correct: it restored PAC integrity to actual dependence on a real secret. It also, as a side-effect, elevated the krbtgt key from &quot;an important secret in the directory&quot; to &quot;the load-bearing secret of every authentication decision in the domain.&quot; From November 18, 2014 onward, an attacker who held the krbtgt key did not just hold a useful credential; the attacker held the &lt;em&gt;only&lt;/em&gt; credential the KDC could not check above.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The MS14-068 patch was correct -- it restored PAC integrity to dependence on the krbtgt key. Its side-effect was to elevate the krbtgt key from &quot;important&quot; to &quot;load-bearing for every authentication decision in the domain.&quot; From November 18, 2014 onward, the krbtgt key was the single secret worth attacking directly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Generation 2 (August 7, 2014): Golden Ticket&lt;/h3&gt;
&lt;p&gt;Skip Duckwall and Benjamin Delpy presented &quot;Abusing Microsoft Kerberos: Sorry you guys don&apos;t get it&quot; at Black Hat USA on August 7, 2014 [@infocondb-bh2014]. The technique they demonstrated is what Sean Metcalf later popularised as the Golden Ticket: with the krbtgt key in hand, an attacker forges a TGT from scratch for any principal SID with any group memberships [@adsec-1640]. The KDC validates the TGT by decrypting &lt;code&gt;enc-part&lt;/code&gt; with the krbtgt key. There is no upstream authority to check, because krbtgt &lt;em&gt;is&lt;/em&gt; the authority. MITRE T1558.001 codifies the technique [@mitre-t1558001]; Benjamin Delpy&apos;s Mimikatz &lt;code&gt;kerberos::golden&lt;/code&gt; command operationalises it [@mimikatz].&lt;/p&gt;

sequenceDiagram
    participant A as Attacker (holds krbtgt key)
    participant L as Local Kerberos cache
    participant K as KDC on a DC
    participant S as Target service
    A-&amp;gt;&amp;gt;A: Choose target SID and groups
    A-&amp;gt;&amp;gt;A: Build EncTicketPart locally
    A-&amp;gt;&amp;gt;A: HMAC PAC signatures under krbtgt key
    A-&amp;gt;&amp;gt;A: AES-encrypt enc-part under krbtgt key
    A-&amp;gt;&amp;gt;L: kerberos::ptt -- inject ticket
    L-&amp;gt;&amp;gt;K: TGS-REQ presenting forged TGT
    K-&amp;gt;&amp;gt;K: Decrypt TGT with krbtgt key -- valid
    K-&amp;gt;&amp;gt;L: TGS-REP for target service
    L-&amp;gt;&amp;gt;S: Present service ticket -- access granted
&lt;p&gt;The Golden Ticket works because of the single-key trust property the 1988 design chose. There is nothing in the protocol that asks &quot;is this TGT in the KDC&apos;s issuance log?&quot; The TGT is self-verifying. If it decrypts and its signatures validate under the key, it is, by definition, a TGT.&lt;/p&gt;
&lt;p&gt;Why, then, does Golden Ticket sometimes get caught? Because the default Mimikatz invocation leaves four observable artefacts that Microsoft Defender for Identity ships dedicated alerts for, under the umbrella of the Suspected-Golden-Ticket alert family [@mdi-classic][@mdi-credential]. Mimikatz historically defaulted to RC4-HMAC encryption (enctype 23), which is anomalous on a modern AD where AES is standard. Mimikatz historically defaulted to a ten-year ticket lifetime, against the AD &lt;code&gt;MaxTicketAge&lt;/code&gt; default of ten hours. The attacker frequently asserts groups the user does not actually hold, which produces a &quot;forged authorization data&quot; anomaly. And the attacker sometimes forges a ticket for an account that does not exist in the directory at all, which produces a &quot;nonexistent account&quot; anomaly. Microsoft&apos;s live MDI alerts page enumerates six External IDs in the family: 2009 (encryption downgrade), 2013 (forged authorization data), 2022 (time anomaly), 2027 (nonexistent account), 2032 (ticket anomaly), and 2040 (ticket anomaly using RBCD) [@mdi-classic].&lt;/p&gt;
&lt;p&gt;The structural observation: every alert in this family detects &lt;em&gt;symptoms of forging from scratch&lt;/em&gt;. None of them detects the primitive of &lt;em&gt;holding the krbtgt key&lt;/em&gt;. That distinction is what makes Generation 4 (Diamond) and Generation 5 (Sapphire) interesting.&lt;/p&gt;
&lt;h3&gt;Generation 3 (parallel path): Silver Ticket&lt;/h3&gt;
&lt;p&gt;Silver Tickets forge a &lt;em&gt;service ticket&lt;/em&gt; (TGS) under a captured service-account key. They sidestep the krbtgt key entirely; the KDC is never involved in the forgery, and the forgery validates only against the one service whose key was captured. MITRE T1558.002 catalogues the technique [@mitre-t1558002]. Mentioned here so the question stops being asked. Silver Tickets are a sibling technique that targets a different trust root (per-service account keys), not the krbtgt key.&lt;/p&gt;
&lt;h3&gt;Generation 4 (June 2022): Diamond Ticket&lt;/h3&gt;
&lt;p&gt;In June 2022, Andrew Schwartz at TrustedSec and Charlie Clark at Semperis co-published &quot;A Diamond in the Ruff,&quot; documenting a refinement of Golden Ticket that defeats every PAC-content anomaly detection in one stroke [@trustedsec-diamond][@semperis-diamond]. The technique: instead of forging the TGT from scratch, the attacker requests a &lt;em&gt;real&lt;/em&gt; TGT from the KDC, then decrypts its &lt;code&gt;enc-part&lt;/code&gt; using the held krbtgt key, modifies the PAC contents, re-signs the PAC under the krbtgt key, re-encrypts the &lt;code&gt;enc-part&lt;/code&gt;, and walks away with a ticket whose every wire property -- &lt;code&gt;sname&lt;/code&gt;, &lt;code&gt;cname&lt;/code&gt;, &lt;code&gt;authtime&lt;/code&gt; skew matching the real KDC&apos;s clock, plausible &lt;code&gt;endtime&lt;/code&gt;, AES-256 envelope -- looks like a legitimate KDC-issued artefact.&lt;/p&gt;

sequenceDiagram
    participant A as Attacker (low-priv user, holds krbtgt key)
    participant K as KDC on a DC
    participant L as Local Kerberos cache
    participant S as Target service
    A-&amp;gt;&amp;gt;K: AS-REQ for low-priv user
    K-&amp;gt;&amp;gt;A: Real TGT, encrypted under krbtgt key
    A-&amp;gt;&amp;gt;A: Decrypt enc-part with held krbtgt key
    A-&amp;gt;&amp;gt;A: Modify PAC SIDs to Domain Admins
    A-&amp;gt;&amp;gt;A: Recompute PAC signatures under krbtgt key
    A-&amp;gt;&amp;gt;A: Re-encrypt enc-part under krbtgt key
    A-&amp;gt;&amp;gt;L: ptt -- inject modified TGT
    L-&amp;gt;&amp;gt;K: TGS-REQ presenting Diamond TGT
    K-&amp;gt;&amp;gt;K: Decrypt -- valid, signatures match
    K-&amp;gt;&amp;gt;L: TGS-REP for target service
    L-&amp;gt;&amp;gt;S: Access granted as Domain Admin
&lt;p&gt;Every MDI Suspected-Golden-Ticket detection disappears, by construction. The encryption type is AES-256 because the KDC issued it that way. The lifetime matches the AD policy because the KDC set it that way. The cname matches a real account because the attacker requested the TGT as a real low-privilege account they own. The only thing the attacker changed is the group SIDs inside the PAC, and the PAC signatures revalidate because the attacker recomputed them under the same krbtgt key the KDC would have used.&lt;/p&gt;
&lt;p&gt;TrustedSec verbatim: Diamond &quot;would almost certainly require access to the AES256 key&quot; [@trustedsec-diamond]. The KDC issued the real TGT in AES-256, so the attacker needs the AES-256 key to decrypt and re-encrypt -- not just the RC4 NTLM hash that the classic Golden Ticket can use.&lt;/p&gt;
&lt;p&gt;The Diamond Ticket disclosure pointed at an architectural problem: with the krbtgt key in hand, every PAC-content anomaly detection is defeated. Microsoft&apos;s structural answer was the Full PAC Signature in November 2022. We come to that in Generation 6.&lt;/p&gt;
&lt;h3&gt;Generation 5 (October 2022): Sapphire Ticket&lt;/h3&gt;
&lt;p&gt;Charlie Bromberg, who publishes under the handle Shutdown (&lt;code&gt;@_nwodtuhs&lt;/code&gt;) at Synacktiv and maintains The Hacker Recipes wiki, disclosed Sapphire Ticket in October 2022 [@hackrecipes-sapphire][@shutdownrepo-sapphire]. Where Diamond modifies the PAC, Sapphire &lt;em&gt;splices&lt;/em&gt; the PAC. The procedure abuses two Kerberos extensions in combination -- Service-for-User-to-Self (S4U2self) and User-to-User (U2U) -- to coerce the KDC into issuing a service ticket whose embedded PAC describes a target user the attacker wishes to impersonate. The attacker then extracts that genuine PAC from the service ticket and embeds it, unchanged, in a freshly constructed TGT signed under the held krbtgt key.&lt;/p&gt;

A Kerberos extension that lets a service request a ticket *to itself*, on behalf of another user, without that user presenting credentials. Originally designed for protocol-transition scenarios (a web service accepting forms-based auth and translating it to Kerberos for downstream calls). Defined in [MS-SFU] (Kerberos Protocol Extensions: Service for User and Constrained Delegation Protocol); referenced from [MS-KILE] [@mssfu].

A Kerberos extension defined in RFC 4120 §3.7 that allows a ticket to be encrypted under the recipient&apos;s session key rather than its long-term key, enabling two clients to authenticate to each other without either being a KDC-registered service [@rfc4120].

sequenceDiagram
    participant A as Attacker (low-priv user, holds krbtgt key)
    participant K as KDC on a DC
    participant L as Local Kerberos cache
    participant S as Target service
    A-&amp;gt;&amp;gt;K: AS-REQ for low-priv user
    K-&amp;gt;&amp;gt;A: Real attacker TGT
    A-&amp;gt;&amp;gt;K: S4U2self + U2U TGS-REQ for target user
    K-&amp;gt;&amp;gt;A: TGS containing target user&apos;s genuine PAC
    A-&amp;gt;&amp;gt;A: Extract genuine PAC from TGS
    A-&amp;gt;&amp;gt;A: Build new TGT, embed genuine PAC
    A-&amp;gt;&amp;gt;A: Sign three PAC signatures under krbtgt key
    A-&amp;gt;&amp;gt;A: Encrypt enc-part under krbtgt key
    A-&amp;gt;&amp;gt;L: ptt -- inject Sapphire TGT
    L-&amp;gt;&amp;gt;K: TGS-REQ presenting Sapphire TGT
    K-&amp;gt;&amp;gt;K: Decrypt -- valid, PAC is genuine
    K-&amp;gt;&amp;gt;L: TGS-REP for target service
    L-&amp;gt;&amp;gt;S: Access granted as target user
&lt;p&gt;By construction, there is no PAC-content anomaly to detect: the PAC inside the resulting TGT is literally a PAC the KDC issued for the target user, because the KDC &lt;em&gt;did&lt;/em&gt; issue it. The PAC&apos;s three signatures revalidate because the attacker held the krbtgt key to sign them; if Microsoft validates the Full PAC Signature on incoming tickets, that signature also validates because the attacker computed it under the same krbtgt key. Detection must move to traffic-flow analysis -- specifically, the anomalous S4U2self plus U2U TGS-REQ sequence on the wire -- and as of May 2026 no vendor has shipped a clean canonical default-enabled analytic for that signal [@unit42-gemstones].&lt;/p&gt;
&lt;p&gt;The Sapphire Ticket disclosure is widely misattributed to Charlie Clark (Semperis). The primary tooling artefact -- the Impacket PR #1411 conversation thread -- addresses the author as &lt;code&gt;@ShutdownRepo&lt;/code&gt;, who is Charlie Bromberg of Synacktiv [@impacket-1411]. The Hacker Recipes wiki and pgj11.com both confirm Bromberg as the author of record [@hackrecipes-sapphire][@pgj11]. The misattribution conflates Sapphire with Clark&apos;s separate &quot;AS Requested Service Tickets&quot; technique.&lt;/p&gt;
&lt;p&gt;The empirical artefact is the Impacket pull request #1411, in which Bromberg added the &lt;code&gt;-impersonate&lt;/code&gt; flag to &lt;code&gt;ticketer.py&lt;/code&gt; to put the tool into &quot;sapphire ticket mode&quot; [@impacket-1411][@shutdownrepo-sapphire]. Palo Alto Unit 42&apos;s &quot;Precious Gemstones&quot; survey is the vendor-side state-of-the-art summary [@unit42-gemstones].&lt;/p&gt;
&lt;h3&gt;Generation 6 (November 2022 to October 2023): KrbtgtFullPacSignature&lt;/h3&gt;
&lt;p&gt;Microsoft&apos;s formal response to the post-2014 attack arc shipped as KB5020805 starting November 8, 2022, addressing CVE-2022-37967 [@kb5020805][@cve-2022-37967]. The fix adds a new PAC signature -- the Full PAC Signature -- computed by the KDC over the &lt;em&gt;entire&lt;/em&gt; PAC including the older two signatures, validated on incoming tickets, and rolled out across five deployment phases:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Phase&lt;/th&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;&lt;code&gt;KrbtgtFullPacSignature&lt;/code&gt; value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Initial Deployment&lt;/td&gt;
&lt;td&gt;November 8, 2022&lt;/td&gt;
&lt;td&gt;Signatures added, validation disabled&lt;/td&gt;
&lt;td&gt;1 (Compatibility)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Second Deployment&lt;/td&gt;
&lt;td&gt;December 13, 2022&lt;/td&gt;
&lt;td&gt;Audit mode default&lt;/td&gt;
&lt;td&gt;2 (Audit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Third Deployment&lt;/td&gt;
&lt;td&gt;June 13, 2023&lt;/td&gt;
&lt;td&gt;Cannot disable signature addition&lt;/td&gt;
&lt;td&gt;(value 0 removed)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default Enforcement&lt;/td&gt;
&lt;td&gt;July 11, 2023&lt;/td&gt;
&lt;td&gt;Enforcement default&lt;/td&gt;
&lt;td&gt;3 (Enforcement)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Removal of Compatibility&lt;/td&gt;
&lt;td&gt;October 10, 2023&lt;/td&gt;
&lt;td&gt;Audit removed, Enforcement permanent&lt;/td&gt;
&lt;td&gt;(registry key removed)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;KB5020805 documents the final state verbatim: &quot;Windows updates released on or after October 10, 2023 will do the following: Removes support for the registry subkey KrbtgtFullPacSignature. Removes support for Audit mode. All service tickets without the new PAC signatures will be denied authentication&quot; [@kb5020805].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The KB number for KrbtgtFullPacSignature is KB5020805, not KB5021131. KB5021131 is the paired but distinct KB for CVE-2022-37966 (encryption-type enforcement). The PAC-signature-specific KB is KB5020805. Secondary sources routinely confuse the two.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here is the structural fact. The Full PAC Signature is &lt;em&gt;also&lt;/em&gt; computed under the krbtgt key. So an attacker who holds the krbtgt key still mints fully-validating tickets, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sapphire Tickets, which never modify the PAC at all; the existing signatures the KDC issued are valid by construction, the Full PAC Signature included.&lt;/li&gt;
&lt;li&gt;Recomputed Diamond Tickets, in which the attacker simply computes the Full PAC Signature alongside the older KDC signature in the same step, because both depend on the same key the attacker holds.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;KrbtgtFullPacSignature retired one specific class of attack (Diamond Tickets that did not recompute the Full PAC Signature). It did not retire the underlying primitive (TGT forgery from a known krbtgt key). The PAC signature surface in Section 3 -- all three signatures terminating at the same key -- is exactly why this is so.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The Full PAC Signature was Microsoft&apos;s structural response to Diamond Ticket. It is itself computed under the krbtgt key. So an attacker who holds the krbtgt key recomputes it in the same step as the KDC signature -- and Sapphire Tickets, which never modify the PAC at all, are unaffected by construction. CVE-2022-37967 retired one class of attack (PAC-modifying Diamond variants); it did not retire the primitive.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Comparing the three forgery variants&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Golden&lt;/th&gt;
&lt;th&gt;Diamond&lt;/th&gt;
&lt;th&gt;Sapphire&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Requires krbtgt key?&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (AES-256)&lt;/td&gt;
&lt;td&gt;Yes (AES-256)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Calls the KDC?&lt;/td&gt;
&lt;td&gt;No (forges from scratch)&lt;/td&gt;
&lt;td&gt;Yes (real AS-REQ)&lt;/td&gt;
&lt;td&gt;Yes (AS-REQ + S4U2self+U2U)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modifies the PAC?&lt;/td&gt;
&lt;td&gt;Builds it from scratch&lt;/td&gt;
&lt;td&gt;Yes (group SIDs)&lt;/td&gt;
&lt;td&gt;No (genuine PAC)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Defeats MDI encryption downgrade alert?&lt;/td&gt;
&lt;td&gt;No (defaults RC4)&lt;/td&gt;
&lt;td&gt;Yes (real AES)&lt;/td&gt;
&lt;td&gt;Yes (real AES)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Defeats MDI time-anomaly alert?&lt;/td&gt;
&lt;td&gt;No (defaults 10y)&lt;/td&gt;
&lt;td&gt;Yes (KDC lifetime)&lt;/td&gt;
&lt;td&gt;Yes (KDC lifetime)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Defeats MDI forged-auth-data alert?&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (still triggers if group mismatch detected via other means)&lt;/td&gt;
&lt;td&gt;Yes (PAC is genuine)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Defeats Full PAC Signature (post-July 2023)?&lt;/td&gt;
&lt;td&gt;Yes (recomputed under held key)&lt;/td&gt;
&lt;td&gt;Yes (recomputed)&lt;/td&gt;
&lt;td&gt;Yes (genuine PAC)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Known wire-residual?&lt;/td&gt;
&lt;td&gt;Encryption type, lifetime, groups&lt;/td&gt;
&lt;td&gt;Re-encryption-under-held-key timing&lt;/td&gt;
&lt;td&gt;S4U2self+U2U conjunction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Six generations from MS14-068 to KrbtgtFullPacSignature, and the residual primitive is exactly what the 1988 paper described: hold the key, mint the ticket. So what does the detection topology in 2026 actually catch?&lt;/p&gt;
&lt;h2&gt;6. The Detection Stack in 2026&lt;/h2&gt;
&lt;p&gt;Detection of krbtgt-class attacks in 2026 is a four-layer stack. Each layer has a specific class of signal it reads, a specific class of attack it catches, and a specific gap that the next layer is supposed to close. Three of the four layers have a known gap above them. The fourth has nothing above it.&lt;/p&gt;

flowchart TD
    L4[&quot;Layer 4 -- S4U2self plus U2U residual (no vendor analytic shipped)&quot;]
    L3[&quot;Layer 3 -- Network/SIEM (Sentinel, Splunk T1558.001)&quot;]
    L2[&quot;Layer 2 -- Behavioural (MDI Suspected-Golden-Ticket family)&quot;]
    L1[&quot;Layer 1 -- Posture (BloodHound DCSync edge)&quot;]
    KEY[&quot;krbtgt long-term key (the attacker&apos;s objective)&quot;]
    L1 --&amp;gt; L2
    L2 --&amp;gt; L3
    L3 --&amp;gt; L4
    L4 --&amp;gt; KEY
&lt;h3&gt;Layer 1: posture (BloodHound DCSync edge)&lt;/h3&gt;
&lt;p&gt;The posture layer asks a question with no per-event component: &quot;Who has rights that &lt;em&gt;could&lt;/em&gt; extract the krbtgt key, regardless of whether they have used those rights?&quot; In Active Directory terms, the answer is &quot;anyone holding &lt;code&gt;DS-Replication-Get-Changes&lt;/code&gt; plus &lt;code&gt;DS-Replication-Get-Changes-All&lt;/code&gt; rights against a writeable DC, plus anyone who holds privileges that allow them to grant those rights to themselves.&quot; BloodHound encodes the answer as a &lt;code&gt;DCSync&lt;/code&gt; edge in its graph; the canonical community Cypher query is &lt;code&gt;MATCH (u)-[:DCSync]-&amp;gt;(d:Domain) RETURN u, d&lt;/code&gt;. The current shipping release of BloodHound Community Edition is v9.1.0, dated 2026-05-06 per the release notes [@bloodhound-notes].&lt;/p&gt;

A replication primitive Mimikatz first productionised in August 2015. The attacker invokes the `DRSGetNCChanges` API call against a writeable domain controller, masquerading as a peer DC, and the target DC obligingly streams back the requested account secrets including the krbtgt long-term key. MITRE T1003.006 catalogues the technique [@mitre-t1003006]. Sean Metcalf&apos;s adsecurity.org write-up notes &quot;DCSync was written by Benjamin Delpy and Vincent Le Toux&quot; [@adsec-1729].
&lt;p&gt;What this layer detects: any principal whose existing AD permissions create a path to the krbtgt key. What this layer misses: any attacker who &lt;em&gt;already&lt;/em&gt; has the key. Posture is preventive, not detective. By the time the attacker is invoking &lt;code&gt;kerberos::golden&lt;/code&gt;, the posture layer has already missed its window.&lt;/p&gt;
&lt;h3&gt;Layer 2: behavioural (Microsoft Defender for Identity)&lt;/h3&gt;
&lt;p&gt;Microsoft Defender for Identity ships an alert family covering classic Golden-Ticket-from-Mimikatz behaviour. The live MDI classic alerts page enumerates six Suspected-Golden-Ticket External IDs: 2009 (encryption downgrade), 2013 (forged authorization data), 2022 (time anomaly), 2027 (nonexistent account), 2032 (ticket anomaly), and 2040 (ticket anomaly using RBCD) [@mdi-classic]. The Credential access section adds External ID 2006 for &quot;Suspected DCSync attack&quot; on the extraction side [@mdi-classic].&lt;/p&gt;
&lt;p&gt;What this layer detects: the Mimikatz Golden Ticket defaults plus the DCSync extraction primitive that produces the krbtgt key in the first place. What this layer misses: Diamond and Sapphire by construction. Diamond removes the PAC-content anomalies because every artefact except the modified group SIDs comes from the real KDC. Sapphire defeats PAC-content anomaly detection entirely by using a PAC the KDC genuinely issued via S4U2self plus U2U.&lt;/p&gt;
&lt;p&gt;The MDI credential-access alerts page is the entry point to the family in the modern Microsoft Defender XDR console layout [@mdi-credential].&lt;/p&gt;
&lt;h3&gt;Layer 3: network and SIEM (Sentinel, Splunk)&lt;/h3&gt;
&lt;p&gt;Multi-vendor SIEM content packs ship analytic rules covering Kerberos behaviours flagged under MITRE T1558.001. Splunk&apos;s research catalogue contains the canonical example: &quot;Kerberos Service Ticket Request Using RC4 Encryption&quot; detects TGS-REQ traffic with encryption-type 0x17 (RC4-HMAC), leveraging Windows Event 4769 from the DCs [@splunk-7d9]. Microsoft Sentinel ships parallel rules under the Microsoft Defender XDR content connector. The pattern these analytics share is reliance on encryption-type anomalies, group-membership anomalies, or lifetime anomalies that appear in Windows event logs after the fact.&lt;/p&gt;
&lt;p&gt;What this layer detects: signature-style indicators of Golden Ticket behaviour on the wire and in the DC event log. What this layer misses: the same encryption-downgrade dependency MDI&apos;s alert 2009 has. The Splunk analytic verbatim acknowledges its own limit: &quot;This detection may be bypassed if attackers use the AES key instead of the NTLM hash&quot; [@splunk-7d9]. Diamond and Sapphire both use the AES-256 key. Both walk through this layer untouched.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Microsoft Sentinel ships rules called &quot;Kerberoasting&quot; that target MITRE T1558.003 (extracting service-account secrets by requesting SPN-bearing service tickets and brute-forcing the resulting RC4-encrypted blobs offline). Those rules target &lt;em&gt;service accounts&lt;/em&gt; with SPNs registered against them. They are not a krbtgt detection asset. The krbtgt account does not have an SPN that any client can request a TGS for; the relevant Sentinel content for krbtgt-class attacks is the T1558.001 Golden-Ticket and Kerberos-anomaly analytic family.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Layer 4: the Sapphire residual&lt;/h3&gt;
&lt;p&gt;What would catch a Sapphire Ticket? The only wire-observable residual of the technique is the conjunction of (a) a TGS-REQ specifying the S4U2self flag, and (b) the same TGT being used to address a User-to-User request to the KDC. No other layer of the stack reads this signal because no other attack has historically produced it as a precondition.&lt;/p&gt;
&lt;p&gt;What ships: nothing canonical. SpecterOps and the BloodHound content team have signalled graph-query work on the U2U TGS issuance pattern in 2026 trend reports [@bloodhound-notes], but no shipped default-enabled analytic. Palo Alto Unit 42&apos;s &quot;Precious Gemstones&quot; survey describes Cortex XDR detection-attempt heuristics but does not publish the rule [@unit42-gemstones]. The gap is engineering, not theoretical: the signal exists, the analytic to read it has simply not been packaged.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; No vendor analytic shipped for the S4U2self plus U2U conjunction as of May 2026. Sapphire is the current frontier and the article&apos;s &quot;what 2026 still cannot do&quot; gap. An attacker who holds the krbtgt key and uses the Sapphire technique walks past every shipping detection layer.&lt;/p&gt;
&lt;/blockquote&gt;

SpecterOps and the BloodHound content team have signalled graph-query work on the U2U TGS issuance pattern; Palo Alto Unit 42&apos;s &quot;Precious Gemstones&quot; survey describes Cortex XDR detection-attempt heuristics [@unit42-gemstones]. Neither has shipped a clean canonical default-enabled analytic. The gap is engineering, not theoretical, and it is the active research front for the 2026 to 2028 cycle.
&lt;h3&gt;Defensive method matrix&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Catches Golden?&lt;/th&gt;
&lt;th&gt;Catches Diamond?&lt;/th&gt;
&lt;th&gt;Catches Sapphire?&lt;/th&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;BloodHound DCSync edge&lt;/td&gt;
&lt;td&gt;preventive only&lt;/td&gt;
&lt;td&gt;preventive only&lt;/td&gt;
&lt;td&gt;preventive only&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MDI Suspected-Golden-Ticket (4 alerts)&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MDI Suspected DCSync (ID 2006)&lt;/td&gt;
&lt;td&gt;extraction step only&lt;/td&gt;
&lt;td&gt;extraction step only&lt;/td&gt;
&lt;td&gt;extraction step only&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sentinel / Splunk T1558.001 RC4 rule&lt;/td&gt;
&lt;td&gt;yes (if RC4)&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sentinel Kerberos-anomaly content pack&lt;/td&gt;
&lt;td&gt;partial (lifetime/groups)&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full PAC Signature (post-July 2023)&lt;/td&gt;
&lt;td&gt;n/a (already signed correctly)&lt;/td&gt;
&lt;td&gt;retires non-recomputing variants&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;n/a (cryptographic enforcement, not detection)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S4U2self+U2U conjunction analytic&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;would catch&lt;/td&gt;
&lt;td&gt;4 (not shipped)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;Adjacent T1558 family techniques that are not krbtgt detections&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Technique&lt;/th&gt;
&lt;th&gt;What it targets&lt;/th&gt;
&lt;th&gt;krbtgt detection?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;T1558.002 Silver Ticket&lt;/td&gt;
&lt;td&gt;service-account long-term keys&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T1558.003 Kerberoasting&lt;/td&gt;
&lt;td&gt;SPN-bearing service accounts via offline RC4 crack&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T1558.004 AS-REP Roasting&lt;/td&gt;
&lt;td&gt;accounts with pre-auth disabled&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OverPass-the-Hash&lt;/td&gt;
&lt;td&gt;user NTLM hashes via Kerberos PA-DATA&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Detection in 2026 is a four-layer stack, and three of the layers leave gaps the next layer is supposed to close. The fourth gap -- the Sapphire residual -- has no layer above it. When the gaps close enough to confirm a krbtgt compromise, what does recovery actually look like?&lt;/p&gt;
&lt;h2&gt;7. Recovery: What the Two-Reset Procedure Actually Does&lt;/h2&gt;
&lt;p&gt;The Microsoft AD Forest Recovery page states the procedure verbatim:&lt;/p&gt;

&quot;You should perform this operation twice. You must wait 10 hours between password resets. 10 hours are the default Maximum lifetime for user ticket and Maximum lifetime for service ticket policy settings, hence in a case where the Maximum lifetime period changes, the minimum waiting period between resets should be greater than the configured value.&quot; -- and -- &quot;The password history value for the krbtgt account is 2, meaning it includes the two most recent passwords. By resetting the password twice you effectively clear any old passwords from the history, so there&apos;s no way another DC replicates with this DC by using an old password.&quot; [@ms-forest-recovery]
&lt;p&gt;What exactly do those two resets buy, and what do they not buy?&lt;/p&gt;
&lt;h3&gt;The mechanics of two-slot eviction&lt;/h3&gt;
&lt;p&gt;The krbtgt account, like every other AD account, stores both &lt;em&gt;current&lt;/em&gt; and &lt;em&gt;previous&lt;/em&gt; keys. A TGT issued at time $T = 0$ under key $K_0$ continues to validate after a rotation at $T = T_1$ (when $K_1$ becomes current and $K_0$ moves to the previous slot), because the KDC tries both keys during the in-flight validation window. One rotation fills the previous slot with the now-replaced $K_0$; the second rotation, separated by at least &lt;code&gt;MaxTicketAge&lt;/code&gt; so that all $K_0$-signed TGTs have expired naturally, fills the previous slot with $K_1$ and evicts $K_0$ entirely. After the second rotation completes and replicates, no key in the krbtgt account matches the attacker&apos;s extracted $K_0$; forged TGTs from that key fail validation cleanly [@ms-forest-recovery].&lt;/p&gt;

The Kerberos policy value that bounds the lifetime of a Ticket-Granting Ticket from the moment of issuance. The Active Directory default is 10 hours, configured via the Default Domain Policy. The AD Forest Recovery procedure waits at least `MaxTicketAge` between krbtgt resets to ensure no in-flight TGT outlives the period between the two rotations [@ms-forest-recovery].

flowchart LR
    A0[&quot;T=0: K_0 current, K_prior previous&quot;] --&amp;gt; A1[&quot;T=T_1: reset 1 -- K_1 current, K_0 previous&quot;]
    A1 --&amp;gt; A2[&quot;T_1 + 10h: K_1 still current, K_0 still previous&quot;]
    A2 --&amp;gt; A3[&quot;T=T_2 (≥ T_1 + 10h): reset 2 -- K_2 current, K_1 previous&quot;]
    A3 --&amp;gt; A4[&quot;After replication: K_0 evicted from both slots&quot;]
&lt;p&gt;The 10-hour wait between resets is not a Microsoft convenience choice; it is a cryptographic requirement. If the second reset lands before all $K_0$-signed TGTs have expired naturally, some of those tickets will hit a DC whose previous slot now holds $K_1$ rather than $K_0$, and the KDC will reject them. This is what KB5020805&apos;s PAC-signature deployment phases also had to navigate during the November 2022 to October 2023 rollout: signature additions and validation transitions had to bracket the maximum in-flight ticket lifetime [@kb5020805].&lt;/p&gt;
&lt;p&gt;{`
// Model the krbtgt account as a two-slot store; simulate the two-reset procedure.
function simulate(events) {
  const slots = { current: &quot;K_prior&quot;, previous: null };
  let stolen = null;
  for (const ev of events) {
    if (ev.kind === &quot;compromise&quot;) {
      stolen = slots.current;
    } else if (ev.kind === &quot;reset&quot;) {
      slots.previous = slots.current;
      slots.current  = ev.newKey;
    }
    const validates =
      stolen &amp;amp;&amp;amp; (stolen === slots.current || stolen === slots.previous);
    console.log(
      &quot;[t=&quot; + ev.t.toString().padStart(3) + &quot;h]&quot;,
      ev.kind.padEnd(11),
      &quot;current=&quot; + slots.current,
      &quot;prev=&quot; + (slots.previous ?? &quot;-&quot;),
      &quot;attacker_validates=&quot; + validates
    );
  }
}&lt;/p&gt;
&lt;p&gt;simulate([
  { t: 0,  kind: &quot;issue&quot;      },
  { t: 1,  kind: &quot;compromise&quot; },  // attacker stores K_prior as stolen
  { t: 3,  kind: &quot;reset&quot;, newKey: &quot;K_1&quot; },
  { t: 13, kind: &quot;reset&quot;, newKey: &quot;K_2&quot; },  // ≥ MaxTicketAge later
  { t: 14, kind: &quot;issue&quot;      },
]);
`}&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;New-KrbtgtKeys.ps1&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Microsoft&apos;s reference automation for the procedure is &lt;code&gt;New-KrbtgtKeys.ps1&lt;/code&gt;, originally distributed as an MSDN Gallery script and currently hosted in the &lt;code&gt;microsoftarchive&lt;/code&gt; GitHub organisation. The repository banner reads, verbatim: &quot;This repository was archived by the owner on Mar 8, 2024. It is now read-only&quot; [@new-krbtgt-keys]. The script remains the canonical reference for the rotation procedure, including pre-reset and post-reset replication-health checks; it is simply no longer actively maintained. Operators in 2026 commonly fork it locally or wrap the same &lt;code&gt;Set-ADAccountPassword&lt;/code&gt; plus replication-status pattern in their own runbooks.&lt;/p&gt;
&lt;h3&gt;What two-reset does&lt;/h3&gt;
&lt;p&gt;Cryptographically invalidates previously-forged TGTs after the second reset replicates fully across all writeable DCs. This is unambiguous and well-documented; the Microsoft Learn page is the primary [@ms-forest-recovery]. After step 3 (the second reset) has replicated, no TGT signed under the pre-compromise key validates anywhere in the domain.&lt;/p&gt;
&lt;h3&gt;What two-reset does not do&lt;/h3&gt;
&lt;p&gt;Any attacker who held the krbtgt key has typically already installed parallel persistence. SpecterOps&apos;s &quot;Domain of Thrones Part II&quot; by Nico Shyne and Josh Prager, published November 6, 2023, names the rotation list verbatim: &quot;Machine accounts ... User accounts ... Service accounts -- Per domain KRBTGT account ... Trust keys and objects related to trust of all other domains; Group-managed service accounts; Key distribution service root keys&quot; [@specterops-dot2]. The same playbook enumerates the persistence vectors an attacker with krbtgt access typically establishes: AdminSDHolder ACL edits, AD CS template alternates spanning the ESC1 through ESC8 abuse classes (canonically catalogued in Schroeder and Christensen&apos;s &quot;Certified Pre-Owned,&quot; SpecterOps, June 2021) [@certified-pre-owned], SID History entries, machine-account secret retention, KDS root key exfiltration, trust-key compromise, and DSRM password exfiltration. Two-reset rotates the krbtgt key only; the rest of the trust-root set is untouched [@specterops-dot1][@specterops-dot2].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Two-reset rotation cryptographically invalidates previously-forged TGTs. It does NOT rotate any of the other secrets an attacker who held the krbtgt key has typically already installed: AdminSDHolder edits, ADCS templates, SID History, machine-account secrets, KDS root keys, trust keys, DSRM passwords. This is why confirmed krbtgt compromise is a forest-rebuild event, not a key-rotation event.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Two-reset rotation is the cryptographic finish; the operational finish spans the rest of the Domain-of-Thrones surface, and the rotation alone cannot reach it. The single-sentence punchline of the article lands at the end of §11.&lt;/p&gt;

Why does Microsoft&apos;s AD Forest Recovery page treat krbtgt rotation as a recoverable rotation event while Mandiant-style and SpecterOps-style playbooks treat confirmed krbtgt compromise as a forest-rebuild event? Both statements are true at once. Microsoft documents the *cryptographic* recovery, which terminates at the krbtgt key. The IR playbooks document the *operational* recovery, which spans seven additional secret classes whose compromise the krbtgt holder typically also achieved. The cryptographic recovery is necessary and well-bounded; the operational recovery is necessary and not bounded by the same key.
&lt;p&gt;Recovery has two pieces: a fast cryptographic part (two resets, well-documented) and a slow operational part (seven other secret classes, days to weeks). Both are necessary. Neither is sufficient. Even the combined procedure leaves three structural residuals, which the next section names.&lt;/p&gt;
&lt;h2&gt;8. Theoretical Limits and Open Problems&lt;/h2&gt;
&lt;p&gt;Even with the full Domain-of-Thrones rotation surface executed correctly, three structural residuals remain. Each has a current best-partial-result; none has a closed solution.&lt;/p&gt;
&lt;h3&gt;(a) The pre-second-reset TGT-lifetime window&lt;/h3&gt;
&lt;p&gt;Any TGT minted from the compromised krbtgt key between the moment of compromise and the moment the second reset replicates remains valid until naturally expired or until step 3 lands. Mimikatz&apos;s default 10-year lifetime makes this a years-long window if the attacker pre-minted tickets and a careless DC missed the time-anomaly signal. The MDI Suspected-Golden-Ticket family includes a time-anomaly alert (the External ID 2022 sibling) [@mdi-classic] that reads the difference between plausible and implausible ticket lifetimes. The window is bounded above by the AD &lt;code&gt;MaxTicketAge&lt;/code&gt; floor: at minimum, the procedure must take 10 hours of wall-clock per Microsoft&apos;s own guidance [@ms-forest-recovery]. Below that floor the cryptographic invalidation does not finish.&lt;/p&gt;
&lt;p&gt;The mitigation is procedural: between detection and the start of the rotation, the IR team treats every TGT in the domain as suspect. In practice that means rejecting cached tickets at high-value services, forcing a TGT renewal cycle, and watching the time-anomaly alert closely. The mitigation is not perfect; an attacker who minted tickets with realistic 10-hour lifetimes inside the typical AD policy survives this residual entirely.&lt;/p&gt;
&lt;h3&gt;(b) AD CS alternate persistence (the ESC class)&lt;/h3&gt;
&lt;p&gt;An attacker who held the krbtgt key long enough to also touch AD Certificate Services has often installed an ESC-class alternate-identity persistence: a backdoored certificate template allowing Domain Admin certificate issuance (ESC1), a misconfigured &lt;code&gt;EnrolleeSuppliesSubject&lt;/code&gt; template (ESC4), an HTTP-bound CA endpoint vulnerable to &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; (ESC8). The ESC class taxonomy is catalogued in Schroeder and Christensen&apos;s &quot;Certified Pre-Owned&quot; white paper (SpecterOps, June 2021) [@certified-pre-owned]. The compromised template or endpoint survives krbtgt rotation entirely. The CA private key is its own trust root, parallel to (not subordinate to) the krbtgt key. Domain-of-Thrones Part II names ADCS as a separate rotation workstream that must be addressed alongside the krbtgt reset [@specterops-dot2].&lt;/p&gt;
&lt;p&gt;The structural fact: a domain with AD CS deployed has at least two cryptographic trust roots (krbtgt long-term key + CA private key) whose compromises are &lt;em&gt;both&lt;/em&gt; recoverable only through different mechanisms. PKINIT, the Kerberos pre-authentication extension that validates certificate-bearing AS-REQs, accepts identities the CA chain attests to. Compromise of the CA chain yields valid Kerberos authentication as any principal, by a different mechanism than holding the krbtgt key, with the same end result.&lt;/p&gt;
&lt;h3&gt;(c) Cross-domain trust-key compromise&lt;/h3&gt;
&lt;p&gt;Within a multi-domain forest, the krbtgt of each domain is trusted by the others through inter-domain trust keys. A krbtgt compromise in a child domain can become a forest-level event if the trust topology is not hardened: SID Filtering misconfigurations, missing Selective Authentication on outbound trusts, or stale forest-trust artefacts from earlier domain migrations all extend the blast radius beyond the directly-compromised domain. Microsoft&apos;s &quot;Recover from systemic identity compromise&quot; guidance and the AD Forest Recovery procedure index together cover the cross-domain rotation requirements; Domain-of-Thrones Part II&apos;s &quot;Trust keys and objects related to trust of all other domains&quot; entry is the concise operational statement [@specterops-dot2].&lt;/p&gt;
&lt;p&gt;The mitigation is architectural: domain-isolation discipline at the design phase plus Selective Authentication on all inbound trusts. After the fact, every domain whose krbtgt the compromised domain trusted (directly or transitively) becomes part of the rotation surface.&lt;/p&gt;
&lt;h3&gt;(d) The HSM-bound krbtgt aspiration&lt;/h3&gt;
&lt;p&gt;A theoretically clean solution exists in the literature: split the krbtgt key material such that no single party -- including the DC&apos;s own KDC service -- could read the full key in cleartext. The construction would be a hardware-security-module-bound krbtgt key (the HSM exposes only sign and verify operations on a key it never releases), or a threshold-cryptography scheme (the key is reconstructed across $n$ DCs, $t$ of which must cooperate per ticket-signing operation). Either construction would close the underlying primitive by making the krbtgt key unreadable in cleartext to anyone with code execution on a DC.&lt;/p&gt;
&lt;p&gt;Neither construction is supported by any [MS-KILE] revision through 47.0 dated April 27, 2026 [@mskile]. Neither is on any published Microsoft roadmap as of May 2026. The closest analogues that have shipped -- LSAISO/Credential Guard&apos;s VBS trustlet for LSASS secrets on workstations and member servers -- explicitly omit the writeable-DC case by design, because a writeable DC must read the krbtgt key to issue tickets.&lt;/p&gt;
&lt;p&gt;Even after two-reset and Domain of Thrones, three residuals remain: a window of time, an alternate trust root, and a topology problem. None of them are theoretical -- all three are operational realities documented in 2024-2026 incident-response practice. But they raise a different question: how does the krbtgt key compare to the other secrets in an AD trust-root set?&lt;/p&gt;
&lt;h2&gt;9. Where KRBTGT Sits in the AD Trust-Root Set&lt;/h2&gt;
&lt;p&gt;A correction to a framing that appears in many secondary write-ups: the krbtgt long-term key is &lt;em&gt;one&lt;/em&gt; of a small set of &quot;AD trust roots,&quot; not the only one. The framing matters because the rotation playbook in Section 7 lists seven secret classes for a reason: each is a candidate trust root that survives compromise of any other.&lt;/p&gt;

flowchart TD
    K[&quot;krbtgt long-term key&quot;] --&amp;gt;|&quot;every TGT in the domain&quot;| ENVA[&quot;Domain-wide Kerberos auth&quot;]
    C[&quot;AD CS root CA private key&quot;] --&amp;gt;|&quot;PKINIT certificates&quot;| ENVA
    G[&quot;KDS root key&quot;] --&amp;gt;|&quot;gMSA password derivation&quot;| SVC[&quot;Service-account auth&quot;]
    T[&quot;Inter-domain trust keys&quot;] --&amp;gt;|&quot;cross-domain TGT minting&quot;| FOR[&quot;Forest-wide auth&quot;]
    D[&quot;DSRM passwords on writeable DCs&quot;] --&amp;gt;|&quot;local-admin equivalent&quot;| DC[&quot;DC-local auth&quot;]
    DC --&amp;gt; ENVA
    DC --&amp;gt; C
    DC --&amp;gt; G
    DC --&amp;gt; T
    DC --&amp;gt; K
&lt;p&gt;&lt;strong&gt;KRBTGT long-term key.&lt;/strong&gt; Issues TGTs for all principals in the domain. Unique property within the Kerberos trust root: holding it forges TGTs for arbitrary principals, including ones that do not exist in the directory. Rotation: the two-reset, ten-hour-interval procedure on the AD Forest Recovery page [@ms-forest-recovery].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AD CS root CA private key.&lt;/strong&gt; Issues certificates that PKINIT trusts for Kerberos pre-authentication. Compromise yields Kerberos auth as any principal via PKINIT -- a different mechanism with the same end result. Rotation: CA hierarchy rebuild, significantly more expensive than krbtgt rotation. SpecterOps &quot;Certified Pre-Owned&quot; (Schroeder + Christensen, June 2021) is the canonical primary on the ESC-class abuses of this trust root, cross-referenced in Domain of Thrones Part II [@certified-pre-owned][@specterops-dot2].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KDS root key.&lt;/strong&gt; Group Managed Service Account passwords are derived deterministically from a &lt;a href=&quot;https://paragmali.com/blog/dpapi-and-dpapi-ng-the-credential-vault-under-everything/&quot; rel=&quot;noopener&quot;&gt;KDS root key&lt;/a&gt; plus a per-account &lt;code&gt;msDS-ManagedPasswordId&lt;/code&gt;. Compromise of the KDS root key reads every gMSA password in the forest. Different blast radius (service accounts only). Rotation: KDS root key rotation followed by gMSA cycling [@specterops-dot2].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Per-domain inter-domain trust keys.&lt;/strong&gt; Bridge Kerberos trust between domains in a forest or across explicit external trusts. Compromise yields cross-domain TGT minting. Rotation: per-trust password rotation, with SID Filtering and Selective Authentication audits as the standard hardening procedure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DSRM passwords on writeable DCs.&lt;/strong&gt; Directory Services Restore Mode is a local-admin equivalent at the DC level; compromise yields a local logon to the DC, which then enables many other paths including direct read of the krbtgt key from &lt;code&gt;ntds.dit&lt;/code&gt;. Rotation: per-DC DSRM password rotation [@specterops-dot2].&lt;/p&gt;
&lt;h3&gt;The precise framing&lt;/h3&gt;
&lt;p&gt;Within the Kerberos trust root of a single domain, the krbtgt key occupies a &lt;em&gt;unique&lt;/em&gt; position: it is the issuer of every TGT, and forging a TGT requires exactly this key. At the forest-AD-trust-graph level, the krbtgt key is one of a handful of high-cost-to-rotate trust roots, not the only one. The framing matters because it explains why Domain of Thrones Part II lists seven rotation workstreams: each is a candidate path to the same end result (arbitrary identity in the forest) through a different cryptographic mechanism.&lt;/p&gt;
&lt;p&gt;Five trust roots, one (krbtgt) with a unique forge-arbitrary-TGTs property, all five surfacing in the rotation list. With the trust-root topology mapped, the article&apos;s last technical job is the practical playbook: what does the reader actually do tomorrow morning?&lt;/p&gt;
&lt;h2&gt;10. Practical Guide: The Rotation and Detection Playbook&lt;/h2&gt;
&lt;p&gt;Four lanes. Each lane is a concrete action a reader can execute starting tomorrow morning.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;strong&gt;Lane 1:&lt;/strong&gt; Preventive hygiene -- rotate krbtgt twice a year on a calendar schedule and audit who can DCSync. &lt;strong&gt;Lane 2:&lt;/strong&gt; Detection deployment -- ship MDI Suspected-Golden-Ticket alerts plus SIEM T1558.001 content. &lt;strong&gt;Lane 3:&lt;/strong&gt; Confirmed-compromise response -- two-reset rotation followed by the Domain-of-Thrones surface. &lt;strong&gt;Lane 4:&lt;/strong&gt; What does NOT work -- four traps to avoid.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Lane 1: preventive hygiene&lt;/h3&gt;
&lt;p&gt;Rotate the krbtgt password twice a year on a calendar schedule, regardless of any specific incident. Use &lt;code&gt;New-KrbtgtKeys.ps1&lt;/code&gt; (or a fork of it) with pre-reset and post-reset replication-health checks [@new-krbtgt-keys]. Verify Active Directory replication health between the two rotations; if replication is lagging on any DC, the second reset can outpace the first in some replicas and break in-flight tickets.&lt;/p&gt;
&lt;p&gt;Move every Tier-0 account into the Protected Users group. Enable Credential Guard on every workstation and member server. Credential Guard does NOT protect the DC itself by design -- DCs must read the krbtgt key unencrypted -- but it kills the worker-station memory-scrape that initially gets an attacker into a position to pivot to the DC.&lt;/p&gt;
&lt;p&gt;Audit who can invoke DCSync. The BloodHound query &lt;code&gt;MATCH (u)-[:DCSync]-&amp;gt;(d:Domain)&lt;/code&gt; returns every principal whose existing AD permissions can extract the krbtgt key without a DC compromise [@bloodhound-notes][@mitre-t1003006]. Every match should map to a justified administrative role; any unexpected match is a finding.&lt;/p&gt;

LSAISO is a Virtualisation-Based Security trustlet that isolates long-term secrets from a SYSTEM-privileged kernel on workstations and member servers. On writeable DCs the design omits LSAISO because the KDC service must read the krbtgt key unencrypted to issue tickets. This is precisely the design property a DCSync-capable attacker exploits.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Two krbtgt rotations per year as preventive hygiene -- not a response to a specific incident. Use &lt;code&gt;New-KrbtgtKeys.ps1&lt;/code&gt; with replication-health checks before, between, and after. The 10-hour wait between rotations is mandatory; do not shorten it [@ms-forest-recovery].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Lane 2: detection deployment&lt;/h3&gt;
&lt;p&gt;Ship the MDI Suspected-Golden-Ticket alert family plus the DCSync alert (External ID 2006) [@mdi-classic][@mdi-credential]. Confirm the Suspected-Golden-Ticket alerts (2009, 2013, 2022, 2027, 2032, 2040) are active for every domain controller MDI is deployed against. Configure Microsoft Sentinel content-pack rules covering T1558.001 Golden Ticket and Kerberos-anomaly patterns (not the T1558.003 Kerberoasting rules, which target service-account SPNs and are not a krbtgt detection asset). Configure Splunk T1558.001 detection [@splunk-7d9] and tune the encryption-type baseline against legacy systems that legitimately negotiate RC4 (or, better, retire those systems).&lt;/p&gt;
&lt;p&gt;Ingest BloodHound for posture-graph visibility. Configure regular collections (the default is weekly) so the DCSync edge list stays current as ACLs change. Cross-reference the DCSync edge inventory against the actual administrative role assignments quarterly.&lt;/p&gt;
&lt;h3&gt;Lane 3: confirmed-compromise response&lt;/h3&gt;
&lt;p&gt;When MDI or Sentinel surfaces a confirmed krbtgt compromise -- DCSync extraction observed against a writeable DC, or a Suspected-Golden-Ticket alert with concrete supporting evidence -- the response runs in two parallel tracks. The cryptographic track executes the two-reset rotation: reset the krbtgt password (replicate, verify), wait at least 10 hours, reset again (replicate, verify) [@ms-forest-recovery]. The operational track executes the Domain-of-Thrones Part II rotation surface [@specterops-dot2]:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AD CS template review covering the ESC1 through ESC8 abuse classes [@certified-pre-owned]; replace or restrict templates with &lt;code&gt;EnrolleeSuppliesSubject&lt;/code&gt;, broad &lt;code&gt;Enroll&lt;/code&gt; permissions, or weak EKU restrictions.&lt;/li&gt;
&lt;li&gt;SID History audit (&lt;code&gt;Get-ADUser -Filter * -Properties SIDHistory&lt;/code&gt;); investigate every account whose SID History contains a Domain Admins or Enterprise Admins SID.&lt;/li&gt;
&lt;li&gt;AdminSDHolder ACL audit; reset Protected Group inherited ACLs and verify the SDProp runs cleanly.&lt;/li&gt;
&lt;li&gt;Machine-account secret rotation, especially for Tier-0 servers.&lt;/li&gt;
&lt;li&gt;KDS root-key rotation followed by gMSA password cycling.&lt;/li&gt;
&lt;li&gt;Trust-key rotation for every inbound and outbound trust.&lt;/li&gt;
&lt;li&gt;DSRM password rotation on every writeable DC.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After both tracks complete, re-baseline detection: the post-incident DC event-log baseline will differ from the pre-incident baseline, and detection thresholds may need re-tuning to suppress the resulting alerts.&lt;/p&gt;

The reference automation runs against the krbtgt SID specifically, not the friendly name, to avoid any ambiguity with a renamed object. Conceptually: `Set-ADAccountPassword -Identity (Get-ADUser -Filter &quot;objectSID -like &apos;*-502&apos;&quot;) -Reset -NewPassword (Convert-To-SecureString (New-RandomPassword) -AsPlainText -Force)`. The Microsoft Learn PowerShell reference for the `Set-ADAccountPassword` cmdlet documents the `-Reset` plus `-NewPassword` parameters used here [@ms-set-adaccountpassword]. The `New-KrbtgtKeys.ps1` script wraps this with replication checks and a confirmation prompt [@new-krbtgt-keys]. Production runbooks always include a pre-check that `Get-ADReplicationFailure` returns no failures before any reset is issued.
&lt;h3&gt;Lane 4: what does NOT work&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;strong&gt;Renaming krbtgt.&lt;/strong&gt; The RID 502 binding is what the KDC derives from, not the &lt;code&gt;sAMAccountName&lt;/code&gt;. The KDC service does not care about the friendly name. &lt;strong&gt;Disabling krbtgt.&lt;/strong&gt; The account is already disabled for interactive logon by design [@ms-default-accounts]. Toggling the field is semantically meaningless to the KDC service, which reads the long-term key directly from the directory. &lt;strong&gt;Single rotation.&lt;/strong&gt; Password-history-of-2 means a single rotation only retires the &lt;em&gt;older&lt;/em&gt; of the two keys, leaving the attacker-extracted key (which was current at compromise) still in the previous slot [@ms-forest-recovery]. The procedure must run twice. &lt;strong&gt;Treating MDI Suspected-Golden-Ticket alerts as sufficient.&lt;/strong&gt; Those alerts do not cover Diamond and Sapphire by construction. Sapphire defeats every PAC-content anomaly detection because the PAC is genuine. Confirmed-compromise response must assume the worst even when MDI is silent.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Preventive hygiene, detection deployment, confirmed-compromise response, and four traps to avoid. The FAQ that follows addresses what remains.&lt;/p&gt;
&lt;h2&gt;11. FAQ&lt;/h2&gt;

No. It retires Diamond Tickets that do not recompute the Full PAC Signature. It does nothing against tickets minted from a known krbtgt key, including Sapphire Tickets (no PAC modification) and recomputed Diamond Tickets (the attacker holds the key and can compute the new signature in the same step as the older KDC signature) [@kb5020805][@mspac].

No. See §10 Lane 4 trap #1: the RID 502 binding is what the KDC derives from, not the `sAMAccountName` [@ms-default-accounts][@ms-sids].

No. See §10 Lane 4 trap #3: password-history-of-2 keeps the previous key valid after a single rotation, so the procedure must run twice with at least `MaxTicketAge` between resets [@ms-forest-recovery][@new-krbtgt-keys].

No. See §10 Aside on why Credential Guard skips the DC: the KDC service on a writeable DC must read the krbtgt key unencrypted to issue tickets, and DCSync is a remote replication API call (DRSGetNCChanges), not a local LSASS memory scrape [@mitre-t1003006][@ms-credential-guard].

Mechanically, in-flight TGT validation requires the previous-key slot to retain validity for at least `MaxTicketAge` after each rotation. Operationally, the recommended cadence is calendar-driven preventive rotation twice a year, with incident-driven rotation as a separate workstream when confirmed compromise is detected [@ms-forest-recovery].

Indirectly. It forces all krbtgt-encrypted tickets to AES, raising the offline-crack bar against a captured ticket and reducing the surface for the Splunk RC4-Kerberos-anomaly detection family [@splunk-7d9]. It does not affect attacks against a captured krbtgt key; both AES-128 and AES-256 derivations are held in the same account and both validate forged TGTs cleanly.

Yes. Each Read-Only Domain Controller has its own `krbtgt_` account whose key signs TGTs only for principals that the RODC can authenticate [@adsec-483]. The full-domain krbtgt is the only account whose key signs TGTs accepted by every DC in the domain; compromise of an RODC-specific `krbtgt_` is a contained event whose blast radius is bounded by the RODC&apos;s allowed-list policy.

No. The IAKerb and Local KDC features shipping in recent Windows builds affect *where* KDCs run (allowing client-to-client Kerberos without a domain-joined intermediary), not the krbtgt-key trust root inside a domain. The post-RC4 enctype work affects *which* enctypes the krbtgt key derives, not the role of the key. As of [MS-KILE] revision 47.0 dated April 27, 2026, the krbtgt long-term key is still the sole trust anchor for every TGT in the domain [@mskile].
&lt;h3&gt;One sentence to take away&lt;/h3&gt;

Krbtgt rotation invalidates forged TGTs; it does not recover the systemic compromise that produced the forged TGTs in the first place.
&lt;p&gt;That is the precise sentence to keep from ten thousand words. The cryptographic question -- &quot;is the ticket valid?&quot; -- terminates at one key. The operational question -- &quot;is the domain still ours?&quot; -- never does. The 1988 design chose to make ticket validation a property of a single shared secret because that choice made the protocol simple and provably correct. The choice remains correct in 2026. What changed is the meaning of the word &lt;em&gt;compromise&lt;/em&gt;: in 1988 the threat model was a passive eavesdropper on a campus LAN; in 2026 the threat model is a remote API call that streams the secret across a &lt;code&gt;DRSGetNCChanges&lt;/code&gt; exchange. The key did not move. The attacker&apos;s reach did.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;krbtgt-the-account-that-owns-active-directory&quot; keyTerms={[
  { term: &quot;KRBTGT account&quot;, definition: &quot;The RID-502 Active Directory account whose long-term key encrypts every TGT in the domain.&quot; },
  { term: &quot;Ticket-Granting Ticket (TGT)&quot;, definition: &quot;The Kerberos credential issued at logon, encrypted under the krbtgt long-term key, that the client presents to request service tickets.&quot; },
  { term: &quot;Privilege Attribute Certificate (PAC)&quot;, definition: &quot;The Windows-specific structure inside the authorization-data field of every Kerberos ticket, carrying SIDs and signatures.&quot; },
  { term: &quot;DCSync&quot;, definition: &quot;A replication-API primitive (MITRE T1003.006) that streams account secrets including the krbtgt key from a writeable DC to any principal with replication rights.&quot; },
  { term: &quot;Golden Ticket&quot;, definition: &quot;A forged TGT minted from a held krbtgt key (MITRE T1558.001).&quot; },
  { term: &quot;Diamond Ticket&quot;, definition: &quot;A real KDC-issued TGT, decrypted with the held krbtgt key, with the PAC modified and re-signed.&quot; },
  { term: &quot;Sapphire Ticket&quot;, definition: &quot;A forged TGT containing a genuine PAC obtained via the S4U2self plus U2U Kerberos extensions.&quot; },
  { term: &quot;MaxTicketAge&quot;, definition: &quot;The Kerberos policy value bounding the lifetime of a TGT; default 10 hours in Active Directory.&quot; }
]} flashcards={[
  { front: &quot;What did the MS14-068 patch elevate the krbtgt key from and to?&quot;, back: &quot;From &apos;an important secret&apos; to &apos;the load-bearing secret of every authentication decision in the domain.&apos; The patch tied PAC integrity to a real keyed HMAC under the krbtgt key, making the krbtgt key the single secret worth attacking directly from November 2014 onward.&quot; },
  { front: &quot;Why does the Full PAC Signature not retire the primitive?&quot;, back: &quot;Because the Full PAC Signature is itself computed under the krbtgt key. An attacker who holds the key recomputes it in the same step as the older KDC signature, and Sapphire Tickets never modify the PAC at all -- so the KDC&apos;s own genuine Full PAC Signature is on the ticket by construction.&quot; },
  { front: &quot;What does the two-reset procedure do and not do?&quot;, back: &quot;It cryptographically invalidates previously-forged TGTs after the second reset replicates. It does NOT rotate the seven other secret classes an attacker with krbtgt access has typically also touched: AdminSDHolder, AD CS templates, SID History, machine-account secrets, KDS root keys, trust keys, DSRM passwords.&quot; }
]} questions={[
  { q: &quot;What makes krbtgt unique among AD trust roots?&quot;, a: &quot;Within the Kerberos trust root of a single domain, the krbtgt long-term key is the only secret whose disclosure forges TGTs for arbitrary principals, including ones that do not exist in the directory. The CA private key, KDS root key, trust keys, and DSRM passwords are other trust roots with their own blast radii, but only the krbtgt key has the forge-arbitrary-TGT property.&quot; },
  { q: &quot;Why does the two-reset procedure require at least 10 hours between resets?&quot;, a: &quot;Because the AD default MaxTicketAge is 10 hours. If the second reset lands before all TGTs issued under the now-displaced previous key have expired, those in-flight tickets fail validation when they reach a DC whose previous slot no longer holds their signing key. The 10-hour floor is a cryptographic requirement of the two-slot eviction mechanism, not a Microsoft convenience choice.&quot; },
  { q: &quot;What is the Sapphire residual, and why does no vendor analytic ship for it?&quot;, a: &quot;The Sapphire residual is the wire conjunction of an S4U2self-flagged TGS-REQ with a U2U TGS-REQ addressing the same TGT. No vendor ships a default-enabled analytic for this signal as of May 2026 because the engineering work to package it across SIEM platforms has not been done. The signal exists; the analytic is the engineering gap.&quot; },
  { q: &quot;Name three secret classes that survive krbtgt rotation.&quot;, a: &quot;Three of seven: AD CS root CA private key (and any ESC-class template backdoors), KDS root key (used to derive gMSA passwords), inter-domain trust keys (used to bridge Kerberos trust across domains). The remaining four from the Domain-of-Thrones rotation list: AdminSDHolder ACL edits, SID History entries, machine-account secrets, DSRM passwords on writeable DCs.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>active-directory</category><category>kerberos</category><category>krbtgt</category><category>security</category><category>golden-ticket</category><category>diamond-ticket</category><category>sapphire-ticket</category><category>windows-server</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>Who is allowed to log in where? The KDC-side answer to credential theft in Active Directory</title><link>https://paragmali.com/blog/who-is-allowed-to-log-in-where-the-kdc-side-answer-to-creden/</link><guid isPermaLink="true">https://paragmali.com/blog/who-is-allowed-to-log-in-where-the-kdc-side-answer-to-creden/</guid><description>A 28-year arc from Paul Ashton&apos;s pass-the-hash demonstration to the 2026 reference deployment of Tiering, Protected Users, and Authentication Policy Silos.</description><pubDate>Sat, 23 May 2026 00:00:00 GMT</pubDate><content:encoded>
Every NTLM and Kerberos credential-theft chain reduces to one operational question: which accounts will the directory authenticate, from which machines, with what credential materials? Active Directory&apos;s KDC-side answer arrived in a single October 2013 release -- the tier model (policy intent), the Protected Users security group (a non-configurable credential-restriction switch), and Authentication Policy Silos (KDC-enforced TGT-acceptance rules). It has since acquired residual closures (the November 2021 PAC hardening, the May 2022 PKINIT strong-mapping) and a cloud counterpart (Entra Conditional Access, a second independent enforcement plane). This article traces the 28-year arc from Paul Ashton&apos;s April 1997 pass-the-hash post to the 2026 reference deployment, names the four residuals the KDC cannot close by construction, and gives a six-phase playbook for putting the three controls into production this quarter.
&lt;h2&gt;1. Two accounts, one TGT, every domain controller&lt;/h2&gt;
&lt;p&gt;On a Tuesday morning in April 1997, an independent researcher named Paul Ashton posted to the NTBugtraq mailing list. His patched Samba &lt;code&gt;smbclient&lt;/code&gt; did not accept a password. It accepted the hash, and the file server gave it everything [@exploit-db-19197]. The directory had no answer for the next sixteen years.&lt;/p&gt;
&lt;p&gt;Skip forward to today. A domain admin&apos;s laptop is compromised by a phishing payload. The attacker runs Mimikatz against &lt;code&gt;lsass.exe&lt;/code&gt;, recovers a Kerberos ticket-granting ticket for the admin account, and from that TGT every domain controller in the forest is reachable. The detection engineer who pulls the incident report knows exactly what happened. The architect on the other side of the table knows the answer was never going to come from the workstation, from the smartcard, or from the RDP client. It had to come from the directory.&lt;/p&gt;
&lt;p&gt;This is what every credential-theft chain reduces to: a question about which accounts the directory will authenticate, from which machines, with which credential materials, for how long, and to whom they may delegate. Until October 2013, Active Directory had no place to answer that question. It had access-control lists, group memberships, and an AdminSDHolder template that re-stamped privileges every hour [@metcalf-p1906]. None of those mechanisms could refuse to issue a stolen credential, because on the wire a stolen credential is identical to a legitimate one.&lt;/p&gt;
&lt;p&gt;Windows Server 2012 R2 changed that on October 18, 2013 [@save-date-blog]. In a single release, the directory acquired three controls that compose into one operational answer. The &lt;strong&gt;tier model&lt;/strong&gt; names which accounts and machines belong to which control plane: T0 holds the domain controllers and the systems that manage them, T1 holds servers and business data, T2 holds workstations [@ms-eam]. The &lt;strong&gt;Protected Users security group&lt;/strong&gt; (well-known RID 525) imposes a non-configurable credential-restriction set: no &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;NTLM&lt;/a&gt;, no DES or RC4 in Kerberos, no delegation, no cached offline-sign-in verifier, and a four-hour non-renewable TGT cap [@ms-pu-current]. &lt;strong&gt;Authentication Policies&lt;/strong&gt; and &lt;strong&gt;Authentication Policy Silos&lt;/strong&gt; are directory objects that tell the Key Distribution Center (KDC) which source machines may authenticate which accounts, at AS-REQ time, before any TGT exists to be stolen [@ms-aps].&lt;/p&gt;
&lt;p&gt;If you arrived here from the earlier posts in this series: this is the operational counterpart to the NTLM relay story, to the Kerberoasting story, and to the Credential Guard story. Silos are how the KDC says no; Credential Guard is how the host says no; Conditional Access is how the cloud says no. The three planes are independent and they compose.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The on-prem AD KDC, keyed on directory state read at issuance time, is the operational answer to credential-theft attack chains. The directory decides which accounts may authenticate, from which machines, with which credential materials, for how long, and to whom they may delegate. The three controls -- tier model, Protected Users, Authentication Policy Silos -- compose into that decision.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The rest of this article pays off the question Ashton&apos;s 1997 post raises. Why did the directory have no answer for sixteen years? What changed in October 2013 that the pre-2013 controls could not deliver? What does a working 2026 deployment look like, and what does it still leave open?&lt;/p&gt;
&lt;h2&gt;2. Why the directory had no answer for a decade&lt;/h2&gt;
&lt;p&gt;Ashton&apos;s 1997 demonstration was not subtle. The NT hash is, on the wire, the credential. Windows NT 4&apos;s challenge-response authentication used the LanMan or NT one-way function output as the long-term key; anyone who could read that value from the SAM, from a network capture, or from &lt;code&gt;lsadump&lt;/code&gt; could authenticate as the principal without ever knowing the password [@exploit-db-19197]. Wikipedia&apos;s secondary anchor attributes the first public demonstration to Ashton and dates it to 1997 [@wiki-pth]; the Exploit-DB mirror of the original patch preserves file modification timestamps that narrow the day to Tuesday, April 8, 1997 [@exploit-db-19197].&lt;/p&gt;

A credential-theft technique that uses an account&apos;s NT one-way function output (the NT hash) to authenticate, instead of the plaintext password. Because the Windows NTLM protocol uses the hash itself as the long-term key, an attacker who reads the hash from memory or from disk can authenticate as the account without ever cracking the password.
&lt;p&gt;For more than a decade after Ashton&apos;s post, Microsoft&apos;s institutional position was that this was a protocol legacy, not a vulnerability. The reasoning was internally consistent: the hash IS the long-term key in the protocol&apos;s design; refusing to honour it would break every existing Windows client. The 2008 Pass-the-Hash Toolkit, written by Hernan Ochoa [@wiki-pth], turned the academic demonstration into a single-binary Windows-native tool that read NT hashes from &lt;code&gt;lsass.exe&lt;/code&gt; and injected them into a running logon session [@wiki-pth]. Microsoft&apos;s &lt;em&gt;Privileged access strategy&lt;/em&gt; page now records the 2008 release of the Pass-the-Hash Toolkit as the proximate cause of the escalation in attacker tooling [@ms-paw-strategy].&lt;/p&gt;
&lt;p&gt;Pre-2012, Microsoft&apos;s public posture toward credential-extraction tooling was, in Benjamin Delpy&apos;s own retelling, &quot;this is not a vulnerability.&quot; The Wired profile records the response he received when he disclosed Mimikatz to Microsoft in 2011 [@wired-mimikatz]. That posture is what made the 2012 white paper a turning point: Microsoft committed to treating the attack class as a vulnerability that had to be mitigated by a Microsoft control, not merely contained by operator discipline.&lt;/p&gt;
&lt;p&gt;The escalation that finally broke the institutional posture was Benjamin Delpy&apos;s Mimikatz, released publicly in May 2011 (closed source) on his personal blog [@mimikatz-blog]. Wired&apos;s biographical piece records the date verbatim: &quot;He released it publicly in May 2011, but as a closed source program&quot; [@wired-mimikatz]. The GitHub repository at &lt;code&gt;github.com/gentilkiwi/mimikatz&lt;/code&gt; opened in April 2014; the &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; command on a SYSTEM-level shell printed plaintext passwords, NT hashes, and Kerberos session keys directly from &lt;code&gt;lsass.exe&lt;/code&gt; [@mimikatz-repo]. Within twenty-four months it was the default post-exploitation credential dumper in every public AD attack-and-defence talk [@metcalf-p1738][@wired-mimikatz].&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s first institutional acknowledgement arrived in December 2012 as &lt;em&gt;Mitigating Pass-the-Hash, Version 1&lt;/em&gt;. The canonical Microsoft Download Center URL for that version has not survived the company&apos;s reorganisations and now returns HTTP 404; the document is preserved through references inside its successor, the 2014 Version 2 paper, which is still hosted [@pth-v2-pdf]. Version 2 introduces tiered administrative segmentation as a deployment shape and is unambiguous about why the previous decade of mitigations had not worked.&lt;/p&gt;

Pass-the-Hash and similar credential theft attacks are 100% successful when an attacker gains administrative privileges on a computer, because once a computer is compromised, the attacker can read any credential stored on that computer. -- Microsoft, *Mitigating Pass-the-Hash, Version 2* (2014) [@pth-v2-pdf]
&lt;p&gt;That sentence is the institutional pivot. It moves the framing from &quot;protocol feature, defend the host&quot; to &quot;credentials, once stolen, win.&quot; The defence cannot live in the host, because the host is where the attacker has already won. It also cannot live in the ACL, because the ACL evaluates the principal that is authenticating, and the stolen credential authenticates as the legitimate principal. If access-control lists cannot stop a stolen credential, what can?&lt;/p&gt;
&lt;h2&gt;3. Five generations of pre-2013 controls and why each one failed&lt;/h2&gt;
&lt;p&gt;Between 1997 and 2013, operators tried five distinct families of controls. Each targeted a different part of the stack. Each failed in the same structural way.&lt;/p&gt;
&lt;p&gt;The first family was &lt;strong&gt;operational discipline&lt;/strong&gt;: give every administrator two accounts, &lt;code&gt;alice&lt;/code&gt; for daily work and &lt;code&gt;alice.da&lt;/code&gt; for domain-administrative work, and trust her not to use the privileged identity from her daily workstation. NT 4 (RTM July 31, 1996) shipped with this as the operating model [@wiki-nt4]. As a control it is a procedure, not an enforcement: there is no directory mechanism that prevents &lt;code&gt;alice.da&lt;/code&gt; from interactively logging on to a tier-2 workstation. The Microsoft 2014 paper named the failure mode plainly: once &lt;code&gt;alice.da&lt;/code&gt; runs anywhere an attacker also runs, the credential material sits in that machine&apos;s LSASS and is replayable forest-wide [@pth-v2-pdf].&lt;/p&gt;
&lt;p&gt;The second family was &lt;strong&gt;directory-ACL hardening&lt;/strong&gt;. AdminSDHolder is an object under &lt;code&gt;CN=System&lt;/code&gt; in the directory that stores a template security descriptor. A background task called SDProp runs every 60 minutes on the PDC emulator and re-stamps that ACL onto every account with &lt;code&gt;adminCount=1&lt;/code&gt; -- Domain Admins, Enterprise Admins, Schema Admins, and the rest of the protected groups [@metcalf-p1906]. The intent is to prevent ACL drift: a helpdesk operator&apos;s misconfigured permission cannot weaken Domain Admin protections for more than an hour. The mechanism survives in modern AD, but its original &lt;em&gt;threat-model framing&lt;/em&gt; as a pass-the-hash mitigation is dead. ACLs evaluate the principal; a stolen credential authenticates as the legitimate principal. Worse, Sean Metcalf&apos;s &lt;em&gt;Sneaky Active Directory Persistence #15&lt;/em&gt; documents the inverse abuse: AdminSDHolder is not protected by AdminSDHolder, so an attacker who writes a Full-Control ACE into it once gets that ACE propagated across every protected member within sixty minutes [@metcalf-p1906].&lt;/p&gt;

`CN=AdminSDHolder,CN=System,DC=...` stores a template security descriptor. The SDProp (Security Descriptor propagator) task runs every 60 minutes on the PDC emulator and copies that ACL onto every member of the protected groups -- objects with `adminCount=1`. The mechanism prevents ACL drift on privileged accounts but does not stop credential theft.
&lt;p&gt;The third family was &lt;strong&gt;smartcard-required admin accounts&lt;/strong&gt;. Setting the &lt;code&gt;SMARTCARD_REQUIRED&lt;/code&gt; flag (UAC bit &lt;code&gt;0x40000&lt;/code&gt;) on a privileged account causes the KDC to refuse any AS-REQ that is not a PKINIT request -- the user must present a certificate chain rooted in the domain, with the matching private key on a smartcard [@rfc-4556]. The phishing-credential-into-fake-portal vector is closed: the operator does not know a password to type. But the PKINIT exchange produces a derived long-term key that lives on the workstation as a normal NT hash. The 2014 &lt;em&gt;Mitigating Pass-the-Hash&lt;/em&gt; paper is unambiguous in §6: &quot;Smart cards do not protect against the Pass-the-Hash credential theft attack vector. When a smart card is used to log in to a system, the system computes a derived NT hash of the password and stores it on the system&quot; [@pth-v2-pdf]. Mimikatz extracts the derived hash like any other.&lt;/p&gt;

The Public Key Cryptography for Initial Authentication in Kerberos extension, specified in RFC 4556. PKINIT lets a client present a certificate (typically held on a smartcard or a TPM) in its AS-REQ instead of a password-derived pre-authentication blob. The KDC validates the certificate against an account binding and issues a TGT. The resulting long-term key still lives in the host&apos;s LSASS process.
&lt;p&gt;The fourth family was &lt;strong&gt;host-side credential protection&lt;/strong&gt;: LSA Protection (&lt;code&gt;RunAsPPL&lt;/code&gt;), WDigest plaintext disablement, and the &lt;code&gt;TokenLeakDetectDelaySecs&lt;/code&gt; registry setting. LSA Protection runs &lt;code&gt;lsass.exe&lt;/code&gt; as a &lt;a href=&quot;https://paragmali.com/blog/protected-process-light-when-the-administrator-isnt-enough/&quot; rel=&quot;noopener&quot;&gt;Protected Process Light&lt;/a&gt;, refusing handles with &lt;code&gt;PROCESS_VM_READ&lt;/code&gt; to anything not signed at PPL level [@ms-lsa-prot]. WDigest plaintext disablement (via &lt;code&gt;UseLogonCredential=0&lt;/code&gt;, shipped in KB 2871997 in May 2014) stops the WDigest SSP from caching the user&apos;s plaintext password [@kb-2871997]. Both moved the bar; neither closed the attack. PPL is enforced by the kernel; on pre-VBS Windows an attacker with a signed kernel driver clears the protection bit, and Mimikatz ships &lt;code&gt;mimidrv.sys&lt;/code&gt; for exactly this purpose [@mimikatz-repo] (on modern hardware-rooted HVCI/VBS, the VTL1 secure kernel closes the signed-driver bypass, but the discussion then moves to where the §6 Credential Guard primitive lives [@ms-cred-guard]). WDigest disablement removes plaintext from memory but does nothing to the NT hash or to Kerberos session keys, which are the actually-replayable material.&lt;/p&gt;
&lt;p&gt;The fifth family was &lt;strong&gt;&lt;a href=&quot;https://paragmali.com/blog/rdp-authentication-26-years/&quot; rel=&quot;noopener&quot;&gt;Restricted Admin Mode for RDP&lt;/a&gt;&lt;/strong&gt;, shipped via the October 14, 2014 revision of KB 2871997 [@kb-2871997]. The intent was to interrupt lateral movement: &lt;code&gt;mstsc /restrictedadmin&lt;/code&gt; causes the RDP client to send a CredSSP-wrapped network logon to the target. The target creates a network-logon token instead of an interactive one, and the user&apos;s NT hash or Kerberos session keys never land on the target [@ms-rcg][@kfalde-restricted-admin]. Within months, Benjamin Delpy demonstrated the inverse: because the RDP client authenticates with the user&apos;s &lt;em&gt;existing&lt;/em&gt; credential material, an attacker on the client can pass a stolen NT hash directly into the RDP session with &lt;code&gt;sekurlsa::pth /user:alice.da /domain:CORP /ntlm:&amp;lt;hash&amp;gt; /run:&quot;mstsc /restrictedadmin&quot;&lt;/code&gt; [@mimikatz-repo]. The defence became the lateral move. Microsoft updated KB 2871997 to acknowledge this, and Restricted Admin is off by default client-side on modern Windows [@kb-2871997].&lt;/p&gt;
&lt;p&gt;Restricted Admin Mode for RDP is the cleanest case in the 28-year arc of a control whose deployment created the inverse of its intent. The mode that protects credentials on the RDP target also enables pass-the-hash &lt;em&gt;into&lt;/em&gt; the RDP target from a compromised client. Microsoft&apos;s response -- disable it on the client side -- is the practical confirmation. This is the strongest argument in the historical record for moving the credential-restriction decision out of the host, the protocol, and the channel, and into the KDC.&lt;/p&gt;

flowchart TD
    Op[&quot;Operator discipline (two-account pattern, 1990s)&quot;] --&amp;gt; Op_x[&quot;Procedure, not enforcement: one mistake compromises the forest&quot;]
    ACL[&quot;AdminSDHolder + SDProp (NT 4 / 2000)&quot;] --&amp;gt; ACL_x[&quot;ACLs evaluate the principal, and a stolen credential authenticates as the legitimate principal&quot;]
    SC[&quot;Smartcard-required (Server 2003+)&quot;] --&amp;gt; SC_x[&quot;PKINIT changes only the AS-REQ method, and the derived NT hash still lives in LSASS&quot;]
    HS[&quot;LSA Protection / WDigest off (2013-14)&quot;] --&amp;gt; HS_x[&quot;PPL bypassable by a signed kernel driver, with NT hash and Kerberos keys still in memory&quot;]
    RA[&quot;Restricted Admin Mode for RDP (Oct 2014)&quot;] --&amp;gt; RA_x[&quot;Inverse-of-intent: enables pass-the-hash via RDP from the compromised client&quot;]
    Op_x --&amp;gt; Sink[&quot;All five enforce in a layer that does not see the directory&apos;s authoritative view of who-may-issue-credentials-from-where&quot;]
    ACL_x --&amp;gt; Sink
    SC_x --&amp;gt; Sink
    HS_x --&amp;gt; Sink
    RA_x --&amp;gt; Sink
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A credential, once usable, is on the wire identical to the legitimate one. Every Generation 1-5 control fails because it enforces in a layer that cannot tell the two apart at the point where it tries to decide. The fix is to refuse to issue or to delegate the credential in the first place -- a decision that has to move one layer up, to the KDC, keyed on directory state.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the operator cannot be trusted, the ACL cannot enforce, the smartcard-derived hash still lives in LSASS, the host-side protections can be bypassed by anyone with privilege to deploy them, and the RDP mode meant to interrupt lateral movement enables it -- where does the decision have to move?&lt;/p&gt;
&lt;h2&gt;4. October 18, 2013: the directory acquires a vocabulary&lt;/h2&gt;
&lt;p&gt;The Microsoft Server team&apos;s August 14, 2013 save-the-date blog post fixed the General Availability of Windows Server 2012 R2 for October 18, 2013 [@save-date-blog]. In that single release, three new directory-side primitives appeared: the &lt;strong&gt;Protected Users&lt;/strong&gt; built-in security group with well-known RID 525, the &lt;strong&gt;&lt;code&gt;msDS-AuthNPolicy&lt;/code&gt;&lt;/strong&gt; AD object class for Authentication Policies, and the &lt;strong&gt;&lt;code&gt;msDS-AuthNPolicySilo&lt;/code&gt;&lt;/strong&gt; AD object class for Authentication Policy Silos [@ms-pu-legacy]. The legacy Windows Server 2012 R2 TechNet documentation, preserved on Microsoft Learn, states the introduction verbatim: &quot;This group was introduced in Windows Server 2012 R2&quot; [@ms-pu-legacy]. The architectural decision visible in the wire format: the KDC, not the application, now decides whether a TGT may be issued, what its lifetime will be, and what delegation operations on it will succeed.&lt;/p&gt;

The Kerberos authentication service, specified in RFC 4120. The KDC handles AS-REQ (issuing a Ticket-Granting Ticket from a long-term key) and TGS-REQ (issuing a service ticket from a TGT). On Windows domains, every domain controller runs a KDC; the KDC reads its policy state from the directory at request time, which is the property the Server 2012 R2 controls exploit [@rfc-4120].

A Microsoft authorisation-data overlay carried inside Kerberos TGTs and service tickets, specified in [MS-PAC]. The PAC&apos;s `PAC_LOGON_INFO` buffer contains the user&apos;s SID, primary-group SID, and a `GroupIds` array of well-known group memberships. Protected Users membership is encoded as RID 525 inside that array. There is no separate Protected Users flag bit [@ms-pac].
&lt;p&gt;The detail that matters: there is no dedicated &quot;Protected Users bit&quot; in the PAC. The encoding is the well-known group SID &lt;code&gt;S-1-5-21-&amp;lt;domain&amp;gt;-525&lt;/code&gt; carried in &lt;code&gt;PAC_LOGON_INFO.GroupIds&lt;/code&gt; ([MS-PAC] §2.5) [@ms-pac][@ms-pu-legacy]. The KDC reads that array at AS-REQ and TGS-REQ time the same way it reads it for every other group; what changes is the behaviour the KDC takes when it sees RID 525.&lt;/p&gt;
&lt;p&gt;The down-level half of the shipment arrived seven months later. On May 13, 2014, Microsoft Security Advisory KB 2871997 backported the &lt;em&gt;client-side honoring&lt;/em&gt; of Protected Users and Authentication Policies to Windows 7, Windows 8, Server 2008 R2, and Server 2012 [@kb-2871997]. KB 2871997 is not the introduction of Protected Users. It is the down-level backport that closed the long-tail Silo-bypass class an enterprise would hit if its 2014-era fleet could not honour the new restriction list. Five months later, the October 14, 2014 revision of the same KB shipped Restricted Admin Mode for RDP -- the mode §3 already taught the reader to treat as a cautionary tale.&lt;/p&gt;
&lt;p&gt;The version-mismatch story matters for the operator who finds a 2014 KB cited as the &quot;introduction&quot; of Protected Users in older blog posts. It is not. The introduction is Server 2012 R2 GA on October 18, 2013; the backport is KB 2871997 on May 13, 2014. The legacy Microsoft Learn page records the introduction date plainly [@ms-pu-legacy].&lt;/p&gt;
&lt;p&gt;Microsoft followed the primitive with a deployment shape. The &lt;em&gt;Securing Privileged Access&lt;/em&gt; reference material, originally published on TechNet circa 2014-2015 and preserved on Microsoft Learn at the &lt;code&gt;privileged-access-workstations&lt;/code&gt; root [@ms-paw-root], codified the &lt;strong&gt;clean-source principle&lt;/strong&gt;: a higher-tier secret must never be exposed to a lower-tier host. T0 holds domain controllers, the PKI root, the identity-sync infrastructure, and the DC backup system. T1 holds servers and business data. T2 holds workstations [@ms-eam]. T0 credentials never authenticate to T1 or T2; T1 credentials never authenticate to T2. The Privileged Access Workstation (PAW) is the dedicated source machine for T0 administration. Server 2012 R2 gave operators the &lt;em&gt;primitives&lt;/em&gt;; SPA gave them the &lt;em&gt;shape&lt;/em&gt;.&lt;/p&gt;

flowchart LR
    A[&quot;Apr 8, 1997: Paul Ashton, NTBugtraq -- hash IS the credential&quot;] --&amp;gt; B[&quot;2008: Hernan Ochoa, Pass-the-Hash Toolkit&quot;]
    B --&amp;gt; C[&quot;May 2011: Benjamin Delpy, Mimikatz public release&quot;]
    C --&amp;gt; D[&quot;Dec 2012: Microsoft, Mitigating Pass-the-Hash v1&quot;]
    D --&amp;gt; E[&quot;Oct 18, 2013: Windows Server 2012 R2 GA -- Protected Users, Authentication Policies, Silos&quot;]
    E --&amp;gt; F[&quot;May 13, 2014: KB 2871997 down-level backport&quot;]
    F --&amp;gt; G[&quot;Oct 14, 2014: KB 2871997 adds Restricted Admin RDP&quot;]
    G --&amp;gt; H[&quot;2014-2015: Securing Privileged Access reference material&quot;]
    H --&amp;gt;     I[&quot;Dec 15, 2020: ESAE retired, Enterprise Access Model begins&quot;]
    I --&amp;gt; J[&quot;Nov 9, 2021: KB 5008380 PAC hardening&quot;]
    J --&amp;gt; K[&quot;May 10, 2022: KB 5014754 PKINIT strong mapping&quot;]
    K --&amp;gt; L[&quot;Feb 11, 2025: KB 5014754 Full Enforcement default&quot;]
    L --&amp;gt; M[&quot;Sep 9, 2025: KB 5014754 Compatibility-mode revert removed&quot;]
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The KDC, not the application, decides whether a TGT may be issued, what its lifetime is, and what delegation operations on it will succeed. The decision is made by reading directory state -- group SID 525 in &lt;code&gt;PAC_LOGON_INFO.GroupIds&lt;/code&gt; for Protected Users, &lt;code&gt;msDS-AssignedAuthNPolicySilo&lt;/code&gt; and &lt;code&gt;msDS-AssignedAuthNPolicy&lt;/code&gt; for Silo and Policy bindings -- at request time. This is the architectural pivot. The credential-on-the-wire identity property no longer matters, because the credential never gets issued in the first place to be stolen.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Three controls, one ship. But how do they compose, exactly -- which decision does the KDC actually make at AS-REQ time, what does it read from the directory, and what does it refuse?&lt;/p&gt;
&lt;h2&gt;5. How the three controls compose: a mechanism walkthrough&lt;/h2&gt;
&lt;p&gt;If you have time to read only one section of this article, read this one. The Server 2012 R2 controls compose into a precise decision the KDC makes at AS-REQ and TGS-REQ time. The mechanism has four moving parts.&lt;/p&gt;
&lt;h3&gt;5.1 The tier model as policy intent&lt;/h3&gt;
&lt;p&gt;The tier model is policy intent, not enforcement. &lt;strong&gt;Tier 0&lt;/strong&gt; is the control plane: every domain controller, every certificate authority that issues domain-trust certificates, the Microsoft Entra Connect server that synchronises identity to the cloud, and the backup systems that can restore any of those. &lt;strong&gt;Tier 1&lt;/strong&gt; is the management and data plane: servers, business applications, and the database engines that hold the data the organisation actually cares about. &lt;strong&gt;Tier 2&lt;/strong&gt; is the user plane: workstations and the devices users carry [@ms-eam]. The rule that defines the model is the clean-source principle: a higher-tier credential must never authenticate to a lower-tier host, because once it lands in the lower-tier host&apos;s memory it is exfiltrable by anyone with privilege on that host [@ms-paw-strategy]. The tier model says nothing about how the rule is enforced. Protected Users and Authentication Policy Silos are how.&lt;/p&gt;
&lt;h3&gt;5.2 Protected Users: the credential-restriction switch&lt;/h3&gt;
&lt;p&gt;Protected Users is a global security group with well-known RID 525, present in every domain at Domain Functional Level 2012 R2 or later. Membership is encoded as the well-known SID &lt;code&gt;S-1-5-21-&amp;lt;domain&amp;gt;-525&lt;/code&gt; carried in the &lt;code&gt;GroupIds&lt;/code&gt; array of the user&apos;s &lt;code&gt;PAC_LOGON_INFO&lt;/code&gt; ([MS-PAC] §2.5) [@ms-pac][@ms-pu-current]. When the KDC reads RID 525 in that array, it applies a non-configurable restriction set documented on Microsoft Learn [@ms-pu-current]:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;No NTLM authentication.&lt;/strong&gt; The DC refuses any NTLM authentication attempt for a Protected Users member -- the NTLM SSP and NetLogon path on the DC enforce the rejection, and the Kerberos KDC enforces the corresponding refusal for AS-REQ flows that fall back to NTLM-style pre-authentication. NTLM relay against the account is structurally impossible because there is no NTLM session to relay.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No NTLM hash caching on the host.&lt;/strong&gt; Even if the user has logged on interactively, the LSA never holds the account&apos;s NT one-way function output. Mimikatz &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; prints &lt;code&gt;(null)&lt;/code&gt; for the NTLM tab.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No DES or RC4 in Kerberos pre-authentication.&lt;/strong&gt; AES-128 or AES-256 only. Kerberoasting against the account becomes inapplicable, because the public roasting tooling requires RC4-HMAC ticket material that the KDC refuses to issue.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No constrained or unconstrained delegation, in either direction.&lt;/strong&gt; The account cannot be the source of a constrained-delegation chain, and S4U2Self / S4U2Proxy against the account as a target is refused at TGS-REQ time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No cached offline-sign-in verifier.&lt;/strong&gt; The Windows Hello for Business PIN-based offline-logon path is unavailable for Protected Users members; this is the operational price of removing the cached verifier from disk.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TGT lifetime capped at 240 minutes, non-renewable.&lt;/strong&gt; Microsoft Learn states the figure verbatim: &quot;For Protected Users members, the group automatically sets these lifetime limits to 240 minutes&quot; [@ms-pu-current]. The cap overrides the domain&apos;s &quot;Maximum lifetime for user ticket&quot; and &quot;Maximum lifetime for user ticket renewal&quot; policies.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The built-in domain Administrator (RID 500) is always exempt from Authentication Policy enforcement even when assigned to a Silo, which makes it a candidate break-glass identity [@ms-pu-current]. That exemption does not extend to the Protected Users restriction set itself: adding RID 500 to Protected Users on a domain whose Administrator account lacks AES keys will lock the account out. Service accounts cannot be enrolled in Protected Users without breaking workflows -- see §6&apos;s canonical Microsoft Learn PullQuote on this point.&lt;/p&gt;
&lt;h3&gt;5.3 Authentication Policies and Silos: the KDC-side policy objects&lt;/h3&gt;
&lt;p&gt;Two AD object classes, layered. The containment direction is the most common practitioner confusion, so be precise about it: &lt;strong&gt;the Silo references the Policy, not the other way&lt;/strong&gt;.&lt;/p&gt;

The container object. A Silo enumerates the user, computer, and service accounts that share a set of restrictions and references one or more `msDS-AuthNPolicy` objects whose rules apply to its members. The Silo carries an `msDS-AuthNPolicySiloEnforced` Boolean that switches between audit-only and enforced modes. Accounts bind to it via `msDS-AssignedAuthNPolicySilo`, with `msDS-AuthNPolicySiloMembers` as the back-link [@ms-aps].

The rules object. A Policy carries the non-renewable TGT lifetime cap, the allowed-from SDDLs on source-machine identity (`UserAllowedToAuthenticateFrom`, `ServiceAllowedToAuthenticateFrom` -- computer accounts have no `-From` variant, only `-To`), the corresponding allowed-to SDDLs for delegation targets (`UserAllowedToAuthenticateTo`, `ServiceAllowedToAuthenticateTo`, `ComputerAllowedToAuthenticateTo`), claim-based authentication access-control conditions, and the option to require Kerberos armoring per RFC 6113 [@ms-aps][@rfc-6113].
&lt;p&gt;The same Policy can be referenced by multiple Silos. Accounts can be bound to a Policy directly via &lt;code&gt;msDS-AssignedAuthNPolicy&lt;/code&gt; without being placed in a Silo at all, though the more common pattern is Silo membership for the broader containment and Policy reuse for the rule definitions.&lt;/p&gt;
&lt;p&gt;The containment direction is the single most-common practitioner confusion. The Silo names the Policy that applies to its members. The same Policy can apply to several Silos. The directory links are role-specific: the Silo carries &lt;code&gt;msDS-UserAuthNPolicy&lt;/code&gt;, &lt;code&gt;msDS-ComputerAuthNPolicy&lt;/code&gt;, and &lt;code&gt;msDS-ServiceAuthNPolicy&lt;/code&gt;, each pointing outward to a Policy object [@ms-aps]. Older blog posts that describe &quot;the Policy attached to the Silo&quot; are using imprecise prose; the link in the schema is Silo to Policy, not the other way.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Policy and Silo objects replicate via standard AD multi-master directory replication -- the &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;DRS Remote Protocol&lt;/a&gt;, MS-DRSR / &lt;code&gt;drsuapi&lt;/code&gt; [@ms-drsr]. They do NOT replicate via FRS or DFSR. FRS and DFSR replicate SYSVOL files (Group Policy content, scripts), not directory objects. Practitioners who chase &quot;my Policy assignment is not replicating&quot; through DFSR diagnostics are looking in the wrong primitive; the right one is &lt;code&gt;repadmin /showrepl&lt;/code&gt; against the DRS partition.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;5.4 The KDC&apos;s decision points&lt;/h3&gt;
&lt;p&gt;The KDC consults the directory at three precise moments, documented in [MS-KILE] §3.3.5 [@ms-kile]:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AS-REQ.&lt;/strong&gt; The KDC reads the requester&apos;s &lt;code&gt;msDS-AssignedAuthNPolicySilo&lt;/code&gt; and any &lt;code&gt;msDS-AssignedAuthNPolicy&lt;/code&gt;. If the Policy specifies a &lt;code&gt;UserAllowedToAuthenticateFrom&lt;/code&gt; SDDL, the KDC evaluates the source-machine identity (as presented in the pre-authentication exchange) against the SDDL. On denial, the KDC returns &lt;code&gt;KDC_ERR_POLICY&lt;/code&gt; and no TGT is issued. The KDC also checks &lt;code&gt;PAC_LOGON_INFO.GroupIds&lt;/code&gt; for RID 525; if present, it applies the Protected Users restriction set to the TGT it is about to issue (AES-only, 240-minute cap, delegation forbidden).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TGS-REQ for S4U2Self.&lt;/strong&gt; The KDC reads the target account&apos;s group memberships and Silo bindings. If the target is a Protected Users member, S4U2Self is refused. If the target&apos;s Silo Policy specifies an allowed-to SDDL, the requesting service identity is evaluated against it [@ms-sfu].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TGS-REQ for S4U2Proxy.&lt;/strong&gt; The KDC evaluates the requesting service&apos;s &lt;code&gt;msDS-AllowedToDelegateTo&lt;/code&gt; and the target&apos;s &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt;, then layers the Silo Policy&apos;s claim requirements on top. Protected Users membership on either side terminates the request [@ms-sfu].&lt;/li&gt;
&lt;/ul&gt;

sequenceDiagram
    participant PAW as PAW (source machine)
    participant KDC as KDC on DC
    participant DS as Directory (LDAP DSA)
    PAW-&amp;gt;&amp;gt;KDC: AS-REQ for alice.da, pre-auth signed
    KDC-&amp;gt;&amp;gt;DS: Read alice.da object (PAC_LOGON_INFO, msDS-AssignedAuthNPolicySilo)
    DS--&amp;gt;&amp;gt;KDC: GroupIds includes RID 525, Silo = &quot;T0 Admins&quot;
    KDC-&amp;gt;&amp;gt;DS: Read referenced Policy (msDS-AuthNPolicy)
    DS--&amp;gt;&amp;gt;KDC: UserAllowedToAuthenticateFrom SDDL pinned to T0 PAWs
    KDC-&amp;gt;&amp;gt;KDC: Evaluate source machine identity against SDDL
    alt Source is in the allowed-from set
        KDC-&amp;gt;&amp;gt;KDC: Apply Protected Users restriction set (AES-only, no NTLM, no delegation)
        KDC-&amp;gt;&amp;gt;KDC: Cap TGT lifetime at 240 minutes non-renewable
        KDC--&amp;gt;&amp;gt;PAW: TGT issued with restriction PAC
    else Source not in the allowed-from set
        KDC--&amp;gt;&amp;gt;PAW: KDC_ERR_POLICY, no TGT issued
    end

flowchart LR
    A[&quot;User account alice.da (msDS-AssignedAuthNPolicySilo)&quot;] --&amp;gt; S[&quot;Silo: T0 Admins (msDS-AuthNPolicySilo)&quot;]
    C[&quot;Computer account paw01 (msDS-AssignedAuthNPolicySilo)&quot;] --&amp;gt; S
    SV[&quot;Service account svc-bkp (msDS-AssignedAuthNPolicySilo)&quot;] --&amp;gt; S
    S -- &quot;references&quot; --&amp;gt; P[&quot;Policy: T0 Source Restriction (msDS-AuthNPolicy)&quot;]
    P --&amp;gt; Rule1[&quot;UserAllowedToAuthenticateFrom SDDL&quot;]
    P --&amp;gt; Rule2[&quot;TGT lifetime cap&quot;]
    P --&amp;gt; Rule3[&quot;Claim transformations&quot;]
    P --&amp;gt; Rule4[&quot;FAST armoring requirement&quot;]
    S -. &quot;alt direct binding&quot; .-&amp;gt; A2[&quot;Account can also bind via msDS-AssignedAuthNPolicy&quot;]
&lt;p&gt;The RunnableCode block below simulates the decision tree as a small JS function. It is pedagogical, not a real KDC, but the logic mirrors what [MS-KILE] specifies. Change the inputs -- move the source machine outside the allowed-from set, flip the Protected Users flag -- and the decision changes.&lt;/p&gt;
&lt;p&gt;{`
function kdcDecideAsReq(account, sourceMachine) {
  // account: { name, inProtectedUsers, siloPolicy: { allowedFrom: [], tgtMinutes, requireFast } }
  // sourceMachine: { name }&lt;/p&gt;
&lt;p&gt;  if (account.siloPolicy &amp;amp;&amp;amp; account.siloPolicy.allowedFrom &amp;amp;&amp;amp;
      !account.siloPolicy.allowedFrom.includes(sourceMachine.name)) {
    return { issued: false, error: &quot;KDC_ERR_POLICY&quot;, reason: &quot;source not in allowed-from set&quot; };
  }&lt;/p&gt;
&lt;p&gt;  const restrictions = [];
  let tgtMinutes = account.siloPolicy ? account.siloPolicy.tgtMinutes : 600;
  let renewable = true;&lt;/p&gt;
&lt;p&gt;  if (account.inProtectedUsers) {
    restrictions.push(&quot;no-NTLM&quot;, &quot;AES-only&quot;, &quot;no-delegation&quot;, &quot;no-cached-verifier&quot;);
    tgtMinutes = Math.min(tgtMinutes, 240);
    renewable = false;
  }&lt;/p&gt;
&lt;p&gt;  return {
    issued: true,
    tgtMinutes,
    renewable,
    restrictions,
    sourceMachine: sourceMachine.name
  };
}&lt;/p&gt;
&lt;p&gt;const alice = {
  name: &quot;alice.da&quot;,
  inProtectedUsers: true,
  siloPolicy: { allowedFrom: [&quot;paw-t0-01&quot;, &quot;paw-t0-02&quot;], tgtMinutes: 480, requireFast: true }
};&lt;/p&gt;
&lt;p&gt;console.log(&quot;From PAW:&quot;, kdcDecideAsReq(alice, { name: &quot;paw-t0-01&quot; }));
console.log(&quot;From workstation:&quot;, kdcDecideAsReq(alice, { name: &quot;wks-finance-77&quot; }));
`}&lt;/p&gt;
&lt;p&gt;The KDC now has a vocabulary it did not have in 1997. Well-known group SID 525 as a credential-restriction switch. &lt;code&gt;msDS-AuthNPolicySilo&lt;/code&gt; and &lt;code&gt;msDS-AuthNPolicy&lt;/code&gt; as policy objects. &lt;code&gt;drsuapi&lt;/code&gt; as the replication primitive that carries policy changes to every DC. The decision is keyed on directory state, made at request time, before any TGT exists to be stolen. With the mechanism in hand, what does a current 2026 reference deployment look like?&lt;/p&gt;
&lt;h2&gt;6. The 2026 reference deployment&lt;/h2&gt;
&lt;p&gt;Microsoft has had thirteen years to settle the deployment shape. As of May 2026, a well-built environment looks like the layered stack below, in which Silos and Protected Users carry the on-prem enforcement and several complementary primitives close residuals the KDC plane cannot address by construction.&lt;/p&gt;

The control plane of an Active Directory environment. T0 contains the domain controllers and every system whose compromise grants forest-wide control: the AD CS certificate authorities, the Microsoft Entra Connect server, the privileged-access workstations used to manage them, and the backup systems that can restore any of those. The SpecterOps Tier Zero Table is the community-maintained canonical asset list and is the practical starting point for any T0 inventory [@tzt-pages][@tzt-github].
&lt;p&gt;The reference deployment composes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tier model present as policy intent&lt;/strong&gt;, with Authentication Policy Silos as the enforcement primitive that makes the tier boundary KDC-visible.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;All human T0 administrators in Protected Users&lt;/strong&gt;, in a &quot;T0 Admins&quot; Silo whose Policy&apos;s &lt;code&gt;UserAllowedToAuthenticateFrom&lt;/code&gt; SDDL pins authentication to a defined set of T0 PAWs. The KDC will return &lt;code&gt;KDC_ERR_POLICY&lt;/code&gt; for any AS-REQ from outside that set [@ms-aps][@ms-kile].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;T0 service accounts in a &quot;T0 Services&quot; Silo&lt;/strong&gt; with a more permissive Policy that still pins source machines. Service accounts cannot be in Protected Users; the Silo plane is the only KDC-side enforcement available to them [@ms-pu-current].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Domain-wide migration off RC4-HMAC&lt;/strong&gt; for AS-REP, with &lt;code&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; audited per account. Protected Users enforces AES-only for free for human members; service accounts need explicit per-account configuration [@ms-config-pa].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&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; default-on&lt;/strong&gt; for non-DC Windows 11 22H2+ and Windows Server 2025+ devices that meet the hardware requirements [@ms-cred-guard]. &lt;strong&gt;Windows LAPS&lt;/strong&gt; managing local-administrator password uniqueness on every workstation [@ms-laps].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Entra PIM for Entra ID privileged roles&lt;/strong&gt; [@ms-pim], with &lt;strong&gt;Conditional Access&lt;/strong&gt; keyed on the synced T0 Admins group requiring phishing-resistant MFA and a compliant device. The CA does not see the Silo; it sees the synced group. The two planes are independent (see §8).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft Defender for Identity&lt;/strong&gt; assessments running, including &quot;Identify privileged accounts that are not protected by Protected Users group&quot; and adjacent recommendations [@ms-mdi]. This is the detection plane that tells the operator the reference deployment is the deployed posture.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the service accounts that cannot be enrolled in Protected Users, the explicit AES enforcement story is direct: set &lt;code&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; to &lt;code&gt;0x18&lt;/code&gt; (AES128 &lt;code&gt;0x08&lt;/code&gt; + AES256 &lt;code&gt;0x10&lt;/code&gt;). To additionally signal Compound-Identity-Supported, use &lt;code&gt;0x20018&lt;/code&gt; (&lt;code&gt;0x18 | 0x20000&lt;/code&gt;) -- Compound-Identity-Supported is the &lt;code&gt;G&lt;/code&gt; bit at position 17 of the [MS-KILE] §2.2.7 &lt;em&gt;Supported Encryption Types Bit Flags&lt;/em&gt; diagram, value &lt;code&gt;0x20000&lt;/code&gt;, not &lt;code&gt;0x40&lt;/code&gt;. The full bit layout per [MS-KILE] §2.2.7 is: DES-CBC-CRC &lt;code&gt;0x01&lt;/code&gt;, DES-CBC-MD5 &lt;code&gt;0x02&lt;/code&gt;, RC4-HMAC &lt;code&gt;0x04&lt;/code&gt;, AES128-CTS-HMAC-SHA1-96 &lt;code&gt;0x08&lt;/code&gt;, AES256-CTS-HMAC-SHA1-96 &lt;code&gt;0x10&lt;/code&gt;, FAST-Supported &lt;code&gt;0x10000&lt;/code&gt;, Compound-Identity-Supported &lt;code&gt;0x20000&lt;/code&gt;, Claims-Supported &lt;code&gt;0x40000&lt;/code&gt;, Resource-SID-Compression-Disabled &lt;code&gt;0x80000&lt;/code&gt;; &lt;code&gt;0x40&lt;/code&gt; is bit 6 (AES128-CTS-HMAC-SHA256-128, an RFC 8009 enctype [@rfc-8009] older KDCs do not fully support and which is &lt;em&gt;not&lt;/em&gt; Compound-Identity-Supported). The value &lt;code&gt;0x18&lt;/code&gt; explicitly excludes RC4 (&lt;code&gt;0x04&lt;/code&gt;) and the two DES flavours (&lt;code&gt;0x01&lt;/code&gt;, &lt;code&gt;0x02&lt;/code&gt;). Note that &lt;code&gt;0x1C&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; AES-only -- it is &lt;code&gt;0x10 | 0x08 | 0x04&lt;/code&gt;, which re-introduces RC4 on the very account you are trying to harden. &lt;a href=&quot;https://paragmali.com/blog/dpapi-and-dpapi-ng-the-credential-vault-under-everything/&quot; rel=&quot;noopener&quot;&gt;Group Managed Service Accounts&lt;/a&gt; (gMSA) are the preferred new-service-account primitive: the Microsoft Key Distribution Service computes a long, automatically-rotated password keyed on a domain-wide root key, and the Microsoft Learn gMSA overview describes the mechanism in detail -- the resulting AES pre-auth tickets are not roastable in practical timeframes [@ms-gmsa-overview]. Microsoft&apos;s &lt;em&gt;How to Configure Protected Accounts&lt;/em&gt; page lays out the per-account migration steps for non-gMSA legacy services [@ms-config-pa].&lt;/p&gt;

Never add accounts for services and computers to the Protected Users group. For those accounts, membership doesn&apos;t provide local protections because the password and certificate is always available on the host. -- Microsoft Learn, *Protected Users Security Group* [@ms-pu-current]
&lt;p&gt;That quote is the operational reason the RBCD residual remains the punchline of §8. Before then, two further pieces of the reference deployment need to be named, because both have been mis-described in widely shared blog posts.&lt;/p&gt;
&lt;p&gt;The first is the &lt;strong&gt;November 2021 PAC hardening&lt;/strong&gt; in KB 5008380, which addressed CVE-2021-42287 and CVE-2021-42278 (&quot;noPAC&quot;). The fix added two new PAC buffer types to the Kerberos TGT: &lt;code&gt;PAC_REQUESTOR&lt;/code&gt; (buffer type 18), which encodes the SID of the principal that requested the ticket, and &lt;code&gt;PAC_ATTRIBUTES_INFO&lt;/code&gt; (buffer type 17), which carries PAC-generation attributes [@kb-5008380][@ms-pac]. The KDC at TGS-REQ time now verifies that the requestor SID in the PAC matches the principal currently presenting the TGT. Initial deployment was November 9, 2021; the Enforcement phase landed October 11, 2022 [@kb-5008380].&lt;/p&gt;
&lt;p&gt;The second is the &lt;strong&gt;May 2022 PKINIT certificate-to-account strong-mapping&lt;/strong&gt; fix in KB 5014754 [@kb-5014754]. Pre-fix, the KDC mapped a PKINIT certificate to an account by sAMAccountName or UPN -- the same comparison that Schroeder and Christensen&apos;s &lt;em&gt;Certified Pre-Owned&lt;/em&gt; whitepaper showed could be spoofed via UPN conflicts or via the trailing dollar-sign convention on machine accounts [@cert-preowned-blog][@cert-preowned-pdf]. The fix added the &lt;code&gt;SecurityIdentifier&lt;/code&gt; X.509 extension OID &lt;code&gt;1.3.6.1.4.1.311.25.2&lt;/code&gt; to certificates issued by AD CS and requires the KDC to match the SID in the certificate against the SID of the account being authenticated. The Full Enforcement default landed February 11, 2025; the Compatibility-mode revert option was removed on September 9, 2025 [@kb-5014754].&lt;/p&gt;

The November 2021 PAC hardening is not the encoding of Protected Users membership. The Protected Users marker is RID 525 in `PAC_LOGON_INFO.GroupIds`, present in the PAC since Windows Server 2012 R2 GA in October 2013. The November 2021 buffers (`PAC_REQUESTOR`, `PAC_ATTRIBUTES_INFO`) are a separate, later KDC anti-spoofing primitive that closes the sAMAccountName-spoofing chain in CVE-2021-42278 plus CVE-2021-42287 [@kb-5008380][@ms-pac]. Conflating them produces wrong threat-model claims: it treats a 2021 anti-spoofing fix as if it were the 2013 credential-restriction marker, and leaves the operator unable to reason about either correctly.
&lt;p&gt;&lt;strong&gt;Reference 2026 deployment: what runs where.&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Account class&lt;/th&gt;
&lt;th&gt;Protected Users?&lt;/th&gt;
&lt;th&gt;Silo membership&lt;/th&gt;
&lt;th&gt;Allowed-from SDDL anchor&lt;/th&gt;
&lt;th&gt;TGT cap&lt;/th&gt;
&lt;th&gt;Host-side&lt;/th&gt;
&lt;th&gt;Cloud-side&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Human T0 admin&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;T0 Admins&lt;/td&gt;
&lt;td&gt;T0 PAWs only&lt;/td&gt;
&lt;td&gt;240 min, non-renewable&lt;/td&gt;
&lt;td&gt;Credential Guard on the PAW; LAPS irrelevant (PAW is unique)&lt;/td&gt;
&lt;td&gt;Entra PIM + CA on synced group, phishing-resistant MFA, compliant device&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T0 service account (gMSA)&lt;/td&gt;
&lt;td&gt;No (breaks workflow)&lt;/td&gt;
&lt;td&gt;T0 Services&lt;/td&gt;
&lt;td&gt;T0 server set&lt;/td&gt;
&lt;td&gt;Default; per-Policy cap&lt;/td&gt;
&lt;td&gt;Credential Guard on every host the account runs on&lt;/td&gt;
&lt;td&gt;n/a (on-prem only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T1 admin&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;T1 Admins&lt;/td&gt;
&lt;td&gt;T1 jump servers&lt;/td&gt;
&lt;td&gt;Default; per-Policy cap&lt;/td&gt;
&lt;td&gt;Credential Guard everywhere&lt;/td&gt;
&lt;td&gt;CA on synced T1 group&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T2 user&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;Default&lt;/td&gt;
&lt;td&gt;Credential Guard default-on, LAPS for local admin&lt;/td&gt;
&lt;td&gt;CA general policy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;If this is the reference deployment, what about the alternative architectures customers actually have in production -- ESAE forests, MIM PAM bastion forests, the Enterprise Access Model?&lt;/p&gt;
&lt;h2&gt;7. Tiered Administration vs. bastion forest vs. Enterprise Access Model&lt;/h2&gt;
&lt;p&gt;Three operational doctrines coexist in 2026 production environments, with a fourth meta-architecture sitting above them. None are interchangeable; choosing the wrong one means over-building, under-building, or building the right thing in the wrong place.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Method A: Tier model + Authentication Policy Silos + Protected Users.&lt;/strong&gt; The current Microsoft recommendation for the on-prem enforcement layer in connected and hybrid environments. The whole of §5 and §6 is the description. Cited references: [@ms-pu-current][@ms-aps][@ms-eam].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Method B: MIM Privileged Access Management with a bastion forest.&lt;/strong&gt; Microsoft Identity Manager PAM with the Server 2016 bastion-forest functional level gives just-in-time activation of privileged group membership in a separate, hardened &quot;bastion&quot; forest with a one-way trust &lt;em&gt;from&lt;/em&gt; production &lt;em&gt;to&lt;/em&gt; bastion. Microsoft Learn&apos;s &lt;em&gt;Raise the bastion forest functional level&lt;/em&gt; page is explicit on the feature pivot: &quot;With Windows Server 2016, PAM features of time-limited group memberships and shadow principal groups are built into Windows Server Active Directory&quot; [@ms-pam-bastion-ffl]. A user requests time-bound activation, MIM validates it, the user is briefly added to a bastion-forest privileged group (a shadow principal at WS 2016 FFL), and the resulting TGT carries the production SIDs via PAC SID History. When the activation expires, the SID History entry disappears from newly issued tickets. The Microsoft Learn page is explicit about scope:&lt;/p&gt;

The PAM approach provided by MIM PAM is not recommended for new deployments in Internet-connected environments. MIM PAM is intended to be used in a custom architecture for isolated AD environments where Internet access is not available, where this configuration is required by regulation, or in high impact isolated environments like offline research laboratories and disconnected operational technology or supervisory control and data acquisition environments. -- Microsoft Learn, *MIM PAM* [@ms-mim-pam]
&lt;p&gt;&lt;strong&gt;Method C: Enhanced Security Admin Environment (ESAE) / Red Forest.&lt;/strong&gt; A separate hardened forest used exclusively for administrative identities, with a one-way trust from production to the admin forest. Production-forest administration is performed by accounts that live exclusively in the admin forest. Microsoft retired ESAE as a mainstream recommendation on December 15, 2020 [@ms-esae-retire].&lt;/p&gt;

A dedicated Active Directory forest containing all administrative identities, with a one-way trust from the production forest to the admin forest. Retired as a mainstream Microsoft recommendation on December 15, 2020 [@ms-esae-retire]; preserved for air-gapped, OT, ICS, and SCADA scenarios where cloud-side privileged-access controls are unavailable. Microsoft&apos;s explicit guidance for existing ESAE deployments is &quot;no urgency to retire&quot; if the deployment is operating as designed.
&lt;p&gt;&lt;strong&gt;Method D: Enterprise Access Model (EAM) / Rapid Modernization Plan (RaMP).&lt;/strong&gt; Microsoft&apos;s current meta-architecture, announced concurrently with the ESAE retirement on December 15, 2020 [@ms-esae-retire][@ms-eam][@ms-ramp]. EAM widens the segmentation from forest boundaries to &lt;em&gt;access levels&lt;/em&gt;: a privileged-access plane (the equivalent of T0, now explicitly including Entra ID admin roles), a management plane (formerly T1), a data/workload plane (where applications run), and a user/app plane (T2). EAM does not deprecate the directory-level controls -- it encloses them inside a larger model that adds the cloud control plane as a first-class object.&lt;/p&gt;

Microsoft&apos;s December 15, 2020 meta-architecture for privileged-access. Replaces forest-level isolation with access-level segmentation across four planes: privileged-access, management, data/workload, and user/app. EAM is the framework; Method A (Tier model + Silos + Protected Users) is the on-prem enforcement layer inside the privileged-access plane; Entra PIM and Conditional Access are the cloud-side enforcement [@ms-eam][@ms-ramp].
&lt;p&gt;&lt;strong&gt;Four operational doctrines, side by side.&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;A: Tier + Silos + Protected Users&lt;/th&gt;
&lt;th&gt;B: MIM PAM bastion&lt;/th&gt;
&lt;th&gt;C: ESAE / Red Forest&lt;/th&gt;
&lt;th&gt;D: EAM + RaMP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Enforcement plane&lt;/td&gt;
&lt;td&gt;KDC (AS-REQ, TGS-REQ, S4U)&lt;/td&gt;
&lt;td&gt;Bastion KDC + MIM workflow&lt;/td&gt;
&lt;td&gt;Admin-forest KDC + one-way trust&lt;/td&gt;
&lt;td&gt;Meta: composes A + cloud + host&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary restriction&lt;/td&gt;
&lt;td&gt;Where a TGT may be issued and to whom delegated&lt;/td&gt;
&lt;td&gt;Whether and for how long a privileged group is populated&lt;/td&gt;
&lt;td&gt;Which forest privileged identities live in&lt;/td&gt;
&lt;td&gt;Which planes are enforced and by what&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AD schema footprint&lt;/td&gt;
&lt;td&gt;4 attributes / 2 classes + RID 525&lt;/td&gt;
&lt;td&gt;Server 2016 PAM FFL + Shadow Principal extensions&lt;/td&gt;
&lt;td&gt;None new; uses standard trust + SID filtering&lt;/td&gt;
&lt;td&gt;n/a (model)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud / hybrid coverage&lt;/td&gt;
&lt;td&gt;On-prem only&lt;/td&gt;
&lt;td&gt;On-prem only (explicitly NOT for connected)&lt;/td&gt;
&lt;td&gt;On-prem only&lt;/td&gt;
&lt;td&gt;First-class hybrid by design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment complexity&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;High (forest pair + SQL + MIM)&lt;/td&gt;
&lt;td&gt;Highest (forest pair + full DR)&lt;/td&gt;
&lt;td&gt;Variable (sum of constituents)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft current status (May 2026)&lt;/td&gt;
&lt;td&gt;Recommended for on-prem enforcement&lt;/td&gt;
&lt;td&gt;OT / ICS / regulated air-gapped only&lt;/td&gt;
&lt;td&gt;Legacy; supported for existing + OT only&lt;/td&gt;
&lt;td&gt;Recommended as top-level architecture&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Method D is the framework; Method A is the on-prem enforcement layer inside it; Methods B and C are the niche answers for environments Method A cannot reach. The four are not in competition for the same job. A connected hybrid enterprise in 2026 runs Method D + Method A on-prem, with B and C reserved for the air-gapped exception cases.&lt;/p&gt;
&lt;p&gt;EAM is the framework. Method A is its on-prem enforcement layer. What does Method A&apos;s enforcement layer NOT close, by construction?&lt;/p&gt;
&lt;h2&gt;8. What the KDC cannot enforce&lt;/h2&gt;
&lt;p&gt;A well-deployed Method A architecture eliminates the credential-theft attack chain at the KDC. It does not close every gap. The remaining gaps are not implementation bugs; they are structural properties of where the KDC sits in the stack. Naming them is not optional.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The RBCD residual.&lt;/strong&gt; &lt;a href=&quot;https://paragmali.com/blog/kerberos-in-windows-the-other-half-of-ntlmless/&quot; rel=&quot;noopener&quot;&gt;Resource-based constrained delegation&lt;/a&gt; is configured by writing the &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt; attribute on the target object [@ms-sfu]. The write is governed by the &lt;em&gt;target object&apos;s&lt;/em&gt; DACL, not by the Silo plane. The KDC never sees the write; it only sees the resulting TGS-REQ. If the target is a service account that is Silo&apos;d but not in Protected Users -- which, per Microsoft Learn&apos;s explicit guidance, is the case for most service accounts -- the RBCD chain remains exploitable. The defence is layered: pin the source machine via the Silo Policy, deny &lt;code&gt;WriteProperty&lt;/code&gt; on &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt; for everyone but directory administrators, prefer Group Managed Service Accounts for new services, and put Defender for Identity detection on the attribute-write event [@ms-mdi].&lt;/p&gt;

A constrained-delegation primitive introduced in Windows Server 2012. Unlike classic constrained delegation (configured by the privileged administrator on the *delegating* service via `msDS-AllowedToDelegateTo`), RBCD is configured on the *target* by writing `msDS-AllowedToActOnBehalfOfOtherIdentity`. The target object&apos;s owner controls which services may impersonate users to it. Governance is at the ACL plane, not the KDC plane, which is why RBCD writes are invisible to Authentication Policy Silo enforcement [@ms-sfu].
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Even after every tier-model, Silo, and Protected Users control is correctly deployed, RBCD remains exploitable against any tier-protected service account that is not also in Protected Users -- which, in practice, is most service accounts. Protected Users would close the gap but breaks delegation workflows. The KDC cannot prevent writes to &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt; because the write is an ACL operation on a directory attribute, not a Kerberos operation. The defence is necessarily layered: ACL the attribute, Silo the target, gMSA the credential material, detect the write at the SIEM.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Physical extraction from a logged-on T0 host.&lt;/strong&gt; The KDC cannot prevent the extraction of credential material from the memory of a machine on which the user is logged on. The credential has to exist somewhere in memory for the user to use it. Credential Guard raises the bar dramatically by placing the credential material in a VBS-protected VTL1 enclave that the VTL0 kernel cannot read, even with a signed driver [@ms-cred-guard]. Remote Credential Guard adds a parallel host-side control for RDP-initiated authentications that redirects Kerberos requests back to the originating client [@ms-rcg]. None of these is a KDC control. The KDC and the host are two layers; both are required.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The on-prem-to-cloud bridge.&lt;/strong&gt; On-prem AD KDC enforcement (Silo membership) and Entra ID Conditional Access enforcement are two independent policy planes by construction. The &lt;a href=&quot;https://paragmali.com/blog/inside-the-primary-refresh-token-the-cryptographic-seam-betw/&quot; rel=&quot;noopener&quot;&gt;Primary Refresh Token&lt;/a&gt; does not carry &lt;code&gt;msDS-AssignedAuthNPolicySilo&lt;/code&gt;. Conditional Access does not consume the Silo binding. Operational alignment is achieved by synchronising the Silo&apos;d group through Microsoft Entra Connect and writing a Conditional Access policy keyed on the synced group. The CA sees the synchronised group; it does not see the Silo. Two planes, both must hold.&lt;/p&gt;
&lt;p&gt;The host-side limit (&quot;Credential Guard moves the bar but cannot eliminate physical extraction&quot;) is the topic of the earlier Credential Guard post in this series; the on-prem-to-cloud limit is the topic of the Conditional Access post. The four-residual recognition in this section is the joint that connects all three.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Closing the on-prem-to-cloud gap requires either a Microsoft product change that projects Silo membership into the Primary Refresh Token, or a third-party policy synthesiser. Neither exists as a product surface in May 2026 -- which is why the §10 Phase 4 workaround (sync the Silo&apos;d group through Microsoft Entra Connect, key the Conditional Access policy on the synced group) is the current production answer. The workaround keeps both planes independent by construction; it does not close the gap, it routes around it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Supply-chain compromise of T0 software.&lt;/strong&gt; The KDC cannot enforce policy against an agent running as SYSTEM on every domain controller. By construction, the agent is outside the KDC&apos;s authorisation scope; it can rewrite the directory the KDC reads its policy from. The canonical instance is the SolarWinds Orion compromise disclosed in December 2020 (CISA Alert AA20-352A): the attackers used a backdoored Orion update to obtain SYSTEM-level access on management hosts and, per the CISA advisory&apos;s &lt;em&gt;User Impersonation&lt;/em&gt; section, in several documented cases used that access to compromise &quot;the SAML signing certificate using their escalated Active Directory privileges&quot; -- the AD FS / Entra Connect token-signing certificate -- and then &quot;create unauthorized but valid tokens&quot; presented to services that trust SAML tokens from the environment, on T0 systems where the secret material has to exist in memory for the system to do its job [@cisa-aa20-352a]. The KDC saw legitimately-signed tickets and made legitimate policy decisions; the enforcement gap is one layer below, where the software running as the KDC&apos;s neighbour ships compromised code. The closure for this residual is not at the KDC; it is at the software-supply-chain layer (code signing, reproducible builds, attested deployment, and strict T0-software inventory).&lt;/p&gt;

Every Method A deployment requires two emergency-access break-glass accounts that are outside every Silo and outside Protected Users -- see §10 Phase 5 for the operational pattern (offline-stored passwords, monthly use-and-rotate, high-fidelity SIEM detection, RID 500 as the canonical first identity). Microsoft&apos;s RaMP guidance treats this as the *first* step of the privileged-access rollout, before any of the controls in §5 and §6 are deployed [@ms-ramp].
&lt;p&gt;A maximally-correct Method A deployment closes the KDC-plane gaps it was designed to close. Four explicit residuals remain by construction. Three need additional controls (target-ACL hardening, Credential Guard, Conditional Access keyed on the synced group); the fourth is closed at the software-supply-chain layer. The architecture is correct. The world is bigger than the architecture.&lt;/p&gt;
&lt;p&gt;What is the active research, and what does a practitioner do on Monday morning to deploy what is settled?&lt;/p&gt;
&lt;h2&gt;9. Active research lines as of mid-2026&lt;/h2&gt;
&lt;p&gt;The community is not standing still. Five lines of work are visible on the public radar.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Projecting Authentication Policy Silo membership into Entra Conditional Access as a first-class signal.&lt;/strong&gt; The most-named open problem in both SpecterOps research and Microsoft&apos;s own post-NTLM roadmap discussion. Matthew Palko&apos;s October 2023 post &lt;em&gt;Evolution of Windows Authentication&lt;/em&gt; is Microsoft&apos;s institutional acknowledgement that the post-NTLM future is Kerberos plus IAKerb plus Local KDC; the post does not commit to projecting Silo membership into the Primary Refresh Token, but it is the closest reading the community has of a hybrid identity direction [@palko-evol]. IAKerb plus Local KDC is plausibly the substrate that could eventually carry Silo state across the on-prem-to-cloud boundary, but no public Microsoft roadmap entry as of May 2026 announces that projection.&lt;/p&gt;

A community-maintained checklist of Active Directory and Microsoft Entra ID assets, annotated with whether each asset is &quot;Tier Zero&quot; (its compromise grants forest-wide or tenant-wide control), what platform it sits on, how to identify it (typically by SID or by role assignment), and what attack techniques apply by default versus by misconfiguration. The repository is `github.com/SpecterOps/TierZeroTable` with a rendered live view at `specterops.github.io/TierZeroTable` [@tzt-github][@tzt-pages].
&lt;p&gt;&lt;strong&gt;Tier Zero scoping at hybrid-cloud scale.&lt;/strong&gt; Defining the boundary of T0 in a hybrid environment is increasingly difficult. The on-prem T0 set (DCs, AD CS, Entra Connect, DC backup) is enumerable. The cloud-side T0 set (Entra ID Application Administrators with Graph permissions over AD-synced objects, Hybrid Identity Administrators, Global Administrators, Privileged Authentication Administrators) is large, dynamic, and contains roles whose tier-0 status is contested. The SpecterOps Tier Zero Table is the community&apos;s canonical operational answer; its GitHub README is explicit that &quot;the table does not include all Tier Zero assets yet&quot; [@tzt-github]. BloodHound Community Edition is the companion discovery primitive: feed it a directory snapshot, ask it for attack paths to T0, fix the paths [@bloodhound]. The introductory blog series at SpecterOps explains the &quot;Defining the Undefined&quot; definitional work behind the table [@tier-zero-part1].&lt;/p&gt;
&lt;p&gt;If you have never used BloodHound against your own forest, that is the most leveraged single action you can take this month. The tool exposes the attack paths your tier model is supposed to be closing -- and the gaps are almost always somewhere you did not look. The Tier Zero Table is the human-readable companion; BloodHound is the machine-readable one [@bloodhound][@tzt-github].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Continued discovery of ADCS misconfiguration classes (ESC1-ESC8+).&lt;/strong&gt; Schroeder and Christensen&apos;s June 17, 2021 &lt;em&gt;Certified Pre-Owned&lt;/em&gt; whitepaper was the inflection [@cert-preowned-blog][@cert-preowned-pdf]. The original taxonomy catalogued ESC1 through ESC8; ESC9 and several subsequently-disclosed classes have been added since by the SpecterOps team and the wider AD CS research community, with the GhostPack &lt;code&gt;Certify&lt;/code&gt; tool tracking the enumerable classes in its active branch [@ghostpack-certify], and adjacent variants continuing to land in the SpecterOps blog stream. Each class is a tier-bypass primitive that survives Method A&apos;s deployment if the AD CS configuration is itself misconfigured: the KDC sees a legitimately-signed certificate and a legitimate AS-REQ. KB 5014754&apos;s strong-mapping closes the specific CVE-2022-26923 (&quot;Certifried&quot;) class; template hardening (manager-approval, no-CT, no-enrollee-supplies-subject) addresses several other classes [@kb-5014754].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kerberos relay primitives.&lt;/strong&gt; The KrbRelay family of attacks, anchored to James Forshaw&apos;s October 2021 Project Zero research on cross-protocol Kerberos relaying [@krb-relay-pz] and operationalised in the &lt;code&gt;cube0x0/KrbRelay&lt;/code&gt; tool released shortly thereafter [@cube0x0-krbrelay], exploits the absence of channel binding in some pre-authentication flows. Silos enforce on the source-machine identity &lt;em&gt;as presented in the AS-REQ&lt;/em&gt;; an attacker who can cause a different machine to issue an AS-REQ on the attacker&apos;s behalf and relay it can satisfy the Silo Policy. FAST (RFC 6113) provides the cryptographic primitive for channel binding [@rfc-6113]; Microsoft&apos;s Kerberos armoring uses FAST, and a Silo Policy can be configured to require FAST armoring. The open deployment question is whether FAST armoring becomes the universal default in legacy environments. The Palko post on the post-NTLM Windows authentication roadmap is the closest Microsoft has come to addressing the deployment direction publicly [@palko-evol].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Service-account placement: Protected Users vs. Silo-only.&lt;/strong&gt; The unsolved sub-problem inside the RBCD residual. Service accounts have two failure modes: they cannot be placed in Protected Users without breaking their delegation workflows, and they cannot be left out without leaving an RBCD-attack primitive against tier-protected service accounts that have writable &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt;. The current best partial result is composite: Group Managed Service Accounts plus a tight Silo Policy plus an ACL on the delegation attribute plus a SIEM rule on attribute writes. The architectural answer would be an extension to Protected Users that retains delegation-as-source but refuses NTLM, RC4, and DES. No such extension appears on Microsoft&apos;s public roadmap as of May 2026 [@ms-pu-current][@ms-mdi].&lt;/p&gt;
&lt;p&gt;The settled controls are deployable. The open research is real and has not been closed. Five years from now, the Silo plane will likely still be the operational answer, with the residuals closed by different parts of the stack. What does that look like to a practitioner reading this on a Monday morning?&lt;/p&gt;
&lt;h2&gt;10. A six-phase playbook for deploying Method A this quarter&lt;/h2&gt;
&lt;p&gt;A staged playbook. The phases are ordered for safety: each phase reduces the blast radius of the next, and the first phase is the most important and the most often skipped.&lt;/p&gt;
&lt;h3&gt;Phase 0: Inventory Tier 0&lt;/h3&gt;
&lt;p&gt;Use the SpecterOps Tier Zero Table as the starting checklist [@tzt-github][@tzt-pages]. Pair it with BloodHound Community Edition to discover the attack paths your environment actually has into the T0 set [@bloodhound]. The Tier Zero Table is intentionally incomplete -- treat it as the floor, not the ceiling -- and add the assets specific to your environment: any service account whose compromise grants write access to a DC, any backup system that can restore a DC&apos;s NTDS.dit, any monitoring system that can run code on a DC. Sean Metcalf&apos;s body of work on secure workstation baselines is the canonical operator-grade reading for this phase [@metcalf-p3299][@metcalf-p1738].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Do not start with Silo creation. Start with the T0 inventory. Every subsequent phase depends on a defensible list of what T0 contains. A T0 asset missed by the inventory is a T0 asset that is not Silo&apos;d, not in Protected Users, and not behind a Conditional Access policy on the cloud side. Phase 0 is the single most-skipped step in failed Method A deployments and the single highest-value step in successful ones.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Phase 1: Create the T0 Admins Silo and Policy in audit mode&lt;/h3&gt;
&lt;p&gt;Create the &lt;code&gt;msDS-AuthNPolicySilo&lt;/code&gt; named &quot;T0 Admins&quot; and its referenced &lt;code&gt;msDS-AuthNPolicy&lt;/code&gt; named &quot;T0 Source Restriction.&quot; Set &lt;code&gt;msDS-AuthNPolicySiloEnforced=FALSE&lt;/code&gt; to start in audit mode [@ms-aps]. Place a single test admin account in Protected Users and assign it to the Silo. Set the Policy&apos;s &lt;code&gt;UserAllowedToAuthenticateFrom&lt;/code&gt; SDDL to a SID set containing exactly one PAW. Confirm that authentication from the PAW succeeds, that authentication from a tier-2 workstation generates the expected audit event (&lt;code&gt;Authentication Policy Silo&lt;/code&gt; audit failure in the Security log), and that nothing else in the environment breaks. Once the audit window is clean, flip the Silo to enforced mode. The KDC now returns &lt;code&gt;KDC_ERR_POLICY&lt;/code&gt; for any AS-REQ from outside the allowed-from set [@ms-kile].&lt;/p&gt;
&lt;h3&gt;Phase 2: Catalogue every delegation relationship in the directory&lt;/h3&gt;
&lt;p&gt;Enumerate every account with &lt;code&gt;msDS-AllowedToDelegateTo&lt;/code&gt; set, every object with &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt; set, and every account with the legacy &lt;code&gt;TrustedForDelegation&lt;/code&gt; UAC bit. For each T0-adjacent service account, decide whether the workflow can survive Protected Users membership. If yes, enrol the account and move on. If no -- which will be the common answer -- create a &quot;T0 Services&quot; Silo with a tight &lt;code&gt;UserAllowedToAuthenticateFrom&lt;/code&gt; Policy, bind the account to the Silo, deny &lt;code&gt;WriteProperty&lt;/code&gt; on &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt; for everyone but directory administrators, and audit Defender for Identity for the corresponding alerts [@ms-mdi]. The composite defence is the current best partial answer to the RBCD residual.&lt;/p&gt;
&lt;p&gt;Group Managed Service Accounts (gMSA) are the preferred new-service-account primitive for the §6 reference deployment. The Microsoft Key Distribution Service (&lt;code&gt;kdssvc.dll&lt;/code&gt;) on the domain controller derives the account&apos;s password from a domain-wide root key plus a per-account key identifier and rotates it on a configurable schedule; service hosts retrieve the current password through an ACL-controlled flow [@ms-gmsa-overview]. The cryptographic-rotation property -- not Silo membership -- is what closes the AS-REP roasting primitive in practical timeframes for a service-account workflow that the §6 PullQuote forbids from enrolling in Protected Users. Microsoft&apos;s &lt;em&gt;How to Configure Protected Accounts&lt;/em&gt; page covers the wider per-account migration shape for legacy non-gMSA services [@ms-config-pa].&lt;/p&gt;
&lt;h3&gt;Phase 3: Roll the human T0 administrators into Protected Users in batches&lt;/h3&gt;
&lt;p&gt;Audit the longest-running tier-0 administrative task in your environment &lt;em&gt;before&lt;/em&gt; you enrol anyone. Forest backups, replication health checks, schema upgrade dry-runs, DC promotions, and emergency operational procedures sometimes exceed four hours; the Protected Users 240-minute non-renewable TGT cap will silently re-authenticate or fail outright when they do [@ms-config-pa]. Enrol in batches of two or three administrators at a time; keep the previous batch in for at least two weeks before adding the next. Microsoft&apos;s &lt;em&gt;How to Configure Protected Accounts&lt;/em&gt; page lays out the staged enrolment shape [@ms-config-pa].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The 240-minute non-renewable TGT cap on Protected Users members is the single most common cause of failed pilot deployments. Tasks that ran fine for years quietly fail at the 4-hour mark, or worse, re-authenticate against a different identity that has lower privilege. Audit your longest-running T0 operations against the cap &lt;em&gt;before&lt;/em&gt; enrolling humans; document workarounds (&lt;code&gt;runas&lt;/code&gt; for long tasks; batch jobs running under gMSAs with a per-Policy lifetime configured deliberately) before the enrolment, not after.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Phase 4: Project the T0 group into Entra Conditional Access&lt;/h3&gt;
&lt;p&gt;Sync the T0 Admins group through Microsoft Entra Connect. Write a Conditional Access policy that requires phishing-resistant MFA (FIDO2, Windows Hello for Business, or certificate-based authentication) for that group, plus a compliant device, plus a known-good location if the threat model justifies it [@ms-pim]. Document explicitly that the CA is keyed on the synchronised group, not on the Silo binding; the two enforcement planes are independent by construction. The Entra side is the topic of the Conditional Access post in this series for the deeper treatment.&lt;/p&gt;
&lt;p&gt;For the cloud-side treatment of Conditional Access policy shapes -- compliant device, phishing-resistant MFA grant control, location and risk conditions -- see the Conditional Access post in this series. The CA policy keyed on the synced T0 group is what holds the two-plane workaround together.&lt;/p&gt;
&lt;h3&gt;Phase 5: Break-glass&lt;/h3&gt;
&lt;p&gt;Two emergency-access accounts that are &lt;em&gt;outside&lt;/em&gt; every Silo, &lt;em&gt;outside&lt;/em&gt; Protected Users, with passwords stored offline in a tamper-evident envelope held by two separate people, with a documented monthly use-and-rotate procedure, and with high-fidelity SIEM detection on every authentication attempt. The cost of the break-glass pair is the deliberate, audited counter-balance to the rest of the architecture. Microsoft&apos;s RaMP guidance treats this as the &lt;em&gt;first&lt;/em&gt; step of the privileged-access rollout [@ms-ramp]. The built-in domain Administrator (RID 500) is the natural canonical first break-glass identity because it is exempt from Authentication Policy enforcement even when assigned to a Silo [@ms-pu-current].&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s RaMP page lists &quot;Emergency access accounts&quot; as the first initiative of the entire Rapid Modernization Plan, ahead of Entra PIM and the on-prem controls [@ms-ramp]. The ordering is deliberate: a privileged-access deployment that locks itself out before it has secured the recovery path is worse than no deployment at all.&lt;/p&gt;

The Active Directory PowerShell module exposes the cmdlets directly. The skeleton below creates a Policy and a Silo in audit mode, then assigns one user. Adapt the SDDL to your PAW computer SIDs before running.&lt;p&gt;&lt;code&gt;New-ADAuthenticationPolicy -Name &quot;T0 Source Restriction&quot; -UserTGTLifetimeMins 240 -UserAllowedToAuthenticateFrom &apos;O:SYG:SYD:(XA;OICI;CR;;;WD;(@USER.ad://ext/AuthenticationSilo == &quot;T0 Admins&quot;))&apos;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;@USER.ad://ext/AuthenticationSilo&lt;/code&gt; token in that SDDL is evaluated at AS-REQ time against the &lt;em&gt;source machine&apos;s&lt;/em&gt; user-token claims, not against the requesting user&apos;s own Silo binding -- the Policy admits the requesting user only from devices whose computer accounts are themselves Silo members of &quot;T0 Admins&quot; (typically the T0 PAW set). The token&apos;s evaluation context is the source-device side of the request, which is the practical encoding of the source-machine pinning Method A relies on [@ms-aps].&lt;/p&gt;
&lt;p&gt;&lt;code&gt;New-ADAuthenticationPolicySilo -Name &quot;T0 Admins&quot; -Enforce:$false -UserAuthenticationPolicy &quot;T0 Source Restriction&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Set-ADAccountAuthenticationPolicySilo -Identity alice.da -AuthenticationPolicySilo &quot;T0 Admins&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Add-ADGroupMember -Identity &quot;Protected Users&quot; -Members alice.da&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Run in audit mode (Enforce:false) for a full audit cycle, validate the Security log for &lt;code&gt;Authentication Policy Silo&lt;/code&gt; events, then flip to enforced mode. The official PowerShell-cmdlet documentation is on the Microsoft Learn AD-cmdlet pages; the relevant deployment shape is described in &lt;em&gt;How to Configure Protected Accounts&lt;/em&gt; [@ms-config-pa].
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;You have a playbook. You also have a set of questions readers are now going to ask. Here they are.&lt;/p&gt;
&lt;h2&gt;11. Frequently asked questions&lt;/h2&gt;


No -- service accounts must not be (see §6&apos;s canonical Microsoft Learn PullQuote), and workstation users do not need to be (the Silo plane and Credential Guard handle their threat model). For human administrators, the answer is &quot;yes, in batches, after testing&quot; -- see §10 Phase 3&apos;s Callout on the 4-hour TGT cap, which is the single most common pilot break.


Indirectly. Kerberoasting per se is defeated by AES-only enforcement and high-entropy passwords. Protected Users forbids RC4 and DES for its members, so a Silo&apos;d and Protected human administrator cannot be roasted with the public RC4-dependent tooling. For service accounts that cannot be Protected, the defence is explicit AES enforcement via `msDS-SupportedEncryptionTypes` plus gMSA-managed high-entropy passwords [@ms-config-pa]. Defender for Identity surfaces accounts that still use RC4 [@ms-mdi].


No. Two independent planes. The PRT does not carry `msDS-AssignedAuthNPolicySilo`, and Conditional Access does not consume it. The standard alignment is to synchronise the Silo&apos;d group through Microsoft Entra Connect and write a CA policy keyed on the synced group. The CA sees the synchronised group, not the Silo. Both planes must hold for a hybrid privileged identity to be safe [@ms-eam][@palko-evol]. Closing the gap requires either a Microsoft product change or a third-party policy synthesiser; neither exists as a product surface in May 2026.


Subtly. ESAE -- the Red Forest pattern -- was retired as a mainstream recommendation on December 15, 2020 [@ms-esae-retire]. The tier model as an *idea* was folded into the Enterprise Access Model [@ms-eam]; the directory-level controls (Authentication Policy Silos, Protected Users) remain Microsoft&apos;s recommended on-prem enforcement layer. New ESAE deployments are not recommended outside air-gapped OT, ICS, and SCADA scenarios; existing ESAE deployments operating as designed have no urgency to retire.


KB 2871997 is the May 13, 2014 down-level backport of Protected Users client-side honoring and Authentication Policy / Silo client-side support to Windows 7, Windows 8, Server 2008 R2, and Server 2012 [@kb-2871997]. It is NOT the introduction of those features -- the introduction is Windows Server 2012 R2 GA on October 18, 2013 [@save-date-blog][@ms-pu-legacy]. The October 14, 2014 revision additionally shipped Restricted Admin Mode for RDP, which has its own cautionary history as the canonical example of a defence that became its own inverse [@kfalde-restricted-admin][@ms-rcg].


The schema supports it -- a Silo&apos;s `msDS-ComputerAuthNPolicy` link carries a Computer Policy with its own Computer TGT Lifetime, and DCs are valid Silo members in principle [@ms-aps]. The operational pattern doesn&apos;t do that, for two reasons. First, DCs are themselves the authentication authority, and Microsoft Learn&apos;s Authentication Policies and Silos page explicitly warns against changing Computer TGT Lifetime on DC class accounts because shortened TGT lifetimes disrupt replication and other DC-to-DC operations (&quot;It is not recommended to change this setting&quot; [@ms-aps]). Second, the Silo plane is built for the accounts that authenticate *to* DCs -- T0 admins, the AD CS computer account, the Entra Connect server -- where source-machine pinning is the high-impact control. Silo the accounts that authenticate to your DCs; protect the DCs themselves with the orthogonal directory primitives (KDC service-account configuration, Defender for Identity sensor deployment, code-signing and update management, physical isolation). The Tier Zero Table and BloodHound surface the DC-adjacent accounts that need Silo membership [@tzt-github][@bloodhound].

&lt;p&gt;The directory now has the answer it lacked for sixteen years. Three controls, one ship, plus thirteen years of operational discipline to compose them, plus an explicit acknowledgement of the four residuals the KDC cannot close by construction. On the Tuesday morning in April 1997 when Paul Ashton posted his patched &lt;code&gt;smbclient&lt;/code&gt; to NTBugtraq, no one in the AD product group could have written this article. They can now -- and the KDC, keyed on directory state, is the layer they would write it from.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;ad-tiering-protected-users-silos&quot; keyTerms={[
  {&quot;term&quot;: &quot;Pass-the-Hash&quot;, &quot;definition&quot;: &quot;Credential-theft technique that uses an account&apos;s NT hash as the long-term key. The NTLM protocol cannot distinguish the legitimate password-holder from anyone holding the hash.&quot;},
  {&quot;term&quot;: &quot;Protected Users&quot;, &quot;definition&quot;: &quot;Global security group (well-known RID 525) introduced in Windows Server 2012 R2. Members get a non-configurable credential-restriction set: no NTLM, no DES or RC4 in Kerberos, no delegation, no cached offline-sign-in verifier, 240-minute non-renewable TGT cap.&quot;},
  {&quot;term&quot;: &quot;Authentication Policy Silo&quot;, &quot;definition&quot;: &quot;The msDS-AuthNPolicySilo container object. Enumerates the user, computer, and service accounts that share a set of restrictions, and references one or more Authentication Policies whose rules apply to its members.&quot;},
  {&quot;term&quot;: &quot;Authentication Policy&quot;, &quot;definition&quot;: &quot;The msDS-AuthNPolicy rules object. Carries the TGT lifetime cap, the allowed-from SDDL on source-machine identity, allowed-to delegation rules, claim transformations, and optional FAST armoring requirement.&quot;},
  {&quot;term&quot;: &quot;KDC (Key Distribution Center)&quot;, &quot;definition&quot;: &quot;The Kerberos authentication service that handles AS-REQ (TGT issuance) and TGS-REQ (service-ticket issuance). On Windows, every DC runs a KDC; the KDC reads policy from the directory at request time.&quot;},
  {&quot;term&quot;: &quot;PAC (Privilege Attribute Certificate)&quot;, &quot;definition&quot;: &quot;Microsoft authorisation-data structure carried inside Kerberos TGTs and service tickets. PAC_LOGON_INFO.GroupIds encodes Protected Users membership via well-known SID 525.&quot;},
  {&quot;term&quot;: &quot;Tier 0 (T0)&quot;, &quot;definition&quot;: &quot;The control plane: domain controllers, AD CS root CAs, Entra Connect servers, DC backup systems, and any system whose compromise grants forest-wide control.&quot;},
  {&quot;term&quot;: &quot;Enterprise Access Model (EAM)&quot;, &quot;definition&quot;: &quot;Microsoft&apos;s December 15, 2020 meta-architecture for privileged-access. Segments by access level (privileged-access, management, data/workload, user/app) rather than by forest boundary, and incorporates Entra ID admin roles as first-class control-plane objects.&quot;},
  {&quot;term&quot;: &quot;RBCD (Resource-Based Constrained Delegation)&quot;, &quot;definition&quot;: &quot;Constrained delegation configured by writing msDS-AllowedToActOnBehalfOfOtherIdentity on the target. Governed by the target object&apos;s ACL, not by the Silo plane; remains exploitable against tier-protected service accounts that cannot be in Protected Users.&quot;},
  {&quot;term&quot;: &quot;Tier Zero Table (SpecterOps)&quot;, &quot;definition&quot;: &quot;Community-maintained checklist of AD and Entra ID assets that must be enclosed in the T0 control plane. Intentionally incomplete; designed to be the floor of the inventory, not the ceiling.&quot;}
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>active-directory</category><category>kerberos</category><category>authentication-silos</category><category>protected-users</category><category>tiering</category><category>credential-theft</category><category>pass-the-hash</category><category>privileged-access</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>Two Checkmarks and the Keys to the Kingdom: How Active Directory&apos;s Replication Protocol Became the Longest-Lived Credential Attack on Windows</title><link>https://paragmali.com/blog/two-checkmarks-and-the-keys-to-the-kingdom-how-active-direct/</link><guid isPermaLink="true">https://paragmali.com/blog/two-checkmarks-and-the-keys-to-the-kingdom-how-active-direct/</guid><description>MS-DRSR was designed for domain controllers to replicate secrets to each other. Its access check gates on an ACL, not on whether the caller is a DC. Eleven years after Mimikatz proved it, no patch can fix it.</description><pubDate>Thu, 21 May 2026 00:00:00 GMT</pubDate><content:encoded>
Active Directory&apos;s replication protocol (MS-DRSR) lets any domain controller pull every secret in the directory from any other domain controller, and the access check gates on an ACL, not on whether the caller is actually a DC. Mimikatz&apos;s `lsadump::dcsync` (August 11, 2015) and `lsadump::dcshadow` (January 2018) are the read and write sides of this loophole; both remain in active operational use eleven years later because the protocol cannot be amended without breaking AD replication. Credential Guard cannot help -- the secret moves from a remote DC&apos;s NTDS.dit over the network, never touching the attacker&apos;s LSASS. The 2026 defender response is four parallel detection layers (posture, behavioral, network, graph) because no single layer catches every case, and the architectural fifth layer that would close the class is not coming.
&lt;h2&gt;1. Two Checkmarks and the Keys to the Kingdom&lt;/h2&gt;
&lt;p&gt;A non-admin service account, created during a 2017 file-server migration and never cleaned up, holds exactly two access-control entries on the &lt;code&gt;contoso.local&lt;/code&gt; domain object: &lt;code&gt;Replicating Directory Changes&lt;/code&gt; and &lt;code&gt;Replicating Directory Changes All&lt;/code&gt;. From a Windows 11 workstation -- not a domain controller, not a tier-zero admin host, just a desk -- the attacker opens a Mimikatz prompt and types:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lsadump::dcsync /domain:contoso.local /user:krbtgt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sixty seconds later they have the &lt;code&gt;krbtgt&lt;/code&gt; NT hash and &lt;a href=&quot;https://paragmali.com/blog/kerberos-in-windows-the-other-half-of-ntlmless/&quot; rel=&quot;noopener&quot;&gt;Kerberos AES keys&lt;/a&gt;, and they own the domain. &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;, enabled on every workstation in the building, never saw the credential transit anywhere in its scope.&lt;/p&gt;
&lt;p&gt;That last sentence is the punchline of the entire field. The secret never touches the attacker&apos;s LSASS, so Credential Guard&apos;s design has nothing to say. The keys move from a remote domain controller&apos;s on-disk database, over an RPC channel, into the attacker&apos;s process memory. Credential Guard isolates LSASS on the &lt;em&gt;local&lt;/em&gt; machine. It has no jurisdiction over what a remote DC chooses to send when asked nicely.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Credential Guard isolates LSASS-resident secrets in a separate virtual trust level. DCSync reads secrets from a remote DC&apos;s NTDS.dit over MS-DRSR -- a network protocol attack, not a local-memory attack. Microsoft&apos;s Credential Guard documentation does not claim protection against MS-DRSR-based credential extraction [@credential-guard-considerations].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The 60-second timeline is not a marketing number. One RPC round trip per principal is the protocol&apos;s per-principal cost, fixed by specification. For a single high-value target -- and &lt;code&gt;krbtgt&lt;/code&gt; is the highest-value target in any Active Directory forest, because its long-term key signs every Kerberos ticket -- the attack is over before a typical SOC operator has finished pouring coffee.&lt;/p&gt;
&lt;p&gt;The four people whose names recur in this story are worth meeting now. Benjamin Delpy (gentilkiwi) wrote Mimikatz and authored both the DCSync read primitive (2015) and, with Vincent Le Toux, the DCShadow write primitive (2018). Vincent Le Toux built the original DCShadow implementation and the PingCastle posture-assessment tool. Sean Metcalf (Trimarc / ADSecurity) translated DCSync into operator vocabulary in the weeks after its release. Microsoft&apos;s Defender for Identity team ships the canonical first-party detections that fire on this attack class today.&lt;/p&gt;
&lt;p&gt;This story is what happens when a 23-year-old domain-controller-to-domain-controller protocol&apos;s access check turns out to gate on an ACL, not on whether the caller is a domain controller. Two ACEs on one object should not give an attacker the entire credential trove. The fact that they do is not a bug in the implementation. It is a 1999 design assumption -- that nobody who is not a DC would ever speak this protocol -- that survived twenty-five years as a social convention and was nowhere written down in the access-check code.&lt;/p&gt;
&lt;p&gt;The next section explains why Microsoft built this protocol in the first place, and why its access check forgot to ask the one question that would have closed the loophole.&lt;/p&gt;
&lt;h2&gt;2. Why the Protocol Exists at All&lt;/h2&gt;
&lt;p&gt;Rewind to February 17, 2000. Microsoft ships Windows 2000 Server, and Active Directory replaces the old NT 4.0 PDC/BDC model [@microsoft-windows-2000-launch]. NT 4.0 was single-master: one Primary Domain Controller held the authoritative account database, every Backup Domain Controller held a read-only copy, and a password change on the PDC propagated to BDCs through a hub-and-spoke replication channel. AD inverts the model. Every domain controller in an AD domain holds a writable copy of the directory; a password change on &lt;em&gt;any&lt;/em&gt; DC must propagate to every other DC within minutes; the replication topology is a mesh, not a star.&lt;/p&gt;
&lt;p&gt;Multi-master replication is the design constraint that forces MS-DRSR&apos;s existence. If any DC can accept a write, then every DC must be able to pull every change -- &lt;em&gt;including secret attributes&lt;/em&gt; like &lt;code&gt;unicodePwd&lt;/code&gt;, &lt;code&gt;dBCSPwd&lt;/code&gt;, &lt;code&gt;ntPwdHistory&lt;/code&gt;, &lt;code&gt;lmPwdHistory&lt;/code&gt;, and &lt;code&gt;supplementalCredentials&lt;/code&gt; -- from every other DC. There is no second protocol. Replication of secrets is replication, and replication is MS-DRSR [@ms-drsr-spec].&lt;/p&gt;

The RPC protocol by which any Active Directory domain controller can replicate any object, including secret attributes, from any other DC in the same forest. Layered over DCE/RPC; the current public specification is revision 46.0 dated March 9, 2026 [@ms-drsr-spec]. MS-DRSR is the mechanism that makes AD&apos;s multi-master replication invariant work.

The MS-DRSR method (opnum 3) that returns changed objects within a naming context. A calling DC supplies a target DN and a set of replication flags; the called DC returns the object&apos;s attribute values, with secret attributes encrypted under a session-derived key. This is the protocol method that DCSync invokes.

flowchart LR
    subgraph Domain[&quot;contoso.local domain&quot;]
        DCA[DC-A&lt;br /&gt;NTDS.dit]
        DCB[DC-B&lt;br /&gt;NTDS.dit]
        DCC[DC-C&lt;br /&gt;NTDS.dit]
    end
    DCA -- IDL_DRSGetNCChanges&lt;br /&gt;unicodePwd, ntPwdHistory --&amp;gt; DCB
    DCB -- IDL_DRSGetNCChanges&lt;br /&gt;supplementalCredentials --&amp;gt; DCA
    DCB -- IDL_DRSGetNCChanges&lt;br /&gt;dBCSPwd --&amp;gt; DCC
    DCC -- IDL_DRSGetNCChanges&lt;br /&gt;unicodePwd --&amp;gt; DCB
    DCA -- IDL_DRSGetNCChanges&lt;br /&gt;ntPwdHistory --&amp;gt; DCC
    DCC -- IDL_DRSGetNCChanges&lt;br /&gt;krbtgt keys --&amp;gt; DCA
&lt;p&gt;The access check that gates &lt;code&gt;IDL_DRSGetNCChanges&lt;/code&gt; is defined in [MS-DRSR] §4.1.10. It asks one question: does the calling principal hold the appropriate extended rights on the naming-context root being replicated? Extended rights are AD&apos;s mechanism for control-access permissions that do not fit into the standard ACL bit set [@ms-drsr-spec].&lt;/p&gt;

A schema-defined access-control right identified by a GUID rather than by a standard ACL bit. Extended rights are granted via an access-control entry on a target object and checked at runtime by the operation that requires them. The three replication extended rights are the canonical example: each is identified only by GUID, and each is checked by `IDL_DRSGetNCChanges` against the caller&apos;s effective rights on the naming-context root.

A top-level replication partition of the Active Directory database. Every AD forest has at least three NCs: the Schema NC, the Configuration NC, and one Domain NC per domain (plus optional Application NCs). DCSync operates against the Domain NC root.
&lt;p&gt;Three extended rights together form what practitioners call the rights triad. The two-checkmark version from §1 is the most-common configuration; the third right unlocks a smaller set of attributes flagged confidential. Microsoft&apos;s own AD schema documentation enumerates each one [@ad-schema-get-changes][@ad-schema-get-changes-all][@ad-schema-get-changes-filtered-set]:&lt;/p&gt;

The combination of three replication extended rights on a naming-context root: `DS-Replication-Get-Changes` (the baseline read), `DS-Replication-Get-Changes-All` (unlocks secret attributes), and `DS-Replication-Get-Changes-In-Filtered-Set` (unlocks attributes with the confidential flag). The first two are what most operators mean when they say &quot;DCSync rights&quot;; the third is sometimes required for completeness.
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Right&lt;/th&gt;
&lt;th&gt;Display name&lt;/th&gt;
&lt;th&gt;Rights-GUID&lt;/th&gt;
&lt;th&gt;What it unlocks&lt;/th&gt;
&lt;th&gt;Introduced&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DS-Replication-Get-Changes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Replicating Directory Changes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Baseline replication read&lt;/td&gt;
&lt;td&gt;Windows 2000 Server [@ad-schema-get-changes]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DS-Replication-Get-Changes-All&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Replicating Directory Changes All&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Secret attribute replication (&lt;code&gt;unicodePwd&lt;/code&gt;, &lt;code&gt;ntPwdHistory&lt;/code&gt;, etc.) [@ad-schema-get-changes-all]&lt;/td&gt;
&lt;td&gt;Windows Server 2003&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DS-Replication-Get-Changes-In-Filtered-Set&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Replicating Directory Changes In Filtered Set&lt;/td&gt;
&lt;td&gt;&lt;code&gt;89e95b76-444d-4c62-991a-0facbeda640c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Confidential-flag attributes [@ad-schema-get-changes-filtered-set]&lt;/td&gt;
&lt;td&gt;Windows Server 2008&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;In a freshly-installed AD domain, four principal sets hold the rights triad by default on the Domain NC root: the &lt;code&gt;Domain Controllers&lt;/code&gt; group, the &lt;code&gt;Domain Admins&lt;/code&gt; group, the &lt;code&gt;Enterprise Admins&lt;/code&gt; group, and the built-in &lt;code&gt;Administrators&lt;/code&gt; group [@sean-metcalf-dcsync-2015]. Every other ACE on that object is a deliberate delegation choice made by some operator at some point in the domain&apos;s history.&lt;/p&gt;
&lt;p&gt;Now read the access check carefully. It asks whether the caller holds the rights. It does not ask anything about &lt;em&gt;who&lt;/em&gt; the caller is. The protocol does not check whether the caller&apos;s Service Principal Name is &lt;code&gt;GC/...&lt;/code&gt; or &lt;code&gt;ldap/...&lt;/code&gt; or anything else. It does not check whether the caller&apos;s machine account is in the &lt;code&gt;Domain Controllers&lt;/code&gt; group. It does not check whether the caller&apos;s Kerberos service ticket was issued for a DC service. The whole gate is the ACL on one object.&lt;/p&gt;
&lt;p&gt;This is the most consequential design omission in any Microsoft network protocol. Every other replication-style protocol in Windows ships some form of caller-machine-identity assertion. MS-DRSR shipped without one because, in 1999, nobody on the design team imagined an unprivileged workstation would speak the DC-to-DC protocol.&lt;/p&gt;
&lt;p&gt;The 1999 closed-population design assumption is the load-bearing fiction underneath this whole story. The protocol&apos;s designers assumed -- entirely reasonably for the deployment universe of that decade -- that the only software that would ever implement an MS-DRSR client was the DC role itself, which Microsoft shipped, signed, and audited. No defender in 1999 was thinking about a Python script speaking DRSUAPI from a desk. The assumption was a social convention dressed as a security model, and it survived for fifteen years.&lt;/p&gt;
&lt;p&gt;If the protocol exists to replicate every secret in the directory, and the access check is the ACL on one object, what stopped anyone from abusing it for the protocol&apos;s first fifteen years? That accidental safety period is the subject of the next section.&lt;/p&gt;
&lt;h2&gt;3. The Fifteen-Year Accidental Safety Period&lt;/h2&gt;
&lt;p&gt;Between 2000 and 2015, attackers who wanted the entire credential trove of an Active Directory domain had exactly one road open to them: reach a domain controller and steal its database. The reasons are not subtle. The credentials lived in one file -- &lt;code&gt;C:\Windows\NTDS\NTDS.dit&lt;/code&gt;, an Extensible Storage Engine database protected by a Password Encryption Key wrapped under the BootKey scattered across four registry values in the SYSTEM hive [@ntdsxtract-repo]. Without code execution on a DC, there was no obvious way to ask the directory for its secrets in bulk.&lt;/p&gt;

The on-disk Extensible Storage Engine (&quot;Jet Blue&quot;) database that holds every Active Directory object, including secret attributes. Located at `C:\Windows\NTDS\NTDS.dit` on every domain controller. The file is locked while AD DS is running; offline copying requires either Volume Shadow Copy snapshots, `ntdsutil ifm` bundling, or DC downtime [@mitre-t1003-003].
&lt;p&gt;Three sub-techniques bloomed inside this constraint, and MITRE catalogs them collectively as T1003.003 OS Credential Dumping: NTDS [@mitre-t1003-003]. Each is operationally distinct, and each requires the same precondition.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;G1a -- Volume Shadow Copy plus offline parse.&lt;/strong&gt; The attacker runs &lt;code&gt;vssadmin create shadow /for=C:&lt;/code&gt; on a domain controller, creating an instant point-in-time snapshot. They copy &lt;code&gt;NTDS.dit&lt;/code&gt; and &lt;code&gt;SYSTEM&lt;/code&gt; out of the shadow path, exfiltrate both files, and parse them offline with Csaba Barta&apos;s &lt;code&gt;ntdsxtract&lt;/code&gt; toolkit [@ntdsxtract-repo] or Impacket&apos;s &lt;code&gt;secretsdump.py&lt;/code&gt; running in offline mode. The parse walks the &lt;code&gt;datatable&lt;/code&gt; ESE table row by row, decrypts the PEK with the BootKey, and decrypts each principal&apos;s secret attributes with the PEK.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;G1b -- &lt;code&gt;ntdsutil&lt;/code&gt; Install From Media.&lt;/strong&gt; The built-in command &lt;code&gt;ntdsutil &quot;activate instance ntds&quot; &quot;ifm&quot; &quot;create full C:\Temp\IFM&quot;&lt;/code&gt; packages NTDS.dit and the SYSTEM hive into a clean bundle, intended for legitimate seeding of a new replica DC. With local admin on any DC, an attacker invokes it without involving VSS.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;G1c -- LSASS injection of the long-term DC secrets.&lt;/strong&gt; Mimikatz&apos;s pre-DCSync technique reads cached long-term secret material (including the &lt;code&gt;krbtgt&lt;/code&gt; key) directly out of &lt;code&gt;lsass.exe&lt;/code&gt; memory on a domain controller via &lt;code&gt;lsadump::lsa /inject /name:krbtgt&lt;/code&gt;. The variant that turned this surface into a persistence implant was Skeleton Key, disclosed by the Dell SecureWorks Counter Threat Unit on January 12, 2015 [@skeleton-key-wayback]. Skeleton Key patches the &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;NTLM&lt;/a&gt; and Kerberos validation routines in LSASS on a DC so that a single master password works for any account.&lt;/p&gt;
&lt;p&gt;Skeleton Key sits at the boundary between credential dumping and persistence. It does not produce usable NT hashes or Kerberos keys for offline forging; it gives the attacker a backdoor at the authentication step. The 2015 community debate over Skeleton Key versus the (then-imminent) DCSync technique was settled decisively by DCSync&apos;s August release: dumping the hashes is more useful than backdooring the auth path, because dumped hashes survive a DC reboot and are forge-ready material [@skeleton-key-wayback].&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sub-technique&lt;/th&gt;
&lt;th&gt;Mechanism&lt;/th&gt;
&lt;th&gt;Canonical tool&lt;/th&gt;
&lt;th&gt;Emitted artifact&lt;/th&gt;
&lt;th&gt;Host artifact on DC&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;G1a VSS + offline parse&lt;/td&gt;
&lt;td&gt;Point-in-time snapshot, file copy, offline ESE parse&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vssadmin&lt;/code&gt; + &lt;code&gt;secretsdump.py&lt;/code&gt; / &lt;code&gt;ntdsxtract&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NT hashes, Kerberos keys, password history&lt;/td&gt;
&lt;td&gt;VSS event in system log&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G1b &lt;code&gt;ntdsutil&lt;/code&gt; IFM&lt;/td&gt;
&lt;td&gt;Built-in admin command produces clean bundle&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ntdsutil &quot;ac i ntds&quot; &quot;ifm&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Identical to G1a&lt;/td&gt;
&lt;td&gt;IFM staging directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G1c LSASS inject&lt;/td&gt;
&lt;td&gt;Read long-term secrets from &lt;code&gt;lsass.exe&lt;/code&gt; memory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mimikatz lsadump::lsa /inject&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;krbtgt&lt;/code&gt; key and other LSA-cached secrets&lt;/td&gt;
&lt;td&gt;Process access of &lt;code&gt;lsass.exe&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The structural cost across all three is the same: code execution as SYSTEM on a domain controller. Read that requirement slowly. In a mature enterprise with even a basic tiered-administration model -- no interactive logon to DCs from workstations, &lt;a href=&quot;https://paragmali.com/blog/rdp-authentication-26-years/&quot; rel=&quot;noopener&quot;&gt;restricted-admin RDP&lt;/a&gt;, Privileged Access Workstations for Domain Admin sessions, Protected Users group membership for Tier Zero principals -- DCs are the most defended boundary in the network. An attacker who has crossed that boundary has, in operational terms, already won. The credential dump is the trophy lap.&lt;/p&gt;

flowchart TD
    Start[Attacker foothold&lt;br /&gt;on workstation]
    Start --&amp;gt; VSS[G1a: VSS snapshot&lt;br /&gt;+ offline parse]
    Start --&amp;gt; IFM[G1b: ntdsutil IFM&lt;br /&gt;create full]
    Start --&amp;gt; Inject[G1c: LSASS inject&lt;br /&gt;on DC]
    VSS --&amp;gt; Gate[SYSTEM on DC]
    IFM --&amp;gt; Gate
    Inject --&amp;gt; Gate
    Gate --&amp;gt; Creds[All domain credentials&lt;br /&gt;NT hashes, Kerberos keys, krbtgt]
&lt;p&gt;This is what made the closed-population design assumption survive its first fifteen years. The protocol&apos;s design was open to abuse from any joined workstation that held the rights triad, but nobody noticed because the cheaper attack road -- compromise a DC, parse the database offline -- still passed through a defended chokepoint. The ACL on the Domain NC was nowhere on a defender&apos;s risk register, because no offensive tooling existed that treated the ACL as the gate.&lt;/p&gt;
&lt;p&gt;There was a question waiting to be asked, though. &lt;em&gt;What if you could ask the DC to send you the credentials, using a protocol the DC already speaks fluently with its peers?&lt;/em&gt; The protocol&apos;s wire format is published. Microsoft Learn hosts the IDL. The DCs trust each other&apos;s calls by ACL. The only missing piece was a client implementation that any attacker could run from any joined machine.&lt;/p&gt;
&lt;p&gt;In August 2015 the missing piece arrived.&lt;/p&gt;
&lt;h2&gt;4. Generation by Generation&lt;/h2&gt;
&lt;p&gt;August 11, 2015, 01:27 Central European Time. Benjamin Delpy commits 47,132 insertions to the Mimikatz repository in a single push titled &lt;em&gt;&quot;DCSync in mimikatz &amp;amp; for XP/2003.&quot;&lt;/em&gt; The diff introduces four new modules -- &lt;code&gt;kull_m_rpc_drsr.c/.h&lt;/code&gt; and &lt;code&gt;kull_m_rpc_ms-drsr.h/_c.c&lt;/code&gt; -- generated from the [MS-DRSR] IDL. They are an MS-DRSR client surface, slotted into &lt;code&gt;kuhl_m_lsadump.c&lt;/code&gt; as the new &lt;code&gt;lsadump::dcsync&lt;/code&gt; command [@mimikatz-dcsync-commit][@mimikatz-repo]. Vincent Le Toux is credited as co-author.&lt;/p&gt;
&lt;p&gt;Six weeks later Sean Metcalf writes the canonical operator post and presents the technique at DerbyCon V on Friday, September 25, 2015, in the Track 1 (Break Me) slot from 3:00 to 3:50 pm [@sean-metcalf-dcsync-2015][@sean-metcalf-derbycon-2015]. The closed-population assumption shatters in a weekend.&lt;/p&gt;

A commit hash widely cited in operator forums for the DCSync introduction -- `79b3577aed999baac0352cb1ba3a5f86b6d29f34`, dated 2015-07-20 -- does not exist in the Mimikatz repository. A `git --no-pager log --all` against a fresh clone returns `fatal: bad object` for that hash; the GitHub commit URL returns 404; the GitHub API returns 422. The actual introducing commit is `7717b7a7173fa6a6b6566bbbc3e7372b464d988f`, authored by Benjamin DELPY at 2015-08-11 01:27:13 +0200, with the subject line *&quot;DCSync in mimikatz &amp;amp; for XP/2003&quot;* [@mimikatz-dcsync-commit]. Sean Metcalf&apos;s contemporary writeup at ADSecurity confirms August 2015 as the release month [@sean-metcalf-dcsync-2015]. The lesson for verifying any third-party claim about a Mimikatz commit is the same lesson Stage 1 of this article&apos;s research pipeline applied: clone the repo, run `git show`.
&lt;p&gt;What follows is the story of four generations of attacker approaches against this protocol, each motivated by the operational limit of the previous one.&lt;/p&gt;
&lt;h3&gt;Generation 2: DCSync (2015-08-11 onward)&lt;/h3&gt;
&lt;p&gt;Mimikatz becomes a DRSUAPI client. Operator invocation is one line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lsadump::dcsync /domain:contoso.local /user:krbtgt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Behind that line, six wire steps fire:&lt;/p&gt;

sequenceDiagram
    participant A as Attacker workstation
    participant DC as Target DC (DRSUAPI)
    A-&amp;gt;&amp;gt;DC: 1. resolve target DC by domain
    A-&amp;gt;&amp;gt;DC: 2. IDL_DRSBind (interface UUID DRSUAPI)
    DC--&amp;gt;&amp;gt;A: 3. bind reply (handle, session key)
    A-&amp;gt;&amp;gt;DC: 4. IDL_DRSGetNCChanges (opnum 3, MTX_ADDR DN, EXOP_REPL_OBJ)
    DC--&amp;gt;&amp;gt;A: 5. DRS_MSG_GETCHGREPLY (encrypted secret attributes)
    A-&amp;gt;&amp;gt;A: 6. decrypt with session key, emit NT hash and Kerberos keys
&lt;p&gt;The wire format is one round trip per principal. To dump every account in the domain, Mimikatz&apos;s &lt;code&gt;/all /csv&lt;/code&gt; mode iterates the request server-side via the same opnum with paginating up-to-date vectors. Per-call wire size is a few kilobytes for a single user; full-domain bulk dumps run to tens of megabytes. Wall-clock time is dominated by network latency to the target DC [@sean-metcalf-dcsync-2015][@trellix-silent-domain-hijack].&lt;/p&gt;
&lt;p&gt;The Generation-1 precondition is gone. The attack runs from any joined workstation. The Generation-1 host artifacts -- VSS events, IFM staging directories, multi-megabyte file copies -- all disappear. The only on-the-wire signature is &lt;em&gt;&quot;an &lt;code&gt;IDL_DRSGetNCChanges&lt;/code&gt; call from an IP that is not a domain controller&quot;&lt;/em&gt; -- which has to be detected at the protocol layer, not the host layer.&lt;/p&gt;
&lt;p&gt;Sean Metcalf&apos;s 2015 post named the detection recipe in the same breath as the attack: &lt;em&gt;&quot;Configure IDS to trigger if DsGetNCChange request originates an IP not on the &apos;Replication Allow List&apos; ...&quot;&lt;/em&gt; [@sean-metcalf-dcsync-2015]. Every network detection rule in this space, including Microsoft&apos;s own ATA &quot;Unusual Protocol Implementation&quot; category two years later, descends from that one sentence [@ata-v17-release-notes].&lt;/p&gt;
&lt;p&gt;DCSync is read-only. The ACL pair the attack exploits does not include directory-write rights. An attacker who wants to plant SID-history backdoors, modify &lt;code&gt;userAccountControl&lt;/code&gt; flags, or write to AdminSDHolder needs a different primitive. The same trust loophole that gave them read access turns out to support a symmetric write side.&lt;/p&gt;
&lt;h3&gt;Generation 3: DCShadow (2018-01-24)&lt;/h3&gt;
&lt;p&gt;January 23-24, 2018. Benjamin Delpy and Vincent Le Toux present at BlueHat IL in Tel Aviv. The talk is titled &lt;em&gt;&quot;Active Directory: What can make your million dollar SIEM go blind?&quot;&lt;/em&gt; [@youtube-bluehat-2018-dcshadow]. Four days later, on January 27, 2018, Delpy pushes the mainline merge to Mimikatz with commit &lt;code&gt;ab18bd1&lt;/code&gt;, subject &lt;em&gt;&quot;Pushing @vletoux DCShadow in current branch with some adaptations&quot;&lt;/em&gt; [@mimikatz-dcshadow-commit].&lt;/p&gt;
&lt;p&gt;Vincent Le Toux contributed the original implementation; the BlueHat IL talk shared joint Delpy/Le Toux billing; the Mimikatz mainline merge commit &lt;code&gt;ab18bd103a5cd7e26fb8d475c5ea0157d6633ca9&lt;/code&gt; is dated 2018-01-27 01:37:55 +0100, four days after the conference disclosure. Le Toux is the same author behind PingCastle&apos;s posture-assessment tooling and the canonical &lt;code&gt;dcshadow.com&lt;/code&gt; reference site [@mimikatz-dcshadow-commit][@dcshadow-com].&lt;/p&gt;
&lt;p&gt;DCShadow inverts DCSync. Where DCSync makes the attacker a DRSUAPI client, DCShadow makes the attacker a DRSUAPI &lt;em&gt;server&lt;/em&gt;. The mechanism: temporarily register an &lt;code&gt;nTDSDSA&lt;/code&gt; object plus the associated SPNs in the Configuration NC; signal to a legitimate DC that the new &quot;DC&quot; wants to push changes via &lt;code&gt;IDL_DRSReplicaAdd&lt;/code&gt; followed by &lt;code&gt;IDL_DRSReplicaSync&lt;/code&gt;; the legitimate DC pulls the attacker&apos;s pre-staged writes through the replication channel as if they were legitimate peer replication; deregister to clean up [@mitre-t1207][@dcshadow-com].&lt;/p&gt;

sequenceDiagram
    participant A as Attacker (rogue DC)
    participant Cfg as Configuration NC
    participant T as Target DC
    A-&amp;gt;&amp;gt;Cfg: 1. create nTDSDSA + server object
    A-&amp;gt;&amp;gt;Cfg: 2. add SPNs (GC, DRS UUID) to machine account
    A-&amp;gt;&amp;gt;T: 3. IDL_DRSReplicaAdd (dsaSrc = attacker)
    T-&amp;gt;&amp;gt;A: 4. IDL_DRSGetNCChanges callback (target pulls)
    A--&amp;gt;&amp;gt;T: 5. staged writes returned as replication payload
    A-&amp;gt;&amp;gt;T: 6. IDL_DRSReplicaDel
    A-&amp;gt;&amp;gt;Cfg: 7. delete nTDSDSA, remove SPNs

A directory operation that does not generate the standard Event ID 4662 / 4738 / 5136 object-modification events that the Domain Services Auditing subsystem emits for normal writes. Legitimate DC-to-DC replication is SACL-silent by design -- the audit subsystem intentionally suppresses change events on the replication channel to avoid drowning every DC in audit traffic on every directory change. DCShadow writes are SACL-silent because they ride the same channel.
&lt;p&gt;That last design fact is the entire point of the talk title. A SIEM watching object-modification events sees nothing when a DCShadow write lands, because the modifications arrive on the replication channel that the SIEM intentionally ignores as routine DC chatter. The original 2018 framing -- &quot;your million-dollar SIEM goes blind&quot; -- was correct for SIEMs that monitored only object-modification events. We will see in §6 how that framing has aged.&lt;/p&gt;
&lt;p&gt;DCShadow is &lt;em&gt;write&lt;/em&gt; capability. An attacker who reaches it can plant SID-history backdoors (write &lt;code&gt;S-1-5-21-...-519&lt;/code&gt; for Enterprise Admins into a low-privileged account&apos;s &lt;code&gt;sIDHistory&lt;/code&gt;), modify &lt;code&gt;userAccountControl&lt;/code&gt; to clear &lt;code&gt;ACCOUNTDISABLE&lt;/code&gt; on dormant high-privilege accounts, add ACEs to AdminSDHolder (which then propagate via the SDProp process to every protected admin account every 60 minutes), or set &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt; on a target computer to enable resource-based constrained delegation chains.&lt;/p&gt;
&lt;h3&gt;Generation 4: Permission-graph attacks (2018-present)&lt;/h3&gt;
&lt;p&gt;By 2018 the attack-side question had shifted. &lt;em&gt;Holding the rights triad directly&lt;/em&gt; was no longer the interesting precondition; the interesting question was how to reach it transitively, through whatever chain of ACL delegations a real-world domain happened to contain. The umbrella term that emerged is permission-graph attack. Its terminal edge is still DCSync; its novelty is the path that gets you to the terminal.&lt;/p&gt;
&lt;p&gt;Three primitives anchor this generation. Elad Shamir&apos;s &lt;em&gt;Wagging the Dog&lt;/em&gt; (January 28, 2019) showed how writing &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt; on a target computer object enables S4U2Self plus S4U2Proxy impersonation of any user to that computer [@shenaniganslabs-wagging-the-dog]. Shamir&apos;s &lt;em&gt;Shadow Credentials&lt;/em&gt; (June 21, 2021) demonstrated that writing &lt;code&gt;msDS-KeyCredentialLink&lt;/code&gt; on a target account adds an attacker-controlled certificate trust, enabling Kerberos PKINIT authentication as that account without resetting its password [@eladshamir-shadow-credentials]. And Sean Metcalf&apos;s earlier work on AdminSDHolder template abuse showed that writing the AdminSDHolder ACL causes SDProp to propagate the new ACL onto every protected admin account every 60 minutes -- self-healing persistence that survives defender cleanup [@sean-metcalf-adminsdholder].&lt;/p&gt;
&lt;p&gt;The unifying observation: DCSync is a terminal in a permission graph. The graph&apos;s nodes are AD principals; its edges are individual access-control entries (&lt;code&gt;WriteDACL&lt;/code&gt;, &lt;code&gt;WriteOwner&lt;/code&gt;, &lt;code&gt;GenericAll&lt;/code&gt;, &lt;code&gt;WriteProperty&lt;/code&gt;, &lt;code&gt;AddMember&lt;/code&gt;, &lt;code&gt;ForceChangePassword&lt;/code&gt;). Whoever can traverse the graph to the rights triad on the domain root has DCSync transitively. The attacker&apos;s job is no longer to invoke &lt;code&gt;IDL_DRSGetNCChanges&lt;/code&gt;; it is to find the shortest path through the graph from a foothold to the rights triad. The defender&apos;s mirror job is to enumerate all paths into the rights triad and either prune them or monitor them.&lt;/p&gt;

gantt
    title Domain replication attack class evolution
    dateFormat YYYY-MM-DD
    axisFormat %Y
    section Attack
    Gen 1 NTDS.dit theft           :a1, 2000-02-17, 2015-08-11
    Gen 2 DCSync                   :active, a2, 2015-08-11, 2026-12-31
    Gen 3 DCShadow                 :active, a3, 2018-01-24, 2026-12-31
    Gen 4 Permission-graph chains  :active, a4, 2018-06-01, 2026-12-31
    section Defense
    BloodHound 1.0 DEF CON 24     :d1, 2016-08-06, 30d
    ATA 1.7 release                :d2, 2017-04-01, 30d
    Azure ATP DCShadow alerts      :d3, 2018-07-24, 30d
    Azure ATP rebrand to MDI       :d4, 2020-09-22, 30d
    BloodHound v6.0                :d5, 2024-09-30, 30d
    BloodHound v6.3 Butterfly      :d6, 2024-12-09, 30d
    BloodHound v8.0 OpenGraph      :d7, 2025-07-29, 30d
    Trellix NDR Silent Hijack      :d8, 2025-12-08, 30d
&lt;p&gt;To make the read-side access check decision concrete -- and to expose how thin it actually is -- here is the logic of the gate written as a runnable function. This is pseudocode for the &lt;em&gt;decision&lt;/em&gt;, not the protocol bytes:&lt;/p&gt;
&lt;p&gt;{`
// Illustrative model of the MS-DRSR access check on IDL_DRSGetNCChanges.
// Returns &quot;secrets returned&quot; or &quot;ACCESS_DENIED&quot; given a caller&apos;s effective
// rights on the naming-context root.
function dcsyncAccessCheck(callerRights, ncRootDn, requestedAttrs) {
  const GET_CHANGES         = &apos;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2&apos;;
  const GET_CHANGES_ALL     = &apos;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2&apos;;
  const GET_CHANGES_FILTERED = &apos;89e95b76-444d-4c62-991a-0facbeda640c&apos;;&lt;/p&gt;
&lt;p&gt;  const SECRET_ATTRS = new Set([&apos;unicodePwd&apos;, &apos;dBCSPwd&apos;,
    &apos;ntPwdHistory&apos;, &apos;lmPwdHistory&apos;, &apos;supplementalCredentials&apos;]);
  const wantsSecrets = requestedAttrs.some(a =&amp;gt; SECRET_ATTRS.has(a));&lt;/p&gt;
&lt;p&gt;  // Baseline read requires GetChanges.
  if (!callerRights.has(GET_CHANGES)) return &apos;ACCESS_DENIED&apos;;
  // Secret attributes require GetChangesAll.
  if (wantsSecrets &amp;amp;&amp;amp; !callerRights.has(GET_CHANGES_ALL))
    return &apos;ACCESS_DENIED&apos;;&lt;/p&gt;
&lt;p&gt;  // Notice what is NOT checked: caller&apos;s SPN, machine-group membership,
  // ticket service, source IP. The access gate is the ACL, full stop.
  return &apos;secrets returned&apos;;
}&lt;/p&gt;
&lt;p&gt;const attacker = new Set([
  &apos;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2&apos;,
  &apos;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2&apos;,
]);
console.log(dcsyncAccessCheck(attacker, &apos;DC=contoso,DC=local&apos;,
  [&apos;unicodePwd&apos;, &apos;ntPwdHistory&apos;]));
`}&lt;/p&gt;
&lt;p&gt;Four generations, eleven years, no Generation 5 in sight. What is the single insight that lets all of this exist, and why has nobody patched it?&lt;/p&gt;
&lt;h2&gt;5. There Is No DC Check&lt;/h2&gt;
&lt;p&gt;The whole structural error of this protocol is one missing question. Specification [MS-DRSR] §4.1.10 defines the access check on &lt;code&gt;IDL_DRSGetNCChanges&lt;/code&gt; as: does the calling principal hold the rights triad on the naming context being replicated? [@ms-drsr-spec] That is the whole gate. There is no second check that asks &quot;is the caller&apos;s service principal name a domain-controller SPN?&quot; or &quot;is the caller&apos;s machine account in the &lt;code&gt;Domain Controllers&lt;/code&gt; group?&quot; or &quot;was the caller&apos;s Kerberos service ticket issued for a DC service?&quot; The spec is empirically and literally just an ACL check on the NC root.&lt;/p&gt;
&lt;p&gt;The empirical proof that a non-DC client succeeds lives in Mimikatz&apos;s &lt;code&gt;kuhl_m_lsadump.c&lt;/code&gt; and its DRSUAPI client surface in &lt;code&gt;kull_m_rpc_drsr*&lt;/code&gt; [@mimikatz-repo]. Mimikatz is software running on a workstation. It binds to the DRSUAPI interface UUID, calls &lt;code&gt;IDL_DRSGetNCChanges&lt;/code&gt;, and the call returns. The protocol&apos;s behavior is correct by specification. The security model is the bug.&lt;/p&gt;

A major feature added to Mimkatz in August 2015 is &apos;DCSync&apos; which effectively &apos;impersonates&apos; a Domain Controller and requests account password data from the targeted Domain Controller. DCSync was written by Benjamin Delpy and Vincent Le Toux. -- Sean Metcalf, ADSecurity, September 2015 [@sean-metcalf-dcsync-2015]
&lt;p&gt;Read Metcalf&apos;s verb carefully: &lt;em&gt;impersonates&lt;/em&gt;. The scare quotes are doing work. The Mimikatz client is not pretending to be a DC in any cryptographic sense. It is not forging a machine-account ticket. It is not spoofing an SPN. It is not bypassing any signature check.&lt;/p&gt;
&lt;p&gt;It is honestly making an authenticated call as the principal it actually is -- some user or service account that happens to hold the rights triad -- and the protocol honestly responds because its gate is satisfied. The &quot;impersonation&quot; framing is operator vocabulary borrowed from the social model the protocol was written under.&lt;/p&gt;
&lt;p&gt;The 1999 designers assumed only DCs would speak. By that social contract, anyone who speaks must be a DC. The spec encoded the social contract by way of &lt;em&gt;not encoding it at all&lt;/em&gt;. The ACL was the whole gate because, in 1999, the ACL was always satisfied by something that was always a DC.&lt;/p&gt;

flowchart TD
    Start[IDL_DRSGetNCChanges request arrives]
    Start --&amp;gt; Q1{&quot;Caller holds rights triad&lt;br /&gt;on the NC root?&quot;}
    Q1 -- yes --&amp;gt; Return[Return encrypted&lt;br /&gt;secret attributes]
    Q1 -- no --&amp;gt; Deny[ERROR_DS_DRA_ACCESS_DENIED]
    Start -.-&amp;gt; Absent[&quot;What the check does NOT ask:&lt;br /&gt;Is the caller a domain controller?&lt;br /&gt;Is the SPN a DC SPN?&lt;br /&gt;Is the machine in Domain Controllers?&quot;]
    Absent -.-&amp;gt; Nothing[no second gate exists]
&lt;p&gt;This is the article&apos;s intellectual fulcrum. The 1999 closed-population assumption -- only DCs speak this protocol -- survives in 2026 as an open-population reality (anyone with the rights speaks it), and the closed-population assumption is nowhere written down in the access-check code. The fix that would close the model would require a second gate. The spec did not write one. The implementation cannot synthesize one without breaking every legitimate consumer that already operates without one (more on this in §8).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The protocol&apos;s design is correct. The security model is the bug. No patch can fix this without breaking Active Directory replication itself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There is a temptation, on first encountering this, to assume the missing gate is an oversight that Microsoft will eventually fix. That intuition is wrong, and it is wrong for a deeper reason than &quot;Microsoft has not gotten around to it.&quot; If the protocol is the bug and the protocol cannot be amended, what defenses can possibly work in 2026? That question carries us into the next section.&lt;/p&gt;
&lt;h2&gt;6. What 2026 Actually Ships Against This&lt;/h2&gt;
&lt;p&gt;If the protocol cannot be fixed, the defender&apos;s question is no longer &quot;how do I prevent DCSync?&quot; but &quot;which layer catches which class of attempt?&quot; Four production detection layers ship against this attack class in 2026. None of them is individually sufficient. A fifth layer -- the architectural one that would close the structural error -- does not exist and is not coming.&lt;/p&gt;
&lt;h3&gt;Posture: enumerate who holds the rights&lt;/h3&gt;
&lt;p&gt;The posture layer reads the static ACL on the Domain NC root and surfaces every principal that holds any of the three rights. Microsoft Defender for Identity ships this as an Accounts security posture assessment family, computed continuously from MDI&apos;s per-DC sensors [@mdi-security-posture-accounts]. Vincent Le Toux&apos;s PingCastle exposes it as the &lt;em&gt;C-DCSync&lt;/em&gt; finding in its critical-risks section. Tenable Identity Exposure exposes it as an indicator of exposure. Christopher Keim&apos;s 2025 practitioner guide documents the PowerShell pattern that AD administrators without a posture-tool license can run on demand [@keim-dcsync-rights]:&lt;/p&gt;
&lt;p&gt;{`&lt;/p&gt;
Illustrative model of the posture-layer check.
In production, replace SAMPLE_ACL with output from Get-Acl in PowerShell
or python-ldap against the live Domain NC root.
&lt;p&gt;GET_CHANGES          = &apos;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2&apos;
GET_CHANGES_ALL      = &apos;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2&apos;
GET_CHANGES_FILTERED = &apos;89e95b76-444d-4c62-991a-0facbeda640c&apos;
TRIAD = {GET_CHANGES, GET_CHANGES_ALL, GET_CHANGES_FILTERED}&lt;/p&gt;
&lt;p&gt;DEFAULTS = {
    &apos;BUILTIN\\Administrators&apos;,
    &apos;CONTOSO\\Domain Controllers&apos;,
    &apos;CONTOSO\\Domain Admins&apos;,
    &apos;CONTOSO\\Enterprise Admins&apos;,
    &apos;NT AUTHORITY\\ENTERPRISE DOMAIN CONTROLLERS&apos;,
}&lt;/p&gt;
&lt;p&gt;SAMPLE_ACL = [
    {&apos;principal&apos;: &apos;CONTOSO\\Domain Admins&apos;,     &apos;right&apos;: GET_CHANGES},
    {&apos;principal&apos;: &apos;CONTOSO\\Domain Admins&apos;,     &apos;right&apos;: GET_CHANGES_ALL},
    {&apos;principal&apos;: &apos;CONTOSO\\Enterprise Admins&apos;, &apos;right&apos;: GET_CHANGES},
    {&apos;principal&apos;: &apos;CONTOSO\\Enterprise Admins&apos;, &apos;right&apos;: GET_CHANGES_ALL},
    {&apos;principal&apos;: &apos;CONTOSO\\backup_svc_2017&apos;,   &apos;right&apos;: GET_CHANGES},
    {&apos;principal&apos;: &apos;CONTOSO\\backup_svc_2017&apos;,   &apos;right&apos;: GET_CHANGES_ALL},
    {&apos;principal&apos;: &apos;CONTOSO\\MSOL_a1b2c3&apos;,       &apos;right&apos;: GET_CHANGES},
    {&apos;principal&apos;: &apos;CONTOSO\\MSOL_a1b2c3&apos;,       &apos;right&apos;: GET_CHANGES_ALL},
]&lt;/p&gt;
&lt;p&gt;residual = {}
for ace in SAMPLE_ACL:
    if ace[&apos;right&apos;] in TRIAD and ace[&apos;principal&apos;] not in DEFAULTS:
        residual.setdefault(ace[&apos;principal&apos;], set()).add(ace[&apos;right&apos;])&lt;/p&gt;
&lt;p&gt;for principal, rights in residual.items():
    print(f&quot;{principal}: {len(rights)} of 3 replication rights&quot;)
`}&lt;/p&gt;
&lt;p&gt;The residual set is the operational unit of work. In a freshly-installed domain it is empty. In a ten-year-old forest with a history of mergers and migrations it typically contains five to twenty entries -- a mix of legitimately delegated identity-sync products and forgotten service accounts from projects nobody on the current operations team remembers.&lt;/p&gt;

In Microsoft&apos;s Enhanced Security Administrative Environment and the BloodHound conventions, the set of principals and assets whose compromise yields domain-wide control. The `krbtgt` account, members of `Domain Admins` and `Enterprise Admins`, the Entra ID Connect MSOL_ sync account, and any non-default principal holding the rights triad on the domain root are all Tier Zero by construction.

The Microsoft Entra ID (formerly Azure AD) Connect synchronization service account, created on-premises during Entra Connect installation. The account name uses an `MSOL_` prefix followed by a hex suffix. It legitimately holds the rights triad on the Domain NC root because it must replicate password hashes to the cloud directory; treating it as Tier Zero is the standard hardening recommendation.

Microsoft Defender for Identity&apos;s (and ATA&apos;s earlier) internal baseline of which computers in the domain legitimately speak DRSUAPI to which DCs. Incoming `IDL_DRSGetNCChanges` requests are matched against this baseline; a request from a source outside the list fires the External ID 2006 alert.
&lt;p&gt;An earlier scope document for this article quoted an MDI assessment titled verbatim &lt;em&gt;&quot;Remove non-admin accounts with DCSync permissions.&quot;&lt;/em&gt; That exact title does not appear on the live MDI Accounts security-posture-assessment page in 2026 [@mdi-security-posture-accounts][@mdi-security-posture-hybrid]. The surface exists -- MDI&apos;s Accounts and Hybrid security posture-assessment families together cover non-default principals with replication rights -- but the verbatim title was not reproducible.&lt;/p&gt;
&lt;h3&gt;Behavioral: catch the act after it fires&lt;/h3&gt;
&lt;p&gt;The behavioral layer watches network traffic and event logs for the act of DCSync or DCShadow as it happens. Microsoft&apos;s first-party stack lives in Defender for Identity and ships three canonical alerts [@mdi-alerts-classic]:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;External ID 2006 -- &quot;Suspected DCSync attack (replication of directory services).&quot;&lt;/strong&gt; Credential Access (TA0006), Persistence (TA0003). Technique T1003.006. Severity High. Trigger: a replication request is initiated from a computer that is not a domain controller.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;External ID 2028 -- &quot;Suspected DCShadow attack (domain controller promotion).&quot;&lt;/strong&gt; Defense Evasion (TA0005). Technique T1207. Trigger: a machine in the network tries to register as a rogue domain controller.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;External ID 2029 -- &quot;Suspected DCShadow attack (domain controller replication request).&quot;&lt;/strong&gt; Defense Evasion (TA0005). Technique T1207. Trigger: a suspicious replication request is generated against a genuine domain controller, indicative of DCShadow.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The product lineage is Microsoft Advanced Threat Analytics 1.7 (April 2017, where DCSync was covered under the umbrella &quot;Unusual Protocol Implementation enhancements&quot; detection category [@ata-v17-release-notes]); Azure Advanced Threat Protection (2018, where Tali Ash&apos;s July 24, 2018 Microsoft Tech Community post announced the two named DCShadow detections that became 2028 and 2029 [@tali-ash-azure-atp-dcshadow]); and Defender for Identity (the Microsoft Ignite 2020 rebrand, week of September 22-24, 2020 [@rcpmag-defender-rebrand]). The detection content carries forward unchanged across product renamings; what changes is the portal it surfaces in [@mdi-whats-new].&lt;/p&gt;
&lt;p&gt;Open-source SIEM equivalents implement the same detection via Event ID 4662 on the domain object. The Sigma rule &lt;em&gt;Mimikatz DC Sync&lt;/em&gt; (id &lt;code&gt;611eab06-a145-4dfa-a295-3ccc5c20f59a&lt;/code&gt;) fires on Event ID 4662 where &lt;code&gt;Properties&lt;/code&gt; contains any of the three rights GUIDs or the literal string &lt;em&gt;Replicating Directory Changes All&lt;/em&gt;, with &lt;code&gt;AccessMask=0x100&lt;/code&gt; [@sigma-rule-dcsync]. Splunk&apos;s parallel detection &lt;em&gt;Windows AD Replication Request Initiated by User Account&lt;/em&gt; (rule &lt;code&gt;51307514-1236-49f6-8686-d46d93cc2821&lt;/code&gt;) implements the equivalent SPL search with the same MITRE T1003.006 annotation and the same known-false-positive list (Azure AD Connect, &lt;code&gt;dcdiag.exe /Test:Replications&lt;/code&gt;) [@splunk-research-dcsync].&lt;/p&gt;
&lt;p&gt;The SACL-event detection layer (Sigma + Splunk + every other SIEM-side implementation) requires that the operator first enable Advanced Security Audit policy &lt;code&gt;Audit Directory Services Access&lt;/code&gt; under &lt;code&gt;DS Access&lt;/code&gt;, with SACLs on the domain root auditing the three rights against &lt;code&gt;Everyone&lt;/code&gt;, &lt;code&gt;Domain Computers&lt;/code&gt;, and &lt;code&gt;Domain Controllers&lt;/code&gt;. A fresh-install AD does not have these SACLs by default [@splunk-research-dcsync]. The detection rule&apos;s documentation calls out the prerequisite explicitly; many operators discover it only after wondering why their Splunk dashboard is silent.&lt;/p&gt;
&lt;h3&gt;Network: NDR on the DRSUAPI interface&lt;/h3&gt;
&lt;p&gt;The network layer parses DCE/RPC traffic on the wire, identifies the DRSUAPI interface by its UUID, and fires when an &lt;code&gt;IDL_DRSGetNCChanges&lt;/code&gt; call originates from a source outside the legitimate-DC baseline. The canonical 2025 reference is Trellix Advanced Research Center&apos;s &lt;em&gt;&quot;Silent Domain Hijack: Uncovering the DCSync Attack and Detecting with Trellix NDR&quot;&lt;/em&gt;, published in week 50 of 2025 [@trellix-silent-domain-hijack]. Equivalent capability ships in Microsoft Defender for Identity&apos;s network analytics layer (the same sensor that powers External ID 2006) [@mdi-alerts-classic].&lt;/p&gt;
&lt;p&gt;The Trellix writeup is explicit about the architecture: &lt;em&gt;&quot;Trellix NDR detects replication protocol abuse by analyzing abnormal DCE/RPC and MS-DRSR traffic. It detects DCSync-like behavior when replication requests are sent from non-DC hosts or unusual users&quot;&lt;/em&gt; [@trellix-silent-domain-hijack]. The detection is independent of host-side telemetry, so it survives EDR tampering and works in environments where a DC is un-sensored from MDI&apos;s perspective.&lt;/p&gt;
&lt;h3&gt;Graph: BloodHound traverses the permission graph&lt;/h3&gt;
&lt;p&gt;The graph layer was built specifically for Generation 4. BloodHound, originally released by Andy Robbins, Rohan Vazarkar, and Will Schroeder at DEF CON 24 on August 6, 2016, models &lt;em&gt;&quot;you have DCSync rights to the domain&quot;&lt;/em&gt; as a directed edge from a principal to the domain node, computed by combining the separately-collected &lt;code&gt;GetChanges&lt;/code&gt; and &lt;code&gt;GetChangesAll&lt;/code&gt; ACEs through nested-group membership [@wald0-bloodhound-intro][@defcon24-bloodhound-pdf][@bloodhound-edge-dcsync]. An operator queries &lt;em&gt;&quot;shortest path from any compromised principal to the DCSync edge into a Domain node&quot;&lt;/em&gt; and gets back every transitive route into the rights triad.&lt;/p&gt;
&lt;p&gt;The 2024-2026 release cadence is dense and matters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;BloodHound v6.0 (September 30, 2024)&lt;/strong&gt; improved logic for identifying and creating complex edges requiring multiple permissions, including DCSync, when &lt;code&gt;Authenticated Users&lt;/code&gt; or &lt;code&gt;Everyone&lt;/code&gt; groups are involved [@bloodhound-v6-0-release-notes]. This closed a long-standing blind spot in which rights granted to a wildcard principal (the worst kind of delegation drift, often dating from compatibility settings in pre-2003 forests) were not surfaced as DCSync edges.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BloodHound v6.3 (December 9, 2024)&lt;/strong&gt; introduced the &lt;em&gt;Butterfly&lt;/em&gt; algorithm -- bi-directional risk analysis. Where the historical query was &lt;em&gt;&quot;which principals can attack this target?&quot;&lt;/em&gt;, Butterfly adds &lt;em&gt;&quot;which targets can be attacked from this compromised principal?&quot;&lt;/em&gt; SpecterOps describes the algorithm in their blog post &lt;em&gt;Unwrapping BloodHound v6.3 with Impact Analysis&lt;/em&gt;: &lt;em&gt;&quot;This is a massive upgrade to BloodHound Enterprise&apos;s risk analysis capability with a new algorithm we call &apos;Butterfly&apos;&quot;&lt;/em&gt; [@specterops-butterfly-blog][@bloodhound-v6-3-release-notes].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BloodHound v8.0 (July 29, 2025)&lt;/strong&gt; introduced &lt;em&gt;OpenGraph&lt;/em&gt;, generalizing the graph engine to model attack paths across non-AD systems (GitHub, 1Password, NPM, Snowflake) using the same Cypher front-end. The DCSync edge remains AD-specific; OpenGraph&apos;s relevance is that hybrid-cloud principals can now be modeled end-to-end [@bloodhound-v8-0-release-notes].&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The graph layer is the only one that catches multi-hop chains to the rights triad. A principal A with &lt;code&gt;GenericAll&lt;/code&gt; on group B, where B has the DCSync triad, is invisible to MDI&apos;s posture assessment but stands out as a one-hop path in BloodHound.&lt;/p&gt;

flowchart TD
    subgraph Posture[Posture layer]
        P1[MDI Accounts assessments]
        P2[PingCastle C-DCSync]
        P3[Keim PowerShell pattern]
    end
    subgraph Behavioral[Behavioral layer]
        B1[MDI 2006 / 2028 / 2029]
        B2[Sigma 611eab06]
        B3[Splunk 51307514]
    end
    subgraph Network[Network layer NDR]
        N1[Trellix NDR]
        N2[MDI per-DC sensor]
        N3[CrowdStrike DCE/RPC IoA]
    end
    subgraph Graph[Graph layer]
        G1[BloodHound DCSync edge]
        G2[v6.3 Butterfly Impact]
        G3[v8.0 OpenGraph]
    end
    P1 --&amp;gt; SOC[SOC alert queue]
    P2 --&amp;gt; SOC
    P3 --&amp;gt; SOC
    B1 --&amp;gt; SOC
    B2 --&amp;gt; SOC
    B3 --&amp;gt; SOC
    N1 --&amp;gt; SOC
    N2 --&amp;gt; SOC
    N3 --&amp;gt; SOC
    G1 --&amp;gt; SOC
    G2 --&amp;gt; SOC
    G3 --&amp;gt; SOC
&lt;p&gt;The full layer-by-layer comparison is the load-bearing matrix of the entire 2026 SOTA:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;What it inputs&lt;/th&gt;
&lt;th&gt;What it detects&lt;/th&gt;
&lt;th&gt;What it misses&lt;/th&gt;
&lt;th&gt;False-positive class&lt;/th&gt;
&lt;th&gt;Detection latency&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Posture&lt;/td&gt;
&lt;td&gt;NC-root ACL&lt;/td&gt;
&lt;td&gt;Direct grant of the rights triad to a non-default principal&lt;/td&gt;
&lt;td&gt;Multi-hop transitive paths; legitimate-principal abuse&lt;/td&gt;
&lt;td&gt;Identity-sync products (Entra Connect MSOL_, third-party HR-IDM); legitimately delegated backup agents&lt;/td&gt;
&lt;td&gt;24h score recomputation; ACE changes near real time&lt;/td&gt;
&lt;td&gt;Built in to MDI; PowerShell variant free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Behavioral&lt;/td&gt;
&lt;td&gt;Event ID 4662 or sensor-captured DRSUAPI traffic&lt;/td&gt;
&lt;td&gt;The act of DCSync, or the DCShadow registration / replication, after it happens&lt;/td&gt;
&lt;td&gt;Pre-attack staging; compromised-DC speaker; un-sensored DC blind spot&lt;/td&gt;
&lt;td&gt;Azure AD Connect syncs; &lt;code&gt;dcdiag.exe /Test:Replications&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Minutes (alert &quot;after the fact&quot;)&lt;/td&gt;
&lt;td&gt;MDI license; Sigma / Splunk free with SACL config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;DCE/RPC packet capture&lt;/td&gt;
&lt;td&gt;Wire signature of &lt;code&gt;IDL_DRSGetNCChanges&lt;/code&gt; from non-DC source&lt;/td&gt;
&lt;td&gt;Encrypted RPC payloads (per-principal granularity); sub-DC replicas misclassified&lt;/td&gt;
&lt;td&gt;Same as behavioral plus Samba-DC peers&lt;/td&gt;
&lt;td&gt;Seconds (passive inspection)&lt;/td&gt;
&lt;td&gt;Commercial NDR appliance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Graph&lt;/td&gt;
&lt;td&gt;LDAP-collected ACEs and group nesting&lt;/td&gt;
&lt;td&gt;Multi-hop graph paths that could reach the rights triad&lt;/td&gt;
&lt;td&gt;Net-new ACEs created after the last collection&lt;/td&gt;
&lt;td&gt;Stale data showing principals that no longer hold the right&lt;/td&gt;
&lt;td&gt;Hours to weeks (collection cadence)&lt;/td&gt;
&lt;td&gt;BloodHound CE free; BHE commercial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architectural (un-shipped)&lt;/td&gt;
&lt;td&gt;TPM-attested DC machine identity&lt;/td&gt;
&lt;td&gt;Pre-empts non-DC speaker entirely&lt;/td&gt;
&lt;td&gt;Compromised DC speaker; rogue &lt;code&gt;nTDSDSA&lt;/code&gt; registration&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A (preventive)&lt;/td&gt;
&lt;td&gt;Requires Microsoft protocol amendment&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Four layers, dozens of products, no shortage of detections. Why isn&apos;t the problem solved?&lt;/p&gt;
&lt;h2&gt;7. Which Gap Does Each Defense Close?&lt;/h2&gt;
&lt;p&gt;The matrix in §6 has one structural observation that earns its keep. Read down the &lt;em&gt;What it misses&lt;/em&gt; column. Each detection layer has a class of cases it cannot see. The posture layer cannot see transitive paths. The behavioral layer cannot see pre-attack staging or compromised-DC speakers. The network layer cannot see encrypted RPC payloads. The graph layer cannot see net-new ACEs created after the last collection. That is the load-bearing reason a mature defender runs all four in parallel instead of picking one.&lt;/p&gt;
&lt;p&gt;Run a thought experiment. Suppose you ship only the posture layer. Your MDI assessment is green: no non-default principals hold the rights triad. An attacker compromises a workstation belonging to an unrelated business unit, finds that the BU has &lt;code&gt;GenericAll&lt;/code&gt; on a group &lt;code&gt;LegacyApp_Operators&lt;/code&gt; that itself has &lt;code&gt;WriteDACL&lt;/code&gt; on the &lt;code&gt;BackupOperators&lt;/code&gt; group, and adds themselves to &lt;code&gt;BackupOperators&lt;/code&gt;. &lt;code&gt;BackupOperators&lt;/code&gt; inherits a forgotten 2014 delegation of the rights triad through three levels of nesting. Then DCSync runs.&lt;/p&gt;
&lt;p&gt;The posture layer never saw this because the residual list at the NC root is the four defaults. The graph layer would have surfaced the path. The behavioral or network layer would have fired the moment the DCSync call hit the wire. Without those layers, your green dashboard is a single-layer fantasy.&lt;/p&gt;
&lt;p&gt;Now consider the inverse. You ship only the behavioral layer. MDI fires External ID 2006 -- but only after the request hits the DC. Your SOC&apos;s mean response time is twelve minutes. The attacker&apos;s mean &lt;em&gt;complete-the-extraction&lt;/em&gt; time is sixty seconds. The detection is real; the response window is not.&lt;/p&gt;
&lt;p&gt;The same structural observation applies on the attack side. The four attack primitives have very different precondition costs:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attack primitive&lt;/th&gt;
&lt;th&gt;Pre-condition&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;th&gt;Default detection layer&lt;/th&gt;
&lt;th&gt;Tier of damage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;DCSync via Mimikatz&lt;/td&gt;
&lt;td&gt;Rights triad on NC root&lt;/td&gt;
&lt;td&gt;Every secret-attribute value for one or all principals&lt;/td&gt;
&lt;td&gt;MDI 2006; Sigma 611eab06; Splunk 51307514; NDR&lt;/td&gt;
&lt;td&gt;Domain takeover (via Golden Ticket from &lt;code&gt;krbtgt&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DCSync via Impacket&lt;/td&gt;
&lt;td&gt;Same as Mimikatz; no on-target binary footprint&lt;/td&gt;
&lt;td&gt;Same as Mimikatz, plus PtH / PtT auth modes&lt;/td&gt;
&lt;td&gt;Same as Mimikatz (wire signature is identical)&lt;/td&gt;
&lt;td&gt;Domain takeover&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DCShadow&lt;/td&gt;
&lt;td&gt;Domain Admin, local administrator on a DC, or &lt;code&gt;KRBTGT&lt;/code&gt; hash (for rogue-DC registration) [@mitre-t1207][@dcshadow-com]&lt;/td&gt;
&lt;td&gt;Arbitrary directory write, SACL-silent&lt;/td&gt;
&lt;td&gt;MDI 2028 + 2029&lt;/td&gt;
&lt;td&gt;Domain persistence (SID-history, AdminSDHolder ACE re-grant)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gen-4 chains&lt;/td&gt;
&lt;td&gt;Any ACE that transitively leads to the triad&lt;/td&gt;
&lt;td&gt;Reach DCSync, then DCSync&apos;s output&lt;/td&gt;
&lt;td&gt;BloodHound DCSync edge inbound paths&lt;/td&gt;
&lt;td&gt;Domain takeover (composite)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;DCSync via Mimikatz and via Impacket [@impacket-secretsdump] share the &lt;em&gt;output&lt;/em&gt; (domain takeover via credential theft) and the &lt;em&gt;default detection&lt;/em&gt; (the wire signature is the same). Their pre-conditions are identical. The Hacker Recipes documents Impacket&apos;s invocation surface for both pass-the-hash and pass-the-ticket modes [@hacker-recipes-dcsync]. This is why Impacket&apos;s &lt;code&gt;secretsdump.py -just-dc&lt;/code&gt; has become the universal red-team and IR tool, while Mimikatz remains the reference implementation that every blue-team detection still names.&lt;/p&gt;
&lt;p&gt;The Generation-4 row is the interesting one. Its pre-condition is dramatically cheaper than the other three (&lt;em&gt;any&lt;/em&gt; ACE that leads to the triad, rather than the triad in hand). Its detection is by graph traversal, not by wire signature. This is why the 2024-2026 frontier in this space has been the graph layer: the attack-side cost asymmetry favors the chain-finding problem, so the defense-side investment has landed there.&lt;/p&gt;

A reader who has internalized the &quot;no DC check&quot; observation will naturally ask: surely the obvious architectural fix is to add a caller-machine-identity check? CVE-2020-1472, popularly known as Zerologon, is the counterexample. Secura&apos;s September 2020 whitepaper, published approximately one month after Microsoft&apos;s August 11, 2020 patch, documented that the Netlogon protocol&apos;s `ComputeNetlogonCredential` AES-CFB8 implementation used an all-zero initialization vector. An attacker who sends an all-zero `ClientChallenge` exploits the IV bug to authenticate with roughly 1-in-256 probability per attempt, then calls `NetrServerPasswordSet2` to reset the DC&apos;s machine account password (commonly to all zeros) and becomes that DC for protocol purposes [@secura-zerologon-whitepaper]. After Zerologon-class compromise, the attacker *is* a DC. Any architectural caller-machine-identity check on `IDL_DRSGetNCChanges` would have been satisfied. Zerologon is the canonical worked proof that promoting the access-check from &quot;rights&quot; to &quot;rights and DC identity&quot; raises the bar but does not change the class.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Every detection layer in this space has a class of cases it cannot see. Mature defenders run all four (posture, behavioral, network, graph) because each layer is the only answer for a specific class of inputs, and accept that the un-shipped fifth layer (architectural) would only narrow the gap, not close it. Single-layer deployments produce confident but incomplete coverage.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If even the hypothetical perfect architectural fix would not close the class, what are the actual theoretical limits of any possible defense?&lt;/p&gt;
&lt;h2&gt;8. Why the Protocol Cannot Be Fixed&lt;/h2&gt;
&lt;p&gt;Two structural ceilings bound any conceivable MS-DRSR amendment. Both are provable from the specification&apos;s own definition of what it must do; both have been corroborated by the post-2018 industry consensus that &lt;em&gt;detection&lt;/em&gt; (not prevention) is the only viable defender posture.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ceiling 1: replicated secret material is the data the protocol exists to carry.&lt;/strong&gt; MS-DRSR is the mechanism by which Active Directory&apos;s multi-master replication invariant holds. If &lt;code&gt;IDL_DRSGetNCChanges&lt;/code&gt; did not return secret attributes -- &lt;code&gt;unicodePwd&lt;/code&gt;, &lt;code&gt;dBCSPwd&lt;/code&gt;, &lt;code&gt;ntPwdHistory&lt;/code&gt;, &lt;code&gt;lmPwdHistory&lt;/code&gt;, &lt;code&gt;supplementalCredentials&lt;/code&gt; -- then a password change on DC-A would not converge to DC-B within the replication interval. AD&apos;s &lt;em&gt;&quot;any DC accepts any write and the others catch up within minutes&quot;&lt;/em&gt; property would collapse [@ms-drsr-spec]. The protocol cannot stop returning secrets without ceasing to be the protocol. This is why &quot;disable MS-DRSR&quot; appears on every list of options that look attractive in a slide deck and break replication in production within minutes of being applied.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ceiling 2: a machine-identity check on the caller would shift the attack class, not close it.&lt;/strong&gt; Suppose Microsoft amended the access check on &lt;code&gt;IDL_DRSGetNCChanges&lt;/code&gt; to require, in addition to the rights triad, a cryptographic proof that the caller&apos;s machine account is in the &lt;code&gt;Domain Controllers&lt;/code&gt; group -- for example, that the call was made under a Kerberos service ticket issued for a DC SPN. This would defeat the Mimikatz-from-workstation case. It would also defeat every legitimate integration that today holds the rights triad on a non-DC service account: the Entra ID Connect MSOL_ account, third-party HR identity-management connectors, every backup and disaster-recovery tool that integrates at the AD level.&lt;/p&gt;
&lt;p&gt;Worse, the new check would shift the attack class to &lt;em&gt;compromising a DC&apos;s machine account&lt;/em&gt; -- CVE-2020-1472 Zerologon being the canonical worked example (see the §7 Aside for the mechanism). After a Zerologon-class compromise the attacker &lt;em&gt;is&lt;/em&gt; a DC, so promoting the speaker check from (rights) to (rights and DC-identity) raises the bar but does not change the class [@secura-zerologon-whitepaper].&lt;/p&gt;

flowchart TD
    Fix[Proposed MS-DRSR fix]
    Fix --&amp;gt; A[Stop returning secrets&lt;br /&gt;in IDL_DRSGetNCChanges]
    Fix --&amp;gt; B[Add machine-identity check&lt;br /&gt;on the caller]
    A --&amp;gt; A1[AD multi-master replication breaks&lt;br /&gt;password changes do not propagate]
    B --&amp;gt; B1[Legitimate integrations break&lt;br /&gt;MSOL_ account, HR IDM, backup tools]
    B --&amp;gt; B2[Attack shifts to compromised DC&lt;br /&gt;machine accounts e.g. Zerologon&lt;br /&gt;CVE-2020-1472]
&lt;p&gt;The honest structural fix would require a different replication architecture: a &lt;a href=&quot;https://paragmali.com/blog/the-tpm-in-windows-one-primitive-twenty-five-years-and-the-c/&quot; rel=&quot;noopener&quot;&gt;TPM&lt;/a&gt;- or HSM-attested DC machine identity, bound to a sealed replication key, with secret attributes encrypted under that key on the wire. No caller without the sealed key (or its hardware-bound equivalent on a different DC) could ever decrypt the response.&lt;/p&gt;
&lt;p&gt;Microsoft has not announced any such architecture. Its closest published precedent in the Windows security stack is the &lt;a href=&quot;https://paragmali.com/blog/vbs-trustlets-what-actually-runs-in-the-secure-kernel/&quot; rel=&quot;noopener&quot;&gt;LSAIso trustlet&lt;/a&gt; that Credential Guard uses for LSASS isolation -- a per-host isolation primitive applied to a per-host secret store. Applying the same idea to a multi-party wire protocol that must interoperate with twenty-five years of installed identity-sync tooling is a different engineering problem at a different scale. Microsoft has not committed to it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The replication attack class is structurally permanent. The honest defender response is detection-and-response, not prevention.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is the article&apos;s humility moment. The reader who arrived at §5 thinking &quot;this is fixable&quot; should now understand why eleven years of attack/defense iteration have produced detection layers, not protocol revisions. The four-layer detection architecture is not a placeholder while we wait for Microsoft to ship the real fix. It is the real fix, conditional on the constraint that the protocol&apos;s job description does not change.&lt;/p&gt;
&lt;p&gt;If the protocol is structurally unfixable, what exactly does 2026 still not solve operationally?&lt;/p&gt;
&lt;h2&gt;9. What 2026 Still Cannot Do&lt;/h2&gt;
&lt;p&gt;Five problems sit on the open-questions register in 2026. Each is documented in the literature. None has a satisfying answer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The DCShadow gap window.&lt;/strong&gt; MDI&apos;s External ID 2029 alert fires on the rogue DC&apos;s replication request, which is structurally &lt;em&gt;after&lt;/em&gt; the rogue &lt;code&gt;nTDSDSA&lt;/code&gt; registration has been committed. The alert documentation describes the detection as firing after the fact [@mdi-alerts-classic]. An attacker who completes the register-replicate-deregister cycle inside the alert&apos;s batch interval commits the persistence write before any SOC responder sees the alert. External ID 2028 (rogue promotion) fires earlier in the kill chain and partially closes the gap, but the gap is structural to the alert-batch model. The directory write that DCShadow lands -- a SID-history injection, an AdminSDHolder ACE re-grant -- survives the alert.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Encrypted-channel DCSync.&lt;/strong&gt; DRSUAPI clients that negotiate &lt;code&gt;AUTH_LEVEL_PKT_PRIVACY&lt;/code&gt; on the RPC binding (the modern hardened-DC default) encrypt the request and response bodies on the wire. Passive NDR sensors that depend on parsing the &lt;code&gt;IDL_DRSGetNCChanges&lt;/code&gt; request to determine which principal is being targeted lose per-principal granularity.&lt;/p&gt;
&lt;p&gt;The interface-bind packet is still in clear, so the existence of a DRSUAPI call is still visible, but the payload is not. The Microsoft channel-binding rollout that began in late 2023 (targeting LDAP rather than DRSUAPI, but cementing the broader trend toward encrypted directory traffic) makes this gap permanent on the wire side [@microsoft-ldap-channel-binding-kb4520412]. Detection moves into the DC itself via the MDI sensor model.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The legitimate-principal-compromise non-detection.&lt;/strong&gt; A hijacked Domain Admin session that uses its rightful DCSync ability triggers no layer. The posture layer sees a default principal. The behavioral layer sees a request from a DC or admin workstation that the Replication Allow List baseline accepts. The network layer sees the same. The graph layer sees the principal as a default Tier Zero member. The MDI alert is explicit: the trigger is &lt;em&gt;&quot;a computer that isn&apos;t a domain controller&quot;&lt;/em&gt; -- a compromised legitimate principal acting from a legitimately-baselined workstation does not fire it [@mdi-alerts-classic].&lt;/p&gt;
&lt;p&gt;This is the failure mode that catches mature SOCs. The attacker who already has Domain Admin does not need to attack DCSync detection because DCSync detection is not designed for legitimate principal abuse. UEBA-style per-principal anomaly detection (&lt;em&gt;&quot;this DA has not run DCSync in 90 days; this DA running DCSync at 03:00 from a workstation it has not used before is anomalous&quot;&lt;/em&gt;) is the partial answer. No production product currently delivers it with low enough false-positive rates to be operationally useful for already-Tier-Zero principals.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cross-forest replication abuse is under-instrumented.&lt;/strong&gt; The interaction of &lt;code&gt;DS-Replication-Get-Changes-In-Filtered-Set&lt;/code&gt; with the SPN-suffix routing matrix in multi-forest environments is poorly covered in public detection guidance. Large enterprises with M&amp;amp;A history hold dozens of trusts; the cross-trust edges are the least-audited surface in their identity architecture. BloodHound&apos;s SharpHound collector can enumerate cross-trust data, and v6.0&apos;s wildcard-principal fix improves the picture, but no fully automated detection pattern exists [@bloodhound-v6-0-release-notes].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Delegation-drift residual long tail.&lt;/strong&gt; Even with the MDI Accounts security posture assessment perfectly tuned, the long tail of forgotten ACE delegations across a twenty-five-year-old forest with mergers, acquisitions, decommissioned products, and migrations remains the canonical entry point. Christopher Keim frames it unambiguously [@keim-dcsync-rights]:&lt;/p&gt;

&quot;The defaults aren&apos;t the problem. The problem is delegation drift, backup agents, identity sync products, and application service accounts accumulate these rights over time, often with no documentation and no review.&quot; -- Christopher Keim, *&quot;DCSync Attack: Finding and Fixing Replication Rights in Active Directory&quot;* (2025) [@keim-dcsync-rights]
&lt;p&gt;The posture-layer detection is necessary but not sufficient; the human-process loop -- documented ownership, periodic review, removal of unjustified ACEs -- is what closes the residual. Most enterprise SOCs are not staffed to run this loop at the cadence the residual requires.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Open problem&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;th&gt;Current best partial result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;DCShadow gap window&lt;/td&gt;
&lt;td&gt;Persistence write commits before SOC sees the alert&lt;/td&gt;
&lt;td&gt;Configure MDI to surface External ID 2028 (rogue promotion) with automated investigation and response to block RPC traffic from the suspected source [@mdi-credential-access-alerts]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encrypted-channel DCSync&lt;/td&gt;
&lt;td&gt;Passive NDR loses per-principal granularity&lt;/td&gt;
&lt;td&gt;Hybrid deployment: NDR for cross-DC visibility, MDI on-DC sensor for per-principal granularity [@trellix-silent-domain-hijack]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Legitimate-principal compromise non-detection&lt;/td&gt;
&lt;td&gt;The Tier Zero principal who already has DCSync rights triggers nothing&lt;/td&gt;
&lt;td&gt;Reduce the count of DCSync-capable principals to a number a human can monitor; surface their DCSync activity to a high-severity review queue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-forest replication abuse&lt;/td&gt;
&lt;td&gt;Cross-trust DCSync paths are not enumerated by default&lt;/td&gt;
&lt;td&gt;SharpHound trust-collection methods; manual BloodHound inspection of foreign-domain principals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delegation-drift residual long tail&lt;/td&gt;
&lt;td&gt;Posture surfaces the principals; humans still have to decide which are legitimate&lt;/td&gt;
&lt;td&gt;Quarterly posture review with documented justification per non-default principal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;What can a defender actually do on Monday morning, given all of the above?&lt;/p&gt;
&lt;h2&gt;10. What a Defender Does on Monday Morning&lt;/h2&gt;
&lt;p&gt;Three action lanes, in priority order.&lt;/p&gt;
&lt;h3&gt;Lane 1: inventory the rights triad&lt;/h3&gt;
&lt;p&gt;Read the Domain NC root&apos;s ACL. Filter on the three rights GUIDs. Subtract the four default principal sets plus any legitimately delegated identity-sync product (Entra ID Connect&apos;s MSOL_ account is the canonical exclusion). Every entry that remains gets a documented owner and a documented justification, or the ACE gets removed.&lt;/p&gt;
&lt;p&gt;{`&lt;/p&gt;
Operator-facing inventory script. The browser-runnable demo uses a
hardcoded SAMPLE_ACL; in production, replace the SAMPLE_ACL with output
from one of:
PowerShell:  Get-Acl &quot;AD:$( (Get-ADDomain).DistinguishedName )&quot;
python-ldap: ldap_search(ncroot_dn, attr=&apos;nTSecurityDescriptor&apos;)
&lt;p&gt;GET_CHANGES          = &apos;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2&apos;
GET_CHANGES_ALL      = &apos;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2&apos;
GET_CHANGES_FILTERED = &apos;89e95b76-444d-4c62-991a-0facbeda640c&apos;
TRIAD = {GET_CHANGES, GET_CHANGES_ALL, GET_CHANGES_FILTERED}&lt;/p&gt;
&lt;p&gt;DEFAULT_OK = {
    &apos;BUILTIN\\Administrators&apos;,
    &apos;CONTOSO\\Domain Controllers&apos;,
    &apos;CONTOSO\\Domain Admins&apos;,
    &apos;CONTOSO\\Enterprise Admins&apos;,
    &apos;NT AUTHORITY\\ENTERPRISE DOMAIN CONTROLLERS&apos;,
}&lt;/p&gt;
MSOL_ accounts: legitimate Entra ID Connect sync principals.
Exclude by prefix, never by exact name (the suffix is random).
&lt;p&gt;def is_known_legitimate(principal):
    return principal in DEFAULT_OK or &apos;\\MSOL_&apos; in principal&lt;/p&gt;
&lt;p&gt;SAMPLE_ACL = [
    {&apos;principal&apos;: &apos;CONTOSO\\Domain Admins&apos;,     &apos;right&apos;: GET_CHANGES_ALL},
    {&apos;principal&apos;: &apos;CONTOSO\\MSOL_a1b2c3d4&apos;,     &apos;right&apos;: GET_CHANGES_ALL},
    {&apos;principal&apos;: &apos;CONTOSO\\backup_svc_2017&apos;,   &apos;right&apos;: GET_CHANGES_ALL},
    {&apos;principal&apos;: &apos;CONTOSO\\hr_idm_connector&apos;,  &apos;right&apos;: GET_CHANGES},
    {&apos;principal&apos;: &apos;CONTOSO\\fileserver_old$&apos;,   &apos;right&apos;: GET_CHANGES_ALL},
]&lt;/p&gt;
&lt;p&gt;findings = []
for ace in SAMPLE_ACL:
    if ace[&apos;right&apos;] not in TRIAD:
        continue
    if is_known_legitimate(ace[&apos;principal&apos;]):
        continue
    findings.append(ace[&apos;principal&apos;])&lt;/p&gt;
&lt;p&gt;print(&quot;Principals to investigate:&quot;)
for p in sorted(set(findings)):
    print(f&quot;  - {p}  -&amp;gt;  document owner or remove ACE&quot;)
`}&lt;/p&gt;
&lt;p&gt;Anything in the &lt;em&gt;Principals to investigate&lt;/em&gt; output is either a legitimately delegated service (document the owner and add to your exclusions; treat as Tier Zero) or a forgotten ACE from a project nobody remembers (remove it). Christopher Keim&apos;s framing is the operationally useful one: every common culprit is a backup tool, an identity-governance tool, or a service account from a long-dead migration [@keim-dcsync-rights].&lt;/p&gt;

The Microsoft Entra ID Connect synchronization service account, created on-premises during Entra Connect installation with an `MSOL_` prefix and a random hex suffix, legitimately holds the rights triad on the Domain NC root. It must -- it has to replicate password hashes to the cloud directory so that Entra ID can validate cloud logons against on-premises credentials. Removing its ACE breaks Entra ID password hash sync within a single replication interval, and your help desk will know about it.&lt;p&gt;The right answer is not to remove the ACE. It is to treat the MSOL_ account as Tier Zero. Dedicated host (the Entra Connect server itself, hardened as a DC-tier asset). No interactive logon. Multi-factor authentication on any privileged use. Conditional access policies that block sign-in from anything other than the Entra Connect service identity. The MDI Hybrid security posture-assessment family documents the surrounding controls [@mdi-security-posture-hybrid].
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Lane 2: enable the canonical alerts and audit&lt;/h3&gt;
&lt;p&gt;Three configuration items.&lt;/p&gt;
&lt;p&gt;First, ensure Microsoft Defender for Identity (or an equivalent identity-threat-detection product) is deployed with a sensor on every DC. The un-sensored-DC gap that the MDI alert documentation explicitly warns about creates a structural blind spot that an attacker will preferentially target [@mdi-alerts-classic].&lt;/p&gt;
&lt;p&gt;Second, enable Advanced Security Audit policy &lt;code&gt;Audit Directory Services Access&lt;/code&gt; under &lt;code&gt;DS Access&lt;/code&gt; and apply SACLs on the Domain NC root that audit the three replication rights against &lt;code&gt;Everyone&lt;/code&gt;, &lt;code&gt;Domain Computers&lt;/code&gt;, and &lt;code&gt;Domain Controllers&lt;/code&gt;. This is what makes Event ID 4662 fire on the request, which is what the Sigma 611eab06 and Splunk 51307514 rules consume [@sigma-rule-dcsync][@splunk-research-dcsync]. A fresh-install AD does not have these SACLs by default; the most common reason a SIEM dashboard for DCSync is silent is that the SACL never got applied.&lt;/p&gt;
&lt;p&gt;Third, deploy or configure NDR coverage on the inter-DC subnet, with a rule that fires on DRSUAPI bind requests originating from source IPs outside the legitimate-DC baseline. Trellix NDR, Microsoft&apos;s MDI sensor, CrowdStrike Falcon, and community Zeek/Suricata rulesets all implement this [@trellix-silent-domain-hijack]. Where commercial NDR is out of budget, Sysmon with the SwiftOnSecurity or Olaf Hartong modular configuration surfaces Event ID 3 (NetworkConnect) and Event ID 22 (DnsQuery) outbound from non-DC hosts to DC RPC endpoints; a SIEM correlation rule can combine this endpoint-side signal with Event ID 4662 on the DC to approximate the network-plus-host signature without an appliance budget.&lt;/p&gt;
&lt;h3&gt;Lane 3: run BloodHound on the domain quarterly&lt;/h3&gt;
&lt;p&gt;Collect with SharpHound at minimum quarterly. Continuous collection if BloodHound Enterprise is available. Run the canonical query for the &lt;code&gt;DCSync&lt;/code&gt; edge into the domain node. Trace inbound paths. Close the longest path first -- the longest paths are the ones a human operator is least likely to have noticed and most likely to have been delegated decades ago for a reason nobody remembers.&lt;/p&gt;
&lt;p&gt;The v6.0 wildcard-principal fix is particularly worth a re-run on any forest that has been operated since before 2003: legacy &lt;code&gt;Authenticated Users&lt;/code&gt; or &lt;code&gt;Everyone&lt;/code&gt; ACEs on the domain root are exactly the kind of thing that survived a Server 2003 upgrade silently and never showed up in any subsequent audit [@bloodhound-v6-0-release-notes]. The v6.3 Butterfly algorithm lets you query the inverse view -- &lt;em&gt;which targets fall if this principal is compromised?&lt;/em&gt; -- which is the right question to ask about any newly-discovered non-default DCSync holder [@specterops-butterfly-blog][@bloodhound-v6-3-release-notes].&lt;/p&gt;
&lt;h3&gt;What does not work&lt;/h3&gt;
&lt;p&gt;Four common misbeliefs are worth naming.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; See §1 -- Credential Guard does not stop DCSync. The secret transits remote-to-remote (a DC&apos;s NTDS.dit to the attacker&apos;s process), never local-to-LSASS, so the trustlet&apos;s isolation boundary has no jurisdiction over the call [@credential-guard-considerations]. Credential Guard is the right control for the local-memory attack surface and the wrong control for the network-protocol attack surface.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; After a confirmed DCSync of &lt;code&gt;krbtgt&lt;/code&gt;, rotate the &lt;code&gt;krbtgt&lt;/code&gt; account password twice, with at least ten hours between rotations. The first rotation invalidates the old key after the current Kerberos ticket lifetime expires. The second rotation invalidates the &lt;em&gt;previous&lt;/em&gt; old key, which the directory stores alongside the current key for compatibility during replication convergence. Rotating only once leaves Golden Tickets forged from the dumped key valid for the duration of the second key. Rotating twice ten hours apart is what closes the window [@microsoft-new-krbtgtkeys]. (And neither rotation removes the ACE that allowed the dump in the first place: come back to Lane 1.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Renaming &lt;code&gt;krbtgt&lt;/code&gt; does nothing. The account&apos;s Relative Identifier (RID 502) is fixed by AD&apos;s design and is what the TGT signing key derives against, not the &lt;code&gt;sAMAccountName&lt;/code&gt; [@microsoft-well-known-sids]. Renaming it to &lt;code&gt;krbtgt-old-do-not-use&lt;/code&gt; confuses operators, not attackers.&lt;/p&gt;
&lt;p&gt;Disabling MS-DRSR is not an option. The protocol is what makes AD replication work. Blocking opnum 3 at the RPC layer or refusing the DRSUAPI bind stops DCSync and stops every DC in the forest from talking to every other DC. Replication grinds. Password changes do not propagate. Domain joins fail. Within hours, the directory is split-brain across DCs, and within days, it is unrecoverable without DR-grade restore from backup: Microsoft&apos;s own AD-replication troubleshooting documentation walks the lingering-object pathology that produces exactly this split-brain when DCs stop replicating for longer than the tombstone lifetime [@microsoft-ad-lingering-objects].&lt;/p&gt;

On any DC, run `auditpol /get /subcategory:&quot;Directory Service Access&quot;` from an elevated prompt. If the output reads `No Auditing`, your Sigma / Splunk SACL-event detection will not fire because Event ID 4662 is not being generated. Enable with `auditpol /set /subcategory:&quot;Directory Service Access&quot; /success:enable /failure:enable`, then apply the SACL on the domain root as described in the Splunk rule&apos;s implementation notes [@splunk-research-dcsync].
&lt;p&gt;The six FAQ items in the next section cover the misconceptions that did not fit into any single lane.&lt;/p&gt;
&lt;h2&gt;11. Frequently Asked Questions&lt;/h2&gt;

No. The access check on `IDL_DRSGetNCChanges` requires both the baseline `DS-Replication-Get-Changes` right *and* `DS-Replication-Get-Changes-All` to read secret attributes [@ad-schema-get-changes][@ad-schema-get-changes-all]. The *All* suffix unlocks the secret attribute set given the baseline right; it is not a self-sufficient gate. Christopher Keim&apos;s PowerShell pattern filters on both GUIDs together [@keim-dcsync-rights]. Confidential-flag attributes additionally require `DS-Replication-Get-Changes-In-Filtered-Set`. Some detection rules (Sigma 611eab06 included) accept either GUID in the SACL event because the operational cost of a false positive on the broader filter is lower than the risk of missing one of the two required ACEs being present without the other [@sigma-rule-dcsync].

No. Credential Guard isolates LSASS-resident secrets in a separate virtual trust level so that local-memory attacks (Mimikatz `sekurlsa::logonpasswords`, comsvcs.dll mini-dumps of `lsass.exe`, and similar) cannot read cached credentials. DCSync does not touch the attacker&apos;s LSASS at all. The secret transits from a remote DC&apos;s NTDS.dit, over an encrypted MS-DRSR session, into the attacker&apos;s process memory. Microsoft&apos;s Credential Guard documentation lists the scenarios Credential Guard does and does not cover; MS-DRSR-based network credential extraction is not in scope [@credential-guard-considerations]. This is one of the clearest examples in the Windows security model of a control that is right for one attack surface and orthogonal to another.

Not anymore. The BlueHat IL 2018 &quot;your million-dollar SIEM goes blind&quot; framing was correct in 2018 against SIEMs that monitored only object-modification events: the replication writes are SACL-silent. By July 24, 2018, Tali Ash announced Azure ATP&apos;s two new preview detections, which fired on the rogue-DC promotion fingerprint (creating an `nTDSDSA` object in the Configuration NC) and the replication request from the rogue, respectively [@tali-ash-azure-atp-dcshadow]. Those detections carried forward as Microsoft Defender for Identity External IDs 2028 and 2029 [@mdi-alerts-classic]. The writes themselves remain SACL-silent; the *registration* fingerprint that has to precede them is not. The honest contemporary statement is &quot;DCShadow&apos;s writes are silent, but the rogue-DC scaffolding is not, and a sensored DC catches the scaffolding.&quot; A skilled attacker who completes the register-replicate-deregister cycle inside the alert batch interval may still commit the persistence write before SOC response.

No. The protocol&apos;s design is the issue. Microsoft has not announced any MS-DRSR amendment that would change the `IDL_DRSGetNCChanges` access check, because amending the access check breaks legitimate non-DC consumers (the Entra ID Connect MSOL_ account is the most prominent) and shifts the attack class to compromised DC machine accounts (Zerologon is the worked example [@secura-zerologon-whitepaper]). The &quot;fixes&quot; that have shipped since 2015 are all detection: ATA 1.7 (April 2017) [@ata-v17-release-notes], Azure ATP (2018) [@tali-ash-azure-atp-dcshadow], Microsoft Defender for Identity (post-Ignite 2020 rebrand) [@rcpmag-defender-rebrand][@mdi-whats-new], and the posture-assessment families that surface non-default rights triad holders [@mdi-security-posture-accounts]. The protocol itself is the same protocol it was in Windows 2000 Server.

The MSOL_ sync account legitimately holds the rights triad on the Domain NC root because it must replicate password hashes to Entra ID. Treat it as Tier Zero with the hardening profile listed in §10&apos;s MSOL_ Aside (dedicated hardened host, no interactive logon, MFA on privileged use, conditional access restricted to the Entra Connect service identity) [@mdi-security-posture-hybrid]. Critically, do *not* remove the ACE from the Domain NC root: doing so breaks Entra ID password hash sync within one replication interval, and your help desk will know about it within hours.

No. DCSync is over DRSUAPI/MS-DRSR, not over LDAP. The directory&apos;s LDAP service refuses to return `unicodePwd` and related secret-attribute values regardless of caller privilege, because the attribute is marked confidential and the LDAP read path does not honor the replication extended rights. There is no &quot;DCSync over LDAP&quot; technique because LDAP simply does not return the data; MITRE T1003.006 names DRSUAPI explicitly as the protocol vector [@mitre-t1003-006]. Operators occasionally confuse this with LDAPS (LDAP over TLS) or with the November 2023 LDAP signing and channel-binding rollout, both of which are channel-protection concerns rather than credential-read concerns.
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;dcsync-dcshadow-and-the-domain-replication-attack-class&quot; keyTerms={[
  { term: &quot;MS-DRSR&quot;, definition: &quot;Directory Replication Service Remote Protocol; the RPC interface by which any AD domain controller can replicate any object including secret attributes from any other DC.&quot; },
  { term: &quot;IDL_DRSGetNCChanges&quot;, definition: &quot;MS-DRSR&apos;s opnum-3 method that returns changed objects within a naming context; the protocol method DCSync invokes.&quot; },
  { term: &quot;Extended Right&quot;, definition: &quot;A schema-defined access-control right keyed by GUID rather than by standard ACL bit. Granted via ACE; checked at runtime by the operation that requires it.&quot; },
  { term: &quot;Naming Context&quot;, definition: &quot;A top-level replication partition of the Active Directory database. DCSync operates against the Domain NC root.&quot; },
  { term: &quot;Rights Triad&quot;, definition: &quot;DS-Replication-Get-Changes, DS-Replication-Get-Changes-All, and DS-Replication-Get-Changes-In-Filtered-Set extended rights on a naming-context root.&quot; },
  { term: &quot;NTDS.dit&quot;, definition: &quot;The on-disk Extensible Storage Engine database holding every AD object including secret attributes.&quot; },
  { term: &quot;SACL-silent&quot;, definition: &quot;A directory operation that does not generate the Event ID 4662/4738/5136 events normally emitted by Domain Services Auditing. Legitimate DC-to-DC replication is SACL-silent by design.&quot; },
  { term: &quot;Tier Zero&quot;, definition: &quot;Principals and assets whose compromise yields domain-wide control. KRBTGT, Domain Admins, the MSOL_ account, and any principal holding the rights triad are all Tier Zero.&quot; },
  { term: &quot;MSOL_ account&quot;, definition: &quot;The Entra ID Connect synchronization service account; legitimately holds the rights triad to replicate password hashes to the cloud directory.&quot; },
  { term: &quot;Replication Allow List&quot;, definition: &quot;MDI&apos;s internal baseline of which computers in the domain legitimately speak DRSUAPI to which DCs.&quot; }
]} flashcards={[
  { front: &quot;What does MS-DRSR §4.1.10 check on IDL_DRSGetNCChanges?&quot;, back: &quot;Only that the calling principal holds the rights triad on the naming-context root. It does not check whether the caller is a domain controller.&quot; },
  { front: &quot;What is the Mimikatz commit hash and date for DCSync&apos;s introduction?&quot;, back: &quot;Commit 7717b7a7173fa6a6b6566bbbc3e7372b464d988f, authored by Benjamin DELPY on 2015-08-11 01:27:13 +0200, subject &apos;DCSync in mimikatz &amp;amp; for XP/2003&apos;.&quot; },
  { front: &quot;What are MDI&apos;s three DCSync/DCShadow alert IDs?&quot;, back: &quot;External ID 2006 (DCSync), 2028 (DCShadow promotion), 2029 (DCShadow replication request).&quot; },
  { front: &quot;Why can&apos;t Microsoft patch DCSync?&quot;, back: &quot;Two structural ceilings: stopping the protocol from returning secrets breaks AD replication; adding a machine-identity check shifts the attack class to compromised DC machine accounts (Zerologon).&quot; },
  { front: &quot;What is the BloodHound v6.3 &apos;Butterfly&apos; algorithm?&quot;, back: &quot;Bi-directional impact analysis: in addition to &apos;which principals can reach this target?&apos;, also computes &apos;which targets fall if this principal is compromised?&apos;.&quot; }
]} questions={[
  { q: &quot;Why does adding a caller-machine-identity check to MS-DRSR not close the attack class?&quot;, a: &quot;Because compromising a DC&apos;s machine account (CVE-2020-1472 Zerologon being the canonical worked example) satisfies the new check while still enabling the original attack.&quot; },
  { q: &quot;Why is Credential Guard the wrong control for DCSync?&quot;, a: &quot;Credential Guard isolates LSASS-resident secrets on the local machine. DCSync reads secrets from a remote DC&apos;s NTDS.dit over MS-DRSR; the secret never transits the attacker&apos;s LSASS.&quot; },
  { q: &quot;Why must the krbtgt password be rotated twice after a confirmed DCSync?&quot;, a: &quot;Each AD account stores both the current and previous password. Rotating once invalidates only the older of the two keys; the most recently dumped key remains valid. Rotating a second time, after the first replication interval has converged, invalidates the dumped key.&quot; },
  { q: &quot;What does each of the four defense layers miss?&quot;, a: &quot;Posture misses transitive paths. Behavioral misses pre-attack staging and compromised-DC speakers. Network misses encrypted RPC payloads. Graph misses net-new ACEs created after the last collection.&quot; },
  { q: &quot;Why is the DCShadow gap window structural?&quot;, a: &quot;MDI External ID 2029 fires on the rogue&apos;s replication request after registration. An attacker who completes register-replicate-deregister inside the alert batch interval commits the persistence write before SOC response.&quot; }
]} /&amp;gt;&lt;/p&gt;
&lt;p&gt;A final observation, since the closing should add something new. The protocol that this article calls structurally unfixable is not unusual. Most Microsoft security primitives that survive long enough enter the same regime -- the LSASS surface, the Kerberos delegation surface, the SMB authentication surface -- where the only honest answer is detection in depth because the protocol&apos;s job description and its abuse surface are the same surface viewed from different chairs.&lt;/p&gt;
&lt;p&gt;The thing that makes MS-DRSR notable is the &lt;em&gt;clarity&lt;/em&gt; with which the structural error is visible. Read §4.1.10 once and you are done. Everything from §6 onward is the industry&apos;s slow accumulation of detection layers around a gate that cannot be moved. Twenty-five years in, the gate is still where it was on February 17, 2000, and the four layers around it are still under active engineering.&lt;/p&gt;
</content:encoded><category>active-directory</category><category>dcsync</category><category>dcshadow</category><category>ms-drsr</category><category>credential-theft</category><category>defender-for-identity</category><category>bloodhound</category><category>kerberos</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>Kerberos in Windows: The Other Half of NTLMless</title><link>https://paragmali.com/blog/kerberos-in-windows-the-other-half-of-ntlmless/</link><guid isPermaLink="true">https://paragmali.com/blog/kerberos-in-windows-the-other-half-of-ntlmless/</guid><description>After NTLM, Kerberos becomes the load-bearing authentication protocol for Windows. Eight years of attacks, the December 2025 Beyond-RC4 cadence, and the H2 2026 IAKerb / Local KDC broad enable.</description><pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate><content:encoded>
**Kerberos was a 1988 protocol that solved one problem: mutual authentication on an untrusted network using a trusted third party.** Then it got piled on for thirty-three years. In 2026 NTLM is being switched off, the AS-REQ / AS-REP / TGS-REQ / TGS-REP skeleton is finally the single load-bearing authentication path for Windows, and the eleven attack primitives that exposed every joint of that skeleton between 2014 and 2022 are still mostly fixable by configuration, not by protocol. This is the companion to [NTLMless](/blog/ntlmless-the-death-of-ntlm-in-windows/): what happens to the protocol that takes over.
&lt;h2&gt;1. A Chain Without NTLM&lt;/h2&gt;
&lt;p&gt;Imagine a defender who has done every NTLM retrofit Microsoft has shipped. NTLM is disabled by default on the workstations. &lt;code&gt;RestrictNTLMInDomain&lt;/code&gt; is on at the domain controller. SMB signing is enforced. Extended Protection for Authentication is set on every IIS endpoint. ESC8 has been patched. The defender has read the &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;NTLMless&lt;/a&gt; post and ticked every box.&lt;/p&gt;
&lt;p&gt;A low-privileged user on that network opens a PowerShell prompt. They run &lt;code&gt;Powermad&lt;/code&gt; to create a fresh computer account. The default &lt;code&gt;MachineAccountQuota&lt;/code&gt; is still &lt;code&gt;10&lt;/code&gt;, which means any authenticated domain user can create up to ten computer objects in Active Directory by design [@shenanigans-rbcd]. They then write a single LDAP attribute, &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt;, on a target file server they have any write permission against. They ask the Key Distribution Center for a service ticket via &lt;code&gt;Rubeus s4u&lt;/code&gt;, present that ticket to the target file server, and walk in as &lt;code&gt;Administrator&lt;/code&gt;. Total elapsed time: less than this paragraph. Total NTLM in the chain: zero.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The post-NTLM Resource-Based Constrained Delegation chain depends on three properties of Kerberos that are features, not bugs: (a) the default &lt;code&gt;MachineAccountQuota = 10&lt;/code&gt; setting on every fresh Active Directory forest, (b) the S4U2Proxy guarantee that always produces a forwardable TGS even when the input ticket was not forwardable, and (c) the absence of any KDC-side check on whether the requesting principal is a &quot;trusted delegator&quot;. All three are documented behaviours of the protocol. None of them is a CVE [@shenanigans-rbcd].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The chain has a name and a primary disclosure: Elad Shamir&apos;s &quot;Wagging the Dog&quot; post on shenaniganslabs.io, January 28, 2019 [@shenanigans-rbcd]. The weaponised tooling is GhostPack&apos;s Rubeus, the C# Kerberos toolset that ships ready-made commands for &lt;code&gt;s4u&lt;/code&gt;, &lt;code&gt;asktgt&lt;/code&gt;, &lt;code&gt;kerberoast&lt;/code&gt;, and &lt;code&gt;diamond&lt;/code&gt; [@ghostpack-rubeus]. The single-line elevation wrapper that splices together Powermad, KrbRelay, Rubeus, and an SCM bypass is &lt;code&gt;KrbRelayUp&lt;/code&gt;, published by Mor Davidovich (&quot;Dec0ne&quot;) on April 24, 2022; its README scopes itself as a universal no-fix local privilege escalation in Windows domain environments where LDAP signing is not enforced (and that is the default) [@krbrelayup].&lt;/p&gt;

sequenceDiagram
    participant U as Low-priv user
    participant DC as Domain Controller / KDC
    participant T as Target file server
    U-&amp;gt;&amp;gt;DC: Powermad: create machine account FAKE (machine account)
    U-&amp;gt;&amp;gt;DC: LDAP write set RBCD attribute on T to allow FAKE
    U-&amp;gt;&amp;gt;DC: AS-REQ for FAKE -&amp;gt; TGT
    U-&amp;gt;&amp;gt;DC: S4U2Self as Administrator (non-forwardable TGS returned)
    U-&amp;gt;&amp;gt;DC: S4U2Proxy with TGS returns forwardable TGS for cifs on T
    U-&amp;gt;&amp;gt;T: AP-REQ presenting Administrator TGS
    T-&amp;gt;&amp;gt;U: SYSTEM access on T
&lt;p&gt;Read the chain twice. The first read shows that every step is a documented Kerberos exchange. The second read shows that &lt;em&gt;removing NTLM did nothing to it&lt;/em&gt;. Restrict-NTLM, EPA, SMB signing, ESC8 -- the entire NTLM-retrofit catalogue has no edge against a Kerberos-only attack path that uses S4U2Self, S4U2Proxy, and the Resource-Based Constrained Delegation attribute exactly as Microsoft documented them in [@ms-kerberos-overview].&lt;/p&gt;
&lt;p&gt;This is the article&apos;s load-bearing thesis. &lt;em&gt;Removing NTLM did not remove the attack surface; it shifted the attack surface onto a protocol that is also thirty-three years old, also retrofitted, and now also the only load-bearing one.&lt;/em&gt; In October 2023, Matthew Palko, Microsoft&apos;s Principal Group Product Manager for Windows authentication, wrote the post that committed Microsoft publicly to deprecating NTLM and named the Kerberos features that would replace it [@ms-palko-evolution]. The NTLMless companion article walked through the NTLM-side mechanics of that transition. This one walks through the Kerberos side.&lt;/p&gt;
&lt;p&gt;The question that drives everything that follows is the question the chain above forces: &lt;em&gt;how did Windows arrive at a state where the most catastrophic post-NTLM Active Directory attack chain depends on Kerberos working exactly as the 1989 designers intended?&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;2. Origins: Needham, Schroeder, Athena, and 1988&lt;/h2&gt;
&lt;p&gt;Kerberos is not new engineering. The story of Windows authentication in 2026 starts with two Xerox PARC researchers and a 1978 paper in Communications of the ACM.&lt;/p&gt;
&lt;p&gt;In December 1978, Roger M. Needham and Michael D. Schroeder published &quot;Using Encryption for Authentication in Large Networks of Computers&quot; in CACM 21(12), pages 993 to 999 [@needham-schroeder]. The paper is paywalled on the ACM Digital Library, but RFC 4120&apos;s own Background section names it as the parent protocol [@rfc4120] and the Wikipedia article on the Needham-Schroeder protocol preserves the message structure verbatim [@wiki-needham-schroeder]. The symmetric-key version of that protocol is five messages long, and it is the structural blueprint of every &quot;ticket from a trusted third party&quot; design that followed.&lt;/p&gt;
&lt;p&gt;$$A \to S:\ A, B, N_A$$
$$S \to A:\ {N_A, K_{AB}, B, {K_{AB}, A}&lt;em&gt;{K&lt;/em&gt;{BS}}}&lt;em&gt;{K&lt;/em&gt;{AS}}$$
$$A \to B:\ {K_{AB}, A}&lt;em&gt;{K&lt;/em&gt;{BS}}$$
$$B \to A:\ {N_B}&lt;em&gt;{K&lt;/em&gt;{AB}}$$
$$A \to B:\ {N_B - 1}&lt;em&gt;{K&lt;/em&gt;{AB}}$$&lt;/p&gt;
&lt;p&gt;&lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; are the principals; &lt;code&gt;S&lt;/code&gt; is the trusted third party; &lt;code&gt;K_AS&lt;/code&gt; and &lt;code&gt;K_BS&lt;/code&gt; are pre-shared long-term keys; &lt;code&gt;K_AB&lt;/code&gt; is the session key that &lt;code&gt;S&lt;/code&gt; mints for the conversation; &lt;code&gt;N_A&lt;/code&gt; and &lt;code&gt;N_B&lt;/code&gt; are nonces. The &quot;ticket&quot; is the part of the third message that &lt;code&gt;A&lt;/code&gt; cannot decrypt and just forwards to &lt;code&gt;B&lt;/code&gt;. That structure -- a server-issued cryptographic envelope intended for somebody else and opaque to the carrier -- is what becomes the Kerberos TGS thirty-eight years later.&lt;/p&gt;
&lt;p&gt;Three years later, in August 1981, Dorothy Denning and Giovanni Maria Sacco published &quot;Timestamps in Key Distribution Protocols&quot; in CACM 24(8), 533-536. The paper is also paywalled on dl.acm.org, but the Wikipedia secondary preserves the finding: the Needham-Schroeder symmetric protocol is vulnerable to a replay attack if an attacker recovers an old session key [@wiki-needham-schroeder]. Denning and Sacco proposed timestamps as the fix. This is the structural reason every Kerberos ticket carries a timestamp and every Kerberos network requires a synchronised time service today.&lt;/p&gt;

A Kerberos administrative boundary, written in uppercase like `CONTOSO.COM`, that scopes a set of principals (users, services, computers) sharing a single Key Distribution Center. Every Kerberos ticket names the issuing domain in its `EncTicketPart.crealm` and `EncTicketPart.cname` fields. Active Directory binds one Kerberos domain to one AD forest root by default [@ms-kerberos-overview].
&lt;p&gt;Between 1983 and 1991, MIT Project Athena -- the joint MIT, DEC, and IBM campus computing effort led by Jerome Saltzer -- needed a working authentication service for a distributed workstation network running over a hostile campus LAN. The Athena Technical Plan Section E.2.1, &quot;Kerberos Authentication and Authorization System&quot; [@mit-athena-plan], is the canonical internal design document. Steve Miller and Clifford Neuman did the protocol work; Jeffrey Schiller ran the network operations.&lt;/p&gt;
&lt;p&gt;In February 1988, MIT published two complementary artefacts. Bill Bryant wrote &quot;Designing an Authentication System: a Dialogue in Four Scenes&quot; -- a pedagogical script in which an engineer named Athena designs her way step by step from &quot;users type their password to every server&quot; to &quot;users obtain time-limited tickets from a trusted third party&quot;. Bryant&apos;s dialogue is the most cited pre-protocol document about why Kerberos exists in the shape it does [@mit-dialogue]. The same month, Jennifer Steiner, Clifford Neuman, and Jeffrey Schiller presented &quot;Kerberos: An Authentication Service for Open Network Systems&quot; at the USENIX Winter Conference in Dallas [@cerias-steiner1988]. The protocol that paper described -- later called Kerberos version 4 -- carried forward to v5 with ASN.1 encoding, extensibility hooks, and pre-authentication, but the AS / TGS / AP message-triple skeleton it specified is unchanged thirty-eight years later.&lt;/p&gt;
&lt;p&gt;On January 24, 1989, MIT shipped the first public release of Kerberos v4 [@wiki-kerberos]. Five years later, in September 1993, the IETF adopted Kerberos v5 as RFC 1510 [@rfc1510]. RFC 1510 added ASN.1 encoding, cross-domain trust, and an extensibility hook called PA-DATA that every Kerberos extension since has used. In July 2005, RFC 4120 replaced RFC 1510 as the Kerberos v5 standard [@rfc4120].&lt;/p&gt;

sequenceDiagram
    participant C as Client
    participant AS as Authentication Service
    participant TGS as Ticket-Granting Service
    participant S as Application Server
    C-&amp;gt;&amp;gt;AS: AS-REQ: identify yourself
    AS-&amp;gt;&amp;gt;C: AS-REP TGT encrypted to TGS, session key wrapped under client long-term key
    C-&amp;gt;&amp;gt;TGS: TGS-REQ: present TGT, ask for service ticket
    TGS-&amp;gt;&amp;gt;C: TGS-REP service ticket encrypted to S, session key wrapped under TGT session key
    C-&amp;gt;&amp;gt;S: AP-REQ: present service ticket
    S-&amp;gt;&amp;gt;C: AP-REP: mutual auth confirmation
&lt;p&gt;Kerberos in 2026 is the same protocol as Kerberos in 1988, with thirty-three years of extensions piled on top. The skeleton you draw on a whiteboard for a graduate seminar is exactly the skeleton a Windows 11 24H2 machine throws at a 2025 domain controller. The interesting question is what those thirty-three years of extensions did to the inside of every message.The default maximum clock skew between client and KDC in Windows Kerberos is five minutes (300 seconds), set by Group Policy &quot;Maximum tolerance for computer clock synchronization&quot; and documented in [@ms-kerberos-overview]. The five-minute window is the residue of Denning and Sacco&apos;s 1981 timestamp fix.&lt;/p&gt;
&lt;h2&gt;3. The Wire in 2026: Six Messages and an Encryption Matrix&lt;/h2&gt;
&lt;p&gt;Every Kerberos textbook draws the same six-message diagram you saw in Section 2. The diagram has been unchanged since 1988. What is different in 2026 is everything inside the messages.&lt;/p&gt;
&lt;p&gt;Look first at the AS-REQ. In raw RFC 4120 the AS-REQ carries a &lt;code&gt;req-body&lt;/code&gt; (client name, target name, requested lifetime, requested enctypes) and an optional &lt;code&gt;padata&lt;/code&gt; field [@rfc4120]. That &lt;code&gt;padata&lt;/code&gt; slot is the load-bearing extensibility hook of the entire protocol. Every Kerberos enhancement since 1993 has been a new PA-DATA type: &lt;code&gt;PA-ENC-TIMESTAMP&lt;/code&gt; (the encrypted-timestamp pre-auth blob), &lt;code&gt;PA-PK-AS-REQ&lt;/code&gt; (PKINIT [@rfc4556]), &lt;code&gt;PA-FX-FAST-REQUEST&lt;/code&gt; (FAST armoring [@rfc6113]), &lt;code&gt;PA-AS-FRESHNESS&lt;/code&gt; (PKINIT freshness [@rfc8070]). The skeleton survives only because the joints are extensible.&lt;/p&gt;

A `SEQUENCE OF { padata-type, padata-value }` field in the Kerberos AS-REQ and AS-REP messages, introduced in RFC 1510 (1993) and carried forward unchanged into RFC 4120 §5.2.7 (2005). PA-DATA is the only protocol-level hook by which a Kerberos client can prove possession of a credential before the KDC issues a Ticket-Granting Ticket, and the only hook by which an enhancement like FAST or PKINIT can attach new behaviour to the AS exchange without breaking compatibility with older clients [@rfc4120].
&lt;p&gt;The AS-REP returns the TGT. The TGT itself is encrypted under the TGS&apos;s long-term key, so the client cannot inspect it. What the client &lt;em&gt;can&lt;/em&gt; inspect is the &lt;code&gt;EncTicketPart&lt;/code&gt; flag bitfield wrapped in the TGT envelope. RFC 4120 §2 enumerates the ticket-flag positions, including &lt;code&gt;forwardable&lt;/code&gt;, &lt;code&gt;proxiable&lt;/code&gt;, &lt;code&gt;postdated&lt;/code&gt;, &lt;code&gt;renewable&lt;/code&gt;, &lt;code&gt;initial&lt;/code&gt;, &lt;code&gt;pre-authent&lt;/code&gt;, &lt;code&gt;hw-authent&lt;/code&gt;, &lt;code&gt;transited-policy-checked&lt;/code&gt;, and &lt;code&gt;ok-as-delegate&lt;/code&gt; [@rfc4120]. (&lt;code&gt;may-postdate&lt;/code&gt; looks like a sibling but is a &lt;code&gt;KDCOptions&lt;/code&gt; request bit per RFC 4120 §5.4.1, not a &lt;code&gt;TicketFlags&lt;/code&gt; bit.) Pay attention to &lt;code&gt;forwardable&lt;/code&gt;. In 2020, Jake Karnes of NetSPI demonstrated that an attacker who knew a service account&apos;s long-term key could decrypt the S4U2Self output ticket, set &lt;code&gt;forwardable = 1&lt;/code&gt;, re-encrypt, and feed the ticket back to the KDC&apos;s S4U2Proxy step. The KDC accepted it. The bypass is CVE-2020-17049 and the attack is called Bronze Bit [@cve-2020-17049] [@netspi-bronze-bit].&lt;/p&gt;
&lt;p&gt;Inside the ticket&apos;s &lt;code&gt;AuthorizationData&lt;/code&gt; field is the Microsoft-specific construction that turns Kerberos into a Windows authorisation system. The Privilege Attribute Certificate, defined in [MS-PAC] revision 26.0 [@ms-pac-overview] [@ms-pac-deeplink], carries the user&apos;s SID, their group SIDs, their logon name, timestamps, and three cryptographic signatures: a Server signature, a KDC signature, and -- since CVE-2022-37967 in November 2022 -- a Full PAC Signature that covers the entire encoded PAC structure instead of just the existing signatures [@cve-2022-37967].&lt;/p&gt;

A Microsoft-specific authorization data element that the Kerberos KDC attaches to every ticket it issues for a Windows principal. The PAC carries the user&apos;s SID, group SIDs, logon name, and timestamps, and is signed by the KDC&apos;s `krbtgt` key and by the target service&apos;s key. The PAC, not the Kerberos ticket itself, is what gives a Windows file server the access-control information it needs to make a permission decision. Defined in [MS-PAC] [@ms-pac-overview].

The KB article URL ends in `cve-2022-37967` and the body text begins by referring to &quot;CVE-2022-37966&quot;. This is not a typo in the citation -- it is a Microsoft filing artefact. November 2022 Patch Tuesday paired two Kerberos CVEs: CVE-2022-37967 (Full PAC Signature, KrbtgtFullPacSignature) and CVE-2022-37966 (default session-key encryption type). KB5021131 covers the deployment of the encryption-type bypass side. A sibling article, KB5020805, covers the Full PAC Signature side. When citing KB5021131 alongside the Full PAC Signature, both CVE numbers are relevant [@ms-kb-5021131] [@cve-2022-37967].
&lt;p&gt;Then there is the encryption matrix. Kerberos abstracts ciphers behind the RFC 3961 framework [@rfc3961], which defines an enctype as a tuple of (encrypt, decrypt, checksum, string-to-key, key-derivation) functions. The history of Windows Kerberos is the history of which enctypes were the default at any given time.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Enctype&lt;/th&gt;
&lt;th&gt;Number&lt;/th&gt;
&lt;th&gt;Spec&lt;/th&gt;
&lt;th&gt;Status in 2026&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;DES-CBC-CRC&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;RFC 3961 [@rfc3961]&lt;/td&gt;
&lt;td&gt;Disabled by default since Server 2008 R2 [@ms-kile-227]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DES-CBC-MD5&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;RFC 3961 [@rfc3961]&lt;/td&gt;
&lt;td&gt;Disabled by default since Server 2008 R2 [@ms-kile-227]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RC4-HMAC&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;RFC 4757 [@rfc4757]&lt;/td&gt;
&lt;td&gt;Informational, not Standards Track; default-removed in mid-2026 per [@ms-beyond-rc4]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-128-CTS-HMAC-SHA1-96&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;RFC 3962 [@rfc3962]&lt;/td&gt;
&lt;td&gt;Default since Server 2008; cross-version compatible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-256-CTS-HMAC-SHA1-96&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;RFC 3962 [@rfc3962]&lt;/td&gt;
&lt;td&gt;Default since Server 2008; the mid-2026 destination&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-128-CTS-HMAC-SHA256-128&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;RFC 8009 [@rfc8009]&lt;/td&gt;
&lt;td&gt;Specified in [MS-KILE] bit K [@ms-kile-227]; no default-enable timeline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-256-CTS-HMAC-SHA384-192&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;RFC 8009 [@rfc8009]&lt;/td&gt;
&lt;td&gt;Specified in [MS-KILE] bit L [@ms-kile-227]; no default-enable timeline&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Enctype 23 is the row that built every Kerberoasting career. Kannan Jaganathan, Larry Zhu, and John Brezak of Microsoft published RFC 4757 in December 2006 [@rfc4757]. The IESG note on the RFC is unusually candid: the document is &lt;em&gt;Informational&lt;/em&gt;, not Standards Track, because RC4-HMAC &quot;do[es] not provide all the required operations in the Kerberos cryptography framework [RFC 3961]&quot; and because of &quot;security concerns with the use of RC4 and MD4&quot;. The choice that made enctype 23 dangerous, however, was upstream of the RFC. To make Windows 2000&apos;s Kerberos rollout backward-compatible with the existing SAM password database, Microsoft set the RC4-HMAC long-term Kerberos key equal to the &lt;em&gt;NT hash of the user&apos;s password&lt;/em&gt; -- the same hash NTLM was already storing. As Microsoft&apos;s own October 2024 Kerberoasting guidance puts it verbatim: &quot;RC4 is more susceptible to the cyberattack because it uses no salt or iterated hash when converting a password to an encryption key&quot; [@ms-kerberoasting-guidance].&lt;/p&gt;

The function that converts a typed password into a Kerberos long-term symmetric key. For RC4-HMAC (enctype 23), `s2k(password) = MD4(UTF-16-LE(password))` -- the NT hash, no salt, no iteration. For AES-CTS-HMAC-SHA1-96 (enctypes 17 and 18), `s2k(password, salt) = PBKDF2-HMAC-SHA1(password, salt, 4096, dklen)` followed by RFC 3962 post-processing into a 128- or 256-bit AES key. The salt is the concatenation of the Kerberos domain name and the user principal name [@rfc3962].
&lt;p&gt;The cryptography in that definition is short enough to read end-to-end. Here it is in JavaScript using the Web Crypto API:&lt;/p&gt;
&lt;p&gt;{`
async function kerberosStringToKey256(password, salt) {
  const enc = new TextEncoder();
  const passKey = await crypto.subtle.importKey(
    &quot;raw&quot;,
    enc.encode(password),
    { name: &quot;PBKDF2&quot; },
    false,
    [&quot;deriveBits&quot;]
  );
  const rawBits = await crypto.subtle.deriveBits(
    {
      name: &quot;PBKDF2&quot;,
      salt: enc.encode(salt),
      iterations: 4096,
      hash: &quot;SHA-1&quot;,
    },
    passKey,
    256
  );
  const hex = [...new Uint8Array(rawBits)]
    .map((b) =&amp;gt; b.toString(16).padStart(2, &quot;0&quot;))
    .join(&quot;&quot;);
  return hex;
}&lt;/p&gt;
&lt;p&gt;const password = &quot;Summer2026!&quot;;
const salt = &quot;CONTOSO.COMalice&quot;;
const keyHex = await kerberosStringToKey256(password, salt);
console.log(&quot;PBKDF2-HMAC-SHA1 output (truncated AES-256 key):&quot;, keyHex);
`}&lt;/p&gt;
&lt;p&gt;That 32-byte output is the value LSA stores when an account is configured with &lt;code&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; bit E set. When a Kerberoasting attacker steals the TGS-REP, what they crack offline is which password produces that key. The RFC 3962 post-processing -- a single round of &lt;code&gt;DK(key, &quot;kerberos&quot;)&lt;/code&gt; -- shapes the output to AES key length but does not slow the dictionary attack down. The dispositive defence is not in the cryptography; it is in the password (or, more precisely, in not having one at all -- the move to gMSA and dMSA replaces typed passwords with KDC-generated random secrets [@ms-gmsa] [@ms-dmsa]).
PBKDF2 at 4,096 iterations is well below modern PHC recommendations -- the 2023 OWASP guideline for PBKDF2-HMAC-SHA1 is 1.3 million iterations [@owasp-password-storage] -- but the 4,096 figure is wired into RFC 3962 and is the same on every supported Windows version. Service accounts using gMSA bypass this entirely: the gMSA&apos;s &quot;password&quot; is a 240-character random secret rotated every 30 days, derived by the Microsoft Key Distribution Service rather than entered by a human [@ms-gmsa].&lt;/p&gt;
&lt;p&gt;The wire in 2026 is therefore six messages and a matrix of seven enctypes. The protocol skeleton is forty years old. In 2014 a SANS instructor named Tim Medin gave a forty-five-minute talk that turned every one of those enctypes into a problem.&lt;/p&gt;
&lt;h2&gt;4. The Attack Cascade: 2014 to 2022&lt;/h2&gt;
&lt;p&gt;September 26-28, 2014. Louisville, Kentucky. DerbyCon 4. Talk slot T120. Tim Medin -- then at Counter Hack Challenges, also a SANS instructor -- walks on stage with a forty-five-minute talk titled &quot;Attacking Microsoft Kerberos: Kicking the Guard Dog of Hades&quot; [@irongeek-derbycon4]. The talk demonstrates that any authenticated domain user can request a TGS for any Service Principal Name in the directory, and that the service-portion of the returned ticket is encrypted under the SPN account&apos;s long-term key -- which, under RC4-HMAC enctype 23, is the NT hash of the password. Cracking the ciphertext is reduced to a dictionary attack against whatever password an admin set on the service account.&lt;/p&gt;
&lt;p&gt;That talk is the moment Kerberos becomes interesting to attackers. The next eight years play out as a cascade. Five generations, each one named after the canonical primitive that defined it, each one exposing a different structural property of the protocol, each one earning its own engineered Microsoft response years later.&lt;/p&gt;

A unique identifier for a service instance in Active Directory, written in the form `service-class/host:port/service-name` (for example `HTTP/web01.contoso.com`). Kerberos uses the SPN to look up which account holds the long-term key that decrypts the service ticket. Any account that has an SPN -- a user account that has had `setspn -A` run against it, every machine account in the directory, every gMSA -- is a candidate for Kerberoasting [@adsecurity-kerberoast].
&lt;h3&gt;Generation 1, 2014: Kerberoasting&lt;/h3&gt;
&lt;p&gt;Tim Medin&apos;s primitive [@irongeek-derbycon4]. Will Schroeder&apos;s PowerShell weaponisation as &lt;code&gt;Invoke-Kerberoast&lt;/code&gt; (later rolled into the C# Rubeus) [@ghostpack-rubeus]. Sean Metcalf&apos;s operational walkthrough on adsecurity.org [@adsecurity-kerberoast]. MITRE catalogued the technique in 2020 as ATT&amp;amp;CK T1558.003, which preserves the structural definition verbatim: &quot;Portions of these tickets may be encrypted with the RC4 algorithm, meaning the Kerberos 5 TGS-REP etype 23 hash of the service account associated with the SPN is used as the private key and is thus vulnerable to offline Brute Force attacks&quot; [@mitre-t1558-003].&lt;/p&gt;
&lt;p&gt;The structural insight is the part that matters. The TGS-REP is encrypted with the service account&apos;s &lt;em&gt;long-term&lt;/em&gt; password-derived key, so any domain user who can issue a TGS-REQ can mine ciphertext offline against any dictionary they care to assemble. The Kerberos protocol has no mechanism by which the KDC could tell whether the requesting user has any business asking for that SPN, because RFC 4120 has no concept of &quot;this service is for these users&quot;. Anyone with a TGT gets the service ticket.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s engineered response did not arrive until ten to twelve years later. Server 2012 introduced Group Managed Service Accounts: passwords randomised to 240 characters, derived by the Microsoft Key Distribution Service via &lt;code&gt;kdssvc.dll&lt;/code&gt;, rotated every 30 days, retrievable from a domain controller by member hosts that are explicitly authorised in &lt;code&gt;msDS-GroupMSAMembership&lt;/code&gt; [@ms-gmsa]. Server 2025 then introduced Delegated Managed Service Accounts (dMSA), which take the next structural step: the dMSA&apos;s secret is &quot;derived from the machine account credential&quot; held by the domain controller, and &quot;the secret can&apos;t be retrieved or found anywhere other than on the DC&quot; [@ms-dmsa]. The October 2024 Microsoft Security Blog formalised the Kerberoasting guidance in a single page that names RC4 as the load-bearing weakness and announces the deprecation [@ms-kerberoasting-guidance]. The December 2025 Beyond-RC4 announcement closed the cadence with a calendar date [@ms-beyond-rc4].&lt;/p&gt;
&lt;h3&gt;Generation 2, 2014-2017: Mimikatz Kerberos and AS-REP Roasting&lt;/h3&gt;
&lt;p&gt;Benjamin Delpy publishes &lt;code&gt;mimikatz&lt;/code&gt; 2.0 on April 6, 2014; the v2 banner inside the repository README reads verbatim &lt;code&gt;mimikatz 2.0 alpha (x86) release &quot;Kiwi en C&quot; (Apr 6 2014 22:02:03)&lt;/code&gt; [@mimikatz]. The Kerberos module contains two commands that define the era: &lt;code&gt;kerberos::golden&lt;/code&gt; (forge a TGT from the KRBTGT account&apos;s long-term key, granting Domain Admin equivalence indefinitely) and &lt;code&gt;kerberos::silver&lt;/code&gt; (forge a TGS from any service account&apos;s long-term key, granting impersonation of any user against that service).&lt;/p&gt;
&lt;p&gt;The structural insight: RFC 4120 has no online ticket validation [@rfc4120]. Once a ticket carries the right signatures, the service trusts it. Whoever holds a long-term key forges any ticket that key signs. Possession of a key collapses to ticket forgeability.&lt;/p&gt;
&lt;p&gt;Around 2017, the same team behind Rubeus publicises AS-REP Roasting [@ghostpack-rubeus]: the same offline-cracking primitive as Kerberoasting, but against any account whose &lt;code&gt;userAccountControl&lt;/code&gt; has &lt;code&gt;UF_DONT_REQUIRE_PREAUTH&lt;/code&gt; (the &lt;code&gt;DONT_REQ_PREAUTH&lt;/code&gt; flag) set. With pre-authentication disabled, the KDC will return an AS-REP encrypted under the user&apos;s password-derived key to &lt;em&gt;anyone&lt;/em&gt; who asks for it, no proof of password possession required. The dispositive Microsoft response was already in place: pre-authentication has been required by default for all new Active Directory accounts since Windows 2000, and the flag has to be deliberately cleared by an administrator. The remaining vulnerability is operational hygiene -- finding the handful of legacy accounts an organisation has left with pre-auth disabled.&lt;/p&gt;
&lt;h3&gt;Generation 3, 2018-2020: Delegation Abuse&lt;/h3&gt;
&lt;p&gt;Three primitives in three years.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SpoolSample / PrinterBug.&lt;/strong&gt; Lee Christensen (tifkin_, SpecterOps) published the PoC on GitHub on October 5, 2018 [@spoolsample]. The MS-RPRN remote-procedure-call interface includes a method, &lt;code&gt;RpcRemoteFindFirstPrinterChangeNotificationEx&lt;/code&gt;, that any authenticated user can invoke against any host&apos;s spooler service to ask the spooler to &lt;em&gt;please call back&lt;/em&gt; to an attacker-controlled address. The spooler obediently authenticates outbound using the machine account&apos;s credentials. Combined with unconstrained Kerberos delegation on the attacker-controlled host, the inbound authentication captures the target machine&apos;s TGT.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wagging the Dog (RBCD).&lt;/strong&gt; Elad Shamir&apos;s January 28, 2019 post on shenaniganslabs.io [@shenanigans-rbcd]. The TL;DR of the post is the load-bearing structural disclosure: &quot;Resource-based constrained delegation does not require a forwardable TGS when invoking S4U2Proxy. S4U2Self works on any account that has an SPN, regardless of the state of the TrustedToAuthForDelegation attribute. S4U2Proxy always produces a forwardable TGS, even if the provided additional TGS in the request was not forwardable. By default, any domain user can abuse the MachineAccountQuota to create a computer account and set an SPN for it, which makes it even more trivial to abuse resource-based constrained delegation to mimic protocol transition&quot; [@shenanigans-rbcd]. Every clause of that TL;DR points at a documented behaviour. The chain in this article&apos;s Hook is built directly on top.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bronze Bit.&lt;/strong&gt; Jake Karnes at NetSPI; CVE-2020-17049; disclosed November 10, 2020 [@netspi-bronze-bit] [@cve-2020-17049]. The NVD entry preserves Microsoft&apos;s verbatim description: &quot;A security feature bypass vulnerability exists in the way Key Distribution Center (KDC) determines if a service ticket can be used for delegation via Kerberos Constrained Delegation (KCD). To exploit the vulnerability, a compromised service that is configured to use KCD could tamper with a service ticket that is not valid for delegation to force the KDC to accept it&quot; [@cve-2020-17049]. The bypass: any service in possession of its own long-term key can decrypt the S4U2Self output ticket, flip the &lt;code&gt;forwardable&lt;/code&gt; bit in &lt;code&gt;EncTicketPart&lt;/code&gt;, and re-encrypt with the same key. Pre-2020 the KDC&apos;s S4U2Proxy validation accepted the resulting ticket because nothing on the ticket independently attested whether the &lt;code&gt;forwardable&lt;/code&gt; flag had been set by the KDC or by the service itself. Microsoft&apos;s November 10, 2020 fix, per the NVD entry verbatim, &quot;addresses this vulnerability by changing how the KDC validates service tickets used with KCD&quot; so that the tampered flag is rejected [@cve-2020-17049]. The PAC signatures, contra a common framing, were never meant to cover the &lt;code&gt;EncTicketPart&lt;/code&gt; flag bits in the first place.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s engineered responses: the November 2020 Bronze Bit patch [@cve-2020-17049] tightened the KDC&apos;s S4U2Proxy ticket-validation step; KB5008383 (November 2021) [@ms-kb-5008383] issued the canonical &quot;set &lt;code&gt;ms-DS-MachineAccountQuota = 0&lt;/code&gt; for non-administrator users&quot; guidance; LDAP signing and channel binding work, ongoing since the &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;NTLMless&lt;/a&gt; era, became the dispositive control against the relay variant of the chain.&lt;/p&gt;
&lt;h3&gt;Generation 4, 2021-2022: Certificate-Based Ticket Forgery and Kerberos Relay&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Certifried.&lt;/strong&gt; Oliver Lyak (ly4k) at IFCR disclosed CVE-2022-26923 to Microsoft, who patched on May 10, 2022 [@cve-2022-26923]. The attack exploited a quirk of how Active Directory Certificate Services (ADCS) bound a certificate&apos;s identity to an AD account when the certificate was used for PKINIT. Before the strong-mapping fix, AD&apos;s account-lookup at PKINIT time used the certificate&apos;s Subject Alternative Name (SAN) and matched the User Principal Name. If an attacker controlled a machine account, they could change the machine&apos;s &lt;code&gt;dNSHostName&lt;/code&gt; to match a domain controller&apos;s, request a certificate via the (overly-permissive) default &lt;code&gt;Machine&lt;/code&gt; template, and use the resulting certificate to PKINIT-authenticate to the KDC as that domain controller. Microsoft&apos;s response is documented end-to-end in KB5014754 [@ms-kb-5014754]: a new &quot;strong certificate mapping&quot; requirement that pins each issued certificate to a specific account SID via an X.509 extension (OID 1.3.6.1.4.1.311.25.2). The original release moved to Compatibility mode on May 10, 2022; full Enforcement mode took effect on February 11, 2025; Disabled-mode rollback was removed on April 11, 2023; the remaining Compatibility-mode fallback was removed on September 9, 2025 [@ms-kb-5014754].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KrbRelayUp.&lt;/strong&gt; Mor Davidovich (&lt;code&gt;Dec0ne&lt;/code&gt;), April 24, 2022 [@krbrelayup]. The README&apos;s universal-no-fix-LPE framing is preserved in the PullQuote below. The chain wraps &lt;code&gt;Powermad&lt;/code&gt; (machine account creation), &lt;code&gt;KrbRelay&lt;/code&gt; (Kerberos relay to LDAP), Rubeus (S4U2Self bypass of Protected Users, RBCD privilege addition), and &lt;code&gt;SCMUACBypass&lt;/code&gt; (a wrapper that uses the resulting ticket to open the local Service Control Manager and create a service running as &lt;code&gt;NT AUTHORITY\SYSTEM&lt;/code&gt;). The class of attack is &quot;Kerberos relay&quot; -- the post-NTLM cousin of NTLM-relay. The dispositive control is not a Kerberos patch; it is domain-wide LDAP signing plus channel binding plus Extended Protection for Authentication on ADCS Web Enrolment.&lt;/p&gt;

A universal no-fix local privilege escalation in windows domain environments where LDAP signing is not enforced (the default settings). -- Mor Davidovich, KrbRelayUp README, April 2022 [@krbrelayup]
&lt;h3&gt;Generation 5, 2022-2023: Forged-Ticket Sophistication&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Diamond Ticket.&lt;/strong&gt; Charlie Clark at Semperis co-authored a blog post in 2022 with Andrew Schwartz at TrustedSec disclosing the modern Diamond Ticket technique [@semperis-diamond] [@trustedsec-diamond]. The Semperis byline names the antecedent: a 2015 Black Hat EU presentation by Tal Be&apos;ery and Michael Cherny (&quot;Watching the Watchdog&quot;) that introduced the &quot;Diamond PAC&quot; idea. Verbatim from the Semperis post: &quot;Golden Ticket attacks take advantage of the ability to forge a ticket granting ticket (TGT) from scratch, Diamond Ticket attacks take advantage of the ability to decrypt and re-encrypt genuine TGTs requested from a domain controller (DC)&quot; [@semperis-diamond]. The structural insight is that a Diamond Ticket has a &lt;em&gt;legitimately issued, KDC-signed&lt;/em&gt; PAC at its base; only the privilege-claim fields inside the PAC are tampered. Before the November 2022 Full PAC Signature fix, the existing Server and KDC signatures only covered specific sub-structures, leaving room to modify the parts they did not sign.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sapphire Ticket.&lt;/strong&gt; Charlie Bromberg, also known online as &quot;Shutdown&quot;, at Synacktiv [@pgj11-diamond-sapphire] [@thehacker-recipes-sapphire]. The community wiki The Hacker Recipes, which Bromberg maintains, documents the Sapphire Ticket technique end-to-end at &lt;code&gt;thehacker.recipes/a-d/movement/kerberos/forged-tickets/sapphire&lt;/code&gt; [@thehacker-recipes-sapphire]. The verifiable third-party attribution lives at pgj11.com, which records verbatim: &quot;One brand new technique is Sapphire Ticket. Created by Charlie Shutdown (twitter.com/_nwodtuhs) this approach is more stealthy. You can create a TGT impersonating any user assembling real TGT and real PAC combining S4U2Self + U2U ... He extended Ticketer from Impacket to add this attack&quot; [@pgj11-diamond-sapphire]. The Sapphire Ticket bolts a &lt;em&gt;legitimately KDC-issued&lt;/em&gt; PAC (obtained by chaining the S4U2Self and User-to-User Kerberos extensions to request a service ticket &lt;em&gt;to oneself&lt;/em&gt; with the PAC of an arbitrary target user) onto a Diamond-style ticket. The result presents PAC signatures that the KDC itself produced. Unit 42&apos;s December 2022 &quot;Next-Gen Kerberos Attacks&quot; writeup is the secondary that joined Diamond and Sapphire into the same article and named them collectively the &quot;Precious Gemstones&quot; [@unit42-precious-gemstones].
Some secondary sources attribute Sapphire Ticket to Charlie Clark of Semperis. The misattribution probably stems from Clark&apos;s separate &quot;AS Requested STs&quot; post on the Semperis blog, which discusses a different technique exploiting unarmored machine-account AS-REQs and is not the Sapphire Ticket primary [@semperis-as-sts]. The verified Sapphire-Ticket originator is Charlie Bromberg (Shutdown, Synacktiv) per [@pgj11-diamond-sapphire].
The adsecurity.org URL &lt;code&gt;?p=2293&lt;/code&gt; is Sean Metcalf&apos;s &quot;Cracking Kerberos TGS Tickets Using Kerberoast -- Exploiting Kerberos to Compromise the Active Directory Domain&quot; (not Metcalf&apos;s separate KRBTGT-account post, which lives at a different URL). The page is the operational walkthrough that pairs with Tim Medin&apos;s 2014 DerbyCon disclosure [@adsecurity-kerberoast].&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s engineered response to both Diamond and Sapphire was CVE-2022-37967, the KrbtgtFullPacSignature [@cve-2022-37967] [@ms-kb-5021131]. It is the first PAC-handling protocol change since Windows 2000&apos;s introduction of the PAC. After full enforcement, the KDC adds a &lt;em&gt;Full PAC Signature&lt;/em&gt; that covers the entire encoded PAC, not just the existing sub-signatures. Diamond and Sapphire variants that modify any PAC field beyond what the Server and KDC sub-signatures already covered will fail validation.&lt;/p&gt;

The accounts most vulnerable to Kerberoasting are those with weak passwords and those that use weaker encryption algorithms, especially RC4. RC4 is more susceptible to the cyberattack because it uses no salt or iterated hash when converting a password to an encryption key, allowing the cyberthreat actor to guess more passwords quickly. -- Microsoft Security Blog, October 11, 2024 [@ms-kerberoasting-guidance]
&lt;h3&gt;The Spine Table&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Generation&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Primitive&lt;/th&gt;
&lt;th&gt;Structural Insight&lt;/th&gt;
&lt;th&gt;Microsoft Response&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2014&lt;/td&gt;
&lt;td&gt;Kerberoasting [@irongeek-derbycon4]&lt;/td&gt;
&lt;td&gt;TGS-REP is encrypted with the SPN account&apos;s long-term key; offline-crackable&lt;/td&gt;
&lt;td&gt;gMSA (2012) [@ms-gmsa]; dMSA (2025) [@ms-dmsa]; Beyond-RC4 (2025-2026) [@ms-beyond-rc4]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2014-2017&lt;/td&gt;
&lt;td&gt;Golden / Silver Ticket [@mimikatz]; AS-REP Roasting [@ghostpack-rubeus]&lt;/td&gt;
&lt;td&gt;RFC 4120 has no online ticket validation [@rfc4120]; long-term key = forge equivalence&lt;/td&gt;
&lt;td&gt;KrbtgtFullPacSignature (2022) [@cve-2022-37967]; preauth-required default since Windows 2000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;2018-2020&lt;/td&gt;
&lt;td&gt;SpoolSample [@spoolsample]; RBCD [@shenanigans-rbcd]; Bronze Bit [@cve-2020-17049]&lt;/td&gt;
&lt;td&gt;MS-RPRN coercion; S4U2Proxy always returns forwardable; pre-2020 KDC did not independently validate the EncTicketPart flags&lt;/td&gt;
&lt;td&gt;Bronze Bit patch (Nov 2020); KB5008383 MachineAccountQuota=0 (Nov 2021); LDAP signing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2022&lt;/td&gt;
&lt;td&gt;Certifried [@cve-2022-26923]; KrbRelayUp [@krbrelayup]&lt;/td&gt;
&lt;td&gt;ADCS template SAN-binding ambiguity; LDAP defaults unsigned&lt;/td&gt;
&lt;td&gt;KB5014754 strong-mapping [@ms-kb-5014754]; LDAP signing + EPA on /certsrv/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;2022&lt;/td&gt;
&lt;td&gt;Diamond [@semperis-diamond]; Sapphire [@pgj11-diamond-sapphire] [@unit42-precious-gemstones]&lt;/td&gt;
&lt;td&gt;PAC sub-signatures did not cover the encoded PAC structure&lt;/td&gt;
&lt;td&gt;KrbtgtFullPacSignature (CVE-2022-37967, Nov 2022) [@cve-2022-37967]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

timeline
    title Kerberos attack cascade
    section 2014
      Sep 2014 : Kerberoasting (Tim Medin, DerbyCon 4)
      Apr 2014 : Mimikatz 2.0 (Golden / Silver Tickets)
    section 2017
      2017 : AS-REP Roasting (Rubeus weaponisation)
    section 2018-2020
      Oct 2018 : SpoolSample (PrinterBug, Lee Christensen)
      Jan 2019 : Wagging the Dog / RBCD (Elad Shamir)
      Nov 2020 : Bronze Bit (Jake Karnes, NetSPI)
    section 2022
      Apr 2022 : KrbRelayUp (Mor Davidovich)
      May 2022 : Certifried (Oliver Lyak / ly4k)
      2022 : Diamond Ticket (Clark / Schwartz)
      2022 : Sapphire Ticket (Charlie Bromberg)
      Nov 2022 : KrbtgtFullPacSignature (Microsoft fix)
&lt;p&gt;Eight years. Eleven structural primitives. One protocol. By 2022 the cascade slowed, not because the protocol got better, but because every primitive a thirty-three-year-old design &lt;em&gt;could&lt;/em&gt; expose had been exposed. The 2022 Microsoft response, KrbtgtFullPacSignature, was the first one that targeted the &lt;em&gt;structural&lt;/em&gt; properties (PAC coverage of its own structure) rather than the per-primitive patches that defined the 2014-2020 era. To see why that was a turning point, it helps to see exactly what the defensive cadence looked like before then.&lt;/p&gt;
&lt;h2&gt;5. The Defensive Cadence Before 2023&lt;/h2&gt;
&lt;p&gt;Each of the eleven primitives in Section 4 shipped with a fix. By 2022 every named primitive &lt;em&gt;had&lt;/em&gt; a fix. And yet the cascade kept producing new primitives. Why?&lt;/p&gt;
&lt;p&gt;The answer is in the shape of the defensive controls. Walk them in chronological order.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Protected Users (Server 2012 R2, October 2013) [@ms-server-2012-r2].&lt;/strong&gt; A new security group that triggers five non-configurable client-side protections and four non-configurable domain-controller-side protections [@ms-protected-users]. The client side: CredSSP &quot;doesn&apos;t cache the user&apos;s plain text credentials&quot;; Windows Digest &quot;doesn&apos;t cache the user&apos;s plaintext credentials&quot;; &quot;NTLM stops caching the user&apos;s plaintext credentials or NT one-way function (NTOWF)&quot;; &quot;Kerberos stops creating Data Encryption Standard (DES) or RC4 keys ... or long-term keys after acquiring the initial Ticket Granting Ticket (TGT)&quot;; &quot;The system doesn&apos;t create a cached verifier at user sign-in or unlock&quot; [@ms-protected-users]. The domain-controller side, also verbatim: members &quot;cannot authenticate with NTLM authentication ... use DES or RC4 encryption types in Kerberos preauthentication ... delegate with unconstrained or constrained delegation ... renew Kerberos TGTs beyond their initial four-hour lifetime&quot; [@ms-protected-users]. The limit is the obvious one: Protected Users breaks every workflow that relied on delegation, RC4, or NTLM, and there are many such workflows still in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Authentication Policy Silos (Server 2012 R2).&lt;/strong&gt; A scope construct that lets administrators apply Protected-Users-equivalent constraints (no RC4, no unconstrained delegation, mandatory FAST) to tiered subsets of an organisation rather than per-account. The standard tier-zero / tier-one / tier-two split fits neatly under three silos [@ms-privileged-access].&lt;/p&gt;

A container of users, computers, and managed service accounts in Active Directory that scopes a single authentication policy. Members can be required to authenticate only from designated hosts, must use AES enctypes, may be excluded from delegation, and (when paired with FAST armoring) sign their AS-REQ inside a machine-account or anonymous-PKINIT armor. Available since Server 2012 R2; the operational granularity that Protected Users does not provide on its own [@ms-protected-users].
&lt;p&gt;&lt;strong&gt;Restricted Admin (2014) and Remote Credential Guard (2016) [@ms-remote-credential-guard].&lt;/strong&gt; The RDP-side companions that block credential exposure on the target host. Both work by changing what gets sent on the wire during a remote sign-in: Restricted Admin (Windows 8.1 / Server 2012 R2 era) uses the user&apos;s TGT to authenticate via Kerberos network logon, so no credentials reach the target; Remote Credential Guard (Windows 10 1607, August 2016) performs the same trick but for interactive sessions, redirecting CredSSP back to the originating workstation [@ms-remote-credential-guard].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Credential Guard (Windows 10 RTM, 2015) [@ms-credential-guard].&lt;/strong&gt; Virtualization-Based-Security-isolated LSASS: secrets that LSASS would otherwise hold in user-mode memory are moved into the LSAISO trustlet running in Virtual Trust Level 1. SYSTEM on the box cannot read VTL1 memory. Credential Guard is the ceiling against memory-side ticket and key theft, and is one of the cross-link points to the &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;NTLMless&lt;/a&gt; companion article.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FAST armoring (RFC 6113, April 2011).&lt;/strong&gt; Sam Hartman and Larry Zhu&apos;s &quot;A Generalized Framework for Kerberos Pre-Authentication&quot; defines the FAST (Flexible Authentication Secure Tunneling) channel [@rfc6113]. The AS-REQ is wrapped in an outer armor envelope, keyed under the machine account&apos;s TGT (for a domain-joined client), an anonymous PKINIT TGT (for a non-domain-joined client), or a compound identity. The armor envelope encrypts the PA-ENC-TIMESTAMP blob and authenticates the entire request, closing the offline-cracking path that targets the encrypted-timestamp pre-auth. The limit: FAST is client opt-in, not on by default, and Server 2012 R2 domain functional level is the floor for compound identity. Many production environments still do not require FAST on their tier-zero accounts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;gMSA (Server 2012).&lt;/strong&gt; The dispositive Kerberoasting defence for service accounts [@ms-gmsa]. The Microsoft Key Distribution Service (&lt;code&gt;kdssvc.dll&lt;/code&gt;) computes a 240-character random password, rotated every 30 days, and member hosts authorised in &lt;code&gt;msDS-GroupMSAMembership&lt;/code&gt; can retrieve it from a domain controller. The decisive property that gMSA closes is the human-typed-password assumption: there is no password to remember, write down, or share.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LDAP signing and channel binding.&lt;/strong&gt; The dispositive KrbRelayUp defence. Set &lt;code&gt;LDAPServerIntegrity = 2&lt;/code&gt; to require signing on every LDAP bind, and &lt;code&gt;LdapEnforceChannelBinding = 2&lt;/code&gt; to require channel binding on TLS-bound LDAP connections. Both are off by default in older domain functional levels, which is exactly the default the [@krbrelayup] README is targeting when it calls itself &quot;no-fix&quot;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KrbtgtFullPacSignature (November 2022).&lt;/strong&gt; The first PAC-handling protocol change since Windows 2000&apos;s introduction of the PAC. After full enforcement, every PAC carries an additional Full PAC Signature covering the entire encoded structure, not just sub-pieces; Diamond and Sapphire variants that previously evaded validation by tampering with un-covered fields now fail [@cve-2022-37967] [@ms-kb-5021131].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MachineAccountQuota = 0 guidance (KB5008383, November 2021) [@ms-kb-5008383].&lt;/strong&gt; The dispositive RBCD defence as a configuration: setting the directory-wide &lt;code&gt;ms-DS-MachineAccountQuota&lt;/code&gt; attribute on the domain root to zero prevents non-administrative users from creating computer accounts at all, which kills the first step of the chain in Section 1&apos;s Hook.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Each defensive control patches a primitive. No control patches the structural property of the protocol -- that any long-term symmetric key is forge-equivalent for every ticket type that key signs, and that the protocol&apos;s offline-validation guarantee makes online ticket revocation incompatible with the design.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Defence&lt;/th&gt;
&lt;th&gt;Target Primitive&lt;/th&gt;
&lt;th&gt;Structural Limit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Protected Users [@ms-protected-users]&lt;/td&gt;
&lt;td&gt;Pass-the-Hash, Pass-the-Ticket, RC4 pre-auth&lt;/td&gt;
&lt;td&gt;Breaks delegation, RC4, and NTLM; four-hour TGT cap may break legacy apps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication Policy Silo [@ms-protected-users]&lt;/td&gt;
&lt;td&gt;Per-tier scope of Protected-Users behaviour&lt;/td&gt;
&lt;td&gt;Requires Server 2012 R2 DFL; FAST armoring requires Server 2012 R2 too&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credential Guard&lt;/td&gt;
&lt;td&gt;LSASS memory theft (Mimikatz &lt;code&gt;sekurlsa::&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Does not prevent ticket theft via legitimate Kerberos APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FAST (RFC 6113) [@rfc6113]&lt;/td&gt;
&lt;td&gt;PA-ENC-TIMESTAMP offline cracking&lt;/td&gt;
&lt;td&gt;Client opt-in; not on by default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gMSA [@ms-gmsa]&lt;/td&gt;
&lt;td&gt;Kerberoasting on service accounts&lt;/td&gt;
&lt;td&gt;Human-managed service accounts unaffected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LDAP signing + channel binding&lt;/td&gt;
&lt;td&gt;KrbRelayUp [@krbrelayup]&lt;/td&gt;
&lt;td&gt;Off by default in older domains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KrbtgtFullPacSignature [@cve-2022-37967]&lt;/td&gt;
&lt;td&gt;Diamond and most Sapphire variants&lt;/td&gt;
&lt;td&gt;Does not stop Sapphire variants whose tampered PAC was issued legitimately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MachineAccountQuota = 0&lt;/td&gt;
&lt;td&gt;RBCD chain [@shenanigans-rbcd]&lt;/td&gt;
&lt;td&gt;Default value is &lt;code&gt;10&lt;/code&gt;; setting requires admin action&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Read the table the way an attacker reads it. Each row is necessary; no row is sufficient. The &quot;structural limit&quot; column is the next-attack catalogue. Protected Users does not stop a Diamond Ticket forged from a stolen KRBTGT key. Credential Guard does not stop the operator who has SYSTEM on a domain controller. FAST does not stop AS-REP Roasting (because AS-REP Roasting only happens on accounts with pre-auth disabled, where FAST is moot). gMSA does not protect a service account someone still manages manually with a Notes-saved password.&lt;/p&gt;
&lt;p&gt;The pattern is the answer to the section&apos;s opening question. Every control attacks one primitive -- a key, a flag, a coercion path, a ticket lifetime -- and none of them closes &lt;em&gt;the&lt;/em&gt; protocol-level structural property that any long-term symmetric key in the domain is forge-equivalent for any ticket type that key signs. By 2022 the engineering catalogue was complete. The 2023 announcement was the first plan that targeted the structure.&lt;/p&gt;
&lt;p&gt;What would a structural fix even look like, given that any &quot;online revocation&quot; change would also give up Kerberos&apos;s O(1) service-side validation, and given that any &quot;deprecate the long-term key&quot; change has to back-compat to clients that have not been touched since Server 2008? The October 2023 Palko post had answers.&lt;/p&gt;
&lt;h2&gt;6. The Breakthrough: Closing the Domainless Gap&lt;/h2&gt;
&lt;p&gt;October 11, 2023. Matthew Palko, Microsoft&apos;s Principal Group Product Manager for Windows authentication, publishes &quot;The evolution of Windows authentication&quot; on the Windows IT Pro Blog. The article&apos;s &lt;code&gt;&amp;lt;meta property=&quot;article:modified_time&quot;&amp;gt;&lt;/code&gt; reads &lt;code&gt;2023-11-11T01:30:49.108-08:00&lt;/code&gt; in the raw HTML; the description metadata reads &quot;Discover how we&apos;re securing authentication and reducing NTLM usage in Windows&quot; [@ms-palko-evolution]. It is the first time Microsoft commits publicly to deprecating NTLM, and the first time Microsoft names the three load-bearing engineering features that move Kerberos from &quot;domain-only&quot; to &quot;load-bearing-for-everything&quot;.&lt;/p&gt;
&lt;p&gt;The plan has four moving parts. Each one closes a specific reason that NTLM survived for thirty years.&lt;/p&gt;
&lt;h3&gt;IAKerb: Kerberos without KDC line-of-sight&lt;/h3&gt;
&lt;p&gt;The structural reason NTLM lived through Server 2003, Server 2008, Server 2012, and Server 2019 is that Windows had no Kerberos-equivalent path for the case where a client cannot reach a KDC. A laptop on a hotel network, a hybrid Azure-joined workstation that can reach the application server but not the AD DC, a workgroup machine attempting to access a domain file share -- all of those flowed back to NTLM by default, because Kerberos required a working AS-REQ to the domain controller before it could mint a TGT.&lt;/p&gt;
&lt;p&gt;IAKerb (Initial and Pass Through Authentication Using Kerberos V5 and the GSS-API) closes that gap. The draft IETF specification, draft-ietf-kitten-iakerb, is by Benjamin Kaduk, Jim Schaad, Larry Zhu, and Jeffrey E. Altman [@iakerb-draft]. The mechanism is GSS-API encapsulation: the client wraps each AS-REQ, AS-REP, TGS-REQ, and TGS-REP message inside a GSS-API token addressed to the application server, and the application server proxies the token to the KDC the server &lt;em&gt;can&lt;/em&gt; reach. From the client&apos;s perspective, it is talking to the application server; from the KDC&apos;s perspective, the AS exchange came from the application server. The protocol&apos;s verbatim problem statement reads: &quot;encapsulating the Kerberos messages inside GSS-API tokens. With these extensions a client can obtain Kerberos tickets for services where the KDC is not accessible to the client, but is accessible to the application server&quot; [@iakerb-draft].&lt;/p&gt;

Initial and Pass Through Authentication Using Kerberos V5 and the GSS-API. An extension to GSS-API Kerberos (RFC 4121) that encapsulates Kerberos AS / TGS exchanges inside GSS-API tokens between client and application server, so the application server can proxy them to a KDC the server can reach but the client cannot. Documented in the IETF draft `draft-ietf-kitten-iakerb` by Kaduk, Schaad, Zhu, and Altman [@iakerb-draft].

A Kerberos Key Distribution Center implemented as an in-process service inside the local Windows Security Authority (LSASS) on a workgroup or Azure-joined machine. The Local KDC issues tickets backed by the local SAM password database, exposing no Kerberos port to the network; clients reach it only through IAKerb encapsulation tunnelled through the application protocol. Closes the &quot;local account auth has no KDC&quot; gap that has kept NTLM alive for workgroups since Windows NT 3.1 [@ms-palko-evolution] [@fosdem-localkdc].
&lt;p&gt;MIT krb5 added IAKERB support fifteen years ago. The README for krb5-1.9, released December 22, 2010, says verbatim: &quot;Add support for IAKERB -- a mechanism for tunneling Kerberos KDC transactions over GSS-API, enabling clients to authenticate to services even when the clients cannot directly reach the KDC that serves the services&quot; [@mit-krb5-19-readme] [@mit-krb5-19-page]. The capability sat in MIT&apos;s mainline Kerberos for over a decade. Windows did not ship the equivalent because, until NTLM was on a deprecation path, Windows did not need it -- NTLM filled the line-of-sight gap. Once NTLM was on the road to removal, IAKerb stopped being optional.
The sixteen-year gap between MIT krb5-1.9 IAKERB (December 22, 2010) and Microsoft&apos;s planned H2 2026 broad enable is the cleanest evidence that Microsoft&apos;s NTLM deprecation is the &lt;em&gt;forcing function&lt;/em&gt; for the Kerberos refit, not a side effect. The specification was waiting for the customer demand to catch up.&lt;/p&gt;
&lt;h3&gt;Local KDC: Kerberos for the workgroup&lt;/h3&gt;
&lt;p&gt;The second structural reason NTLM survived was that Windows local accounts had no concept of &quot;domain&quot;. Without an AD domain, there was no KDC. Without a KDC, there were no Kerberos tickets. Local-account authentication therefore flowed through NT challenge-response (NTLMv2) by default.&lt;/p&gt;
&lt;p&gt;Local KDC closes this. The Local KDC, shipping in Windows 11 24H2 and Server 2025 with broad enablement targeted for H2 2026 [@ms-palko-evolution], is a Kerberos KDC built directly on top of the local SAM database. LSA derives an AES-256 long-term key from the local account&apos;s password rather than persisting the legacy RC4 NT hash. The Local KDC exposes no listening Kerberos port; clients reach it only through IAKerb encapsulation inside the application protocol (SMB, RDP, HTTP).&lt;/p&gt;
&lt;p&gt;The parallel open-source path was demonstrated by Alexander Bokovoy and Andreas Schneider at FOSDEM 2025, where they presented &quot;localkdc: A General Local Authentication Hub&quot; [@fosdem-localkdc]. The abstract reads verbatim: &quot;A local Kerberos Key Distribution Center (KDC) is not a new invention. It is a useful tool in combination with the Kerberos IAKerb extension but also allows to map SSO from a web authentication to local authentication or in a network environment isolated from the rest of the enterprise environment ... how use of NTLM in SMB protocol will be replaced by a localkdc in combination with IAKerb&quot; [@fosdem-localkdc]. Samba 4.21 carries the prototype implementation.&lt;/p&gt;

The Bokovoy / Schneider talk is the cleanest external evidence that Local KDC is a *protocol-level* architecture, not a Microsoft-proprietary one. Samba, Heimdal, MIT krb5, and Microsoft are converging on the same design: an in-process KDC, GSS-API-tunnelled Kerberos exchanges, AES-keyed local accounts. The IETF draft-ietf-kitten-iakerb specification [@iakerb-draft] is the shared standardisation layer.

Add support for IAKERB -- a mechanism for tunneling Kerberos KDC transactions over GSS-API, enabling clients to authenticate to services even when the clients cannot directly reach the KDC that serves the services. -- MIT krb5-1.9 release notes, December 22, 2010 [@mit-krb5-19-readme]
&lt;h3&gt;PKINIT and the freshness extension&lt;/h3&gt;
&lt;p&gt;The third gap NTLM filled was non-password credentials. Windows Hello for Business, smart cards, and Federal Information Processing Standard token logon all need to translate &quot;I hold this private key&quot; into &quot;I hold this Kerberos TGT&quot;. PKINIT (Public Key Cryptography for Initial Authentication in Kerberos), RFC 4556, by Larry Zhu (Microsoft) and Brian Tung (Aerospace Corporation), is the protocol for that [@rfc4556]. The AS-REQ carries a &lt;code&gt;PA-PK-AS-REQ&lt;/code&gt; PA-DATA element wrapping an &lt;code&gt;AuthPack&lt;/code&gt; CMS structure signed by the client&apos;s private key; the AS-REP carries the TGT keyed for the client to decrypt with either RSA key transport or Diffie-Hellman key exchange.&lt;/p&gt;
&lt;p&gt;The 2006 RFC 4556 PKINIT had a replay window: an attacker who recorded a &lt;code&gt;signedAuthPack&lt;/code&gt; could replay it indefinitely until the client&apos;s certificate expired. RFC 8070, &quot;PKINIT Freshness Extension,&quot; by Michiko Short, Seth Moore, and Peter Miller of Microsoft (February 2017) closed it [@rfc8070]. The AS-REP issues an opaque &lt;code&gt;PA-AS-FRESHNESS&lt;/code&gt; blob in a preliminary KDC-error round-trip; the client must echo the blob in its next signed AS-REQ; replays after the freshness window fail. Verbatim from RFC 8070 abstract: &quot;exchange an opaque data blob that a Key Distribution Center (KDC) can validate to ensure that the client is currently in possession of the private key during a PKINIT Authentication Service (AS) exchange&quot; [@rfc8070].&lt;/p&gt;
&lt;p&gt;Together, RFC 4556 plus RFC 8070 anchor every modern non-password Windows credential: Windows Hello for Business, smart-card logon, FIDO2 keys mediated by Windows Hello, and the upcoming Entra-issued cloud TGTs. The 2022 Certifried CVE [@cve-2022-26923] forced the &lt;em&gt;strong-mapping&lt;/em&gt; layer on top of all of this: every certificate used for PKINIT must carry an X.509 extension binding it to a specific AD account SID. KB5014754 [@ms-kb-5014754] tracks the rollout; see §4 for the full Compatibility / Enforcement / rollback-removal date sequence.&lt;/p&gt;
&lt;h3&gt;FAST armoring as default&lt;/h3&gt;
&lt;p&gt;The fourth gap was the trust assumption at the start of an AS-REQ: the encrypted-timestamp pre-auth blob, &lt;code&gt;PA-ENC-TIMESTAMP&lt;/code&gt;, is keyed under the client&apos;s password-derived key, which is offline-crackable on observation. FAST (RFC 6113) wraps the AS-REQ inside an armor envelope keyed under a separate key the attacker does not see [@rfc6113]. In a domain-joined client the armor key is derived from the machine account&apos;s TGT; in a non-domain-joined client it is derived from an anonymous PKINIT TGT; in a compound-identity scenario it is the combination of both.&lt;/p&gt;
&lt;p&gt;What changes in the 2023 plan is the &lt;em&gt;default-on&lt;/em&gt; posture: Authentication Policy Silos can now require FAST for every AS-REQ from a silo member, and Local KDC clients use anonymous PKINIT armoring out of the box because the SAM-derived long-term key is the only credential available and offline-crackability would be catastrophic.&lt;/p&gt;

sequenceDiagram
    participant C as Client (no KDC reach)
    participant S as Application Server
    participant KDC as KDC (reachable from S)
    C-&amp;gt;&amp;gt;S: GSS-API token: IAKerb (AS-REQ wrapper)
    S-&amp;gt;&amp;gt;KDC: AS-REQ (forwarded)
    KDC-&amp;gt;&amp;gt;S: AS-REP (forwarded)
    S-&amp;gt;&amp;gt;C: GSS-API token: IAKerb (AS-REP wrapper)
    C-&amp;gt;&amp;gt;S: GSS-API token: IAKerb (TGS-REQ wrapper)
    S-&amp;gt;&amp;gt;KDC: TGS-REQ (forwarded)
    KDC-&amp;gt;&amp;gt;S: TGS-REP (forwarded)
    S-&amp;gt;&amp;gt;C: GSS-API token: IAKerb (TGS-REP wrapper)
    C-&amp;gt;&amp;gt;S: AP-REQ presenting service ticket
    S-&amp;gt;&amp;gt;C: AP-REP -- session established
&lt;h3&gt;The Gap-to-Closure Mapping&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;NTLM-fallback gap&lt;/th&gt;
&lt;th&gt;Engineered closure&lt;/th&gt;
&lt;th&gt;Primary source&lt;/th&gt;
&lt;th&gt;Ship target&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Client has no KDC line-of-sight&lt;/td&gt;
&lt;td&gt;IAKerb GSS-API encapsulation&lt;/td&gt;
&lt;td&gt;[@iakerb-draft]&lt;/td&gt;
&lt;td&gt;Windows 11 24H2 / Server 2025; broad enable H2 2026 [@ms-palko-evolution]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local accounts have no domain KDC&lt;/td&gt;
&lt;td&gt;Local KDC on SAM + AES-256 derivation&lt;/td&gt;
&lt;td&gt;[@ms-palko-evolution] [@fosdem-localkdc]&lt;/td&gt;
&lt;td&gt;Windows 11 24H2 / Server 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Non-password credentials need an AS path&lt;/td&gt;
&lt;td&gt;PKINIT (RFC 4556) + Freshness (RFC 8070) + strong mapping (KB5014754)&lt;/td&gt;
&lt;td&gt;[@rfc4556] [@rfc8070] [@ms-kb-5014754]&lt;/td&gt;
&lt;td&gt;Enforcement February 11, 2025; Disabled mode removed April 2023; Compatibility mode removed Sept 9, 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AS-REQ pre-auth is offline-crackable&lt;/td&gt;
&lt;td&gt;FAST armoring (RFC 6113) default-on in silos&lt;/td&gt;
&lt;td&gt;[@rfc6113]&lt;/td&gt;
&lt;td&gt;Available since Server 2012 R2; default-on with new silos&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;After thirty-three years of layered extensions, Kerberos in 2026 is finally a single-protocol authentication path for every Windows scenario. Domain-joined, workgroup, Azure-joined without AD line-of-sight, local-account to local-account. The mechanism that closes the last gap -- IAKerb -- is a sixteen-year-old MIT protocol coming to Windows for the first time. What&apos;s left for Kerberos to fix is encryption-type hygiene, and a December 2025 Microsoft post named the calendar dates for that too.&lt;/p&gt;
&lt;h2&gt;7. The Beyond-RC4 Cadence&lt;/h2&gt;
&lt;p&gt;December 3, 2025. The Microsoft Windows Server Blog publishes &quot;Beyond RC4 for Windows authentication&quot; [@ms-beyond-rc4]. The post is short and specific. Verbatim: &quot;By mid-2026, we will be updating the domain controller default assumed supported encryption types. The assumed supported encryption types is applied to service accounts that do not have an explicit configuration defined. Secure Windows authentication does not require RC4; AES-SHA1 can be used across all supported Windows versions since it was introduced in Windows Server 2008&quot; [@ms-beyond-rc4]. For the first time in twenty years, RC4-HMAC is on a removal cadence with a calendar date and an enforcement CVE.&lt;/p&gt;
&lt;p&gt;The rollout has three phases.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 1, January 2026, audit only.&lt;/strong&gt; Domain controllers gain new fields in Event ID 4768 (TGT issued) and Event ID 4769 (TGS issued): &lt;code&gt;msDS-SupportedEncryptionTypes&lt;/code&gt;, &lt;code&gt;Available Keys&lt;/code&gt;, and &lt;code&gt;Session Encryption Type&lt;/code&gt;. The fields tell an administrator, for each ticket issued, which enctypes the requesting account had configured and which one the KDC actually chose. Two new PowerShell auditing scripts ship in the &lt;code&gt;microsoft/Kerberos-Crypto&lt;/code&gt; GitHub repository: &lt;code&gt;List-AccountKeys.ps1&lt;/code&gt; enumerates every account and the enctype configuration on each; &lt;code&gt;Get-KerbEncryptionUsage.ps1&lt;/code&gt; parses the 4768 / 4769 log stream and prints accounts still requesting or being issued RC4 tickets [@ms-beyond-rc4]. Verbatim from the post: &quot;we have enhanced existing information within the Security Event Log and developed new PowerShell auditing scripts. These enhancements are available in Windows Server versions 2019, 2022, and 2025&quot; [@ms-beyond-rc4].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 2, April 2026, default flip.&lt;/strong&gt; The &quot;assumed&quot; &lt;code&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; on accounts that have no explicit setting changes from &quot;anything the client asks for, including RC4&quot; to &quot;AES-SHA1 only&quot;. AES-SHA1 (RFC 3962 enctypes 17 and 18) has shipped on every supported Windows version since Server 2008 [@rfc3962], so the flip is theoretically backward-compatible with every domain-joined client; in practice the casualties are third-party Kerberos clients (legacy Linux MIT krb5 with RC4-only keytabs, network-attached-storage appliances stuck on older krb5 libraries, SQL Server linked servers with manually-configured service-principal RC4 entries).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 3, mid-2026, enforcement.&lt;/strong&gt; RC4 tickets require explicit per-account opt-in. The enforcement boundary is &lt;em&gt;CVE-2026-20833&lt;/em&gt;, called out by name in the Microsoft post [@ms-beyond-rc4]. After that date, an account that has not had &lt;code&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; explicitly written to include &lt;code&gt;0x4&lt;/code&gt; (RC4) will not be issued RC4 tickets, and DCs will reject any TGS-REQ that asks for one against an account configured AES-only.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The mid-2026 RC4-default removal is gated on CVE-2026-20833, named in the December 2025 &quot;Beyond RC4&quot; post as the enforcement boundary [@ms-beyond-rc4]. The audit window closes when this date lands. Production environments that have not migrated their service accounts to gMSA or explicitly set &lt;code&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; will find Kerberos authentication failing for those accounts the day Phase 3 ships.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The interesting question is why the migration destination is AES-SHA1 (enctypes 17 and 18) and not AES-SHA2 (enctypes 19 and 20). RFC 8009 specifies AES-SHA2 [@rfc8009]; Microsoft&apos;s &lt;code&gt;[MS-KILE]&lt;/code&gt; §2.2.7 supported-encryption-types bit table includes bits K (&lt;code&gt;AES128-CTS-HMAC-SHA256-128&lt;/code&gt;) and L (&lt;code&gt;AES256-CTS-HMAC-SHA384-192&lt;/code&gt;) [@ms-kile-227]. Linux MIT krb5 has shipped RFC 8009 since version 1.15 (December 2016) [@mit-krb5-115]. Cross-domain interoperability between AES-SHA2 Windows and AES-SHA2 MIT works. The remaining work is purely Microsoft-side default enablement and the auditing infrastructure analogous to the RC4 cadence.&lt;/p&gt;
&lt;p&gt;The Beyond-RC4 post does not name an AES-SHA1 -&amp;gt; AES-SHA2 timeline at all. The audit-default-enforce cadence Microsoft has now demonstrated for RC4 -- audit instrumentation in event logs, default flip with backward-compatible enctypes, enforcement gated by a named CVE -- has no announced analogue for AES-SHA1 yet.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The cadence Microsoft has is audit, default, enforce. The RC4 to AES-SHA1 transition has all three: audit instrumentation in Phase 1, the default flip in Phase 2, and named enforcement via CVE-2026-20833 in Phase 3. The AES-SHA1 to AES-SHA2 transition has none. The [MS-KILE] bits exist; the cross-domain interoperability works; the Microsoft-side rollout is the missing piece.
The &lt;code&gt;microsoft/Kerberos-Crypto&lt;/code&gt; GitHub repository ships the two PowerShell auditing scripts (&lt;code&gt;List-AccountKeys.ps1&lt;/code&gt;, &lt;code&gt;Get-KerbEncryptionUsage.ps1&lt;/code&gt;) that the December 2025 post names as the Phase 1 instrumentation. They are the right tools for an administrator who wants to find their RC4-dependent service accounts before the audit window closes mid-2026 [@ms-beyond-rc4].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Mid-2026 is the audit-window-closes date. The question for every AD operator is &lt;em&gt;which&lt;/em&gt; of their service accounts will still be requesting RC4 tickets when the default flips, and whether their detection tooling sees them in the window. Two quarters from now, the answer &quot;we&apos;ll just turn RC4 off and see what breaks&quot; stops being a defensible operating posture.&lt;/p&gt;

timeline
    title Beyond-RC4 rollout
    section Phase 1 -- Audit
      Jan 2026 : Event 4768 / 4769 fields msDS-SupportedEncryptionTypes Available Keys Session Encryption Type
      Jan 2026 : Kerberos-Crypto GitHub repo with List-AccountKeys.ps1 and Get-KerbEncryptionUsage.ps1
    section Phase 2 -- Default flip
      Apr 2026 : Assumed msDS-SupportedEncryptionTypes flips to AES-SHA1-only for accounts without explicit configuration
    section Phase 3 -- Enforcement
      Mid 2026 : CVE-2026-20833 enforcement boundary -- RC4 tickets require explicit per-account opt-in
&lt;h2&gt;8. What Removing NTLM Cannot Buy You&lt;/h2&gt;
&lt;p&gt;After everything in Section 6 and Section 7 ships, Kerberos in 2026 is still vulnerable to four classes of attack. None of them are protocol bugs; all of them are protocol &lt;em&gt;structure&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kerberos has its own relay class.&lt;/strong&gt; The KrbRelayUp README explicitly scopes itself to Windows domain environments where LDAP signing is not enforced -- the post-NTLM cousin of NTLM-relay [@krbrelayup]. The relay primitive survives the move from NTLM to Kerberos because the attack does not target the authentication protocol -- it targets the LDAP protocol&apos;s lack of mandatory integrity, and any authenticated bind (Kerberos or NTLM) is fair game once the channel is unsigned. The dispositive control is LDAP signing plus channel binding domain-wide, plus Extended Protection for Authentication on every AD CS Web Enrolment endpoint. It is a configuration, not a protocol fix. The &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;NTLMless&lt;/a&gt; companion article walks through the LDAP-side work in detail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The long-term-key problem is intrinsic to symmetric Kerberos.&lt;/strong&gt; Whoever holds the &lt;code&gt;krbtgt&lt;/code&gt; account&apos;s long-term key forges any TGT (the Golden Ticket primitive). Whoever holds an SPN account&apos;s long-term key forges any TGS for that service (the Silver Ticket primitive). RFC 4120&apos;s offline-validation property [@rfc4120] &lt;em&gt;requires&lt;/em&gt; that the service trust the key alone -- the AP-REQ contains no callback to the KDC; the service decrypts the ticket, validates the signatures, and decides. Any change that adds an online &quot;is this ticket still valid?&quot; check also gives up Kerberos&apos;s O(1) service-side scaling and the offline-validation guarantee that makes the protocol cheap. Authentication Policy Silos, Protected Users, TPM-backed credentials, and Credential Guard all raise the cost of obtaining the key; they do not close the forge-equivalence property. Mathematically, if you have the key, you are the principal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The PAC is a signed vouching token, not a verified live query.&lt;/strong&gt; KrbtgtFullPacSignature [@cve-2022-37967] closes the &lt;em&gt;modification&lt;/em&gt; side of Diamond and Sapphire. It does not close the &lt;em&gt;staleness&lt;/em&gt; side. A user removed from &lt;code&gt;Domain Admins&lt;/code&gt; at 09:00 still presents service tickets attesting Domain Admin membership until the ticket expires (default 10 hours user TGT, 7 days renewable; Protected Users members are capped at 4 hours [@ms-protected-users]). The PAC vouching window is the residual stale-authorization gap. The defender&apos;s option is shorter ticket lifetimes or out-of-band ACL flips at the service tier; the protocol itself has no callback by which a service learns about a group-membership change before the ticket expires.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Domainless does not mean keyless.&lt;/strong&gt; Local KDC binds the SAM password to an AES-256 long-term key. The wire form of pass-the-hash is gone: there is no NT hash on the line, no &lt;code&gt;LMv2&lt;/code&gt; challenge response, no DES-CBC-MD5 keytab. But a &lt;code&gt;NT AUTHORITY\SYSTEM&lt;/code&gt;-level attacker on the box still recovers the AES key, because LSA must materialise that key in user-mode memory to hand it to Kerberos. The chip- and VBS-based countermeasures (TPM-backed credentials, Microsoft Pluton, Credential Guard) remain orthogonal and necessary; none of them is replaced by Local KDC.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; H2 2026 ships Kerberos as the load-bearing single authentication protocol; it does not ship a Kerberos in which (1) the Kerberos-relay class is closed, (2) long-term-key forge-equivalence is closed, (3) PAC staleness is closed, or (4) local-key recovery from a SYSTEM-level attacker on the box is closed. The arc is a transition between tradeoffs, not out of them.&lt;/p&gt;
&lt;/blockquote&gt;

The Phase-3-as-transition-between-tradeoffs framing is mirrored in the [NTLMless](/blog/ntlmless-the-death-of-ntlm-in-windows/) companion article&apos;s Section 8 -- the symmetric framing is deliberate. Read the two articles together as a paired diagnosis: NTLMless is the eulogy and the migration story; this article is the inheritance and the to-do list.
&lt;h2&gt;9. Open Problems and the 2026-2027 Edge&lt;/h2&gt;
&lt;p&gt;Five problems sit on the May-2026 research agenda. None has a shipping Microsoft answer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The AES-SHA1 to AES-SHA2 Windows-default timeline.&lt;/strong&gt; RFC 8009 [@rfc8009] is nine years old. The &lt;code&gt;[MS-KILE]&lt;/code&gt; §2.2.7 supported-encryption-types bit table already includes the AES-SHA2 bits K and L [@ms-kile-227]. Linux MIT krb5 shipped RFC 8009 in version 1.15 (December 2016) [@mit-krb5-115]. Cross-domain Kerberos interop between MIT clients and Windows DCs over AES-SHA2 works in the laboratory. What is missing is a Microsoft-side equivalent of the audit / default / enforce cadence already in place for the RC4 transition, especially because the hard part is not the cryptography but the long tail of third-party Kerberos clients and pre-2017 keytabs that an AES-SHA2 audit would have to enumerate before the default can flip. The 8009 cadence is the largest Windows-side cryptographic gap that has no announcement.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Quantum risk.&lt;/strong&gt; Kerberos symmetric primitives (AES-128 and AES-256) retain a Grover-bound effective security margin of 64 and 128 bits respectively, which is durable against the near-term cryptographically-relevant quantum computer. PKINIT is the exposed half: the CMS signature chains in &lt;code&gt;AuthPack&lt;/code&gt; are RSA or ECDSA per RFC 4556 §3.2 [@rfc4556], and both are broken by Shor&apos;s algorithm. Anonymous PKINIT, used for FAST armoring on non-domain-joined clients, has the same exposure. Microsoft has not announced a PKINIT-specific post-quantum cryptography plan; the Kerberos team&apos;s standardisation tracking sits on the IETF kitten working group&apos;s queue rather than on a shipping Windows roadmap. Cross-link to the post-quantum cryptography sibling article in this series.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;dMSA field-deployment maturity.&lt;/strong&gt; Server 2025 introduced Delegated Managed Service Accounts as the successor to gMSA [@ms-dmsa]. The protocol-level differences -- &quot;Authentication for dMSA is linked to the device identity ... dMSA uses a randomized secret (derived from the machine account credential) that is held by the Domain Controller (DC) to encrypt tickets&quot; -- close several gMSA gaps, including the multi-tenant-key problem. But the 14-day account-migration window, the four-ticket-lifetime startup state during which both the legacy account and the dMSA can authenticate, and the cross-domain plus cross-forest behaviours are still being shaken out in field deployments. As of the May 2026 reading, dMSA is shipping but not yet the default for new service accounts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cross-cloud Kerberos.&lt;/strong&gt; Kerberos Cloud Trust for Windows Hello for Business is the architectural piece that lets an Azure-joined laptop obtain TGTs from Entra ID rather than from an on-premises DC, with the on-premises DC trusting Entra&apos;s signatures via federation. Per [@ms-palko-evolution] the architecture is planned but unproven in the field at scale. The role of Local KDC in pure-Entra (no AD on-prem) deployments is still being defined. The trust graph for &quot;Local KDC + Entra ID + on-premises AD&quot; is one of the open architectural problems the Palko post mentions but does not yet detail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open-source IAKerb and Local KDC.&lt;/strong&gt; Samba&apos;s &lt;code&gt;localkdc&lt;/code&gt; work, demonstrated by Alexander Bokovoy and Andreas Schneider at FOSDEM 2025 [@fosdem-localkdc], is the most public open-source mirror of Microsoft&apos;s Local KDC plan. Heimdal has a partial implementation. MIT krb5 IAKERB has been shipping since krb5-1.9 on December 22, 2010 [@mit-krb5-19-readme] and is mature. The Local-KDC-on-the-SAM pattern is new to the Windows world specifically; in the open-source world the equivalent (a Kerberos KDC fed from a local user database) has existed in textbooks since Kerberos v4.&lt;/p&gt;
&lt;p&gt;Each of the five problems is a residual. Each is the next decade&apos;s research. None of them invalidates the Phase 3 shipping commitment. The article&apos;s load-bearing closing claim is honest about that: H2 2026 is a &lt;em&gt;transition&lt;/em&gt;, and what comes next will be its own multi-year cadence.&lt;/p&gt;
&lt;h2&gt;10. What an AD Engineer Should Do This Quarter&lt;/h2&gt;
&lt;p&gt;If you read nothing else from this article, read this. Seven controls; each one is tied to one primary Microsoft Learn or MSRC URL; each one closes one of the attack primitives in Section 4. Cross-link to the parallel practical-guide section in the &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;NTLMless&lt;/a&gt; companion article.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Run the two PowerShell scripts in &lt;code&gt;microsoft/Kerberos-Crypto&lt;/code&gt;: &lt;code&gt;List-AccountKeys.ps1&lt;/code&gt; enumerates every account&apos;s configured enctypes; &lt;code&gt;Get-KerbEncryptionUsage.ps1&lt;/code&gt; parses your Event 4768 / 4769 stream and lists accounts still requesting or being issued RC4 tickets. The audit window closes mid-2026 when Phase 2 flips the default [@ms-beyond-rc4]. Every account on the list above is a Phase-3 production incident if you do nothing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Do not rely on the mid-2026 default flip. Explicitly write &lt;code&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; with the value &lt;code&gt;0x18&lt;/code&gt; (AES-128 + AES-256, no RC4) on every service account that does not have a documented RC4 dependency. For service accounts that do, write &lt;code&gt;0x1C&lt;/code&gt; (AES-128 + AES-256 + RC4) and put a calendar reminder against the RC4 dependency so it gets remediated before Phase 3 [@ms-beyond-rc4].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Manually-managed service-account passwords are the Kerberoasting attack surface per [@ms-kerberoasting-guidance]. gMSA gives you 240-character KDS-derived passwords rotated every 30 days [@ms-gmsa]. dMSA on Server 2025 binds the account secret to the device identity and stores it only on the domain controller, where it can be further protected by Credential Guard [@ms-dmsa]. There is no service-account workflow gMSA or dMSA does not cover; the migration is operational, not architectural.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Setting &lt;code&gt;ms-DS-MachineAccountQuota&lt;/code&gt; on the domain root to zero kills the first step of the RBCD chain in Section 1 [@shenanigans-rbcd] and the KrbRelayUp chain [@krbrelayup]. The default value of 10 has been the de facto attack-surface enabler since Windows 2000. The control is one PowerShell line: &lt;code&gt;Set-ADDomain -Identity (Get-ADDomain) -Replace @&amp;amp;#123;&apos;ms-DS-MachineAccountQuota&apos;=0&amp;amp;#125;&lt;/code&gt;. The breakage surface is small: only legitimate computer-account bootstrap workflows that today rely on user-driven &lt;code&gt;djoin.exe&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Protected Users gives every member the five non-configurable client protections plus the 4-hour TGT cap [@ms-protected-users]. Wrap an Authentication Policy Silo around the same population to add mandatory FAST armoring [@rfc6113] and per-silo logon-from constraints. Both controls have been available since Server 2012 R2; the operational reason most environments still have not adopted them is the breakage in legacy delegation workflows. Audit and remediate those workflows; do not skip Protected Users.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Set &lt;code&gt;LDAPServerIntegrity = 2&lt;/code&gt; (require signing) and &lt;code&gt;LdapEnforceChannelBinding = 2&lt;/code&gt; (require channel binding on TLS-bound connections) via Group Policy. This is the dispositive KrbRelayUp defence [@krbrelayup] and the dispositive defence against any Kerberos-relay-class attack that targets the LDAP control plane. Pair with Extended Protection for Authentication on every AD CS Web Enrolment endpoint to close the Certifried-style certificate-issuance variant [@ms-kb-5014754].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Flight the &lt;code&gt;RC4DefaultDisablementPhase&lt;/code&gt; Group Policy setting in your Insider channel; pilot non-production AES-only configurations on a representative subset of service accounts; identify legacy NAS appliances, Linux MIT krb5 clients with keytabs older than 2017, and SQL Server linked-server SPNs before Phase 2 closes the audit window [@ms-beyond-rc4]. Phase 3 ships with CVE-2026-20833; production environments that have not run the audit will discover the dependency list the day enforcement lands.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Three quarters from now (mid-2026), every default in this list will have changed. Do the work in the audit window or do it in the post-flip ticket queue. The cost of an audit-window migration is a quarter of engineering time; the cost of a post-flip remediation is a sixty-minute outage on every undocumented RC4 dependency the directory holds. Cross-link to the &lt;a href=&quot;https://paragmali.com/blog/pluton-a-tpm-on-silicon-microsoft-can-patch/&quot; rel=&quot;noopener&quot;&gt;Pluton&lt;/a&gt;, TPM, and Credential Guard sibling articles for the hardware-backing layer that protects the long-term keys these controls assume.&lt;/p&gt;
&lt;h2&gt;11. Frequently Asked Questions&lt;/h2&gt;

AES-SHA1 (RFC 3962 enctypes 17 and 18) is enough against the 2026 attack picture: there is no known cryptographic attack against AES-256-CTS-HMAC-SHA1-96 within Kerberos&apos;s threat model, and AES eliminates the salt-less / iteration-less Kerberoasting weakness of RC4-HMAC [@rfc3962] [@ms-kerberoasting-guidance]. AES-SHA2 (RFC 8009 enctypes 19 and 20) is the obvious next step and is supported by [MS-KILE] bits K and L [@ms-kile-227]. Quantum threats are not the immediate worry for symmetric Kerberos; the exposed surface is PKINIT, not the ticket cipher.The Grover speedup applied to AES-256 leaves an effective 128-bit security margin, which is durable for the lifetime of any current cryptographic system [@nist-pqc].

Yes, for delegation, and that is the point. Per [@ms-protected-users], members cannot use unconstrained or constrained delegation, cannot use DES or RC4 in Kerberos pre-auth, and have their TGT capped at four hours. Workflows that today rely on a domain admin&apos;s TGT being forwardable to a downstream service must be reworked. Use Authentication Policy Silos for the per-account scope where some delegation must remain.

Yes, with risk. The mid-2026 enforcement boundary CVE-2026-20833 [@ms-beyond-rc4] is the formal cutover. Disabling RC4 today by setting `msDS-SupportedEncryptionTypes` to `0x18` (AES-only) on accounts will work, but expect breakage from Linux clients with MIT krb5 keytabs older than 2017, network-attached-storage appliances with hard-coded RC4 entries, and SQL Server linked-server SPNs that have not been updated. The audit-then-migrate cadence in Section 10 is the operationally honest path.

No. It kills *unsigned-PAC* Golden Tickets and most Diamond and Sapphire variants that tampered with PAC fields outside the original sub-signatures [@cve-2022-37967]. If an attacker has the actual `krbtgt` long-term key, they still mint correctly-signed tickets -- the Full PAC Signature is computed with that same key. The defence is rapid `krbtgt` rotation (the dual-password scheme means you must rotate twice with an interval) plus Credential Guard to keep the key out of LSASS user-mode memory.

PKINIT [@rfc4556] exists, Active Directory Certificate Services exists, Windows Hello for Business is built on top of PKINIT. The reason &quot;everywhere&quot; was hard is Certifried (CVE-2022-26923) [@cve-2022-26923] and the strong-mapping retrofit [@ms-kb-5014754]: the original ADCS templates allowed a certificate&apos;s Subject Alternative Name to be set independently of the AD account that requested the certificate, which let an attacker mint a certificate claiming to be a domain controller. Strong mapping (the SID-binding X.509 extension) closed that, but the rollout took years to land in Enforcement mode (see §4 for the full date sequence).

It eliminates the *wire* form. There is no NT hash on the LSA-to-Local-KDC path; the long-term key is an AES-256 derivation. A SYSTEM-level attacker on the box still recovers that AES key, because LSA must hold it in user-mode memory to hand to the Kerberos SSP. The chip-side defences (TPM, Microsoft Pluton, Credential Guard) remain orthogonal and necessary per [@fosdem-localkdc]. Local KDC closes the relay-from-the-wire class, not the SYSTEM-on-the-box class.

Kerberos Cloud Trust for Windows Hello for Business issues TGTs from Entra ID and federates trust back to on-premises AD, so an Entra-joined laptop can present a domain-trusted Kerberos ticket to a file server it has never directly authenticated to. The on-premises KDC role is partially federated; the on-prem AD signs nothing for the Entra-issued TGT but trusts Entra&apos;s signature via Cloud Trust. Per [@ms-palko-evolution] the architecture is shipping in stages. The full story is its own article in this series.

Not in this decade. The architectural trajectory is &quot;Kerberos + PKINIT + FAST + Local KDC + IAKerb + Authentication Policy Silos + TPM-backed long-term keys&quot; -- not a replacement protocol. The closest thing to a replacement on the horizon is post-quantum PKINIT, which is more of a re-cipher than a re-protocol. The Kerberos message triple (AS-REQ, TGS-REQ, AP-REQ) is genuinely durable.Compared with the 28-year deprecation cycle NTLM took, replacing Kerberos would be a thirty-year project on the same precedent. Microsoft&apos;s stated direction is to harden the joints, not to throw out the skeleton.

The commands below assume Server 2019 or later with the `microsoft/Kerberos-Crypto` repo cloned locally. Run on a domain controller; output names every account whose configured `msDS-SupportedEncryptionTypes` allows RC4 or has no explicit setting (in which case it inherits the pre-Phase-2 default of &quot;anything goes&quot;). Cross-reference with the 4768 / 4769 audit stream from `Get-KerbEncryptionUsage.ps1` to identify which of those accounts is actually being issued RC4 tickets in practice.&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;# Enumerate accounts and configured enctypes
Import-Module ActiveDirectory
.\List-AccountKeys.ps1 -OutputCsv accounts.csv

# Parse 4768 / 4769 events for issued ticket enctypes
.\Get-KerbEncryptionUsage.ps1 -LookbackDays 30 -OutputCsv tickets.csv

# Join the two on account name -- the accounts that
# both have RC4-allowed AND were issued RC4 tickets
# are your Phase 3 incident list.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;kerberos-in-windows-the-other-half-of-ntlmless&quot; keyTerms={[
  { term: &quot;Kerberos Domain&quot;, definition: &quot;A Kerberos administrative boundary scoping principals and a single Key Distribution Center; written in uppercase like CONTOSO.COM.&quot; },
  { term: &quot;Ticket-Granting Ticket (TGT)&quot;, definition: &quot;A Kerberos ticket issued by the AS that the client uses to obtain service tickets from the TGS without re-presenting its password.&quot; },
  { term: &quot;Privilege Attribute Certificate (PAC)&quot;, definition: &quot;Microsoft-specific authorization data attached by the KDC to every Windows Kerberos ticket; carries the user&apos;s SID and group SIDs and is covered by three signatures after CVE-2022-37967.&quot; },
  { term: &quot;String-to-Key (s2k)&quot;, definition: &quot;The function converting a password into a Kerberos long-term symmetric key. RC4: MD4(UTF-16-LE(password)). AES: PBKDF2-HMAC-SHA1 at 4,096 iterations.&quot; },
  { term: &quot;Pre-authentication Data (PA-DATA)&quot;, definition: &quot;The extensibility hook in AS-REQ/AS-REP that every Kerberos enhancement since 1993 has used to layer new behaviour on the original protocol.&quot; },
  { term: &quot;Service Principal Name (SPN)&quot;, definition: &quot;A unique identifier for a service instance in AD; any account with an SPN is a Kerberoasting candidate.&quot; },
  { term: &quot;Authentication Policy Silo&quot;, definition: &quot;A scope construct in AD that applies Protected-Users-equivalent constraints to tiered subsets of accounts; enables mandatory FAST armoring per silo.&quot; },
  { term: &quot;IAKerb&quot;, definition: &quot;Initial and Pass Through Authentication Using Kerberos V5 and the GSS-API; encapsulates AS/TGS exchanges inside GSS-API tokens so a client without KDC line-of-sight can authenticate via the application server.&quot; },
  { term: &quot;Local KDC&quot;, definition: &quot;An in-process Kerberos KDC on the local Windows host backed by the SAM database; closes the workgroup and Azure-joined no-KDC-line-of-sight gap that kept NTLM alive.&quot; },
  { term: &quot;Resource-Based Constrained Delegation (RBCD)&quot;, definition: &quot;A delegation model where the target service writes msDS-AllowedToActOnBehalfOfOtherIdentity to authorise who may use S4U2Proxy against it; the structural foundation of the post-NTLM RBCD chain in this article&apos;s Hook.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>kerberos</category><category>active-directory</category><category>windows-security</category><category>authentication</category><category>iakerb</category><category>rc4</category><category>rbcd</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>NTLMless: The Death of NTLM in Windows</title><link>https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/</link><guid isPermaLink="true">https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/</guid><description>Thirty years of pass-the-hash, NTLM relay, PetitPotam, and ESC8 -- and the Kerberos engineering that finally lets Microsoft turn NTLM off by default.</description><pubDate>Sun, 10 May 2026 00:00:00 GMT</pubDate><content:encoded>
**NTLM is the 30-year-old fallback authentication protocol that Active Directory still rests on whenever Kerberos cannot do the job -- and every consequential modern AD attack (pass-the-hash, NTLM relay, PetitPotam, ESC8) lives in that fallback path.** Microsoft&apos;s exit plan (IAKerb, Local KDC, NEGOEX, the Negotiate-everywhere refactor) closes the four reasons NTLM survived, and the January 2026 roadmap names &quot;disabled by default in the next major Windows release&quot; as Phase 3. This article tells the whole arc as one story: how NTLM works on the wire, every attack class against it, exactly what is being removed -- and what is not.
&lt;h2&gt;1. Eight Minutes&lt;/h2&gt;
&lt;p&gt;A defender has done every retrofit Microsoft has shipped over twenty years. SMB signing enforced on every member server. EPA enabled on every IIS endpoint. &lt;a href=&quot;https://paragmali.com/blog/the-windows-secure-kernel/&quot; rel=&quot;noopener&quot;&gt;Credential Guard&lt;/a&gt; on. Restrict NTLM in audit mode. KB 5005413 applied to AD CS. An attacker with no credentials joins their network, runs &lt;code&gt;Coercer&lt;/code&gt; against a domain controller, and a handful of seconds later holds a Kerberos ticket-granting ticket for the Domain Admin account [@gh-coercer, @specterops-cert-preowned-blog]. Total elapsed time: less than the time it took you to read this paragraph. Total prerequisites for the chain: that NTLM still exists as a fallback path on Windows.&lt;/p&gt;
&lt;p&gt;The chain has a name. ESC8, from Will Schroeder and Lee Christensen&apos;s &quot;Certified Pre-Owned&quot; whitepaper, published June 17, 2021 [@specterops-cert-preowned-blog, @specterops-cert-preowned-pdf]. Its coercion primitive has another name. PetitPotam, from Lionel Gilles, published the next month. Together they take a fully retrofitted Active Directory environment to Domain Admin in four steps.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; 1. &lt;strong&gt;Coerce.&lt;/strong&gt; Call &lt;code&gt;EfsRpcOpenFileRaw&lt;/code&gt; against any Windows server -- including a DC -- over LSARPC. The service, running as SYSTEM, NTLM-authenticates back to an attacker-controlled UNC path. No credentials required. 2. &lt;strong&gt;Relay.&lt;/strong&gt; &lt;code&gt;ntlmrelayx.py&lt;/code&gt; from Impacket sits on the listening side and forwards the live NTLM exchange to the AD CS Web Enrollment endpoint at &lt;code&gt;/certsrv/certfnsh.asp&lt;/code&gt; [@gh-impacket]. 3. &lt;strong&gt;Enroll.&lt;/strong&gt; The relayed authentication enrolls the DC&apos;s machine account for a client certificate against the &lt;code&gt;Machine&lt;/code&gt; template (or any default-enabled template that allows enrollment) [@specterops-cert-preowned-pdf]. 4. &lt;strong&gt;Forge.&lt;/strong&gt; The attacker uses the certificate to perform PKINIT against the KDC, obtains a TGT for the DC&apos;s machine account, and uses the DC machine account&apos;s TGT to DCSync the domain&apos;s hashes -- including the krbtgt hash -- achieving full domain compromise. Domain Admin in under ten minutes [@specterops-cert-preowned-blog].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Pause on what is and is not true here. SMB signing did not fail; SMB signing was not in the chain. EPA failed because it was deployed on IIS authentication endpoints generally but the &lt;code&gt;/certsrv/&lt;/code&gt; deployment lagged [@ms-kb5005413]. Credential Guard did not fail; Credential Guard protects the NT-hash, and the attacker never touched a hash. Restrict NTLM in audit mode worked exactly as labelled: it audited.&lt;/p&gt;
&lt;p&gt;The retrofits are not wrong. They patch the named primitives. The chain exploits the &lt;em&gt;existence&lt;/em&gt; of the fallback path, not a primitive. Every protective control is honest about what it does and silent about what it does not.&lt;/p&gt;

sequenceDiagram
    autonumber
    actor A as Attacker (no creds)
    participant DC as Domain Controller
    participant R as ntlmrelayx listener
    participant CA as AD CS /certsrv/
    participant KDC as KDC (PKINIT)
    A-&amp;gt;&amp;gt;DC: EfsRpcOpenFileRaw -- UNC to attacker share
    DC-&amp;gt;&amp;gt;R: NTLM AUTHENTICATE (SYSTEM (DC machine account))
    R-&amp;gt;&amp;gt;CA: Relay NTLM, enroll Machine cert as DC
    CA--&amp;gt;&amp;gt;R: Client certificate for DC
    R-&amp;gt;&amp;gt;KDC: PKINIT AS-REQ with DC cert
    KDC--&amp;gt;&amp;gt;A: TGT for DC, request service tickets at will
&lt;p&gt;This is the question that drives the rest of the article: &lt;em&gt;how did Windows arrive at a state where the most catastrophic modern Active Directory attack chain depends on a thirty-year-old fallback nobody wants?&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;2. Origins: Why NTLM Existed at All&lt;/h2&gt;
&lt;p&gt;Rewind to 1987. IBM and Microsoft ship LAN Manager 1.0 for OS/2. PCs are still mostly file-and-print islands on Token Ring or 10BASE-2 coax; networking exists, but &quot;domain&quot; is a word for what a single server controls. LAN Manager needs an authentication scheme that can run on hardware with 640 KB of RAM, no DES export licence, and roughly zero institutional knowledge about cryptography. What it produces, the LM hash, is a near-perfect snapshot of every constraint and assumption of its moment [@wp-lan-manager].&lt;/p&gt;
&lt;p&gt;The construction is short enough to write out. Take the password. Uppercase it. Pad or truncate to exactly fourteen ASCII characters. Split into two seven-byte halves. Convert each half into a 56-bit DES key (the eighth bit of each byte is a parity bit). Use each key to DES-encrypt the eight-byte constant &lt;code&gt;KGS!@#$%&lt;/code&gt;. Concatenate the two eight-byte ciphertexts. That is the LM hash [@wp-lan-manager, @wp-nt-lan-manager].&lt;/p&gt;

The LAN Manager password hash from 1987. Constructed by uppercasing the password, truncating or padding to 14 characters, splitting into two 7-byte halves, and DES-encrypting the constant `KGS!@#$%` with each half as a key. The two halves are independent, the password is case-insensitive, and there is no salt. Every property of this construction enables an attack class that survives into NTLMv2 [@wp-lan-manager].
&lt;p&gt;The eight-byte constant &lt;code&gt;KGS!@#$%&lt;/code&gt; is what you get when somebody types &quot;KGS&quot; and then mashes shift-1, shift-2, shift-3, shift-4, shift-5 on a 1980s American IBM keyboard. The constant is in the protocol because the protocol predates the cryptographic-engineering norm that constants should look random. It would not survive a 2026 design review; in 1987 nobody asked.&lt;/p&gt;
&lt;p&gt;Every choice tells a story about 1987. Uppercase, because some clients normalised case anyway and the developers wanted authentication to &quot;just work&quot; across mixed locale settings. Fourteen characters, because that was the field width DOS dictated. Two halves, because a 56-bit DES key already maxed out the practical computation; nobody was going to chain two DES operations through a feedback function with that much per-keystroke latency. No salt, because the deployment model was one server, one user database, and identical-password collisions were a feature for the help desk, not a leak.&lt;/p&gt;
&lt;p&gt;The result is password-equivalent: anyone who possesses the LM hash &lt;em&gt;is&lt;/em&gt; the user, forever, regardless of how the wire protocol presents the credential.&lt;/p&gt;
&lt;p&gt;Six years later, July 27, 1993, Windows NT 3.1 ships. NTLM(v1) arrives with it [@wp-nt-lan-manager]. The NT-hash is what you would design if you started over with mid-1990s assumptions but were not yet willing to abandon DES at the response layer. It is simpler than the LM hash and stronger in exactly one place: &lt;code&gt;NT-hash = MD4(UTF-16LE(password))&lt;/code&gt; [@wp-nt-lan-manager]. No truncation. No case folding. Sixteen bytes of output. The hash is still password-equivalent; what changes is that the &lt;em&gt;input&lt;/em&gt; to the hash is now whatever Unicode string the user typed, in full.&lt;/p&gt;
&lt;p&gt;The wire protocol around the NT-hash is the famous three-message handshake. NEGOTIATE from the client. CHALLENGE from the server (an eight-byte random nonce). AUTHENTICATE from the client, carrying a DES-based response computed from the NT-hash and the server challenge. The whole exchange is self-contained: nothing in the three messages binds the authentication to a particular transport, a particular client, a particular server, or a particular service [@ms-nlmp]. That property -- the absence of &lt;em&gt;binding&lt;/em&gt; -- is the property NTLM relay will eat for the next twenty-five years.&lt;/p&gt;

`MD4(UTF-16LE(password))`. Sixteen bytes. The single long-term secret that every NTLM authentication ever performed for a given user derives from. Possession of the NT-hash is mathematically equivalent to possession of the password for every authentication purpose. NTLMv2 changes the response computation but not the hash [@wp-nt-lan-manager].

timeline
    title NTLM and Windows authentication, 1987-2027
    1987 : LAN Manager 1.0 ships : LM hash construction
    1993 : Windows NT 3.1 : NTLMv1 + NT-hash MD4(UTF-16LE(pwd))
    1998 : NT 4.0 SP4 : NTLMv2 with HMAC-MD5 and AV_PAIRS
    2000 : Windows 2000 : Kerberos is the default; NTLM demoted to fallback
    2008 : MS08-068 patches SMB self-relay (CVE-2008-4037)
    2015 : Windows 10 RTM ships Credential Guard
    2019 : CVE-2019-1040 Drop the MIC (Simakov/Zinar)
    2021 : PetitPotam (Gilles) + ESC8 (Schroeder/Christensen)
    2023 : Palko commits to removing NTLM (October 11)
    2024 : NTLM marked deprecated (June); NTLMv1 removed in 24H2/Server 2025
    2025 : KB 5064479 enhanced NTLM auditing
    2026 : Phase 1 (audit) + IAKerb/Local KDC pre-release (Phase 2)
    2027 : Phase 3 -- NTLM disabled by default (next major Windows release)
&lt;p&gt;The third revision arrives with NT 4.0 Service Pack 4, October 1998. NTLMv2 throws away DES at the response layer and replaces it with HMAC-MD5. It introduces a &lt;em&gt;client&lt;/em&gt; challenge (so the response is no longer purely a function of the server&apos;s choice). It introduces AV_PAIRS, a small TLV structure carrying the target name, a timestamp, and -- in much later retrofits -- the channel binding hash and message integrity field [@ms-nlmp, @wp-nt-lan-manager]. NTLMv2 defeats pre-computation attacks against the response. It does not change the long-term secret. The NT-hash is still the NT-hash; possession is still authority.An intermediate variant, NTLM2 Session Security, shipped in NT 4.0 SP4 alongside NTLMv2 and is the dead end most often confused for v2. It added an 8-byte client challenge to the NTLMv1 DES envelope without touching the long-term hash, hoping to defeat pre-computation while preserving wire compatibility. It survived only as a transitional &lt;code&gt;LMCompatibilityLevel&lt;/code&gt; setting; nothing in the modern attack catalogue treats NTLM2 SS as a distinct target [@ms-nlmp].&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;LM hash (1987)&lt;/th&gt;
&lt;th&gt;NTLMv1 (1993)&lt;/th&gt;
&lt;th&gt;NTLMv2 (1998)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Hash function for the long-term secret&lt;/td&gt;
&lt;td&gt;DES of constant with password halves&lt;/td&gt;
&lt;td&gt;MD4(UTF-16LE(password))&lt;/td&gt;
&lt;td&gt;MD4(UTF-16LE(password))&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Case-sensitive&lt;/td&gt;
&lt;td&gt;No (uppercase only)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Max input length&lt;/td&gt;
&lt;td&gt;14 characters (truncated)&lt;/td&gt;
&lt;td&gt;Unlimited Unicode&lt;/td&gt;
&lt;td&gt;Unlimited Unicode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Salted&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Per-exchange client challenge + timestamp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Response keyed MAC&lt;/td&gt;
&lt;td&gt;DES (3 keys, 56-bit each)&lt;/td&gt;
&lt;td&gt;DES (3 keys, 56-bit each)&lt;/td&gt;
&lt;td&gt;HMAC-MD5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binds to target server name&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;AV_PAIR &lt;code&gt;MsvAvTargetName&lt;/code&gt; (retrofit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binds to TLS endpoint&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;AV_PAIR &lt;code&gt;MsvAvChannelBindings&lt;/code&gt; (retrofit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Possession of hash = authority&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

The two production response constructions on top of the same NT-hash. NTLMv1 chains three 56-bit DES operations across `K1 = NT-hash[0:7]`, `K2 = NT-hash[7:14]`, `K3 = NT-hash[14:16] || \x00\x00\x00\x00\x00`, encrypting the eight-byte server challenge under each. The third sub-key has only 16 bits of real entropy. NTLMv2 replaces all three DES operations with one HMAC-MD5 over `server_challenge || client_challenge || timestamp || av_pairs`, keyed by `NTOWFv2 = HMAC_MD5(NT-hash, UNICODE(Upper(user) || domain))` [@ms-nlmp, @wp-nt-lan-manager].
&lt;p&gt;Then comes Windows 2000, and Kerberos. Microsoft&apos;s plan was simple: in a domain, Kerberos handles everything; NTLM stays around as a compatibility blanket for the cases Kerberos cannot cover yet [@microsoft-ntlm-overview]. The trouble was that &quot;the cases Kerberos cannot cover yet&quot; turned out to be a permanent set, not a transitional one. Twenty-three years later, the same four cases would be the table-of-contents of Microsoft&apos;s NTLM-removal plan [@palko-2023-evolution]:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;No domain-controller line-of-sight.&lt;/strong&gt; A laptop on a hotel Wi-Fi authenticating to a corporate file share through a VPN tunnel terminator has no Kerberos KDC to talk to. NTLM does not need one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Local accounts.&lt;/strong&gt; A user signing into a workgroup machine or a domain-joined machine&apos;s local SAM has no domain at all; Kerberos has nothing to authenticate against.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No service principal name.&lt;/strong&gt; Kerberos requires a known SPN for the target service. Connect to a server by raw IP, by an alias DNS name not yet in the SPN database, or by a CNAME the operator forgot to register -- there is no SPN, so Kerberos cannot run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hard-coded NTLM.&lt;/strong&gt; Application code that calls &lt;code&gt;AcquireCredentialsHandleW(..., &quot;Ntlm&quot;, ...)&lt;/code&gt; or RPC code that asks for &lt;code&gt;RPC_C_AUTHN_WINNT&lt;/code&gt; directly bypasses the negotiator and forces NTLM regardless of what is available.&lt;/li&gt;
&lt;/ol&gt;

The Simple and Protected GSS-API Negotiation Mechanism. When two parties want to authenticate but do not know which security mechanism they share, SPNEGO offers a list and picks the best one both support. On Windows the SSPI provider is called `Negotiate`, and it has historically chosen Kerberos when possible and NTLM otherwise [@microsoft-ntlm-overview]. The &quot;otherwise&quot; path is where every modern NTLM attack lives.
&lt;p&gt;Each fallback case is one shutter through which NTLM continues to leak into a Kerberos-by-default world. &lt;em&gt;The demotion was supposed to be terminal. Why did the four fallback cases turn out to cover most of the real-world authentication surface, and what does that look like on the wire?&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;3. The Wire: Three Messages and One Hash&lt;/h2&gt;
&lt;p&gt;Most defenders have never read an NTLM authentication off the wire. The cryptography is short enough to fit on one screen, and the structural property that drives the next 28 years of attacks is visible inside those three messages. The point of this section is to make that property impossible to miss.&lt;/p&gt;
&lt;h3&gt;NEGOTIATE, CHALLENGE, AUTHENTICATE&lt;/h3&gt;
&lt;p&gt;The client opens with &lt;code&gt;NEGOTIATE&lt;/code&gt;, advertising its capability flags: which signing modes it supports, whether it is willing to do session security, whether it is asking for extended session keys, and so on. The server replies with &lt;code&gt;CHALLENGE&lt;/code&gt;. The body of &lt;code&gt;CHALLENGE&lt;/code&gt; contains a single 64-bit nonce (the server challenge) and a TLV blob called &lt;code&gt;TargetInfo&lt;/code&gt;: a list of attribute-value pairs the server wants to bind into the authentication [@ms-nlmp].&lt;/p&gt;
&lt;p&gt;The client computes its response and sends &lt;code&gt;AUTHENTICATE&lt;/code&gt;. That message contains the user name, the workstation name, the response itself, the AV_PAIRS the client wants to echo back, a Message Integrity Code field (HMAC-MD5 of the concatenation of all three NTLM messages), and -- in EPA-enforced deployments -- a hash of the TLS endpoint certificate placed in the &lt;code&gt;MsvAvChannelBindings&lt;/code&gt; AV_PAIR [@ms-nlmp, @ms-epa-wcf].&lt;/p&gt;

sequenceDiagram
    autonumber
    participant C as Client
    participant S as Server
    C-&amp;gt;&amp;gt;S: NEGOTIATE (capability flags)
    S-&amp;gt;&amp;gt;C: CHALLENGE (server nonce 8B, TargetInfo AV_PAIRS)
    Note over C: NTOWFv2 = HMAC_MD5(NT-hash, UNICODE(Upper(user) plus domain))
    Note over C: NTProofStr = HMAC_MD5(NTOWFv2, ServerChallenge plus temp) where temp = version plus Z(6) plus Time plus ClientChallenge plus Z(4) plus ServerName plus Z(4)
    C-&amp;gt;&amp;gt;S: AUTHENTICATE (user, NTProofStr, temp, MIC, CBT)
    Note over S: Server replays the same HMAC_MD5 with its copy of the NT-hash to verify
&lt;h3&gt;The NTLMv2 response, verbatim&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;[MS-NLMP]&lt;/code&gt; §3.3.2 gives the response algorithm in three lines of pseudocode [@ms-nlmp]:&lt;/p&gt;
&lt;p&gt;$$\text{NTOWFv2} = \text{HMAC-MD5}\big(\text{NT-hash},\ \text{UNICODE}(\text{Upper(user)} \mathbin{|} \text{domain})\big)$$&lt;/p&gt;
&lt;p&gt;$$\text{temp} = \text{Responserversion} \mathbin{|} \text{HiResponserversion} \mathbin{|} Z(6) \mathbin{|} \text{Time} \mathbin{|} \text{ClientChallenge} \mathbin{|} Z(4) \mathbin{|} \text{ServerName} \mathbin{|} Z(4)$$&lt;/p&gt;
&lt;p&gt;$$\text{NTProofStr} = \text{HMAC-MD5}\big(\text{NTOWFv2},\ \text{ServerChallenge} \mathbin{|} \text{temp}\big)$$&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;temp&lt;/code&gt; byte string carries two version bytes, six zero bytes, the 8-byte FILETIME, the 8-byte client challenge, four zero bytes, the AV_PAIR list the spec calls &lt;code&gt;ServerName&lt;/code&gt;, and a final four zero bytes. The client sends &lt;code&gt;NTProofStr || temp&lt;/code&gt; as the response. The server, which holds its own copy of &lt;code&gt;NT-hash&lt;/code&gt; for the user (cached or fetched from the domain controller), recomputes the same three lines and checks equality. That is the entire response protocol.&lt;/p&gt;
&lt;p&gt;Notice what &lt;code&gt;NTOWFv2&lt;/code&gt; is. It is a function of two inputs: the NT-hash, and a normalised user/domain string. Both inputs are static once the user logs in. &lt;em&gt;Knowing the NT-hash is sufficient to compute every NTLMv2 response forever, against every server, for every challenge, until the password changes&lt;/em&gt; [@wp-pass-the-hash].Why is HMAC-MD5 considered fine for the response side but considered weak for the &lt;em&gt;key&lt;/em&gt; side? The response side is being asked: given a known key, can a verifier check a freshly computed tag? HMAC-MD5 still answers that without a known break. The key side is being asked: given a stolen 16-byte value, how hard is it to mount a precomputation attack on candidate passwords? MD4 of UTF-16LE is so cheap on modern GPUs that an 8-character password is in the minutes-to-hours range. Hashcat lists NetNTLMv2 (mode 5600) as the practical attack format and benchmarks NTLM cracking accordingly.&lt;/p&gt;
&lt;h3&gt;AV_PAIRS, MIC, and channel binding -- retrofits all the way down&lt;/h3&gt;
&lt;p&gt;AV_PAIRS is a TLV structure. The server places target NetBIOS, target DNS, a timestamp, and various flags into the &lt;code&gt;TargetInfo&lt;/code&gt; of &lt;code&gt;CHALLENGE&lt;/code&gt;. The client echoes the structure into &lt;code&gt;AUTHENTICATE&lt;/code&gt; and adds two retrofit fields when both ends agree to use them [@ms-nlmp]:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;MsvAvFlags&lt;/code&gt;&lt;/strong&gt; is a bit field signalling that the client has computed a MIC and is therefore willing to bind all three NTLM messages together.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;MsvAvChannelBindings&lt;/code&gt;&lt;/strong&gt; holds a hash of the server&apos;s TLS endpoint certificate when the authentication is happening over an HTTPS-style transport that the client can see. This is the Extended Protection for Authentication (EPA) channel-binding-token mechanism [@ms-epa-wcf].&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The MIC field itself is added to &lt;code&gt;AUTHENTICATE&lt;/code&gt;. It is &lt;code&gt;HMAC_MD5(ExportedSessionKey, NEGOTIATE || CHALLENGE || AUTHENTICATE)&lt;/code&gt;. &lt;code&gt;ExportedSessionKey&lt;/code&gt; coincides with &lt;code&gt;SessionBaseKey&lt;/code&gt; in the common case; when &lt;code&gt;NTLMSSP_NEGOTIATE_KEY_EXCH&lt;/code&gt; is set, the client generates a random session key, encrypts it under &lt;code&gt;KeyExchangeKey&lt;/code&gt;, and &lt;code&gt;ExportedSessionKey&lt;/code&gt; is the random key. The MIC always uses &lt;code&gt;ExportedSessionKey&lt;/code&gt;, and it is intended to make tampering with any of the three messages detectable [@ms-nlmp].&lt;/p&gt;

A length-prefixed TLV list carried inside the `TargetInfo` byte string of NTLM `CHALLENGE` and the AV-list byte string of `AUTHENTICATE`. AV_PAIRS hold the target server names, a timestamp, the `MsvAvFlags`, the `MsvAvChannelBindings` (EPA), and the optional `MsvAvTargetName` (SPN). NTLMv2 reserved AV_PAIRS in 1998 but most of the fields are 2009-2019-era retrofits onto the original wire format [@ms-nlmp].

A 16-byte HMAC-MD5, keyed by `ExportedSessionKey`, computed over the concatenation of the NTLM `NEGOTIATE`, `CHALLENGE`, and `AUTHENTICATE` messages and embedded in `AUTHENTICATE`. (`ExportedSessionKey` equals `SessionBaseKey` unless `NTLMSSP_NEGOTIATE_KEY_EXCH` is negotiated; the MIC always uses the exported key.) Introduced as a retrofit so that a man-in-the-middle relay could not silently strip the signing-required flags from the negotiate phase. Drop-the-MIC (CVE-2019-1040) demonstrated that the *presence* of the MIC was itself a negotiated property and could be stripped [@ms-nlmp, @nvd-cve-2019-1040].

A hash of the server&apos;s TLS endpoint certificate placed in `MsvAvChannelBindings` so the authentication is bound to the specific TLS channel the client believed it was talking over. When both ends enforce CBT, an attacker who terminates one TLS channel and opens a different TLS channel to the real server cannot reuse the captured NTLM response. Microsoft documents three enforcement modes: None, Partial, and Full [@ms-epa-wcf].
&lt;h3&gt;Run it&lt;/h3&gt;
&lt;p&gt;The whole thing fits in a few dozen lines of JavaScript. The point of the runnable demo is not to teach you to crack hashes; it is to make the password-equivalence claim land as code rather than as an assertion.&lt;/p&gt;
&lt;p&gt;{`
// Demonstrates the [MS-NLMP] NTLMv2 response algorithm.
//
// The point: NTProofStr is a deterministic function of the NT-hash plus
// values that travel in the clear or that the attacker controls. If you
// possess the NT-hash, you can compute NTProofStr for any (challenge,
// client_challenge, timestamp, av_pairs). That is the protocol-level
// proof of password-equivalence.
//
// In a real client, NT-hash = MD4(UTF-16LE(password)). MD4 is removed from
// most modern browser/Node crypto providers, so we use a precomputed
// NT-hash for password &quot;Summer2026!&quot; and focus on the structural property
// that matters: knowledge of those 16 bytes is sufficient forever.&lt;/p&gt;
&lt;p&gt;const crypto = require(&quot;crypto&quot;);&lt;/p&gt;
&lt;p&gt;// Precomputed NT-hash for password &quot;Summer2026!&quot; (16 bytes, hex):
//   reference value verified against impacket&apos;s NTOWFv1() helper offline.
const ntHash = Buffer.from(&quot;41aed72cec76816423703d8e545eea31&quot;, &quot;hex&quot;);&lt;/p&gt;
&lt;p&gt;const user = &quot;alice&quot;, domain = &quot;CONTOSO&quot;;&lt;/p&gt;
&lt;p&gt;// NTOWFv2 = HMAC-MD5(NT-hash, UNICODE(Upper(user) || domain))
const userDomain = Buffer.from((user.toUpperCase() + domain), &quot;utf16le&quot;);
const ntowfv2 = crypto.createHmac(&quot;md5&quot;, ntHash).update(userDomain).digest();&lt;/p&gt;
&lt;p&gt;// NTProofStr = HMAC-MD5(NTOWFv2, ServerChallenge || temp)
// where temp = ResponserVersion(0x01) || HiResponserVersion(0x01) || Z(6) ||
//              Time(8) || ClientChallenge(8) || Z(4) || ServerName || Z(4)
const serverChal = Buffer.from(&quot;0123456789abcdef&quot;, &quot;hex&quot;);
const clientChal = Buffer.from(&quot;fedcba9876543210&quot;, &quot;hex&quot;);
const ts = Buffer.alloc(8);                       // any 8-byte FILETIME
const serverName = Buffer.from(&quot;00000000&quot;, &quot;hex&quot;); // empty AV_PAIR list
const tempBuf = Buffer.concat([
  Buffer.from(&quot;0101000000000000&quot;, &quot;hex&quot;),           // version 1.1 || Z(6)
  ts, clientChal,
  Buffer.from(&quot;00000000&quot;, &quot;hex&quot;),                 // Z(4)
  serverName,
  Buffer.from(&quot;00000000&quot;, &quot;hex&quot;),                 // Z(4)
]);
const ntProofStr = crypto.createHmac(&quot;md5&quot;, ntowfv2)
  .update(Buffer.concat([serverChal, tempBuf])).digest();&lt;/p&gt;
&lt;p&gt;console.log(&quot;NT-hash    :&quot;, ntHash.toString(&quot;hex&quot;));
console.log(&quot;NTOWFv2    :&quot;, ntowfv2.toString(&quot;hex&quot;));
console.log(&quot;NTProofStr :&quot;, ntProofStr.toString(&quot;hex&quot;));
console.log(&quot;&quot;);
console.log(&quot;Now change serverChal/clientChal/ts and rerun: NTProofStr changes,&quot;);
console.log(&quot;but only the &lt;em&gt;first&lt;/em&gt; line of input (the NT-hash) is a secret. The&quot;);
console.log(&quot;rest travels in the clear inside the three NTLM messages. Possessing&quot;);
console.log(&quot;ntHash IS possessing the credential -- forever, on every server.&quot;);
`}&lt;/p&gt;
&lt;p&gt;The demo prints three lines, then a punchline. The lines are not impressive; the punchline is.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The NT-hash is not a credential; it &lt;em&gt;is&lt;/em&gt; the credential. Knowing the hash IS authentication. Every pass-the-hash tool ever written, from Paul Ashton&apos;s modified Samba in 1997 to the present, is a different packaging of the same realisation: an authentication that is a deterministic function of a static secret turns possession of that secret into permanent authority [@wp-pass-the-hash].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If possession of the hash is the protocol, the last 28 years of attacks are not surprises -- they are obvious next steps. What are those steps?&lt;/p&gt;
&lt;h2&gt;4. The Three-Decade Attack Cascade&lt;/h2&gt;
&lt;p&gt;Five generations of attacks. Each one is named, each one is dated, each one took Microsoft years to respond to, and each Microsoft response always closed the &lt;em&gt;primitive&lt;/em&gt; and left the &lt;em&gt;class&lt;/em&gt; alive. They are not five surprises; they are five logical consequences of the wire protocol you just read.&lt;/p&gt;
&lt;h3&gt;Generation 1 -- 1997: Pass-the-Hash (Paul Ashton)&lt;/h3&gt;
&lt;p&gt;The first published exploit of password-equivalence comes from Paul Ashton, posted to the Bugtraq mailing list in 1997. Ashton ships a patch against the Samba SMB client that takes a 16-byte NT-hash directly on the command line, &lt;em&gt;instead&lt;/em&gt; of asking for a cleartext password [@wp-pass-the-hash]. The patch is a one-paragraph change against an open-source codebase, and that fact -- the brevity of the change -- is the lesson.&lt;/p&gt;
&lt;p&gt;The NTLM response function has no input that depends on knowing the plaintext password. Replacing the plaintext-password input with a literal NT-hash input does not change the bytes that go on the wire. The server cannot tell the difference.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s response, for more than a decade, is &lt;em&gt;do not lose your hashes&lt;/em&gt;. There is no protocol fix because there is no protocol bug to fix; the design is doing exactly what it was designed to do. The response is operational guidance: tier your admins, scrub LSASS, do not run privileged sessions on workstations.&lt;/p&gt;
&lt;h3&gt;Generation 2 -- 2001: NTLM Relay (Sir Dystic / SMBRelay)&lt;/h3&gt;
&lt;p&gt;If you do not have to &lt;em&gt;steal&lt;/em&gt; the hash to use the credential, you also do not have to &lt;em&gt;steal&lt;/em&gt; the live exchange. You can simply &lt;em&gt;relay&lt;/em&gt; it. On March 31, 2001, at the @lanta.con conference, Sir Dystic of the Cult of the Dead Cow (Josh Buchbinder) releases SMBRelay: a small program that accepts an SMB connection on port 139, opens a second SMB connection back to &lt;em&gt;another&lt;/em&gt; server, and shuttles the NEGOTIATE / CHALLENGE / AUTHENTICATE messages between the two sides [@cdc-smbrelay].&lt;/p&gt;
&lt;p&gt;The attack works because the three NTLM messages are not bound to a particular client, server, or service. Whoever sits between them can replay the credential against whatever destination the attacker chooses, as that user, for the duration of the exchange.The colourful provenance matters. The Cult of the Dead Cow released SMBRelay alongside Back Orifice 2000; &quot;Sir Dystic&quot; is the same Josh Buchbinder who later wrote the SMBProxy authentication-relay framework. The point is not the chrome -- it is that the relay class was disclosed publicly &lt;em&gt;at a conference&lt;/em&gt; in 2001, with working code on the cDc website, and Microsoft did not ship a fix for the trivial case (self-relay) until November 2008 [@cdc-smbrelay].&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s response is incomplete and slow. SMB signing exists from Windows 2000 onward, but it is off by default on member servers for more than a decade [@ms-smb-signing]. MS08-068, in November 2008, finally patches the &lt;em&gt;self-relay&lt;/em&gt; case (CVE-2008-4037): the SMB server now refuses to accept an authentication that the client itself just generated against the same server [@nvd-cve-2008-4037]. NVD notes that reliable sources report the original fix as insufficient for CVE-2000-0834 -- meaning the patch closed exactly the self-relay case and nothing else [@nvd-cve-2008-4037]. Seven years to fix the simplest variant; the &lt;em&gt;cross-server&lt;/em&gt; relay class is still wide open.&lt;/p&gt;
&lt;h3&gt;Generation 3 -- 2008-2014: Credential Theft as a Service&lt;/h3&gt;
&lt;p&gt;By 2008, the operational guidance &quot;do not lose your hashes&quot; stops being defensible. On February 29, 2008, Hernan Ochoa releases the Pass-the-Hash Toolkit v1.3, two native Windows binaries called &lt;code&gt;iam.exe&lt;/code&gt; and &lt;code&gt;whosthere.exe&lt;/code&gt; that read the NT-hash out of LSASS memory and inject it into a new logon session. PtH stops being a Linux-and-Samba trick and becomes a Windows-everywhere reality.&lt;/p&gt;
&lt;p&gt;Three years later, Benjamin Delpy publishes &lt;a href=&quot;https://paragmali.com/blog/windows-access-control-25-years-of-attacks/&quot; rel=&quot;noopener&quot;&gt;Mimikatz&lt;/a&gt;. The first version is closed-source, released in May 2011 [@wired-greenberg-mimikatz]. By April 6, 2014, the GitHub repository goes public with the version string &quot;mimikatz 2.0 alpha (x86) release &apos;Kiwi en C&apos; (Apr 6 2014 22:02:03)&quot; [@gh-mimikatz]. The repo description is a near-perfect summary of what LSASS is to an attacker: &quot;extract plaintexts passwords, hash, PIN code and kerberos tickets from memory. mimikatz can also perform pass-the-hash, pass-the-ticket or build Golden tickets&quot; [@gh-mimikatz]. LSASS becomes the universal credential oracle.Delpy did not intend Mimikatz to be a weapon. Wired&apos;s Andy Greenberg documents the trajectory in detail: Delpy &quot;released it publicly in May 2011, but as a closed source program.&quot; In mid-2011, Delpy learned for the first time that Mimikatz had been used in an intrusion of an unnamed foreign government network. That September, it appeared again in the landmark DigiNotar hack. An unidentified man was found at his laptop in his Moscow conference hotel room -- the stranger apologised and quickly left, claiming a wrong room. A second man in a dark suit later demanded a copy of Mimikatz on a USB drive. He went open-source partly fearing for his own safety after the hotel confrontations, and partly to make the security industry confront what lived in LSASS [@wired-greenberg-mimikatz].&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s response is structural and specific. Credential Guard ships in Windows 10 RTM (Enterprise and Education editions), July 29, 2015 [@ms-credential-guard]. It uses Virtualization-Based Security to isolate &lt;code&gt;lsaiso.exe&lt;/code&gt; in VTL1 within the same root partition; the kernel can no longer read NTLM hashes or Kerberos TGTs even at SYSTEM-level privilege. Protected Users and Restricted Admin in Server 2012 R2 / Windows 8.1 narrow the surface further. LSASS-as-PPL adds a process-protection layer between user-mode debuggers and the LSASS address space [@ms-credential-guard].&lt;/p&gt;
&lt;p&gt;Credential Guard works -- against the credential-&lt;em&gt;theft&lt;/em&gt; class. It does nothing against credential-&lt;em&gt;use&lt;/em&gt;. An attacker who never extracts a hash, because they never need to, sails right past it. Relay does not need the hash. Coercion does not need the hash. ESC8 does not need the hash. That is the next generation.&lt;/p&gt;
&lt;h3&gt;Generation 4 -- 2018-2021: Forced-Authentication Coercion&lt;/h3&gt;
&lt;p&gt;In 2018 at DerbyCon 8, Lee Christensen releases SpoolSample, known publicly as &quot;PrinterBug.&quot; The GitHub description is exact: &quot;PoC tool to coerce Windows hosts authenticate to other machines via the MS-RPRN RPC interface&quot; [@gh-spoolsample]. The trick is that the Print Spooler service runs as SYSTEM, accepts a remote RPC call (&lt;code&gt;RpcRemoteFindFirstPrinterChangeNotificationEx&lt;/code&gt;) that takes a UNC path, and dutifully NTLM-authenticates back to whatever path the caller named -- on behalf of the machine account. Any Windows service running as SYSTEM that accepts a UNC path is a confused deputy that will authenticate on demand.&lt;/p&gt;

Microsoft&apos;s initial classification of SpoolSample was *authenticated-only / by design*: a caller needed valid domain credentials to reach the spooler endpoint, and authenticated callers triggering machine-account authentications was deemed within spec. The classification held through 2018, 2019, and most of 2020. PetitPotam broke it, because PetitPotam used MS-EFSRPC over LSARPC, which accepts *unauthenticated* binds on a domain controller&apos;s named-pipe interface. With the authentication requirement gone, &quot;by design&quot; stopped being a coherent defence. Microsoft started shipping fixes.
&lt;p&gt;Marina Simakov and Yaron Zinar of Preempt (now CrowdStrike) publish &quot;Drop the MIC&quot; on June 11, 2019. The vulnerability is CVE-2019-1040: a tampering bug where &quot;a man-in-the-middle attacker is able to successfully bypass the NTLM MIC (Message Integrity Check) protection&quot; [@crowdstrike-drop-the-mic, @nvd-cve-2019-1040]. The bypass works by stripping the &lt;code&gt;NTLMSSP_NEGOTIATE_SIGN&lt;/code&gt; and &lt;code&gt;NTLMSSP_NEGOTIATE_ALWAYS_SIGN&lt;/code&gt; flags from the initial &lt;code&gt;NEGOTIATE&lt;/code&gt;, removing the MIC field from &lt;code&gt;AUTHENTICATE&lt;/code&gt;, and removing the &lt;code&gt;Version&lt;/code&gt; field that drives MIC detection.&lt;/p&gt;
&lt;p&gt;Servers that should have required a MIC silently accept the modified message. The MIC -- the retrofit integrity layer that was supposed to make tampering detectable -- turns out to be itself untethered to the negotiation [@crowdstrike-drop-the-mic].&lt;/p&gt;
&lt;p&gt;Lionel Gilles (topotam77) publishes PetitPotam in July 2021, CVE-2021-36942. The GitHub repository description reads: &quot;PoC tool to coerce Windows hosts to authenticate to other machines via MS-EFSRPC EfsRpcOpenFileRaw or other functions&quot;. The decisive new property compared to SpoolSample is that PetitPotam needs &lt;em&gt;no credentials&lt;/em&gt; against a domain controller: LSARPC accepts unauthenticated binds, so the coercion can be triggered by an attacker who has merely joined the network.&lt;/p&gt;
&lt;p&gt;In 2022, Remi Gascou (p0dalirius) publishes Coercer, a Python script that consolidates the coercion class across MS-RPRN, MS-EFSR, MS-DFSNM, MS-FSRVP, and many more RPC interfaces. The README describes it succinctly: &quot;A python script to automatically coerce a Windows server to authenticate on an arbitrary machine through many methods&quot; [@gh-coercer].&lt;/p&gt;
&lt;h3&gt;Generation 5 -- 2021: ADCS Web-Enrollment Relay (ESC8)&lt;/h3&gt;
&lt;p&gt;On June 17, 2021, Will Schroeder and Lee Christensen of SpecterOps publish &quot;Certified Pre-Owned,&quot; a whitepaper and matching blog post that maps eight new attack classes against Active Directory Certificate Services [@specterops-cert-preowned-blog, @specterops-cert-preowned-pdf]. ESC1 through ESC7 are template and configuration weaknesses. ESC8 is the keystone of this article.&lt;/p&gt;
&lt;p&gt;ESC8 says: AD CS Web Enrollment endpoints (&lt;code&gt;/certsrv/&lt;/code&gt;) accept NTLM authentication. Coerce a server&apos;s machine account to authenticate to your relay listener; relay the authentication to &lt;code&gt;/certsrv/&lt;/code&gt;; enroll the relayed identity for a machine-template certificate; use that certificate to perform PKINIT against the KDC and request a TGT [@specterops-cert-preowned-blog]. The NTLM-vs-Kerberos boundary stops being a meaningful one. NTLM is the protocol on the front side of the attack; Kerberos is the trust token on the back side; the certificate is the conduit between them.&lt;/p&gt;
&lt;p&gt;The point of ESC8 is not just that it works. The point is that it works against a perfectly retrofitted environment. SMB signing did not enter the chain. LDAP signing did not enter the chain. EPA was supposed to enter the chain on the &lt;code&gt;/certsrv/&lt;/code&gt; side but was unevenly deployed. Credential Guard never had a hash to protect.&lt;/p&gt;

flowchart TD
    A[Gen 1 -- 1997 Pass-the-Hash&lt;br /&gt;Paul Ashton, modified Samba]
    A --&amp;gt; A1[Response: operational guidance&lt;br /&gt;Do not lose your hashes]
    A1 --&amp;gt; B[Gen 2 -- 2001 SMBRelay&lt;br /&gt;Sir Dystic, atlanta.con]
    B --&amp;gt; B1[Response: MS08-068 2008&lt;br /&gt;Patches self-relay only]
    B1 --&amp;gt; C[Gen 3 -- 2008-2014 LSASS extraction&lt;br /&gt;Ochoa PtH Toolkit, Delpy Mimikatz]
    C --&amp;gt; C1[Response: Credential Guard 2015&lt;br /&gt;Closes theft; not use]
    C1 --&amp;gt; D[Gen 4 -- 2018-2021 Coercion&lt;br /&gt;SpoolSample, Drop-the-MIC, PetitPotam, Coercer]
    D --&amp;gt; D1[Response: KB 5005413, EPA&lt;br /&gt;Closes primitive; not class]
    D1 --&amp;gt; E[Gen 5 -- 2021 ESC8&lt;br /&gt;Schroeder/Christensen Certified Pre-Owned]
    E --&amp;gt; E1[Response: remove NTLM]

sequenceDiagram
    autonumber
    actor A as Attacker
    participant V as &quot;Victim SYSTEM service (Spooler, EFSR, DFSNM)&quot;
    participant R as Attacker NTLM relay
    participant T as &quot;Target service (LDAP, SMB, certsrv)&quot;
    A-&amp;gt;&amp;gt;V: RPC call with UNC path \\attacker\share
    V-&amp;gt;&amp;gt;R: NTLM NEGOTIATE (as machine account)
    R-&amp;gt;&amp;gt;T: Open new authenticated session
    T-&amp;gt;&amp;gt;R: NTLM CHALLENGE
    R-&amp;gt;&amp;gt;V: Forward CHALLENGE
    V-&amp;gt;&amp;gt;R: NTLM AUTHENTICATE (signed by machine account)
    R-&amp;gt;&amp;gt;T: Forward AUTHENTICATE -- T treats attacker session as the victim
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Generation&lt;/th&gt;
&lt;th&gt;Primitive&lt;/th&gt;
&lt;th&gt;Public date&lt;/th&gt;
&lt;th&gt;Microsoft response&lt;/th&gt;
&lt;th&gt;What survived&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;1. Pass-the-Hash&lt;/td&gt;
&lt;td&gt;Use the hash directly&lt;/td&gt;
&lt;td&gt;1997, Paul Ashton, Bugtraq [@wp-pass-the-hash]&lt;/td&gt;
&lt;td&gt;Operational guidance&lt;/td&gt;
&lt;td&gt;Hash is still password-equivalent on the wire&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. NTLM relay (SMB)&lt;/td&gt;
&lt;td&gt;Forward live exchange&lt;/td&gt;
&lt;td&gt;March 31, 2001, Sir Dystic, @lanta.con [@cdc-smbrelay]&lt;/td&gt;
&lt;td&gt;MS08-068 (Nov 2008) -- self-relay only [@nvd-cve-2008-4037]&lt;/td&gt;
&lt;td&gt;Cross-server, cross-protocol relay&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. LSASS extraction&lt;/td&gt;
&lt;td&gt;Steal hashes from memory&lt;/td&gt;
&lt;td&gt;Feb 2008 (Ochoa); May 2011 closed / Apr 2014 open (Delpy) [@gh-mimikatz, @wired-greenberg-mimikatz]&lt;/td&gt;
&lt;td&gt;Credential Guard (Jul 29, 2015) [@ms-credential-guard]&lt;/td&gt;
&lt;td&gt;Hash &lt;em&gt;use&lt;/em&gt; outside LSASS path; SYSTEM-level Mimikatz on the SAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. Coercion&lt;/td&gt;
&lt;td&gt;Make SYSTEM authenticate on demand&lt;/td&gt;
&lt;td&gt;2018 SpoolSample [@gh-spoolsample]; 2019 Drop-the-MIC [@crowdstrike-drop-the-mic, @nvd-cve-2019-1040]; 2021 PetitPotam; 2022 Coercer [@gh-coercer]&lt;/td&gt;
&lt;td&gt;Per-interface patches; KB 5005413 EPA recipe [@ms-kb5005413]&lt;/td&gt;
&lt;td&gt;The pattern of &quot;SYSTEM holds an unanchored credential&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5. ESC8 ADCS Web Enrollment relay&lt;/td&gt;
&lt;td&gt;NTLM coerce -&amp;gt; /certsrv/ -&amp;gt; TGT via PKINIT&lt;/td&gt;
&lt;td&gt;June 17, 2021, Schroeder/Christensen, &quot;Certified Pre-Owned&quot; [@specterops-cert-preowned-blog, @specterops-cert-preowned-pdf]&lt;/td&gt;
&lt;td&gt;KB 5005413; AD CS hardening; eventually Phase 3 of NTLM removal&lt;/td&gt;
&lt;td&gt;Kerberos relay class on the other side (KrbRelay/KrbRelayUp) [@gh-krbrelayup]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

KrbRelayUp -- a universal no-fix local privilege escalation in windows domain environments where LDAP signing is not enforced (the default settings). -- Dec0ne, KrbRelayUp README [@gh-krbrelayup]
&lt;p&gt;The reader who started Section 4 believing &quot;if I patch each named NTLM attack, the protocol is safe&quot; finishes Section 4 believing something else. Every retrofit patches a &lt;em&gt;primitive&lt;/em&gt;; none addresses the &lt;em&gt;existence&lt;/em&gt; of the fallback path. The next attack is always one cross-protocol step away. The retrofit strategy is structurally incapable of closing the class.&lt;/p&gt;
&lt;p&gt;By the end of 2021, NTLM-the-protocol cannot be removed because four use cases require it, and NTLM-the-fallback cannot be kept because ESC8 turned it into a domain-takeover oracle. Something has to change. What?&lt;/p&gt;
&lt;h2&gt;5. The Retrofit Strategy and Its Funeral&lt;/h2&gt;
&lt;p&gt;Before naming the answer, name the strategy that failed. Microsoft&apos;s defensive cadence between 2001 and 2021 splits into three families, each effective against a named primitive, each defeated by an unanchored cousin of that primitive.&lt;/p&gt;
&lt;h3&gt;Family A -- Per-protocol message authentication&lt;/h3&gt;
&lt;p&gt;SMB signing. LDAP signing and sealing. The idea is to anchor the &lt;em&gt;content&lt;/em&gt; of each authenticated request inside a per-session signature derived from the authentication. SMB signing introduces an HMAC over every SMB message keyed by a per-session &lt;code&gt;SigningKey&lt;/code&gt;; LDAP signing and sealing do the equivalent for LDAP operations [@ms-smb-signing].&lt;/p&gt;
&lt;p&gt;Family A works when the &lt;em&gt;target&lt;/em&gt; protocol enforces it. SMB-to-SMB relay against an SMB server with required signing fails; LDAP-to-LDAP relay against an LDAP server with required signing fails. The strategy assumes the attacker stays in the same protocol family. Cross-protocol relay -- SMB authentication relayed to LDAP, or SMB authentication relayed to &lt;code&gt;/certsrv/&lt;/code&gt; -- defeats it. The MS-EFSR coercion can produce an authentication that originates &quot;as if from SMB&quot; and gets accepted by an unrelated HTTPS service that ignores the SMB signing flag entirely [@nvd-cve-2019-1040, @specterops-cert-preowned-blog].&lt;/p&gt;
&lt;h3&gt;Family B -- Per-channel binding tokens and the MIC&lt;/h3&gt;
&lt;p&gt;EPA (channel binding) and the NTLMv2 MIC are the response to cross-protocol relay. Both try to tie the authentication to &lt;em&gt;the specific channel&lt;/em&gt; the client believes it is using. EPA places a hash of the TLS endpoint certificate into the &lt;code&gt;MsvAvChannelBindings&lt;/code&gt; AV_PAIR; an HTTPS server with EPA required compares it to its own certificate&apos;s hash and rejects the authentication if they do not match [@ms-epa-wcf]. The MIC binds all three NTLM messages together so a relay cannot strip the signing-required flags from &lt;code&gt;NEGOTIATE&lt;/code&gt; after the client sets them [@ms-nlmp].&lt;/p&gt;
&lt;p&gt;Family B works when both ends agree to enforce. Drop-the-MIC (CVE-2019-1040) demonstrated that the &lt;em&gt;presence&lt;/em&gt; of the MIC was negotiated and could be stripped, so a server that supported MIC-less clients silently accepted MIC-less messages from a relay [@crowdstrike-drop-the-mic, @nvd-cve-2019-1040]. EPA suffers from the same enforcement-asymmetry: when an IIS endpoint runs with &lt;code&gt;policyEnforcement=&quot;None&quot;&lt;/code&gt; or &lt;code&gt;&quot;Partial&quot;&lt;/code&gt;, the binding is not checked. KB 5005413 published the explicit &lt;code&gt;&amp;lt;extendedProtectionPolicy policyEnforcement=&quot;Always&quot; /&amp;gt;&lt;/code&gt; recipe for &lt;code&gt;/certsrv/&lt;/code&gt; because field deployments had been running with weaker settings [@ms-kb5005413].&lt;/p&gt;
&lt;h3&gt;Family C -- Credential isolation&lt;/h3&gt;
&lt;p&gt;Credential Guard. LSASS-as-PPL. Protected Users. Restricted Admin. These attack the &lt;em&gt;theft&lt;/em&gt; surface. Credential Guard moves the NT-hash into &lt;code&gt;lsaiso.exe&lt;/code&gt; inside VTL1; the kernel can no longer read it. Microsoft now ships it enabled by default on domain-joined, non-DC systems running Windows 11 22H2 and Server 2025 on hardware that meets the requirements [@ms-credential-guard].&lt;/p&gt;
&lt;p&gt;Family C is honest about what it covers. It does nothing about coercion flows that never touch the NT-hash. PetitPotam and ESC8 do not need a hash; the relay session uses the live NTLM exchange and is never persisted. Credential Guard cannot help.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Family&lt;/th&gt;
&lt;th&gt;What it closes&lt;/th&gt;
&lt;th&gt;What it does not close&lt;/th&gt;
&lt;th&gt;Defeating attack&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;A. Per-protocol message auth (SMB/LDAP signing)&lt;/td&gt;
&lt;td&gt;Same-protocol relay against the target&lt;/td&gt;
&lt;td&gt;Cross-protocol relay; targets that do not enforce&lt;/td&gt;
&lt;td&gt;LDAP relay from SMB coercion [@nvd-cve-2019-1040]; ESC8 relay to /certsrv/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B. Channel binding (EPA) + MIC&lt;/td&gt;
&lt;td&gt;Same-channel relay through TLS termination&lt;/td&gt;
&lt;td&gt;MIC stripping in negotiation; EPA at None/Partial; non-TLS targets&lt;/td&gt;
&lt;td&gt;Drop-the-MIC [@nvd-cve-2019-1040]; under-enforced EPA [@ms-kb5005413]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C. Credential isolation (Credential Guard, LSASS-PPL)&lt;/td&gt;
&lt;td&gt;Hash theft from running LSASS&lt;/td&gt;
&lt;td&gt;Hash &lt;em&gt;use&lt;/em&gt; in live relay; SAM extraction from disk; coercion&lt;/td&gt;
&lt;td&gt;ESC8 + PetitPotam [@specterops-cert-preowned-blog]; SAM hive offline [@ms-credential-guard]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Every retrofit Microsoft has shipped against NTLM attacks one &lt;em&gt;primitive&lt;/em&gt; of NTLM. None address the &lt;em&gt;existence&lt;/em&gt; of NTLM as a fallback path. ESC8 was the funeral of the retrofit strategy because ESC8 turned a fully retrofitted environment into a domain takeover without defeating any retrofit.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &quot;Certified Pre-Owned&quot; did not break a Microsoft fix; it composed the existing infrastructure. The chain assumes SMB signing is on, EPA is on (somewhere), and Credential Guard is on. It still works, because none of those controls cover the path that goes Coercer -&amp;gt; NTLM relay -&amp;gt; AD CS Web Enrollment -&amp;gt; PKINIT. After 2021, the question stopped being &quot;what&apos;s the next retrofit?&quot; and became &quot;what does it take to remove the fallback?&quot; [@specterops-cert-preowned-blog, @ms-kb5005413].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To remove ESC8 without rebuilding AD CS, Microsoft has to remove NTLM. To remove NTLM, Microsoft has to remove the four reasons NTLM existed as a fallback in the first place. What does that look like in shippable form?&lt;/p&gt;
&lt;h2&gt;6. The Breakthrough: Closing the Fallback&lt;/h2&gt;
&lt;p&gt;October 11, 2023. Matthew Palko, Windows IT Pro Blog. &quot;The evolution of Windows authentication.&quot; For the first time in twenty-three years, Microsoft publicly commits to &lt;em&gt;removing&lt;/em&gt; NTLM, not restricting it, and names the three load-bearing features that make removal possible [@palko-2023-evolution].&lt;/p&gt;
&lt;p&gt;The plan starts where every honest plan starts -- by stating the problem in its own words. There are four fallback reasons NTLM persisted: no DC line-of-sight, no domain at all (local accounts), no SPN for the target, and hard-coded NTLM in application code [@palko-2023-evolution]. Each gets an engineered answer. The four-to-three correspondence (three protocols plus one refactor) is the new architecture.&lt;/p&gt;

Our end goal is eliminating the need to use NTLM at all to help improve the security bar of authentication for all Windows users. -- Matthew Palko, Microsoft Windows IT Pro Blog, October 11, 2023 [@palko-2023-evolution]
&lt;h3&gt;IAKerb -- closing &quot;no DC line-of-sight&quot;&lt;/h3&gt;
&lt;p&gt;IAKerb stands for &lt;em&gt;Initial and Pass Through Authentication Using Kerberos V5 and the GSS-API&lt;/em&gt;. The IETF draft has a four-author list -- Benjamin Kaduk, Jim Schaad, Larry Zhu, and Jeffrey E. Altman -- and a quiet history [@draft-ietf-kitten-iakerb].&lt;/p&gt;
&lt;p&gt;The premise is simple. A client wants to authenticate to an application server with Kerberos but cannot reach a KDC -- maybe the client is behind a firewall, maybe the KDC is only reachable from the server&apos;s side of a VPN. IAKerb wraps the Kerberos &lt;code&gt;AS-REQ&lt;/code&gt; and &lt;code&gt;TGS-REQ&lt;/code&gt; messages inside GSS-API tokens and asks the application server to proxy them to a KDC that the server &lt;em&gt;can&lt;/em&gt; reach. The client never opens a direct TCP/UDP connection to a KDC; the application server acts as the carrier.&lt;/p&gt;

The honesty duty: IAKerb&apos;s IETF draft (`draft-ietf-kitten-iakerb`) was marked &quot;Dead WG Document&quot; on August 29, 2019, by Robbie Harwood [@draft-ietf-kitten-iakerb]. Harwood&apos;s note read, roughly, that IAKerb was historical at that point and the working group had no interest left. The last revision (`-03`) is from March 30, 2017, by Benjamin Kaduk. Microsoft is now reviving the protocol in 2023-2026 for Windows 11 and Windows Server 2025 -- without acknowledging the dead-WG status in its own blog posts. This is the gap between an IETF standards-track document and what a vendor ships; the article reports both [@draft-ietf-kitten-iakerb, @palko-2023-evolution].

Initial and Pass Through Authentication Using Kerberos V5 and the GSS-API. A GSS-API-wrapped Kerberos exchange in which the client cannot reach a KDC directly and the application server proxies `AS-REQ` / `TGS-REQ` on the client&apos;s behalf. Defined by `draft-ietf-kitten-iakerb` (IETF kitten WG, currently a Dead WG Document). MIT Kerberos has shipped IAKerb since 1.9 (released February 2011); Apple ships `GSS_IAKERB_MECHANISM` since macOS 10.14. Microsoft is implementing IAKerb in Windows 11 / Server 2025 [@draft-ietf-kitten-iakerb, @palko-2023-evolution, @ms-cuomo-ad2025].
&lt;h3&gt;Local KDC -- closing &quot;no domain at all&quot;&lt;/h3&gt;
&lt;p&gt;Local accounts in the machine SAM have never had a KDC. Workgroup machines have no domain at all. Both cases force NTLM today. The fix is conceptually trivial: run a tiny Kerberos KDC against the local SAM, exposed only through IAKerb-wrapped exchanges so the wire protocol is the same as the trust-traversing case [@palko-2023-evolution, @ms-cuomo-ad2025].&lt;/p&gt;
&lt;p&gt;This is the late-adopter move that surprises Linux-side practitioners. MIT Kerberos has had IAKerb since 1.9 (released February 2011). Samba has been working on a &lt;code&gt;localkdc&lt;/code&gt; for years. At FOSDEM 2025 (February 2, 2025), Alexander Bokovoy and Andreas Schneider gave a talk explicitly framed as &quot;localkdc -- a general local authentication hub&quot; [@cryptomilk-localkdc]. Schneider&apos;s companion blog post the next week summarised the work: a parallel local-authentication hub for Linux that interoperates with the IAKerb wire format Windows is now adopting [@cryptomilk-localkdc].&lt;/p&gt;

A small Kerberos Key Distribution Center process that runs against a machine&apos;s local user database (the SAM on Windows; a file or sssd on Linux) and is exposed only through IAKerb. It lets local-account authentications use Kerberos under the same Negotiate / NEGOEX wire envelope used by domain authentications -- removing one of the four reasons NTLM persisted. Shipping in Windows 11 / Server 2025 [@palko-2023-evolution, @ms-cuomo-ad2025]; parallel Linux/Samba work coordinated under the FOSDEM 2025 `localkdc` umbrella [@cryptomilk-localkdc].
&lt;h3&gt;NEGOEX -- carrying IAKerb under the existing &lt;code&gt;Negotiate&lt;/code&gt; API&lt;/h3&gt;
&lt;p&gt;You do not want to teach every application a new SSPI provider. Existing code calls &lt;code&gt;AcquireCredentialsHandle(&quot;Negotiate&quot;, ...)&lt;/code&gt;; that should keep working, and IAKerb should be one of the mechanisms &lt;code&gt;Negotiate&lt;/code&gt; is willing to pick. The piece of plumbing that makes this possible is NEGOEX: SPNEGO Extended Negotiation [@ms-negoex, @draft-zhu-negoex].&lt;/p&gt;
&lt;p&gt;NEGOEX adds a pair of meta-data messages on top of the standard SPNEGO &lt;code&gt;NegTokenInit&lt;/code&gt; / &lt;code&gt;NegTokenResp&lt;/code&gt; exchange, so that mechanisms (like IAKerb) that need a richer negotiation can ride inside the &lt;code&gt;Negotiate&lt;/code&gt; envelope. The Microsoft Open Specification &lt;code&gt;[MS-NEGOEX]&lt;/code&gt; is currently at revision 4.0 (April 23, 2024), with the original revision dated July 9, 2020 [@ms-negoex]. The expired Microsoft IETF draft &lt;code&gt;draft-zhu-negoex&lt;/code&gt; from January 2011 is the historical anchor; four Microsoft authors -- Michiko Short, Larry Zhu, Kevin Damour, and Dave McPherson -- are listed verbatim in the draft metadata [@draft-zhu-negoex].&lt;/p&gt;
&lt;p&gt;A correction is owed here. Scope notes inherited from earlier in this project cited &quot;RFC 8143&quot; as the NEGOEX standard. RFC 8143 is actually titled &quot;Using Transport Layer Security (TLS) with Network News Transfer Protocol (NNTP)&quot; and updates RFC 4642; it has nothing to do with NEGOEX [@rfc-8143]. The correct primary references for NEGOEX are &lt;code&gt;[MS-NEGOEX]&lt;/code&gt; and &lt;code&gt;draft-zhu-negoex&lt;/code&gt;, both used consistently throughout this article [@ms-negoex, @draft-zhu-negoex].&lt;/p&gt;

The SPNEGO Extended Negotiation security mechanism. Adds a meta-data exchange inside the SPNEGO envelope so that richer mechanisms (like IAKerb) can be negotiated without changing the SSPI surface. Primary sources: Microsoft Open Specification `[MS-NEGOEX]` revision 4.0 (April 2024); expired IETF draft `draft-zhu-negoex` (January 2011). Despite a common scope-doc error, RFC 8143 is *not* NEGOEX; RFC 8143 is &quot;Using TLS with NNTP&quot; [@ms-negoex, @draft-zhu-negoex, @rfc-8143].
&lt;h3&gt;Negotiate-everywhere refactor -- closing &quot;hard-coded NTLM&quot;&lt;/h3&gt;
&lt;p&gt;The last fallback case is the most prosaic: application code that calls &lt;code&gt;AcquireCredentialsHandleW(..., &quot;Ntlm&quot;, ...)&lt;/code&gt; or RPC code that asks for &lt;code&gt;RPC_C_AUTHN_WINNT&lt;/code&gt;. Both bypass &lt;code&gt;Negotiate&lt;/code&gt; and force NTLM no matter what is on the wire. The fix is editorial -- audit Windows internals, replace each hard-coded &lt;code&gt;Ntlm&lt;/code&gt; call with &lt;code&gt;Negotiate&lt;/code&gt; -- and very large in surface area. Dan Cuomo&apos;s &quot;Active Directory improvements in Windows Server 2025&quot; post summarises the Windows Server Summit 2024 session in one sentence: &quot;we have created completely new Kerberos features to minimize use of NTLM in your environments. This session explains and demonstrates IAKerb, Local KDC, IP SPN, and the roadmap to the end of NTLM&quot; [@ms-cuomo-ad2025].&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fallback reason&lt;/th&gt;
&lt;th&gt;Closure mechanism&lt;/th&gt;
&lt;th&gt;Primary source&lt;/th&gt;
&lt;th&gt;Ship target&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;No DC line-of-sight&lt;/td&gt;
&lt;td&gt;IAKerb (GSS-wrapped Kerberos through the app server)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;draft-ietf-kitten-iakerb&lt;/code&gt; (Dead WG, revived by Microsoft) [@draft-ietf-kitten-iakerb]&lt;/td&gt;
&lt;td&gt;Windows 11 / Server 2025 [@palko-2023-evolution, @ms-cuomo-ad2025]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No domain at all (local accounts)&lt;/td&gt;
&lt;td&gt;Local KDC over IAKerb&lt;/td&gt;
&lt;td&gt;Palko 2023; Samba &lt;code&gt;localkdc&lt;/code&gt; parallel [@palko-2023-evolution]&lt;/td&gt;
&lt;td&gt;Windows 11 / Server 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No SPN&lt;/td&gt;
&lt;td&gt;IP-SPN policy under Negotiate&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[MS-NEGOEX]&lt;/code&gt;; Cuomo 2024 session [@ms-negoex, @ms-cuomo-ad2025]&lt;/td&gt;
&lt;td&gt;Windows Server 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard-coded NTLM&lt;/td&gt;
&lt;td&gt;Audit + replace &lt;code&gt;AcquireCredentialsHandle(&quot;Ntlm&quot;)&lt;/code&gt; with &lt;code&gt;Negotiate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Palko 2023 [@palko-2023-evolution]&lt;/td&gt;
&lt;td&gt;Editorial, ongoing through Phase 2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

flowchart LR
    R1[No DC line-of-sight] --&amp;gt; M1[IAKerb&lt;br /&gt;draft-ietf-kitten-iakerb]
    R2[No domain at all&lt;br /&gt;local accounts] --&amp;gt; M2[Local KDC&lt;br /&gt;over IAKerb]
    R3[No SPN for target] --&amp;gt; M3[IP-SPN policy&lt;br /&gt;under Negotiate]
    R4[Hard-coded NTLM&lt;br /&gt;in app code] --&amp;gt; M4[Negotiate-everywhere&lt;br /&gt;refactor]
    M1 --&amp;gt; N[NEGOEX&lt;br /&gt;SPNEGO extension]
    M2 --&amp;gt; N
    M3 --&amp;gt; N
    N --&amp;gt; P[Negotiate SSPI&lt;br /&gt;same call sites]

sequenceDiagram
    autonumber
    participant C as Client (no KDC reach)
    participant S as Application server (KDC reach)
    participant K as KDC
    C-&amp;gt;&amp;gt;S: SPNEGO NegTokenInit with NEGOEX MetaData, mechs=[Kerberos, IAKerb]
    S--&amp;gt;&amp;gt;C: NegTokenResp, server picks IAKerb
    C-&amp;gt;&amp;gt;S: IAKerb token wrapping AS-REQ
    S-&amp;gt;&amp;gt;K: AS-REQ
    K--&amp;gt;&amp;gt;S: AS-REP
    S--&amp;gt;&amp;gt;C: IAKerb token wrapping AS-REP -&amp;gt; client now has TGT
    C-&amp;gt;&amp;gt;S: IAKerb token wrapping TGS-REQ for service ticket
    S-&amp;gt;&amp;gt;K: TGS-REQ
    K--&amp;gt;&amp;gt;S: TGS-REP (service ticket)
    S--&amp;gt;&amp;gt;C: IAKerb token wrapping TGS-REP
    Note over C,S: From now on, ordinary AP-REQ / AP-REP over Kerberos -- no NTLM needed
&lt;p&gt;What does this mean for Linux and macOS clients in a Windows domain? IAKerb is a GSS-API mechanism, and MIT&apos;s &lt;code&gt;krb5&lt;/code&gt; library shipped IAKerb in 1.9 (released February 2011) -- well before Microsoft. Apple&apos;s Heimdal-derived GSS framework has shipped &lt;code&gt;GSS_IAKERB_MECHANISM&lt;/code&gt; since macOS 10.14 (Mojave, 2018). The cross-platform interoperability story is therefore &lt;em&gt;better&lt;/em&gt; in 2026 than it has been in years: a Linux client using MIT 1.9+ or an Apple client using macOS 10.14+ can already speak IAKerb to a Windows Server 2025 Local KDC. The parallel Samba &lt;code&gt;localkdc&lt;/code&gt; effort closes the symmetric case: a Linux machine acting as the IAKerb server [@cryptomilk-localkdc].&lt;/p&gt;
&lt;p&gt;The reader who started Section 6 believing &quot;NTLM is too entrenched to remove&quot; finishes Section 6 believing something else. The entrenchment is &lt;em&gt;exactly four&lt;/em&gt; named cases, and &lt;em&gt;each one&lt;/em&gt; has been given an engineered answer. Removal is now a sequencing problem, not an architecture problem.&lt;/p&gt;
&lt;p&gt;The engineering existed by October 2023. The shipping commitment came in January 2026. What is Microsoft actually shipping, and on what schedule?&lt;/p&gt;
&lt;h2&gt;7. The Three-Phase Roadmap&lt;/h2&gt;
&lt;p&gt;January 29, 2026. The Windows IT Pro Blog publishes &quot;Advancing Windows security: Disabling NTLM by default&quot; under the byline &lt;code&gt;mariam_gewida&lt;/code&gt; [@gewida-2026-disabling]. The post documents Microsoft&apos;s published roadmap and opens with a caveat that the rest of this article works hard not to forget.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &quot;Disabling NTLM by default does not mean completely removing NTLM from Windows yet... during phase 3, NTLM will remain present in the OS and can be explicitly re-enabled via policy if you still need it.&quot; -- mariam_gewida, &quot;Advancing Windows security: Disabling NTLM by default,&quot; Microsoft Windows IT Pro Blog, January 29, 2026 [@gewida-2026-disabling]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The plan has three phases. They are sequenced; each phase produces the inputs the next phase needs.&lt;/p&gt;
&lt;h3&gt;Phase 1 (now) -- Audit&lt;/h3&gt;
&lt;p&gt;Phase 1 is auditing. The deliverable is enhanced NTLM logging in Windows 11 24H2 and Windows Server 2025, documented in KB 5064479 (published July 11, 2025) [@ms-kb5064479]. The new logging surface is &lt;code&gt;Applications and Services Logs &amp;gt; Microsoft &amp;gt; Windows &amp;gt; NTLM &amp;gt; Operational&lt;/code&gt;, gated by two GPOs called &quot;NTLM Enhanced Logging&quot; and &quot;Log Enhanced Domain-wide NTLM Logs.&quot; For each NTLM authentication, the event tells the administrator three things: &lt;em&gt;who&lt;/em&gt; called (the process), &lt;em&gt;why&lt;/em&gt; (the negotiated SSPI provider chose NTLM), and &lt;em&gt;where&lt;/em&gt; (the target service). The KB also names per-event warning classes for NTLMv1, MIC-less, and EPA-not-supported authentications [@ms-kb5064479].&lt;/p&gt;
&lt;p&gt;Phase 1 also closes the oldest residual: NTLMv1. Microsoft&apos;s deprecation page added an NTLM entry in June 2024 with verbatim language: &quot;All versions of NTLM, including LANMAN, NTLMv1, and NTLMv2, are no longer under active feature development and are deprecated. Use of NTLM will continue to work in the next release of Windows Server and the next annual release of Windows. Calls to NTLM should be replaced by calls to Negotiate&quot; [@ms-deprecated-features].&lt;/p&gt;
&lt;p&gt;The same row adds: &quot;NTLMv1 is removed starting in Windows 11, version 24H2 and Windows Server 2025&quot; -- the November 2024 update note [@ms-deprecated-features]. The KB 4090105 pre-24H2 NTLMv1 auditing surface (Event ID 4624 with &lt;code&gt;Package Name (NTLM only): NTLM V1&lt;/code&gt;) remains valid for legacy environments [@ms-ntlmv1-dc-audit].&lt;/p&gt;
&lt;h3&gt;Phase 2 (H2 2026) -- IAKerb + Local KDC + Negotiate-first refactor in pre-release&lt;/h3&gt;
&lt;p&gt;Phase 2 puts the engineered closures from Section 6 into pre-release. IAKerb and Local KDC ship for Windows Insiders and Server preview channels. The Negotiate-first refactor lands -- Microsoft&apos;s own subsystems audit their &lt;code&gt;AcquireCredentialsHandleW(&quot;Ntlm&quot;, ...)&lt;/code&gt; and &lt;code&gt;RPC_C_AUTHN_WINNT&lt;/code&gt; call sites and replace them with &lt;code&gt;Negotiate&lt;/code&gt; calls. Per-machine policy controls for NTLM scope make finer-grained restriction possible. IP-SPN policy lands so the &quot;no SPN&quot; case can be closed without naming every server by FQDN [@gewida-2026-disabling, @ms-cuomo-ad2025].&lt;/p&gt;
&lt;p&gt;The Microsoft outreach mechanism for Phase 2 is the &lt;code&gt;ntlm@microsoft.com&lt;/code&gt; mailbox; the January 2026 post names it explicitly as the channel for surfacing cross-forest, federated, and ISV-edge cases that need engineering help before Phase 3 [@gewida-2026-disabling].&lt;/p&gt;
&lt;h3&gt;Phase 3 (next major Windows / Windows Server release) -- Disabled by default&lt;/h3&gt;
&lt;p&gt;Phase 3 is the default-off flip. Network NTLM authentication is disabled by default in the next major Windows and Windows Server release. The disablement is a configuration, not a binary removal: NTLM remains in the OS, callable through &lt;code&gt;Negotiate&lt;/code&gt; only when a policy explicitly re-enables it for a named scope [@gewida-2026-disabling]. The Hacker News&apos; summary of the roadmap published February 2026 documents the same three-phase structure for industry-press consumption [@thn-2026-ntlm-phaseout].&lt;/p&gt;

flowchart LR
    P1[Phase 1 -- NOW&lt;br /&gt;KB 5064479 enhanced auditing&lt;br /&gt;NTLMv1 removed in 24H2 / WS2025] --&amp;gt; P2
    P2[Phase 2 -- H2 2026&lt;br /&gt;IAKerb + Local KDC pre-release&lt;br /&gt;Negotiate-first refactor&lt;br /&gt;Per-machine NTLM scope policy] --&amp;gt; P3
    P3[Phase 3 -- next major Windows&lt;br /&gt;Network NTLM disabled by default&lt;br /&gt;Re-enablement requires explicit policy]
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Phase&lt;/th&gt;
&lt;th&gt;Deliverable&lt;/th&gt;
&lt;th&gt;Date / target&lt;/th&gt;
&lt;th&gt;Prerequisite&lt;/th&gt;
&lt;th&gt;Primary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Phase 1&lt;/td&gt;
&lt;td&gt;Enhanced NTLM auditing&lt;/td&gt;
&lt;td&gt;KB 5064479, July 11, 2025&lt;/td&gt;
&lt;td&gt;Windows 11 24H2 / Server 2025&lt;/td&gt;
&lt;td&gt;[@ms-kb5064479]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phase 1&lt;/td&gt;
&lt;td&gt;NTLMv1 removal&lt;/td&gt;
&lt;td&gt;Windows 11 24H2 / Server 2025, November 2024&lt;/td&gt;
&lt;td&gt;NTLM family deprecation (June 2024)&lt;/td&gt;
&lt;td&gt;[@ms-deprecated-features]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phase 2&lt;/td&gt;
&lt;td&gt;IAKerb + Local KDC pre-release&lt;/td&gt;
&lt;td&gt;H2 2026, Windows Insider channel&lt;/td&gt;
&lt;td&gt;Phase 1 audit data identifies callers&lt;/td&gt;
&lt;td&gt;[@gewida-2026-disabling, @ms-cuomo-ad2025]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phase 2&lt;/td&gt;
&lt;td&gt;Negotiate-first refactor of Windows subsystems&lt;/td&gt;
&lt;td&gt;H2 2026&lt;/td&gt;
&lt;td&gt;Phase 1 audit data&lt;/td&gt;
&lt;td&gt;[@palko-2023-evolution, @gewida-2026-disabling]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phase 2&lt;/td&gt;
&lt;td&gt;IP-SPN policy for &quot;no SPN&quot; case&lt;/td&gt;
&lt;td&gt;Windows Server 2025 + flighting&lt;/td&gt;
&lt;td&gt;NEGOEX in Negotiate&lt;/td&gt;
&lt;td&gt;[@ms-cuomo-ad2025]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phase 3&lt;/td&gt;
&lt;td&gt;Network NTLM disabled by default&lt;/td&gt;
&lt;td&gt;Next major Windows / Server release&lt;/td&gt;
&lt;td&gt;All Phase 2 features GA&lt;/td&gt;
&lt;td&gt;[@gewida-2026-disabling]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Phase 3 is the first default configuration in 30 years that does not include NTLM. It is &lt;em&gt;not&lt;/em&gt; the first configuration in 30 years without authentication-relay attacks. Why not?&lt;/p&gt;
&lt;h2&gt;8. What Disabling NTLM Cannot Buy You&lt;/h2&gt;
&lt;p&gt;A blunt section. Phase 3 is real progress. It is not the end of authentication attacks on Windows. Three structural ceilings survive the transition; the article will not pretend otherwise.&lt;/p&gt;
&lt;h3&gt;Disabled is not removed&lt;/h3&gt;
&lt;p&gt;Phase 3 still ships NTLM in the OS. The default is off; the policy lockout is exactly as strong as the domain&apos;s tier-0 administrative segregation, not stronger. An attacker who reaches a domain controller with Group Policy edit rights can flip the policy and re-enable NTLM for the scope they want. The wording in the January 2026 post is precise: &quot;during phase 3, NTLM will remain present in the OS and can be explicitly re-enabled via policy if you still need it&quot; [@gewida-2026-disabling].&lt;/p&gt;
&lt;p&gt;This is the design choice Microsoft has to make, because removing NTLM binaries entirely would brick every third-party application that hard-codes &lt;code&gt;Ntlm&lt;/code&gt; and every legacy device that has not been firmware-updated since 2018. &quot;Disabled by default with policy override&quot; is the only configuration that has any chance of getting deployed.&lt;/p&gt;
&lt;h3&gt;Kerberos has its own relay class&lt;/h3&gt;
&lt;p&gt;The relay &lt;em&gt;class&lt;/em&gt; does not depend on NTLM. KrbRelay, KrbRelayUp, RBCD abuse, unconstrained-delegation abuse, S4U2Self / S4U2Proxy chains -- the entire taxonomy survives the move to Kerberos with different named primitives. Dec0ne&apos;s KrbRelayUp README, quoted at the end of Section 4, calls the class a universal no-fix local privilege escalation; the rest of the README enumerates the LDAP-signing default and the RBCD primitive that drive the post-NTLM relay surface [@gh-krbrelayup].&lt;/p&gt;
&lt;p&gt;What changes is the protocol. What does not change is that an application server that receives an authenticated message without enforcing message integrity or channel binding can be coerced into accepting an attacker-relayed authentication. The named primitives change. The class survives.&lt;/p&gt;
&lt;h3&gt;Local SAM hashes remain password-equivalent&lt;/h3&gt;
&lt;p&gt;The Local KDC reads the SAM. An attacker with SYSTEM-level access to the same machine reads the SAM too. Once they have the hash in hand, they can either feed it to a Local KDC running on a machine they control, or they can attempt offline cracking. IAKerb does not change either of those facts; what it changes is whether the &lt;em&gt;wire&lt;/em&gt; exposes the password-equivalent secret. Defence in depth -- &lt;a href=&quot;https://paragmali.com/blog/the-tpm-in-windows-one-primitive-twenty-five-years-and-the-c/&quot; rel=&quot;noopener&quot;&gt;TPM&lt;/a&gt;-backed key wrapping, Credential Guard for VBS isolation of process credentials, &lt;a href=&quot;https://paragmali.com/blog/bitlocker-on-windows-architecture-attacks-and-the-limits-of-/&quot; rel=&quot;noopener&quot;&gt;BitLocker&lt;/a&gt; for the cold-boot scenario -- remains necessary [@ms-credential-guard].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Phase 3 is a transition between tradeoffs, not a transition out of them. The exit from NTLM-the-protocol is not the exit from the authentication-relay class, or from the chip-layer credential class. The arc closes one specific 30-year-old attack surface and opens different conversations about the next.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the structural classes survive, what practical problems remain that an administrator should worry about between today and Phase 3?&lt;/p&gt;
&lt;h2&gt;9. Open Problems and the 2026-2027 Edge&lt;/h2&gt;
&lt;p&gt;Five named problems sit between Phase 1 (now) and Phase 3 GA. Each one has a primary source and a &quot;best partial result&quot; available today.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ESC8 field deployment of EPA on &lt;code&gt;/certsrv/&lt;/code&gt; is uneven.&lt;/strong&gt; Microsoft published KB 5005413 on July 23, 2021 with the dispositive recipe: &lt;code&gt;&amp;lt;extendedProtectionPolicy policyEnforcement=&quot;Always&quot; /&amp;gt;&lt;/code&gt; on every &lt;code&gt;/certsrv/&lt;/code&gt; virtual directory, plus disabling plain HTTP. Server 2025 hardening pushes EPA to required-by-default in many AD CS templates. Many environments are not on Server 2025 yet, and CISA&apos;s Known Exploited Vulnerabilities catalog still lists CVE-2021-36942 as actively exploited. CVE-2022-26925 (&quot;Windows LSA Spoofing Vulnerability&quot;) is the LSARPC NTLM-relay variant that emerged after the initial PetitPotam patches; it is on the same KEV list [@ms-kb5005413].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Third-party and legacy-app hard-coded NTLM.&lt;/strong&gt; Microsoft&apos;s Negotiate-everywhere refactor covers Microsoft&apos;s own code. Independent software vendors must do the same audit for theirs. Phase 1&apos;s enhanced auditing surface (KB 5064479) is the practical instrument for identifying the callers: every NTLM authentication carries the calling process name and a reason code [@ms-kb5064479]. The post-Phase-3 default-off configuration will surface these as outages on any environment that has not run the audit first.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cross-forest and federated IAKerb edges.&lt;/strong&gt; Single-forest IAKerb is well-defined. Multi-forest, federated, and partner-trust scenarios get implementation-defined quickly: NEGOEX has to carry IAKerb tokens through &lt;code&gt;Negotiate&lt;/code&gt; across trust boundaries where the proxying server may not be in the same forest as the KDC. Microsoft&apos;s &lt;code&gt;ntlm@microsoft.com&lt;/code&gt; outreach mailbox exists precisely to surface these edge cases before Phase 3 [@draft-ietf-kitten-iakerb, @gewida-2026-disabling].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Linux and macOS parallel.&lt;/strong&gt; MIT Kerberos has had IAKerb since 1.9 (released February 2011). Apple ships &lt;code&gt;GSS_IAKERB_MECHANISM&lt;/code&gt; since macOS 10.14. The Samba and &lt;code&gt;localkdc&lt;/code&gt; effort from Bokovoy and Schneider (FOSDEM 2025) is the parallel open-source path: a Linux machine that can act as the IAKerb application server for a Windows client, or vice versa, under the same &lt;code&gt;Negotiate&lt;/code&gt; envelope [@cryptomilk-localkdc]. The interoperability story should be &lt;em&gt;better&lt;/em&gt; in 2026-2027 than it has been in twenty years.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Policy pressure.&lt;/strong&gt; EU NIS2 mandates cybersecurity risk-management measures for entities in critical sectors; the Cyber Resilience Act adds mandatory security requirements for products with digital elements. Both frameworks make legacy authentication a documented compliance concern. Deprecation of NTLM under Microsoft&apos;s own deprecation page (&lt;code&gt;ms-deprecated-features&lt;/code&gt;) gives a clean audit surface that did not exist before; an organisation can point to KB 5064479 audit data showing NTLM call sites with named callers and target services, and demonstrate progress on retirement [@ms-deprecated-features].The EU regulatory framing here is touched lightly because the primary texts (NIS2 Directive, Cyber Resilience Act) are extensive regulatory documents this article does not quote verbatim beyond the European Commission&apos;s official summaries. The relevant connection is operational: deprecation pages and audit logs give compliance teams an artifact for &quot;we are retiring this class of credential under a published deprecation,&quot; which is the kind of evidence regulators ask for.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All five problems converge to one question for the AD engineer reading this article: &lt;em&gt;what should I do this quarter?&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;10. What an AD Engineer Should Do This Quarter&lt;/h2&gt;
&lt;p&gt;Six numbered actions, ordered by impact. No filler, no compliance boilerplate.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This is the prerequisite. Without Who/Why/Where data, Phase 3 surfaces breakage as outage. Enable the &quot;NTLM Enhanced Logging&quot; and &quot;Log Enhanced Domain-wide NTLM Logs&quot; GPOs on every domain controller and member server you operate. Subscribe to the &lt;code&gt;Applications and Services Logs &amp;gt; Microsoft &amp;gt; Windows &amp;gt; NTLM &amp;gt; Operational&lt;/code&gt; channel. Identify every process that initiates NTLM, the reason &lt;code&gt;Negotiate&lt;/code&gt; declined Kerberos, and the target service. Triage by call volume and criticality [@ms-kb5064479].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Set &lt;code&gt;LDAPClientIntegrity = 2&lt;/code&gt; and &lt;code&gt;LdapEnforceChannelBinding = 2&lt;/code&gt; on every domain controller. This closes SMB-to-LDAP relay regardless of whether the originating authentication was NTLM or Kerberos. KrbRelayUp&apos;s existence makes this &lt;em&gt;more&lt;/em&gt; urgent post-NTLM, not less: the relay class on Kerberos uses the same un-anchored LDAP target [@gh-krbrelayup].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The KB 5005413 recipe is verbatim: add &lt;code&gt;&amp;lt;extendedProtectionPolicy policyEnforcement=&quot;Always&quot; /&amp;gt;&lt;/code&gt; to the authentication element of the IIS virtual directory and disable plain HTTP. &lt;code&gt;/certsrv/&lt;/code&gt; is the dispositive ESC8 target. Web Enrollment proxy endpoints (&lt;code&gt;/certenroll/&lt;/code&gt;, &lt;code&gt;/adpolicyprovider_cep_kerberos/&lt;/code&gt; and similar) are the second tier. Audit every IIS authentication endpoint in the estate and confirm &lt;code&gt;policyEnforcement=&quot;Always&quot;&lt;/code&gt; is the value, not &lt;code&gt;&quot;None&quot;&lt;/code&gt; or &lt;code&gt;&quot;Partial&quot;&lt;/code&gt; [@ms-kb5005413].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Print Spooler service is the single highest-impact MS-RPRN coercion surface. Disabling Spooler on every server that does not actually print closes the entire &lt;code&gt;RpcRemoteFindFirstPrinterChangeNotificationEx&lt;/code&gt; coercion class on those hosts. Microsoft&apos;s hardening guidance and the PrintNightmare disclosures (2021) made this an explicit recommendation [@gh-spoolsample].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Coercer&apos;s scan mode is the canonical defensive auditing tool: it inventories which RPC coercion methods a given server still answers. Run it against every server you operate, in scan mode. The output is a list of unauthenticated and authenticated coercion endpoints to either patch, disable, or compensate around. Treat unauthenticated endpoints (LSARPC, &lt;code&gt;\PIPE\lsarpc&lt;/code&gt;) as P0 [@gh-coercer].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Microsoft&apos;s preferred sequence: Windows Insider flighting -&amp;gt; pilot non-production NTLM-off configurations -&amp;gt; identify hard-coded &lt;code&gt;Ntlm&lt;/code&gt; SSPI calls in your in-house code -&amp;gt; stage Phase-3 rollout against your audit data. If you wait, the cut-over surfaces breakage as outage. If you audit, the cut-over is uneventful [@gewida-2026-disabling].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Phase 1 audit is the load-bearing piece. Action 1 produces the data that makes Actions 2-6 prioritise correctly. The following snippet sketches the audit-event query logic an administrator would express in PowerShell -- the JavaScript runs the same logic so you can think through edge cases interactively.&lt;/p&gt;
&lt;p&gt;{`
// Sketch of the triage logic an administrator would run against
// &quot;Applications and Services Logs &amp;gt; Microsoft &amp;gt; Windows &amp;gt; NTLM &amp;gt; Operational&quot;
// after enabling the KB 5064479 enhanced auditing GPOs. The point of running
// this in JavaScript is to make the rules explicit so you can think through
// edge cases without standing up a Windows event channel.&lt;/p&gt;
&lt;p&gt;const sampleEvents = [
  { process: &quot;C:\\app\\legacy.exe&quot;,      reason: &quot;NoSPN&quot;,          target: &quot;ldap/dc01.example.local&quot;, count: 142 },
  { process: &quot;C:\\Program Files\\Backup\\agent.exe&quot;, reason: &quot;ExplicitNtlm&quot;,   target: &quot;cifs/backup02.example.local&quot;, count: 9 },
  { process: &quot;C:\\Windows\\System32\\spoolsv.exe&quot;,   reason: &quot;NoDcReach&quot;,      target: &quot;cifs/attacker.example.local&quot;, count: 1 },
  { process: &quot;C:\\Windows\\System32\\lsass.exe&quot;,     reason: &quot;LocalAccount&quot;,   target: &quot;host\\WORKGROUP-PC01&quot;,   count: 38 },
  { process: &quot;C:\\Windows\\System32\\svchost.exe&quot;,   reason: &quot;NoSPN&quot;,          target: &quot;host/aliased.example.local&quot;, count: 7 },
];&lt;/p&gt;
&lt;p&gt;function triage(events) {
  const out = [];
  for (const e of events) {
    let severity = &quot;info&quot;;
    let actions = [];
    if (e.reason === &quot;ExplicitNtlm&quot;) {
      severity = &quot;high&quot;;
      actions.push(&quot;Fix caller: replace AcquireCredentialsHandle(&apos;Ntlm&apos;) with &apos;Negotiate&apos;&quot;);
    }
    if (e.reason === &quot;NoSPN&quot;) {
      severity = &quot;medium&quot;;
      actions.push(&quot;Register an SPN for the target or enable IP-SPN policy&quot;);
    }
    if (e.reason === &quot;LocalAccount&quot;) {
      severity = &quot;medium&quot;;
      actions.push(&quot;Plan Local KDC enrollment in Phase 2 pilot&quot;);
    }
    if (/spoolsv\.exe$/i.test(e.process) &amp;amp;&amp;amp; /attacker/i.test(e.target)) {
      severity = &quot;critical&quot;;
      actions.push(&quot;Suspicious: Spooler authenticating to non-domain UNC. Likely coercion attempt -- isolate, then disable Spooler on this host&quot;);
    }
    out.push({ process: e.process, severity, actions });
  }
  return out;
}&lt;/p&gt;
&lt;p&gt;for (const row of triage(sampleEvents)) {
  console.log(`[${row.severity.toUpperCase()}] ${row.process}`);
  for (const a of row.actions) console.log(&quot;    -&amp;gt; &quot; + a);
}
`}&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; - &lt;strong&gt;&lt;code&gt;LMCompatibilityLevel = 5&lt;/code&gt; without audit.&lt;/strong&gt; Forcing NTLMv2-only on every DC is correct as an endpoint, but flipping it without first running KB 5064479 audit will outage legacy applications that still attempt NTLMv1 [@ms-kb5064479]. - &lt;strong&gt;&lt;code&gt;RestrictNTLM:Deny&lt;/code&gt; without exceptions.&lt;/strong&gt; The Restrict NTLM family of GPOs supports per-server exemptions. Going straight to &lt;code&gt;Deny&lt;/code&gt; without an exemption list is the classic outage path. - &lt;strong&gt;EPA on HTTPS-only while leaving plain HTTP enabled.&lt;/strong&gt; KB 5005413 explicitly requires &lt;em&gt;both&lt;/em&gt; &lt;code&gt;policyEnforcement=&quot;Always&quot;&lt;/code&gt; and disabling plain HTTP on &lt;code&gt;/certsrv/&lt;/code&gt;. Leaving HTTP up makes the EPA enforcement moot [@ms-kb5005413]. - &lt;strong&gt;Trusting Credential Guard against coercion.&lt;/strong&gt; Credential Guard protects against credential &lt;em&gt;theft&lt;/em&gt;. It does not protect against ESC8, PetitPotam, or any other relay-of-live-authentication chain [@ms-credential-guard].&lt;/p&gt;
&lt;/blockquote&gt;

On a non-production Windows 11 Insider machine, the per-machine NTLM scope policy lives under `HKLM\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0`. Microsoft&apos;s pre-release documentation will name the value used to gate the Phase 2 IAKerb / Local KDC behaviours; consult the Windows Insider release notes that ship with the Phase 2 flight rather than hard-coding a value here -- the keys are subject to change up to GA. Use the `ntlm@microsoft.com` outreach channel for any environment-specific question [@gewida-2026-disabling].
&lt;p&gt;This is the work. The Phase 3 deadline is the next major Windows release; the Phase 1 audit window is right now. If you wait, the cut-over surfaces breakage as outage. If you audit, the cut-over is uneventful.&lt;/p&gt;
&lt;h2&gt;11. Frequently Asked Questions&lt;/h2&gt;

No. NTLMv2 is the version Drop-the-MIC, PetitPotam, and ESC8 all attack [@nvd-cve-2019-1040, @specterops-cert-preowned-blog]. The HMAC-MD5 response is strong against the response side, but the password-equivalence of the NT-hash and the lack of binding to the underlying transport are the structural properties every modern attack exploits. NTLMv2 is the *least bad* NTLM, not a safe NTLM.

Phase 1 controls let you *audit*. Phase 2 features (IAKerb, Local KDC, IP-SPN, the Negotiate refactor) are what make disabling *survivable* for most organisations. If you go straight to `RestrictNTLM:Deny` without running the KB 5064479 audit first, you will outage legacy applications and possibly your help-desk laptops. The honest answer is: audit now, pilot Phase 2 in H2 2026, default-off at Phase 3 [@gewida-2026-disabling, @ms-kb5064479].

No. Credential Guard fixes credential *theft* from LSASS. It does nothing about credential *use* (relay), coercion (PetitPotam), or cross-protocol chains (ESC8). It is necessary -- ESC8 + Mimikatz is worse than ESC8 alone -- but it is not sufficient against the relay class [@ms-credential-guard].

No. KrbRelay and KrbRelayUp demonstrate the relay *class* survives on Kerberos. What changes is the named primitives, not the existence of relay. Defence is the same shape after Phase 3 as before: LDAP signing and channel binding everywhere, EPA enforced on every authentication endpoint, message integrity required at every level [@gh-krbrelayup].

Because the four fallback reasons (no DC, local accounts, no SPN, hard-coded NTLM) had no engineered answer until IAKerb, Local KDC, NEGOEX, and the Negotiate refactor existed in shippable form. The standards work, the IETF drafts (one of which was marked Dead WG Document in 2019 and is being revived), the MIT 1.9 parity, and the Apple precedent all had to exist before Microsoft had a credible removal path that did not break enterprise deployments [@palko-2023-evolution, @draft-ietf-kitten-iakerb].

Yes. MIT Kerberos has had IAKerb since 1.9 (released February 2011). Apple ships `GSS_IAKERB_MECHANISM` since macOS 10.14 (Mojave, 2018). The Samba `localkdc` effort from Bokovoy and Schneider (FOSDEM 2025) is the parallel open-source path for a Linux local KDC. Heterogeneous Windows-domain estates with Linux file servers and macOS clients are positioned to interoperate with Phase 3 *better* than they did with NTLMv2 [@cryptomilk-localkdc].
&lt;p&gt;NTLM was the answer to a 1987 problem and a 1993 problem. It survived because removing it required engineering four orthogonal capabilities that did not exist. They exist now. The next major Windows release ships without it on by default. The attacks that follow it -- KrbRelayUp, RBCD chains, S4U2Self abuse, certificate-template misconfiguration -- target a different protocol with a different vocabulary. The relay &lt;em&gt;class&lt;/em&gt; persists. The protocol it targets is no longer NTLM.&lt;/p&gt;
&lt;p&gt;If you read this article as part of a sequence, the prior pieces cover the &lt;a href=&quot;https://paragmali.com/blog/windows-access-control-25-years-of-attacks/&quot; rel=&quot;noopener&quot;&gt;access-control model&lt;/a&gt; (&lt;code&gt;SeAccessCheck&lt;/code&gt; and its inputs), the chip-layer credential story (TPM, &lt;a href=&quot;https://paragmali.com/blog/pluton-a-tpm-on-silicon-microsoft-can-patch/&quot; rel=&quot;noopener&quot;&gt;Pluton&lt;/a&gt;, Credential Guard, BitLocker), and the &lt;a href=&quot;https://paragmali.com/blog/windows-app-identity-33-year-reinvention/&quot; rel=&quot;noopener&quot;&gt;application-identity layer&lt;/a&gt; (Authenticode, signed binaries, AppLocker, smart application control). NTLM removal is one strand of the broader move from &quot;trust the perimeter&quot; to &quot;tie every credential to a token, a chip, or a Kerberos ticket whose lifetime you can name.&quot; Each strand by itself is incomplete; together they are how the next decade of Windows authentication looks.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;ntlmless-the-death-of-ntlm-in-windows&quot; keyTerms={[
  { term: &quot;LM hash&quot;, definition: &quot;1987 LAN Manager hash. Uppercase the password, pad/truncate to 14 characters, split into two 7-byte halves, DES-encrypt KGS!@#$% with each half. Password-equivalent, case-insensitive, no salt.&quot; },
  { term: &quot;NT-hash&quot;, definition: &quot;MD4(UTF-16LE(password)). Sixteen bytes. The long-term secret every NTLM response derives from. Possession equals authority.&quot; },
  { term: &quot;NTLMv2&quot;, definition: &quot;HMAC-MD5 response over server_challenge || client_challenge || timestamp || av_pairs, keyed by NTOWFv2 = HMAC_MD5(NT-hash, UNICODE(Upper(user)||domain)). Ships in NT 4.0 SP4, October 1998.&quot; },
  { term: &quot;SPNEGO / Negotiate&quot;, definition: &quot;The GSS-API negotiation mechanism Windows uses to pick between Kerberos and NTLM. The Windows SSPI provider is called Negotiate.&quot; },
  { term: &quot;MIC&quot;, definition: &quot;Message Integrity Code -- HMAC-MD5 keyed by ExportedSessionKey over the concatenation of all three NTLM messages. Defeated by Drop-the-MIC (CVE-2019-1040).&quot; },
  { term: &quot;EPA / CBT&quot;, definition: &quot;Extended Protection for Authentication / Channel Binding Token. A hash of the TLS endpoint certificate placed in the MsvAvChannelBindings AV_PAIR.&quot; },
  { term: &quot;Pass-the-Hash&quot;, definition: &quot;Using a stolen NT-hash directly as the credential, without ever knowing the cleartext password. First published by Paul Ashton in 1997.&quot; },
  { term: &quot;NTLM relay&quot;, definition: &quot;Forwarding a live NTLM exchange between a victim client and a third-party target. First public PoC: Sir Dystic&apos;s SMBRelay (March 31, 2001).&quot; },
  { term: &quot;Coercion&quot;, definition: &quot;Causing a Windows service running as SYSTEM to NTLM-authenticate to an attacker-controlled destination via an RPC method that takes a UNC path. SpoolSample (2018), PetitPotam (2021), Coercer (2022).&quot; },
  { term: &quot;ESC8&quot;, definition: &quot;Coerced NTLM relayed to AD CS Web Enrollment (/certsrv/), yielding a certificate that yields a TGT via PKINIT. Schroeder + Christensen, Certified Pre-Owned, June 17, 2021.&quot; },
  { term: &quot;IAKerb&quot;, definition: &quot;Initial and Pass Through Authentication Using Kerberos V5 and the GSS-API. Lets a client with no KDC reach proxy AS-REQ / TGS-REQ through an application server.&quot; },
  { term: &quot;Local KDC&quot;, definition: &quot;A small Kerberos KDC against the local SAM, exposed via IAKerb. Shipping in Windows 11 / Server 2025.&quot; },
  { term: &quot;NEGOEX&quot;, definition: &quot;SPNEGO Extended Negotiation. Adds a meta-data exchange inside the SPNEGO envelope so IAKerb can be negotiated under Negotiate. NOT RFC 8143 (which is NNTP+TLS); the correct primaries are [MS-NEGOEX] and draft-zhu-negoex.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows-security</category><category>ntlm</category><category>kerberos</category><category>active-directory</category><category>pass-the-hash</category><category>ntlm-relay</category><category>petitpotam</category><category>esc8</category><author>noreply@paragmali.com (Parag Mali)</author></item></channel></rss>