<?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: authentication</title><description>Posts tagged authentication.</description><link>https://paragmali.com/</link><language>en-US</language><lastBuildDate>Sun, 07 Jun 2026 04:13:14 GMT</lastBuildDate><atom:link href="https://paragmali.com/tags/authentication/rss.xml" rel="self" type="application/rss+xml"/><item><title>From Password-in-the-Pipe to Cloud-Issued Session: Twenty-Six Years of RDP Authentication</title><link>https://paragmali.com/blog/rdp-authentication-26-years/</link><guid isPermaLink="true">https://paragmali.com/blog/rdp-authentication-26-years/</guid><description>How five generations of Windows RDP authentication -- classic delegation, NLA via CredSSP, Restricted Admin, Remote Credential Guard, and PRT-over-RDP -- retreated from the 1998 design that gave attackers the keys to every target.</description><pubDate>Tue, 12 May 2026 00:00:00 GMT</pubDate><content:encoded>
**Remote Desktop Protocol** has spent twenty-six years retreating from one design decision: in 1998, &quot;the user&apos;s password becomes the target&apos;s credential.&quot; Five generations now coexist on a Windows estate. **Classic credential delegation** sends the user&apos;s NT one-way function into the target&apos;s `lsass.exe`. **Network Level Authentication via CredSSP** [@rdpbcgr-credssp] (Windows Vista, 2006) moves authentication before the session starts but still delivers credential material. **Restricted Admin mode** [@ms-adv-2871997] (Windows 8.1 / Server 2012 R2 RTM, October 17, 2013) stops delivering credentials and runs the user&apos;s session as the target&apos;s machine identity. **Remote Credential Guard** [@msl-rcg] (Windows 10 1607, August 2, 2016) forwards Kerberos operations back to the caller&apos;s `lsass.exe`, with VTL1 trustlet protection conditional on the caller having local Credential Guard enabled. **PRT-over-RDP** [@msl-prtrdp-mstsc] (October 11, 2022 cumulative updates) uses a Microsoft Entra ID Primary Refresh Token cookie scoped to the Conditional Access app `a4a365df-50f1-4397-bc59-1a1564b8bb9c`. **CVE-2018-0886** [@nvd-2018-0886] (CredSSP MITM) and **CVE-2019-0708** [@nvd-2019-0708] (BlueKeep, pre-auth channel-setup) are the canonical RDP CVEs. The residual classes are RBCD against `TERMSRV` [@shamir-wagging], PRT extraction at the session host [@mollema-prt2], and the architectural SYSTEM-on-target floor that no RDP mode can close.
&lt;h2&gt;1. Four sekurlsa Dumps, One Target&lt;/h2&gt;
&lt;p&gt;A red-team operator with &lt;code&gt;SYSTEM&lt;/code&gt; on a single Windows 11 25H2 host runs &lt;code&gt;mimikatz sekurlsa::logonpasswords&lt;/code&gt; four times in a row [@mimikatz-github]. Each time, a different user has just disconnected an RDP session. Each time, the dump looks different.&lt;/p&gt;
&lt;p&gt;The first dump shows the user&apos;s NT one-way function. The second dump shows the target machine&apos;s identity instead of the user&apos;s. The third dump shows the user&apos;s identity but no hash that can be replayed anywhere. The fourth dump shows no password-equivalent material for the user at all -- only a Primary Refresh Token bound to the target&apos;s own TPM.&lt;/p&gt;
&lt;p&gt;Four RDP sessions, one target, four entirely different post-exploitation pivots. The difference is not in what the attacker did. The difference is in which authentication mode the client negotiated before the session was established.&lt;/p&gt;
&lt;p&gt;This article is about those four modes -- classic, Restricted Admin, Remote Credential Guard, and PRT-over-RDP -- and the fifth (NLA via CredSSP) that sits underneath them all. It is the story of a twenty-six-year retreat from &quot;the user&apos;s password becomes the target&apos;s credential.&quot;&lt;/p&gt;
&lt;p&gt;The wire-protocol selectors are public, even if their names mostly are not. The &lt;code&gt;RDP_NEG_REQ&lt;/code&gt; structure [@rdpbcgr-negreq] sets &lt;code&gt;requestedProtocols&lt;/code&gt; to one of &lt;code&gt;PROTOCOL_RDP (0x00)&lt;/code&gt;, &lt;code&gt;PROTOCOL_SSL (0x01)&lt;/code&gt;, &lt;code&gt;PROTOCOL_HYBRID (0x02)&lt;/code&gt; for CredSSP-based NLA, &lt;code&gt;PROTOCOL_HYBRID_EX (0x08)&lt;/code&gt;, or &lt;code&gt;PROTOCOL_RDSAAD (0x10)&lt;/code&gt; for the Entra-based path. Inside &lt;code&gt;PROTOCOL_HYBRID&lt;/code&gt;, two &lt;code&gt;flags&lt;/code&gt; bits switch the sub-mode: &lt;code&gt;RESTRICTED_ADMIN_MODE_REQUIRED (0x01)&lt;/code&gt; and &lt;code&gt;REDIRECTED_AUTHENTICATION_MODE_REQUIRED (0x02)&lt;/code&gt;. Five wire-level paths. Five different answers to the same question: what does the target&apos;s &lt;code&gt;lsass.exe&lt;/code&gt; end up holding?&lt;/p&gt;
&lt;p&gt;The next twelve sections walk each mode end-to-end, the CVEs that broke each layer, the Microsoft Learn comparison matrix verbatim, the residual class that survives each generation, and the operational guide for the engineer who has to make these primitives interoperate on Monday morning. Before we can read the four dumps, we have to understand the one credential-delivery decision every later generation was built to correct. That decision shipped in 1998.&lt;/p&gt;
&lt;h2&gt;2. Terminal Services and the Password-in-the-Pipe Era (1998-2005)&lt;/h2&gt;
&lt;p&gt;In 1998 Microsoft shipped a remote-display product that solved an obvious problem -- run a Windows desktop over the network -- and a second, less obvious problem along the way: every machine that accepted an RDP connection now needed to be a credential reservoir for every user who connected to it.&lt;/p&gt;
&lt;p&gt;The product was Windows NT 4.0 Terminal Server Edition [@wiki-nt4tse], built on top of MultiWin technology that Microsoft had licensed from Citrix the previous year [@wiki-rdp]. The protocol that carried the display and the keystrokes was the Remote Desktop Protocol, version 4.0, listening on TCP port 3389 (and, much later, UDP port 3389 for the QUIC variant) [@wiki-rdp]. The protocol itself was an extension of the ITU-T T.128 application-sharing protocol [@wiki-rdp], with RC4 channel encryption layered on top using a 40-bit, 56-bit, or 128-bit session key (a FIPS-validated 3DES variant was added in Server 2003) [@rdpbcgr-index].&lt;/p&gt;

timeline
    title Twenty-six years of RDP authentication
    1998 : NT 4.0 Terminal Server Edition / RDP 4.0
         : Password delivered to target&apos;s lsass
    2001 : SMBRelay (cDc) names credential-in-motion attack
    2006 : Windows Vista / RDP 6.0 ships NLA via CredSSP
    2013 : Windows 8.1 / 2012 R2 ships Restricted Admin
    2014 : KB2871997 backports Restricted Admin to Win 7
    2016 : Windows 10 1607 / 2016 ships Remote Credential Guard
    2018 : CVE-2018-0886 CredSSP RCE; AllowEncryptionOracle
    2019 : CVE-2019-0708 BlueKeep pre-auth channel-setup RCE
    2022 : KB5018418 ships PRT-over-RDP / Entra SSO for RDP
    2025 : Win 11 24H2 KIR recovers from RDP-stack regression

Microsoft&apos;s multi-user remote-desktop subsystem, introduced in Windows NT 4.0 Terminal Server Edition (1998) [@wiki-rdp]. Renamed to Remote Desktop Services in Windows Server 2008 R2. Provides interactive Windows sessions over TCP/3389 using the Remote Desktop Protocol, an extension of the ITU-T T.128 application-sharing protocol family.
&lt;p&gt;Authentication, in 1998, looked nothing like authentication today. The client opened a TCP/3389 connection. The server sent a Proprietary Certificate containing an RSA public key. The client generated a 32-byte Client Random, encrypted it with that RSA public key, and both sides derived RC4 session keys from the shared random [@rdpbcgr-index].&lt;/p&gt;
&lt;p&gt;The user then typed a username and password into the remote login screen, and the password traveled into the target&apos;s &lt;code&gt;Winlogon&lt;/code&gt; process inside that RC4 channel. The target&apos;s &lt;code&gt;lsass.exe&lt;/code&gt; ran NTLM challenge-response against a domain controller (or against its local SAM) and, on success, materialised an interactive session for the user. The target now held the user&apos;s NT one-way function for the lifetime of that session.&lt;/p&gt;
&lt;p&gt;The architectural property was simple: the target was the credential reservoir. Five accounting clerks who RDP&apos;d into a Terminal Server during a shift left five NT-OWF entries in that host&apos;s &lt;code&gt;lsass.exe&lt;/code&gt; memory. An attacker who later got &lt;code&gt;SYSTEM&lt;/code&gt; on the Terminal Server held the credential material for all five.&lt;/p&gt;
&lt;p&gt;Two years later, Windows 2000 made Terminal Services a built-in server feature, and Windows XP Professional (October 2001) shipped the desktop-side variant under the brand &quot;Remote Desktop&quot; [@wiki-rdp]. The credential-aggregation surface, previously confined to dedicated Terminal Server hosts, now extended to every workstation in the estate.&lt;/p&gt;
&lt;p&gt;The first public articulation that &lt;em&gt;credential material in motion is itself an attack surface&lt;/em&gt; came on March 31, 2001, when Sir Dystic of Cult of the Dead Cow released SMBRelay at the &lt;code&gt;@lanta.con&lt;/code&gt; convention in Atlanta [@cdc-smbrelay]. SMBRelay was an SMB man-in-the-middle that hijacked an inbound NTLM authentication and relayed it onward.The Wikipedia SMBRelay article gives March 21, 2001 [@wiki-smbrelay], but the primary source -- Sir Dystic&apos;s own publication at cultdeadcow.com -- says March 31, 2001 [@cdc-smbrelay]. Primary-source dating wins. The Wikipedia article also says &quot;receives a connection on UDP port 139,&quot; which is incorrect; NetBIOS Session Service has always run over TCP/139, and the SMBRelay v0.98 source listing on cultdeadcow.com explicitly binds a TCP socket to port 139. RDP was not yet a direct target, but the principle was now public: pass-the-hash and credential relay would work against any protocol that put credential material on the wire.&lt;/p&gt;
&lt;p&gt;RDP 5.2 (Server 2003, XP SP2) responded to the wire-confidentiality problem in 2003 by adding an optional &lt;code&gt;Security Layer = SSL&lt;/code&gt; setting that wrapped the RDP traffic in TLS [@rdpbcgr-index]. The header byte called &lt;code&gt;selectedProtocol&lt;/code&gt; could now take the value &lt;code&gt;PROTOCOL_SSL = 0x01&lt;/code&gt;, meaning the channel was TLS-encrypted before the legacy basic-settings exchange ran. TLS solved the wire-snooping problem.&quot;Security Layer = SSL&quot; in RDP 5.2 was &lt;em&gt;transport confidentiality only&lt;/em&gt;. The TLS handshake authenticated the server&apos;s certificate (or did not, in many production configurations); the user authentication still happened later, inside the basic-settings exchange and the &lt;code&gt;Logon_Info&lt;/code&gt; PDU. The credential the target ended up with was identical to classic-RDP credential delivery. The distinction between &quot;TLS protects the wire&quot; and &quot;TLS protects the credential&quot; is the load-bearing precision the next section will need. It did not solve the credential-aggregation problem.&lt;/p&gt;
&lt;p&gt;By 2005 the architectural problem was named. Microsoft&apos;s eventual response would shape the next two decades of Windows authentication strategy. It would also, on its first attempt, fix the wrong half of the problem.&lt;/p&gt;
&lt;h2&gt;3. Network Level Authentication via CredSSP (2006-2013)&lt;/h2&gt;
&lt;p&gt;Network Level Authentication is the policy that requires authentication before the RDP session is established. NLA is not a protocol. NLA is implemented by CredSSP -- the Credential Security Support Provider -- running over TLS [@rdpbcgr-credssp]. The difference between those two sentences is the one that matters.&lt;/p&gt;
&lt;p&gt;Windows Vista (November 2006) shipped RDP 6.0, the first Windows release to include NLA and CredSSP support. NLA was selectable in System Properties but did not become the Remote Desktop default until Windows 7 / Server 2008 R2 [@wiki-rdp]. The MS-CSSP open specification documents CredSSP&apos;s role and its lineage, with the protocol summary listing its first revision in December 2006 [@mscssp-index] -- the same shipping window as Vista.&lt;/p&gt;
&lt;p&gt;MS-CSSP defines CredSSP as a protocol that &quot;enables an application to securely delegate a user&apos;s credentials from a client to a target server&quot; [@mscssp-index]. That phrasing matters: from CredSSP&apos;s own design statement, the credential is delegated &lt;em&gt;to&lt;/em&gt; the target. The credential still ends up on the target. The protocol design did not change that property; it changed &lt;em&gt;when&lt;/em&gt; the delivery happens and &lt;em&gt;what&lt;/em&gt; protects it on the wire.&lt;/p&gt;

A policy on the RDP server that requires the connecting user to authenticate before the RDP session is established (before the basic-settings exchange and the virtual-channel binding). Implemented by CredSSP over TLS [@rdpbcgr-credssp]. NLA reduces denial-of-service exposure and gates the pre-auth channel-setup attack surface (the failure mode BlueKeep would later exploit) but does not change the credential material the target receives.

The Microsoft authentication protocol, specified in MS-CSSP [@mscssp-index] and used by RDP and Windows Remote Management, that &quot;amalgamates&quot; TLS with Kerberos and NT LAN Manager [@rdpbcgr-credssp]. CredSSP runs SPNEGO inside a TLS channel, performs Kerberos or NTLM authentication inside SPNEGO, and finally delivers a `TSCredentials` payload to the target. CredSSP is what NLA *is*, at the wire.

The CredSSP payload structure that carries the user&apos;s credential material to the target after the SPNEGO and Kerberos/NTLM phases complete [@mscssp-index]. The classic form is `TSPasswordCreds` (username + domain + plaintext password). Two later forms -- the credential-less form for Restricted Admin and the redirected form (`TSRemoteGuardCreds`) for Remote Credential Guard -- change what travels in this slot without changing the surrounding exchange.
&lt;p&gt;The wire choreography is documented verbatim in section 5.4.5.2 of MS-RDPBCGR. CredSSP is &quot;essentially the amalgamation of TLS with Kerberos and NT LAN Manager (NTLM)&quot; [@rdpbcgr-credssp]. The exchange runs in this order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Client opens TCP/3389.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RDP_NEG_REQ&lt;/code&gt; carries &lt;code&gt;requestedProtocols &amp;amp; PROTOCOL_HYBRID = 0x02&lt;/code&gt; (or &lt;code&gt;PROTOCOL_HYBRID_EX = 0x08&lt;/code&gt;, which adds an Early User Authorization Result PDU) [@rdpbcgr-negreq].&lt;/li&gt;
&lt;li&gt;TLS handshake completes inside the RDP transport.&lt;/li&gt;
&lt;li&gt;SPNEGO negotiates Kerberos or NTLM inside the TLS channel.&lt;/li&gt;
&lt;li&gt;Kerberos or NTLM authenticates the user (and, for Kerberos, the server as well).&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;TSCredentials&lt;/code&gt; payload is sent to the target inside the still-open TLS channel. &quot;Once Kerberos or NTLM has completed successfully, the user&apos;s credentials are sent to the server&quot; [@rdpbcgr-credssp].&lt;/li&gt;
&lt;li&gt;The RDP basic-settings exchange and virtual-channel binding proceed.&lt;/li&gt;
&lt;/ol&gt;

sequenceDiagram
    autonumber
    participant C as Client (mstsc.exe)
    participant T as Target (lsass.exe + termsrv)
    participant K as KDC / domain controller
    C-&amp;gt;&amp;gt;T: TCP/3389 + RDP_NEG_REQ (PROTOCOL_HYBRID 0x02)
    T--&amp;gt;&amp;gt;C: RDP_NEG_RSP (PROTOCOL_HYBRID selected)
    C-&amp;gt;&amp;gt;T: TLS Client Hello
    T--&amp;gt;&amp;gt;C: TLS Server Hello + cert chain
    C-&amp;gt;&amp;gt;T: SPNEGO NegTokenInit inside TLS
    C-&amp;gt;&amp;gt;K: AS-REQ / TGS-REQ for target SPN
    K--&amp;gt;&amp;gt;C: AS-REP / TGS-REP
    C-&amp;gt;&amp;gt;T: AP-REQ inside SPNEGO inside TLS
    T--&amp;gt;&amp;gt;C: AP-REP (mutual auth)
    C-&amp;gt;&amp;gt;T: TSCredentials (TSPasswordCreds)
    T-&amp;gt;&amp;gt;T: lsass logs user on, NT-OWF cached
    C-&amp;gt;&amp;gt;T: RDP basic-settings exchange + session
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &quot;Enable NLA&quot; in the System Properties dialog flips a server-side policy that requires the connecting client to authenticate via CredSSP before the RDP session is established. NLA is &lt;em&gt;that policy&lt;/em&gt;. CredSSP [@mscssp-index] is the wire protocol that satisfies it. When operators say &quot;we require NLA,&quot; they mean &quot;we accept only &lt;code&gt;requestedProtocols = PROTOCOL_HYBRID&lt;/code&gt; or &lt;code&gt;PROTOCOL_HYBRID_EX&lt;/code&gt;,&quot; which is enforced by Windows refusing the &lt;code&gt;RDP_NEG_REQ&lt;/code&gt; if those bits are not set. The protocol carrying the credential to the target is CredSSP, today and twenty years from now.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What NLA accomplishes is real. The unauthenticated RDP channel-setup code -- basic-settings exchange, virtual-channel binding, the &lt;code&gt;MS_T120&lt;/code&gt; handler that BlueKeep would exploit a decade later -- is no longer reachable from the network. An attacker who reaches TCP/3389 must complete a CredSSP handshake (with valid Kerberos or NTLM credentials) before any RDP-stack code beyond the negotiation header runs. That is a denial-of-service mitigation and a pre-auth-RCE mitigation. It is not a credential-isolation mitigation.&lt;/p&gt;
&lt;p&gt;What NLA does not accomplish is what happens at step 6. The output of CredSSP is &lt;code&gt;TSPasswordCreds&lt;/code&gt;, which is the user&apos;s plaintext password (or its NTLM equivalent in some paths) delivered to the target&apos;s &lt;code&gt;lsass.exe&lt;/code&gt;. Mimikatz &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; against the target after the session ends returns the user&apos;s NT-OWF [@mimikatz-github, @wiki-mimikatz], exactly as it would against a 1998-era classic-RDP target. The 2014 Microsoft &lt;em&gt;Mitigating Pass-the-Hash&lt;/em&gt; whitepaper (version 2) [@msl-pthv2] named this failure mode eight years after NLA shipped: NLA is necessary but not sufficient.&lt;/p&gt;
&lt;p&gt;Mimikatz had given the failure mode a name. Benjamin Delpy released the first version in May 2011, initially closed-source [@wiki-mimikatz]. In September 2011 a version of the exploit was used in the DigiNotar incident [@wiki-mimikatz]. By 2012, on a Windows estate running NLA-mandatory RDP since 2007, attackers were still pivoting from a compromised admin&apos;s workstation to every server that admin had logged into, harvesting NT-OWFs as they went. NLA was on the wire. The Pass-the-Hash playbook still worked.&lt;/p&gt;
&lt;p&gt;NLA moved when the authentication happened. It did not change what the target ended up with. Pass-the-Hash against a 2012-era CredSSP-authenticated RDP target was identical to Pass-the-Hash against a 1998-era classic-RDP target. Microsoft&apos;s architectural response shipped in October 2013 -- and it was a structurally different idea.&lt;/p&gt;
&lt;h2&gt;4. BlueKeep, CVE-2018-0886, and the Two Failure Modes of CredSSP&lt;/h2&gt;
&lt;p&gt;The same NLA that mitigates BlueKeep also introduces CVE-2018-0886. The CVE class is not a coincidence. CredSSP is both the protocol that gates the pre-auth channel-setup code &lt;em&gt;and&lt;/em&gt; the protocol whose own logic now has to be correct. Two CVEs anchor this section, six years apart.&lt;/p&gt;
&lt;h3&gt;CVE-2018-0886: CredSSP Remote Code Execution&lt;/h3&gt;
&lt;p&gt;On March 13, 2018, Microsoft patched a CredSSP logical flaw discovered by Preempt (now CrowdStrike) [@crowdstrike-credssp]. The NVD record states the vulnerability allows &quot;a remote code execution vulnerability due to how CredSSP validates request during the authentication process&quot; [@nvd-2018-0886] and classifies it as CWE-287 (Improper Authentication). The affected matrix is wide: Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8.1 / RT 8.1, Windows Server 2012 and R2, Windows 10 (1507 through 1709), Windows Server 2016, and Windows Server version 1709 [@nvd-2018-0886].&lt;/p&gt;
&lt;p&gt;The mechanism is a man-in-the-middle injection. Preempt&apos;s disclosure timeline (verbatim from the CrowdStrike advisory) is &quot;20/08/2017: Initial disclosure to MSRC; 30/08/2017: MS repro attack and acknowledge issue; 18/09/2017: Microsoft requested an extension on 90 days SLA; 12/03/2018: Microsoft fixes CVE-2018-0886 as part of March patch Tuesday&quot; [@crowdstrike-credssp]. The attack scenarios are real-world: ARP poisoning on a flat LAN, KRACK against a poorly-patched Wi-Fi network, or a vulnerable router on the path between client and target.&lt;/p&gt;

The vulnerability consists of a logical flaw in Credential Security Support Provider protocol (CredSSP), which is used by RDP (Remote Desktop Protocol) and Windows Remote Management (WinRM)... The vulnerability can be exploited by attackers by employing a man-in-the-middle attack. -- CrowdStrike (formerly Preempt) [@crowdstrike-credssp]
&lt;p&gt;The architectural lesson is that CredSSP&apos;s role as a security boundary creates a second security boundary inside the protocol itself. NLA gates the pre-auth code path &lt;em&gt;behind CredSSP&lt;/em&gt;. If CredSSP has a bug, NLA does not protect anything beyond it; the bug &lt;em&gt;is&lt;/em&gt; the pre-auth code path.&lt;/p&gt;
&lt;h3&gt;The AllowEncryptionOracle deployment incident&lt;/h3&gt;
&lt;p&gt;KB4093492 (May 8, 2018) is the worked example of how a protocol-layer compatibility shim becomes a deployment hazard [@msl-kb4093492]. The patch introduced a three-state registry value at &lt;code&gt;HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters\AllowEncryptionOracle&lt;/code&gt;. The states are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Force Updated Clients (0)&lt;/strong&gt; -- the client refuses to communicate with non-patched servers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mitigated (1)&lt;/strong&gt; -- the client accepts patched servers and refuses unpatched servers (default after May 8, 2018).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vulnerable (2)&lt;/strong&gt; -- the client accepts both, preserving compatibility with unpatched servers (transitional default).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On May 8, 2018, Microsoft flipped the default from &lt;code&gt;Vulnerable (2)&lt;/code&gt; to &lt;code&gt;Mitigated (1)&lt;/code&gt;. The KB article states bluntly: &quot;By default, after this update is installed, patched clients cannot communicate with unpatched servers&quot; [@msl-kb4093492]. RDP between patched and unpatched estates broke worldwide for a week. The diagnostic Event ID 6041 (&lt;code&gt;LsaSrv&lt;/code&gt;, &quot;Error encountered while reading from the protected payload of the bilateral exchange&quot;) appeared in millions of system logs.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A protocol-layer compatibility shim is itself a deployment surface. The May 2018 default-flip from &lt;code&gt;Vulnerable (2)&lt;/code&gt; to &lt;code&gt;Mitigated (1)&lt;/code&gt; [@msl-kb4093492] was correct as a security posture and disastrous as a rollout sequence. Patch the servers before the clients; verify with &lt;code&gt;Get-ItemProperty &apos;HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters&apos;&lt;/code&gt;; do not assume that &quot;GPO push to clients&quot; is the right first step.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;CVE-2019-0708: BlueKeep&lt;/h3&gt;
&lt;p&gt;On May 14, 2019, Microsoft shipped a fix for a use-after-free in the &lt;code&gt;MS_T120&lt;/code&gt; virtual-channel binding handler inside &lt;code&gt;termdd.sys&lt;/code&gt; -- the kernel-mode driver that handles RDP transport-layer code [@wiki-bluekeep]. The vulnerability, named BlueKeep by Kevin Beaumont on Twitter and discovered by the UK National Cyber Security Centre [@wiki-bluekeep], allowed pre-authentication remote code execution at &lt;code&gt;SYSTEM&lt;/code&gt; on the target. The NVD record (CVE-2019-0708) lists references to PacketStorm exploits, Siemens advisories, the MSRC vendor advisory, and the CISA Known Exploited Vulnerabilities catalog [@nvd-2019-0708].&lt;/p&gt;
&lt;p&gt;The affected matrix is &quot;Windows XP, Windows Vista, Windows 7, Windows Server 2003, Windows Server 2008, and Windows Server 2008 R2&quot; [@wiki-bluekeep]. Microsoft issued out-of-band patches for the end-of-life operating systems (Windows XP and Server 2003) [@wiki-bluekeep] -- a step the company reserves for vulnerabilities expected to be weaponised at scale. CISA, the NSA, and Microsoft all issued emergency advisories.&lt;/p&gt;

The common shorthand for BlueKeep is that it was &quot;a vulnerability in pre-NLA RDP.&quot; The shorthand is wrong, and the precision matters because it sets up the wrong intuition for every authentication mode that follows.&lt;p&gt;NLA existed natively in every BlueKeep-affected operating system from Windows Vista onward -- Windows 7, Server 2008, and Server 2008 R2 all shipped NLA support, and many of those estates ran with NLA on. Windows XP and Server 2003 did not ship NLA natively; CredSSP / NLA was retrofitted to both via KB951608 (March 2009) [@wiki-bluekeep]. BlueKeep is a vulnerability in the channel-setup code reachable when NLA is &lt;em&gt;not enforced&lt;/em&gt; -- the channel-setup code being the &lt;code&gt;MS_T120&lt;/code&gt; virtual-channel binder in &lt;code&gt;termdd.sys&lt;/code&gt;, which is reachable only after the negotiation header but before the basic-settings exchange when CredSSP is not gating the path [@wiki-bluekeep].&lt;/p&gt;
&lt;p&gt;When &lt;code&gt;requestedProtocols = PROTOCOL_RDP (0x00)&lt;/code&gt; and the server permits it, the client skips the CredSSP gate and walks straight into the basic-settings exchange. The &lt;code&gt;MS_T120&lt;/code&gt; channel binding happens in that pre-authentication window. NLA closes that window by requiring &lt;code&gt;PROTOCOL_HYBRID (0x02)&lt;/code&gt; (or &lt;code&gt;_HYBRID_EX 0x08&lt;/code&gt;) before any RDP-stack code beyond the negotiation header runs. The mitigation guidance every operator received in May 2019 -- &quot;enable NLA&quot; -- worked because of this layering, not because BlueKeep was a vulnerability in a pre-NLA era.&lt;/p&gt;
&lt;p&gt;The framing matters because the same precision applies to every later mode. Restricted Admin, Remote Credential Guard, and PRT-over-RDP all sit on top of CredSSP gating (or, for PRT-over-RDP, on top of a different gate entirely). None of them protect anything in the channel-setup phase. NLA does.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The BlueKeep out-of-band patch for Windows XP and Server 2003 [@wiki-bluekeep] is one of the rare exceptions to Microsoft&apos;s end-of-life policy. The 2017 WannaCry / EternalBlue cycle made Microsoft cautious about wormable pre-auth RCE on end-of-life operating systems; BlueKeep met the same threshold. The pattern -- a pre-auth RCE in long-deployed Windows networking code, with end-of-life patches issued out-of-band -- recurs about once every five years.&lt;/p&gt;
&lt;p&gt;NLA mitigates BlueKeep but does not stop Pass-the-Hash. CredSSP itself has a non-trivial logical-attack surface. The architectural response to the Pass-the-Hash failure had already shipped five years before BlueKeep -- and it took the opposite approach. Instead of delivering the credential more securely, it stopped delivering the credential at all.&lt;/p&gt;
&lt;h2&gt;5. Restricted Admin: User Is the Machine (2013)&lt;/h2&gt;
&lt;p&gt;On October 17, 2013, Microsoft shipped a feature whose entire architectural insight fits in one sentence: stop delivering the user&apos;s credential to the target, and let the target log the user on as the target itself.&lt;/p&gt;
&lt;p&gt;The feature is Restricted Admin mode, part of the CredSSP protocol family. It first shipped with Windows 8.1, Windows Server 2012 R2, and Windows RT 8.1 at RTM. Microsoft Security Advisory 2871997 states this verbatim: &quot;Supported editions of Windows 8.1, Windows Server 2012 R2, and Windows RT 8.1 already include these features and do not need the 2871997 update&quot; [@ms-adv-2871997]. The advisory is the load-bearing primary that pins the October 2013 ship date, because the advisory itself was the &lt;em&gt;backport&lt;/em&gt; notice for older operating systems.&lt;/p&gt;

The shorthand &quot;Restricted Admin shipped with KB2871997 in 2014&quot; is a recurring misreading worth defusing. Restricted Admin shipped on three separate dates:&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;October 17, 2013&lt;/strong&gt; -- Windows 8.1, Windows Server 2012 R2, and Windows RT 8.1 RTM. Restricted Admin is in the box. No update required [@ms-adv-2871997].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;May 13, 2014&lt;/strong&gt; -- KB2871997 backported the &lt;em&gt;CredSSP-layer&lt;/em&gt; support to Windows 7, Windows Server 2008 R2, Windows 8, Windows Server 2012, and Windows RT [@ms-adv-2871997]. The advisory text reads verbatim: &quot;On May 13, 2014, Microsoft released the 2871997 update for supported editions of Windows 8, Windows RT, Windows Server 2012, Windows 7, and Windows Server 2008 R2 that improves credential protection and domain authentication controls to reduce credential theft. This update provides additional protection for the Local Security Authority (LSA), adds a restricted admin mode for Credential Security Support Provider (CredSSP)...&quot; [@ms-adv-2871997].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;October 14, 2014&lt;/strong&gt; -- the &lt;em&gt;RDP-client-side&lt;/em&gt; backport in KB2984972 (Win 7 / Server 2008 R2), KB2984976 (Win 7), KB2984981 (Win 7), and KB2973501 (Server 2012). Without the client-side update, Win 7 clients could not &lt;em&gt;initiate&lt;/em&gt; a Restricted Admin RDP connection even though their CredSSP layer supported the protocol after May 2014 [@ms-adv-2871997].&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you read &quot;2014 KB2871997&quot; as the introduction date, the feature looks like a Windows-7-and-back retrofit. It is the opposite: Restricted Admin was a Windows 8.1 RTM feature whose value to the existing fleet was unlocked by two later backports.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;The wire protocol&lt;/h3&gt;
&lt;p&gt;Restricted Admin opt-in lives in two bytes on the wire, both documented verbatim in MS-RDPBCGR. The client sets &lt;code&gt;RDP_NEG_REQ.flags &amp;amp; RESTRICTED_ADMIN_MODE_REQUIRED = 0x01&lt;/code&gt; to signal the request: &quot;Indicates that the client requires credential-less logon over CredSSP (also known as &apos;restricted admin mode&apos;). If the server supports this mode then it is acceptable for the client to send empty credentials in the &lt;strong&gt;TSPasswordCreds&lt;/strong&gt; structure&quot; [@rdpbcgr-negreq]. The server confirms support by setting &lt;code&gt;RDP_NEG_RSP.flags &amp;amp; RESTRICTED_ADMIN_MODE_SUPPORTED = 0x08&lt;/code&gt; in the response: &quot;Indicates that the server supports credential-less logon over CredSSP&quot; [@rdpbcgr-negrsp].&lt;/p&gt;
&lt;p&gt;The CredSSP exchange itself runs end-to-end. TLS handshake completes; SPNEGO selects Kerberos or NTLM; the user authenticates. At step 6 -- where classic CredSSP would send a populated &lt;code&gt;TSPasswordCreds&lt;/code&gt; -- the client sends an &lt;em&gt;empty&lt;/em&gt; &lt;code&gt;TSPasswordCreds&lt;/code&gt;. No password, no NT-OWF, no forwarded TGT. The target receives no credential material.&lt;/p&gt;

A CredSSP sub-mode signalled by the `RDP_NEG_REQ.flags &amp;amp; RESTRICTED_ADMIN_MODE_REQUIRED 0x01` bit [@rdpbcgr-negreq]. The client completes authentication to the target but sends an empty `TSPasswordCreds` payload; the target then logs the user on using the target&apos;s own machine account, restricting the session to actions the local Administrators group can perform. Introduced at Windows 8.1 / Server 2012 R2 RTM (October 17, 2013) [@ms-adv-2871997]; backported to Windows 7 / Server 2008 R2 via KB2871997 (May 13, 2014) and the October 14, 2014 client-side KBs.
&lt;h3&gt;The mechanism: the user becomes the machine&lt;/h3&gt;
&lt;p&gt;When the target sees an empty &lt;code&gt;TSPasswordCreds&lt;/code&gt; and the &lt;code&gt;RESTRICTED_ADMIN_MODE_REQUIRED&lt;/code&gt; flag, it does not refuse the logon. It logs the user on by impersonating the target&apos;s own machine account (&lt;code&gt;&amp;lt;TARGETNAME&amp;gt;$&lt;/code&gt;). The machine account is in the local Administrators group by default; the user requesting the session must already be a member of the same group on the target. Microsoft Learn states the access prerequisite for Restricted Admin as &quot;Membership of &lt;strong&gt;Administrators&lt;/strong&gt; group on remote host&quot; [@msl-rcg].&lt;/p&gt;

sequenceDiagram
    autonumber
    participant C as Client
    participant T as Target
    participant K as KDC
    C-&amp;gt;&amp;gt;T: RDP_NEG_REQ (PROTOCOL_HYBRID 0x02 + flags 0x01)
    T--&amp;gt;&amp;gt;C: RDP_NEG_RSP (flags 0x08 supported)
    C-&amp;gt;&amp;gt;T: TLS handshake
    C-&amp;gt;&amp;gt;K: Kerberos AS / TGS for target SPN
    C-&amp;gt;&amp;gt;T: AP-REQ inside SPNEGO (user authenticated)
    C-&amp;gt;&amp;gt;T: TSPasswordCreds (EMPTY)
    T-&amp;gt;&amp;gt;T: LogonUser as TARGET$ machine account
    T-&amp;gt;&amp;gt;T: Token in local Administrators
    C-&amp;gt;&amp;gt;T: RDP session as machine identity
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The breakthrough in Restricted Admin is not a new crypto primitive. It is the realisation that the target can act on the user&apos;s behalf by impersonating &lt;em&gt;itself&lt;/em&gt; -- the target&apos;s own machine account -- which is already a local Administrator. The session has access to local resources, the user has full administrative use of the target, and the target&apos;s &lt;code&gt;lsass.exe&lt;/code&gt; holds no user credential material. The trade is the user&apos;s downstream identity: the session cannot use the user&apos;s credentials for SSO, because the session is not the user. The session is the target.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;The trade-offs, verbatim from Microsoft Learn&lt;/h3&gt;
&lt;p&gt;Microsoft Learn publishes a comparison matrix that lays out the trade-offs across Remote Desktop (classic), Remote Credential Guard, and Restricted Admin [@msl-rcg]. For Restricted Admin, the row entries are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prevent use of user&apos;s identity during connection: yes.&lt;/li&gt;
&lt;li&gt;Prevent use of credentials after disconnection: yes.&lt;/li&gt;
&lt;li&gt;Prevent Pass-the-Hash: yes.&lt;/li&gt;
&lt;li&gt;Single sign-on to other systems: no.&lt;/li&gt;
&lt;li&gt;Multi-hop RDP: no.&lt;/li&gt;
&lt;li&gt;Supported authentication: any negotiated by CredSSP (Kerberos or NTLM).&lt;/li&gt;
&lt;li&gt;Credentials supported from the client: signed-in credentials, supplied creds, saved creds.&lt;/li&gt;
&lt;li&gt;RDP access granted with: membership of Administrators on the remote host [@msl-rcg].&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the architectural trade. The user is gone the moment the session ends. The attacker who compromises the target during the session gets local Administrator -- but via the machine identity, not via the user&apos;s credential.&lt;/p&gt;
&lt;h3&gt;The RBCD residual class&lt;/h3&gt;
&lt;p&gt;There is no free lunch. Restricted Admin&apos;s &quot;user becomes the machine identity&quot; design creates a different residual surface. If the attacker can write the &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt; attribute on the target&apos;s computer object in Active Directory, the attacker can use Resource-Based Constrained Delegation to S4U2self + S4U2proxy a Kerberos service ticket for &lt;code&gt;TERMSRV/&amp;lt;target&amp;gt;&lt;/code&gt; and RDP in as &lt;em&gt;anyone&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Elad Shamir documented this in his January 28, 2019 essay &quot;Wagging the Dog&quot; [@shamir-wagging]. The TL;DR points are precise: &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 &lt;code&gt;TrustedToAuthForDelegation&lt;/code&gt; attribute... if an attacker can control a computer object in Active Directory, then it may be possible to abuse it to compromise the host. S4U2Proxy always produces a forwardable TGS, even if the provided additional TGS in the request was not forwardable&quot; [@shamir-wagging].&lt;/p&gt;

A Kerberos delegation model introduced in Windows Server 2012 where the *target* resource controls which principals can delegate to it via the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute on its own computer object. Combined with S4U2self and S4U2proxy, RBCD lets any principal that can write that attribute on a target&apos;s computer object obtain a forwardable Kerberos service ticket for any service on the target, including `TERMSRV` (the RDP service principal) [@shamir-wagging]. See the companion *NTLMless* article on this site for the wider S4U and Kerberos-relay discussion.

Computer accounts just got a lot more interesting. Start hunting for more primitives to trigger attack chains! -- Elad Shamir, *Wagging the Dog* (2019) [@shamir-wagging]
&lt;p&gt;Dec0ne&apos;s KrbRelayUp (2022) productionised the chain as &quot;essentially a universal no-fix local privilege escalation in windows domain environments where LDAP signing is not enforced (the default settings)&quot; [@krbrelayup]. The tool wraps Rubeus, KrbRelay, and ADCSPwn for a kerberos-relay-to-RBCD-to-ShadowCred-to-S4U2self-to-SCMUACBypass chain that ends in &lt;code&gt;SYSTEM&lt;/code&gt; on the target. Restricted Admin&apos;s machine-identity-as-session design is exactly what this chain rewards: the attacker walks away with Administrator on the target via the machine identity, with no need to harvest the user&apos;s credential.&lt;/p&gt;
&lt;p&gt;Restricted Admin solves the credential-aggregation problem for jump servers. It does so by eliminating SSO and requiring local Administrator on the target -- which means it cannot be the answer for regular user RDP. If the target needs to act as the user during the session but never holds the user&apos;s credentials, the only place those credentials can live is back on the caller. That insight took three more years to ship.&lt;/p&gt;
&lt;h2&gt;6. Remote Credential Guard: Challenges Redirect to Caller (2016)&lt;/h2&gt;
&lt;p&gt;Remote Credential Guard is what you get if you take Restricted Admin&apos;s &quot;no credential material delivered to the target&quot; rule and add &quot;but the target still needs to act as the user during the session.&quot; Both halves are achievable. The cost is one extra RPC round-trip for every Kerberos operation the session performs -- and a hard dependency on Kerberos itself.&lt;/p&gt;
&lt;p&gt;On August 2, 2016, Microsoft shipped Windows 10 1607 (the Anniversary Update) and Windows Server 2016 with Remote Credential Guard [@msl-rcg]. The Microsoft Learn page states the design property in one sentence: &quot;Remote Credential Guard helps protecting credentials over a Remote Desktop (RDP) connection by redirecting Kerberos requests back to the device that&apos;s requesting the connection. If the target device is compromised, the credentials aren&apos;t exposed because both credential and credential derivatives are never passed over the network to the target device&quot; [@msl-rcg].&lt;/p&gt;
&lt;h3&gt;The wire protocol&lt;/h3&gt;
&lt;p&gt;Opt-in lives in two more flag bits on the CredSSP negotiation. The client sets &lt;code&gt;RDP_NEG_REQ.flags &amp;amp; REDIRECTED_AUTHENTICATION_MODE_REQUIRED = 0x02&lt;/code&gt; to signal the request: the flag indicates &quot;the client can send a redirected logon buffer in the TSRemoteGuardCreds structure&quot; [@rdpbcgr-negreq]. The server confirms by setting &lt;code&gt;RDP_NEG_RSP.flags &amp;amp; REDIRECTED_AUTHENTICATION_MODE_SUPPORTED = 0x10&lt;/code&gt;: &quot;Indicates that the server supports credential-less logon over CredSSP with credential redirection (also known as &apos;Remote Credential Guard&apos;)&quot; [@rdpbcgr-negrsp].&lt;/p&gt;
&lt;p&gt;The credential payload changes. Instead of an empty &lt;code&gt;TSPasswordCreds&lt;/code&gt; (Restricted Admin) or a populated one (classic CredSSP), the client sends a &lt;code&gt;TSRemoteGuardCreds&lt;/code&gt;. The ASN.1 structure is documented verbatim in MS-CSSP [@mscssp-trgcreds]:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TSRemoteGuardCreds ::= SEQUENCE {
    logonCred         [0] TSRemoteGuardPackageCred,
    supplementalCreds [1] SEQUENCE OF TSRemoteGuardPackageCred OPTIONAL
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The payload does not carry a password or a hash. It carries a &lt;em&gt;handle&lt;/em&gt; that lets the target forward authentication challenges back to the caller. MS-CSSP states that &quot;The logon credential is passed to the Negotiate package, which in turn passes the credential to the default authentication package&quot; [@mscssp-trgcreds] -- the negotiate package on the &lt;em&gt;target&lt;/em&gt; receives a redirect-handle, not a credential.&lt;/p&gt;

A CredSSP sub-mode signalled by the `RDP_NEG_REQ.flags &amp;amp; REDIRECTED_AUTHENTICATION_MODE_REQUIRED 0x02` bit [@rdpbcgr-negreq]. The session preserves the user&apos;s identity (unlike Restricted Admin), but every downstream Kerberos operation is performed by the caller&apos;s `lsass.exe` on behalf of the session, forwarded via RPC. Kerberos-only -- no NTLM fallback. Introduced in Windows 10 1607 and Windows Server 2016 (August 2, 2016) [@msl-rcg].

The CredSSP payload used by Remote Credential Guard [@mscssp-trgcreds]. A `SEQUENCE` of a `logonCred` and zero or more `supplementalCreds`, each of type `TSRemoteGuardPackageCred`. The handle is opaque to the target&apos;s authentication package; the target uses it only to request operations from the caller.
&lt;h3&gt;The runtime mechanism&lt;/h3&gt;
&lt;p&gt;The interesting half of Remote CG runs &lt;em&gt;after&lt;/em&gt; the session establishes. Suppose the user, now logged into the target as themselves, opens a file from a network share, mounts a database connection, or starts a second RDP hop. Each of those actions needs a Kerberos service ticket. The session host does not call &lt;code&gt;KerbCreateTicket()&lt;/code&gt; itself. It packages an RPC request and sends it back to the caller&apos;s machine, where the caller&apos;s &lt;code&gt;lsass.exe&lt;/code&gt; performs the operation using the caller&apos;s TGT and session key, then returns the resulting service ticket to the target session.&lt;/p&gt;

sequenceDiagram
    autonumber
    participant C as Client + caller lsass
    participant T as Target session host
    participant K as KDC
    participant F as File server (TGS target)
    C-&amp;gt;&amp;gt;T: RDP_NEG_REQ (flags 0x02)
    T--&amp;gt;&amp;gt;C: RDP_NEG_RSP (flags 0x10)
    C-&amp;gt;&amp;gt;T: TLS handshake
    C-&amp;gt;&amp;gt;T: TSRemoteGuardCreds (handle)
    T-&amp;gt;&amp;gt;T: Session start as user identity
    T-&amp;gt;&amp;gt;C: RPC: TGS-REQ for cifs/fileserver
    C-&amp;gt;&amp;gt;K: TGS-REQ
    K--&amp;gt;&amp;gt;C: TGS-REP
    C--&amp;gt;&amp;gt;T: TGS-REP forwarded back
    T-&amp;gt;&amp;gt;F: AP-REQ with forwarded TGS
    F--&amp;gt;&amp;gt;T: AP-REP, SMB session
&lt;p&gt;The cost is a round-trip per Kerberos operation. Over a LAN that is a few milliseconds; over a WAN that can be 50 milliseconds or more.About 5ms LAN, 50ms WAN, per operation.Remote CG is the only RDP authentication mode with runtime overhead proportional to downstream Kerberos hops. Classic CredSSP, Restricted Admin, and PRT-over-RDP all complete their credential exchange before the session starts; the session then talks to downstream services using credentials that already live on the target. Remote CG keeps the credentials at home and pays an RPC round-trip every time the session needs one. On a chatty workload -- mounting multiple SMB shares, opening many database connections, or chaining RDP hops -- this overhead is observable.&lt;/p&gt;
&lt;h3&gt;The trustlet conditional&lt;/h3&gt;
&lt;p&gt;A common belief about Remote Credential Guard is that it stores the redirected-authentication signing material in the caller&apos;s VBS trustlet &lt;code&gt;LsaIso.exe&lt;/code&gt;. That is &lt;em&gt;partly&lt;/em&gt; true and worth getting precise.&lt;/p&gt;
&lt;p&gt;Remote Credential Guard always redirects challenges to the caller&apos;s &lt;code&gt;lsass.exe&lt;/code&gt;. Where the long-lived signing material lives on the caller is a separate question:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the caller has local Credential Guard enabled, the secrets that back the redirected operations live in the caller&apos;s VTL1 &lt;code&gt;LsaIso.exe&lt;/code&gt; trustlet, isolated from VTL0 user-mode code on the caller.&lt;/li&gt;
&lt;li&gt;If the caller does &lt;em&gt;not&lt;/em&gt; have local Credential Guard, the same material lives in regular user-mode &lt;code&gt;lsass.exe&lt;/code&gt; on the caller, with no VTL1 isolation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The protocol still works in both cases. The redirection still happens. What changes is the protection the caller&apos;s lsass gets from an attacker who later compromises the caller. See the companion &lt;em&gt;Credential Guard&lt;/em&gt; article on this site for the LsaIso internals.&lt;/p&gt;

The &quot;isolated LSA&quot; trustlet that runs in VTL1 under Virtualization-Based Security when Credential Guard is enabled. Stores credential-derived secrets (NTLM hash, Kerberos session key, TGT key, certificate private keys) outside the reach of VTL0 code, including kernel-mode rootkits. Documented in detail in the companion *Credential Guard* article on this site.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Remote Credential Guard always protects the credential from the &lt;em&gt;target&lt;/em&gt; -- the target never sees it, regardless of caller configuration. Remote Credential Guard protects the credential from a &lt;em&gt;post-compromise of the caller&lt;/em&gt; only if the caller has local Credential Guard enabled. The shorthand &quot;Remote CG runs in a VBS trustlet&quot; is true only for the second protection; for the first, the protection lives in the protocol, not in VBS.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Kerberos-only -- and what that means for NTLM-mixed estates&lt;/h3&gt;
&lt;p&gt;Remote CG depends on Kerberos. Microsoft Learn is explicit: &quot;Must use Kerberos authentication to connect to the remote host. If the client can&apos;t connect to a domain controller, then RDP attempts to fall back to NTLM. Remote Credential Guard doesn&apos;t allow NTLM fallback because it would expose credentials to risk&quot; [@msl-rcg].&lt;/p&gt;
&lt;p&gt;The reason is structural. NTLM challenge-response sends a chosen-plaintext-style hash of the user&apos;s NT-OWF to the target. Remote CG&apos;s redirection scheme works for Kerberos because the target can ask the caller to mint a service ticket; there is no equivalent operation in NTLM. Remote CG has nothing to redirect that does not eventually require the caller to hand over usable hash material.&lt;/p&gt;
&lt;p&gt;Operationally, this means a 2026 estate that has not finished NTLM deprecation work cannot universally deploy Remote CG. Any RDP path that would fall back to NTLM -- a workgroup machine, a target whose Kerberos SPN registration is broken, a destination behind a DC-isolating firewall rule -- refuses to negotiate Remote CG and either fails the session or falls back to Restricted Admin (depending on the &lt;code&gt;RestrictedRemoteAdministration&lt;/code&gt; GPO setting). See the companion &lt;em&gt;NTLMless&lt;/em&gt; article on this site for the wider context.The UWP Remote Desktop client (the modern Microsoft Store variant) does not support Remote Credential Guard [@msl-rcg]. Only the classic &lt;code&gt;mstsc.exe&lt;/code&gt; Win32 client implements the negotiation. Operators planning to enforce Remote CG must inventory which client binaries connect to which targets; mixing UWP clients into a Remote-CG-mandatory target pool produces silent connection failures.&lt;/p&gt;
&lt;p&gt;Remote CG closes credential-after-disconnection and Pass-the-Hash without sacrificing SSO. It does so by demanding Kerberos and one extra RPC per downstream hop. But the model assumes the user has on-prem-AD-routable Kerberos credentials -- which a Microsoft-Entra-joined laptop without hybrid join does not. The next generation throws away Kerberos entirely.&lt;/p&gt;
&lt;h2&gt;7. PRT-over-RDP: No Password, No Hash, No Ticket (2022)&lt;/h2&gt;
&lt;p&gt;On October 11, 2022, Microsoft shipped the first RDP authentication mode that has no &lt;code&gt;lsass.exe&lt;/code&gt;-credential-delivery story to tell -- because there is no NTLM hash, no Kerberos ticket, and no password in the entire exchange. The credential is a JSON Web Token issued by Microsoft Entra ID.&lt;/p&gt;
&lt;p&gt;The shipping vehicle was the October 2022 cumulative updates: KB5018418 (Windows 11), KB5018410 (Windows 10 20H2+), and KB5018421 (Windows Server 2022). KB5018418&apos;s release notes pin the date precisely: &quot;Release Date: 10/11/2022. Version: OS Build 22000.1098&quot; [@msl-kb5018418]. The Microsoft Learn page for the feature lists the same prerequisites: &quot;The remote PC and your local device must be running one of the following operating systems: Windows 11 with 2022-10 Cumulative Updates for Windows 11 (KB5018418) or later installed&quot; [@msl-prtrdp-mstsc].&lt;/p&gt;

PRT-over-RDP (Microsoft&apos;s official name: &quot;Microsoft Entra single sign-on for Remote Desktop&quot;) is sometimes attributed to &quot;2025.&quot; The misreading is worth defusing because the date affects what one believes is on the deployment frontier.&lt;p&gt;The feature shipped in October 2022 [@msl-prtrdp-mstsc, @msl-kb5018418]. The 2025 angles are two: Windows 11 24H2 reached broad consumer GA in October 2024, and a CredSSP/RDP regression in 24H2 produced session hangs and 65-second disconnects in early 2025; Microsoft rolled out a Known Issue Rollback (&quot;KIR&quot;) via Group Policy in March 2025, and the Windows 11 24H2 release-health page now reads &quot;There are no active known issues at this time&quot; as of March 27, 2025 [@msl-24h2-status]. PRT-over-RDP itself has been a generally-available feature since October 2022; the 2025 events were deployment-stack stability work, not feature ship dates.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;The wire protocol&lt;/h3&gt;
&lt;p&gt;Microsoft introduced a new value for &lt;code&gt;requestedProtocols&lt;/code&gt; -- &lt;code&gt;PROTOCOL_RDSAAD = 0x10&lt;/code&gt; [@rdpbcgr-negreq] -- and an entirely new sub-protocol underneath it, &quot;RDS AAD Auth.&quot; Section 5.4.5.4 of MS-RDPBCGR documents it verbatim: &quot;RDS AAD Auth is a variation of Enhanced RDP Security that is used to authenticate a user to an Azure AD-joined device or to a Hybrid Azure AD-joined device. Server authentication, encryption, decryption, and data integrity checks are implemented by using the TLS security protocol, while user authentication is accomplished by exchanging RDS AAD Auth PDUs directly following the TLS handshake&quot; [@rdpbcgr-rdsaad].&lt;/p&gt;
&lt;p&gt;The CredSSP exchange is &lt;em&gt;replaced entirely&lt;/em&gt;. No SPNEGO. No Kerberos. No NTLM. No &lt;code&gt;TSCredentials&lt;/code&gt;. The TLS handshake still happens, because TLS is providing the wire confidentiality and server authentication. After the TLS handshake, the new RDS-AAD-Auth PDU stream takes over. The user-side credential becomes a PRT-cookie scoped to a Conditional Access application.&lt;/p&gt;

A long-lived OAuth refresh token bound to a Microsoft-Entra-joined or hybrid-joined device. The PRT holds proof of the user&apos;s primary authentication (typically including a Windows Hello for Business gesture or FIDO2 ceremony) and signs short-lived JWT cookies that authenticate the user to Entra-ID-integrated applications. The PRT&apos;s signing key is held in the device&apos;s TPM where possible. See the companion *Entra ID and the Primary Refresh Token* article on this site for the full mechanism.

The Cloud Authentication Provider, an LSA authentication package introduced for Microsoft Entra ID (then Azure AD) sign-in. CloudAP runs inside `lsass.exe` and manages PRT issuance, refresh, and the minting of PRT-cookies for downstream authentication. On the target side of a PRT-over-RDP session, CloudAP validates the inbound PRT-cookie and produces the user&apos;s Windows session token without ever contacting a domain controller [@mollema-prt2].
&lt;h3&gt;The mechanism: from &lt;code&gt;.rdp&lt;/code&gt; file to Entra-issued session&lt;/h3&gt;
&lt;p&gt;The client-side flow starts with an &lt;code&gt;.rdp&lt;/code&gt; connection file that includes &lt;code&gt;enablerdsaadauth:i:1&lt;/code&gt; [@msl-rdp-files]. The official MSTSC user-facing label is &quot;Use a web account to sign in to the remote computer.&quot; When the user clicks Connect:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The local CloudAP plugin generates a PRT-cookie scoped to the Conditional Access application &lt;code&gt;a4a365df-50f1-4397-bc59-1a1564b8bb9c&lt;/code&gt; (&quot;Microsoft Remote Desktop&quot;). The Microsoft Learn documentation pins this app ID verbatim: &quot;Conditional Access policies can be applied to the application &lt;strong&gt;Microsoft Remote Desktop&lt;/strong&gt; with ID &lt;strong&gt;a4a365df-50f1-4397-bc59-1a1564b8bb9c&lt;/strong&gt; to control access to the remote PC when single sign-on is enabled&quot; [@msl-prtrdp-mstsc].&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mstsc.exe&lt;/code&gt; opens TCP/3389 (or UDP/3389 for Shortpath) and sends &lt;code&gt;RDP_NEG_REQ&lt;/code&gt; with &lt;code&gt;requestedProtocols = PROTOCOL_RDSAAD (0x10)&lt;/code&gt; [@rdpbcgr-negreq].&lt;/li&gt;
&lt;li&gt;TLS handshake completes; the target&apos;s server certificate is validated against the Entra device-identity.&lt;/li&gt;
&lt;li&gt;The client sends RDS-AAD-Auth PDUs containing the PRT-cookie [@rdpbcgr-rdsaad].&lt;/li&gt;
&lt;li&gt;The target&apos;s CloudAP plugin validates the cookie against Microsoft Entra ID. Entra ID evaluates the Conditional Access policies that target &lt;code&gt;a4a365df-...&lt;/code&gt;, including device compliance, location, sign-in risk, and Authentication Strength.&lt;/li&gt;
&lt;li&gt;On success, Entra ID issues an access token scoped to the target. The target&apos;s CloudAP plugin signs the user in. The RDP session starts.&lt;/li&gt;
&lt;/ol&gt;

sequenceDiagram
    autonumber
    participant C as Caller (CloudAP + mstsc)
    participant T as Target (CloudAP + termsrv)
    participant E as Microsoft Entra ID
    C-&amp;gt;&amp;gt;C: CloudAP mints PRT-cookie for a4a365df
    C-&amp;gt;&amp;gt;T: RDP_NEG_REQ (PROTOCOL_RDSAAD 0x10)
    T--&amp;gt;&amp;gt;C: RDP_NEG_RSP (PROTOCOL_RDSAAD selected)
    C-&amp;gt;&amp;gt;T: TLS handshake
    C-&amp;gt;&amp;gt;T: RDS-AAD-Auth PDU with PRT-cookie
    T-&amp;gt;&amp;gt;E: Validate cookie + apply CA policies
    E--&amp;gt;&amp;gt;T: Access token for target SPN
    T-&amp;gt;&amp;gt;T: CloudAP signs user in
    C-&amp;gt;&amp;gt;T: RDP session as Entra principal

The `.rdp` connection-file property that opts into RDS-AAD-Auth (PRT-over-RDP) [@msl-rdp-files]. Verbatim from Microsoft Learn: &quot;Determines whether the client will use Microsoft Entra ID to authenticate to the remote PC. When used with Azure Virtual Desktop, this provides a single sign-on experience. This property replaces the property `targetisaadjoined`.&quot; The two valid values are `0` (disable) and `1` (enable).
&lt;h3&gt;Two GUIDs, two purposes&lt;/h3&gt;
&lt;p&gt;PRT-over-RDP brings two distinct Microsoft Entra IDs into play, and the article must keep them separate.The user-facing Conditional Access application &quot;Microsoft Remote Desktop&quot; has the application ID &lt;code&gt;a4a365df-50f1-4397-bc59-1a1564b8bb9c&lt;/code&gt; [@msl-prtrdp-mstsc]. The AVD-side configuration uses a distinct service principal &quot;Windows Cloud Login&quot; with ID &lt;code&gt;270efc09-cd0d-444b-a71f-39af4910ec45&lt;/code&gt; [@msl-avdsso], configured via &lt;code&gt;Update-MgServicePrincipal ... -Settings @{ isRemoteDesktopProtocolEnabled = $true }&lt;/code&gt;. Both IDs exist for legitimate reasons; both pages are alive; they configure different layers. The Conditional Access policy in the admin console targets &lt;code&gt;a4a365df-...&lt;/code&gt;; the AVD-side enablement flag flips on &lt;code&gt;270efc09-...&lt;/code&gt;. The &lt;code&gt;a4a365df-...&lt;/code&gt; application is the user-facing PRT-cookie audience; Conditional Access policies that gate RDP sign-in (require WHfB, require compliant device, block from foreign geographies) target this app ID. The &lt;code&gt;270efc09-...&lt;/code&gt; service principal is the AVD-side enablement flag for the configuration described in Azure Virtual Desktop documentation: &quot;Your session hosts must be Microsoft Entra joined or Microsoft Entra hybrid joined. Session hosts joined to Microsoft Entra Domain Services or to Active Directory Domain Services only aren&apos;t supported&quot; [@msl-avdsso].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; PRT-over-RDP is the first RDP authentication mode whose wire-protocol selector does not have a CredSSP underneath it. &lt;code&gt;PROTOCOL_RDSAAD (0x10)&lt;/code&gt; [@rdpbcgr-negreq] is its own path. The user&apos;s credential is a JWT cookie [@msl-prtrdp-mstsc] signed by a key derived from the device&apos;s session key (and bound to the TPM where possible). There is no NTLM hash to extract from the target; there is no Kerberos session key to relay. The residual surface is PRT-extraction from the &lt;em&gt;caller&apos;s&lt;/em&gt; CloudAP cache -- not from the target.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;PRT-over-RDP is the first RDP authentication mode that is intrinsically phishing-resistant when paired with Windows Hello for Business [@msl-prtrdp-mstsc]. It is also the first mode that requires both endpoints to be Microsoft-Entra-joined (or hybrid-joined) [@msl-avdsso]. A 2026 enterprise estate ends up running all five modes in parallel -- none retiring the others -- because no single Pareto-optimal point dominates the others.&lt;/p&gt;
&lt;h2&gt;8. Five Modes, One Matrix, 2026 Operational Reality&lt;/h2&gt;
&lt;p&gt;By 2026 the RDP authentication stack ships five compositional modes, negotiated by two distinct mechanisms in MS-RDPBCGR. The &lt;code&gt;requestedProtocols&lt;/code&gt; field [@rdpbcgr-negreq] selects between classic RDP, TLS, CredSSP, and RDS-AAD-Auth. The &lt;code&gt;flags&lt;/code&gt; byte signals the Restricted Admin and Remote Credential Guard sub-modes inside CredSSP. A real estate runs all five in different connection paths. None of them retire the others.&lt;/p&gt;
&lt;p&gt;The Microsoft Learn page for Remote Credential Guard publishes the canonical practitioner-grade comparison matrix [@msl-rcg]. Reproducing it verbatim:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Remote Desktop&lt;/th&gt;
&lt;th&gt;Remote Credential Guard&lt;/th&gt;
&lt;th&gt;Restricted Admin&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Single sign-on (SSO) for sessions&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-hop RDP&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prevent use of user&apos;s identity during connection&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prevent use of credentials after disconnection&lt;/td&gt;
&lt;td&gt;No&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;Prevent Pass-the-Hash&lt;/td&gt;
&lt;td&gt;No&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;Supported authentication&lt;/td&gt;
&lt;td&gt;Any negotiable by SSP&lt;/td&gt;
&lt;td&gt;Kerberos only&lt;/td&gt;
&lt;td&gt;Any negotiable by SSP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credentials supported from the client device&lt;/td&gt;
&lt;td&gt;Signed-in creds, supplied creds, saved creds&lt;/td&gt;
&lt;td&gt;Signed-in creds only&lt;/td&gt;
&lt;td&gt;Signed-in creds, supplied creds, saved creds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RDP access granted with&lt;/td&gt;
&lt;td&gt;Remote Desktop Users (target)&lt;/td&gt;
&lt;td&gt;Remote Desktop Users (target)&lt;/td&gt;
&lt;td&gt;Administrators (target)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The matrix anchors three points of precision. First, &quot;Prevent use of user&apos;s identity during connection&quot; is &lt;code&gt;No&lt;/code&gt; for both classic Remote Desktop &lt;em&gt;and&lt;/em&gt; Remote Credential Guard. Only Restricted Admin can promise that the user&apos;s identity is not exercised on the target -- because only Restricted Admin replaces the user&apos;s identity with the target&apos;s machine identity.&lt;/p&gt;
&lt;p&gt;Second, &quot;Prevent use of credentials after disconnection&quot; is &lt;code&gt;Yes&lt;/code&gt; for Remote CG and Restricted Admin but &lt;code&gt;No&lt;/code&gt; for classic. Third, &quot;RDP access granted with&quot; is the &lt;em&gt;access control&lt;/em&gt; primitive, not the &lt;em&gt;credential&lt;/em&gt; primitive: Restricted Admin demands Administrators-group membership on the target because the user is impersonating the machine account.&lt;/p&gt;
&lt;p&gt;The matrix excludes the two non-CredSSP modes -- classic-RDP (&lt;code&gt;PROTOCOL_RDP = 0x00&lt;/code&gt;) and PRT-over-RDP (&lt;code&gt;PROTOCOL_RDSAAD = 0x10&lt;/code&gt;). Extending the matrix to all five modes:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Classic RDP&lt;/th&gt;
&lt;th&gt;NLA (CredSSP)&lt;/th&gt;
&lt;th&gt;Restricted Admin&lt;/th&gt;
&lt;th&gt;Remote Credential Guard&lt;/th&gt;
&lt;th&gt;PRT-over-RDP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Wire selector&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PROTOCOL_RDP 0x00&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PROTOCOL_HYBRID 0x02&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CredSSP + &lt;code&gt;0x01&lt;/code&gt; flag&lt;/td&gt;
&lt;td&gt;CredSSP + &lt;code&gt;0x02&lt;/code&gt; flag&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PROTOCOL_RDSAAD 0x10&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credential delivered to target&lt;/td&gt;
&lt;td&gt;Password in RC4 channel&lt;/td&gt;
&lt;td&gt;Password in TLS (TSPasswordCreds)&lt;/td&gt;
&lt;td&gt;Empty TSPasswordCreds&lt;/td&gt;
&lt;td&gt;TSRemoteGuardCreds handle&lt;/td&gt;
&lt;td&gt;Entra PRT-cookie (JWT)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target session identity&lt;/td&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;Machine (&lt;code&gt;TARGET$&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;User (Entra principal)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User credential at target lsass&lt;/td&gt;
&lt;td&gt;Yes (NT-OWF + plaintext)&lt;/td&gt;
&lt;td&gt;Yes (NT-OWF)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSO to downstream services&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (via caller RPC)&lt;/td&gt;
&lt;td&gt;Yes (Entra token cache)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-hop RDP&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (Entra)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requires Administrators on target&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&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;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NTLM fallback allowed&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;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pre-auth-RCE protection (NLA)&lt;/td&gt;
&lt;td&gt;No&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;td&gt;Yes (via TLS-first gate)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;First shipped&lt;/td&gt;
&lt;td&gt;RDP 4.0 / 1998&lt;/td&gt;
&lt;td&gt;RDP 6.0 / Vista / Nov 2006&lt;/td&gt;
&lt;td&gt;Win 8.1 / Server 2012 R2 / Oct 17, 2013&lt;/td&gt;
&lt;td&gt;Win 10 1607 / Server 2016 / Aug 2, 2016&lt;/td&gt;
&lt;td&gt;KB5018418 / Oct 11, 2022&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canonical CVE&lt;/td&gt;
&lt;td&gt;BlueKeep (channel-setup)&lt;/td&gt;
&lt;td&gt;CVE-2018-0886 (CredSSP RCE)&lt;/td&gt;
&lt;td&gt;RBCD against TERMSRV&lt;/td&gt;
&lt;td&gt;Kerberos RBCD residual&lt;/td&gt;
&lt;td&gt;PRT-extraction at session host&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; The five modes are not strictly ordered. Each occupies a different point on the Pareto frontier of (no-credential-leak × SSO × universality × Kerberos-compatibility). An operator&apos;s job is to choose two of {Entra-issued sessions, on-prem Kerberos SSO, no credential delegation, no local-admin requirement} per RDP pair -- the matrix exists because nobody gets all four.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The 2026 operational defaults split along clean lines. The universal baseline is &lt;code&gt;NLA mandatory&lt;/code&gt; (refuse &lt;code&gt;PROTOCOL_RDP = 0x00&lt;/code&gt;), &lt;code&gt;AllowEncryptionOracle = 0&lt;/code&gt; (Force Updated Clients) [@msl-kb4093492], NTLMv1 disabled at the domain controller, and the target-side GPO &quot;Remote host allows delegation of nonexportable credentials&quot; set so Remote CG can opt in without prompting. On top of that baseline:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Admin-tier jump servers: Restricted Admin (&lt;code&gt;RestrictedRemoteAdministration&lt;/code&gt; GPO mode 1, &quot;Require Restricted Admin&quot;) [@msl-rcg].&lt;/li&gt;
&lt;li&gt;User-tier domain RDP: Remote Credential Guard (&lt;code&gt;RestrictedRemoteAdministration&lt;/code&gt; GPO mode 2 for &quot;Require Remote Credential Guard&quot;, or mode 3 for &quot;Restrict credential delegation&quot; -- the composite that prefers Remote CG and falls back to Restricted Admin when Remote CG cannot complete) [@msl-rcg].&lt;/li&gt;
&lt;li&gt;Entra-joined estates and AVD / Cloud-PC: PRT-over-RDP via &lt;code&gt;enablerdsaadauth:i:1&lt;/code&gt; [@msl-rdp-files], gated by Conditional Access on the &lt;code&gt;a4a365df-...&lt;/code&gt; app [@msl-prtrdp-mstsc].&lt;/li&gt;
&lt;li&gt;Legacy compatibility lane: NLA-mandatory classic CredSSP, accepting that the target&apos;s lsass will hold credential material for the session duration.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Regardless of which higher-level mode you choose, four settings should be on every Windows target before you read further: NLA mandatory; &lt;code&gt;AllowEncryptionOracle = 0&lt;/code&gt; [@msl-kb4093492]; NTLMv1 disabled; &quot;Remote host allows delegation of nonexportable credentials&quot; set so Remote CG opt-in does not prompt. These four are the floor. Everything else is a per-target choice on top of them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The matrix is the load-bearing artifact. The next four sections walk what it does not solve: the perimeter mitigations the matrix excludes, the theoretical limits no mode can close, the open problems still in the literature, and the practical guide an operator runs on Monday.&lt;/p&gt;
&lt;h2&gt;9. Adjacent Mitigations: What Else Protects RDP (And What It Does Not Protect)&lt;/h2&gt;
&lt;p&gt;Six adjacent mechanisms get called &quot;RDP security&quot; in vendor marketing. None of them are credential-protection mechanisms. They solve different problems at different layers, and conflating them with the five-mode matrix is the load-bearing operational confusion in modern RDP deployments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remote Desktop Gateway / RDS Gateway.&lt;/strong&gt; A network-layer reverse-proxy that tunnels RDP inside HTTPS on TCP/443. The Gateway terminates the TLS connection from the internet, authenticates the user (often via smart card or Microsoft Entra), and forwards the inner RDP session to the back-end target. Gateway solves &quot;RDP exposed to the internet on TCP/3389.&quot; It does not change which CredSSP sub-mode the inner session negotiates. If the inner session is classic-NLA, the target&apos;s lsass receives the user&apos;s NT-OWF, gateway or not.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A common misconception is that an RDS Gateway &quot;protects credentials.&quot; It does not. The Gateway proxies the RDP session, which still negotiates classic, Restricted Admin, Remote CG, or PRT-over-RDP between the client and the back-end target. The Gateway is a perimeter primitive, not an authentication mode. An operator who deploys RDS Gateway &lt;em&gt;and&lt;/em&gt; enforces Remote CG on the back-end pool has stacked two complementary mitigations. An operator who deploys RDS Gateway and leaves the back-end pool on classic NLA has hardened the perimeter without changing the post-exploitation pivot.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Just-Enough Administration (JEA) over PowerShell Remoting.&lt;/strong&gt; The &quot;don&apos;t use RDP for admin in the first place&quot; answer. JEA constrains a PowerShell Remoting session to a curated set of cmdlets executed under a managed virtual account. The transport is WSMan over HTTPS (TCP/5986 with TLS, or TCP/5985 plain), not RDP.&lt;/p&gt;
&lt;p&gt;WSMan has its own CredSSP exposure -- CVE-2018-0886 affects WinRM as well as RDP [@nvd-2018-0886] -- but a JEA endpoint configured for &lt;code&gt;RunAsVirtualAccount&lt;/code&gt; does not delegate the operator&apos;s credentials at all. JEA combined with Remote Credential Guard for the remaining graphical-admin paths is the de facto 2026 reference architecture for admin-tier work.&lt;/p&gt;

A PowerShell-Remoting feature that constrains a remote session to a whitelisted set of commands executed under a managed virtual account, eliminating credential delegation for the operator. JEA is not an RDP mode; it is the &quot;use a different protocol entirely&quot; alternative for administrative tasks that do not need a graphical session. Configured via PowerShell session-configuration files (`.pssc`) and role-capability files (`.psrc`).
&lt;p&gt;&lt;strong&gt;Smart-card and FIDO2 as the underlying credential.&lt;/strong&gt; A user can authenticate to NLA / CredSSP using a smart card (Kerberos with PKINIT) or, for PRT-over-RDP, a Windows Hello for Business or FIDO2 ceremony. The credential type matters for &lt;em&gt;phishing resistance&lt;/em&gt; and for &lt;em&gt;replayability&lt;/em&gt;. It does not change what the target ends up with after the CredSSP exchange completes. A smart-card-backed NLA session still ends with a Kerberos session key in the target&apos;s &lt;code&gt;lsass.exe&lt;/code&gt;. Phishing-resistant authentication is necessary but not sufficient; the post-exchange credential isolation lives in Restricted Admin, Remote CG, or PRT-over-RDP.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Azure Bastion / AWS Session Manager.&lt;/strong&gt; Cloud-managed jump-host services that present a web UI and proxy RDP / SSH connections to back-end VMs without exposing 3389 to the internet. Bastion handles the network-layer exposure problem. The credential-protection guarantees still depend on which CredSSP sub-mode the inner RDP session negotiates. Bastion does not magic away the requirement to also configure Restricted Admin or Remote CG on the back-end pool.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RDP-over-QUIC / AVD RDP Shortpath.&lt;/strong&gt; The Microsoft Azure Virtual Desktop &quot;Shortpath&quot; feature carries RDP traffic over UDP, with four variants documented verbatim on Microsoft Learn: &quot;RDP Shortpath for managed networks; RDP Shortpath for managed networks with ICE/STUN; RDP Shortpath for public networks with ICE/STUN; RDP Shortpath for public networks via TURN&quot; [@msl-shortpath]. The transport sits on QUIC, the UDP-based transport standardised in RFC 9000 [@rfc-9000].&lt;/p&gt;
&lt;p&gt;The Tech Community announcement of public-networks GA states verbatim: &quot;We are pleased to announce the general availability of RDP Shortpath for public networks... We started deploying RDP Shortpath in September and now the feature is 100% rolled out&quot; [@tc-shortpath-blog]; the announcement is dated late 2022. The TURN-relayed variant is GA in late 2024 per the Microsoft AVD blog series.&lt;/p&gt;

Microsoft&apos;s QUIC/UDP transport for RDP, used inside Azure Virtual Desktop and Windows 365 [@msl-shortpath]. Four variants cover managed networks, ICE/STUN-mediated traversal, public-network NAT traversal, and TURN-relayed paths through restrictive NAT. The authentication stack above the transport is unchanged from TCP-based RDP; QUIC replaces TCP/TLS with UDP/QUIC at the bottom of the stack only.
&lt;p&gt;What changes with QUIC transport is the detection surface. Network sensors keyed on &lt;code&gt;TCP/3389 + TLS handshake + CredSSP TS Request/Response&lt;/code&gt; see nothing for an AVD Shortpath session; what they should look for instead is &lt;code&gt;UDP/&amp;amp;lt;ephemeral&amp;amp;gt; + QUIC handshake + STUN/ICE candidate exchange&lt;/code&gt;. The credential-protection guarantees are &lt;em&gt;identical&lt;/em&gt; to the underlying RDP mode; the visibility-engineering work is real.FreeRDP and xrdp -- the two widely-used non-Microsoft RDP stacks -- implement a subset of the five modes. xrdp does not implement CredSSP server-side, so xrdp targets are reachable only via &lt;code&gt;PROTOCOL_RDP&lt;/code&gt; or &lt;code&gt;PROTOCOL_SSL&lt;/code&gt;; an operator who enables NLA on an xrdp host has effectively prevented Windows clients from connecting. FreeRDP supports classic, NLA / CredSSP, and Restricted Admin as a client, but does not implement Remote Credential Guard or PRT-over-RDP. Detection engineering for mixed-stack estates must account for these limits.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conditional Access, Microsoft Entra PIM, Just-In-Time access.&lt;/strong&gt; Workflow-level controls that &lt;em&gt;grant&lt;/em&gt; RDP access (the user must satisfy a PIM activation request before the JIT-provisioned admin group adds them; the Conditional Access policy must pass before the PRT-cookie is minted). These are orthogonal to what happens &lt;em&gt;during&lt;/em&gt; the RDP session. A PIM-elevated admin session that runs classic-NLA RDP still leaves the admin&apos;s credential in the target&apos;s lsass when the session ends.&lt;/p&gt;
&lt;p&gt;None of these mechanisms change the credential the target ends up with. That is the load-bearing fact. The next section walks the four classes of attack that no RDP mode -- regardless of how many adjacent mitigations are stacked -- can close.&lt;/p&gt;
&lt;h2&gt;10. Theoretical Limits: The Four Things RDP Authentication Cannot Close&lt;/h2&gt;
&lt;p&gt;The five modes between them close credential delegation (Restricted Admin), credential-after-disconnection (Restricted Admin and Remote CG), the password-and-hash entirely (PRT-over-RDP), and the pre-auth channel-setup surface (NLA). The four limits below are what is left. Each has a formal lower bound. None is closable by a sixth mode.&lt;/p&gt;
&lt;h3&gt;Limit 1: The SYSTEM-on-target floor&lt;/h3&gt;
&lt;p&gt;Any RDP mode that grants the user an actionable identity on the target permits a &lt;code&gt;SYSTEM&lt;/code&gt;-on-target adversary to use that identity for as long as the user stays connected. The session host kernel must materialise the user&apos;s security token to enforce ACL checks. An attacker with &lt;code&gt;SYSTEM&lt;/code&gt; on the target can call &lt;code&gt;OpenProcessToken&lt;/code&gt; against any process in the user&apos;s session, then &lt;code&gt;DuplicateTokenEx&lt;/code&gt; and &lt;code&gt;ImpersonateLoggedOnUser&lt;/code&gt; to perform actions as the user. Microsoft Learn encodes this as &quot;Prevent use of user&apos;s identity during connection: No&quot; for both Remote Desktop and Remote Credential Guard [@msl-rcg].&lt;/p&gt;

Remote Credential Guard helps protecting credentials over a Remote Desktop (RDP) connection by redirecting Kerberos requests back to the device that&apos;s requesting the connection. If the target device is compromised, the credentials aren&apos;t exposed because both credential and credential derivatives are never passed over the network to the target device. -- Microsoft Learn [@msl-rcg]
&lt;p&gt;That sentence promises protection of &lt;em&gt;credentials&lt;/em&gt;. It does not promise protection of the user&apos;s identity in-session. The two properties are different and only one is closable by an authentication-protocol redesign.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; No RDP mode can simultaneously give the target the ability to act as the user &lt;em&gt;and&lt;/em&gt; prevent a SYSTEM adversary on the target from acting as the user. The defense is not to close in-session impersonation; the defense is to not put the user on a compromised target. Restricted Admin closes it by giving up the user&apos;s identity entirely. Every mode that preserves the user&apos;s identity (classic, NLA, Remote CG, PRT-over-RDP) leaves the SYSTEM-on-target floor open.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Limit 2: The CredSSP residue&lt;/h3&gt;
&lt;p&gt;Even on a 2026 Entra-joined estate using PRT-over-RDP, CredSSP remains on the wire for every RDP path touching a non-Entra-joined endpoint. Legacy admin tooling, multi-hop sessions into on-prem servers, RDS deployments, hybrid scenarios -- all of them fall back to CredSSP. CredSSP has shipped at least one logical-flaw RCE (CVE-2018-0886) [@nvd-2018-0886] and the &lt;code&gt;AllowEncryptionOracle&lt;/code&gt; compatibility window [@msl-kb4093492] remains a deployment hazard whenever a new CredSSP patch ships.&lt;/p&gt;
&lt;p&gt;The architectural answer (deprecate CredSSP wholly, replace it with RDS-AAD-Auth for every RDP path) is not on Microsoft&apos;s public roadmap. MS-CSSP&apos;s current revision is 21.0, dated April 23, 2024 [@mscssp-index] -- the protocol is actively maintained, not deprecated. Operationally, CredSSP is a permanent fixture of any Windows estate that includes on-premises identity.&lt;/p&gt;
&lt;h3&gt;Limit 3: The RBCD-against-TERMSRV class&lt;/h3&gt;
&lt;p&gt;Restricted Admin closes credential delegation. It does not close the machine-identity-as-attack-primitive class. Any principal that can write &lt;code&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/code&gt; on a target&apos;s computer object can S4U2self + S4U2proxy a &lt;code&gt;TERMSRV/&amp;lt;target&amp;gt;&lt;/code&gt; ticket and RDP in as any account -- including a Domain Admin [@shamir-wagging]. Dec0ne&apos;s KrbRelayUp productionises this as &quot;a universal no-fix local privilege escalation in windows domain environments where LDAP signing is not enforced (the default settings)&quot; [@krbrelayup].&lt;/p&gt;
&lt;p&gt;The phrase &quot;no-fix&quot; is doing real work. The chain depends on default LDAP-signing settings, default kerberos delegation behaviour for resource-based constrained delegation, and the user-creatable computer object quota of &lt;code&gt;ms-DS-MachineAccountQuota = 10&lt;/code&gt; [@shamir-wagging] -- four configurations that are independently defensible per protocol but that compose into the chain. Tightening any one of them mitigates KrbRelayUp; Microsoft has not chosen to do so by default.&lt;/p&gt;
&lt;h3&gt;Limit 4: The Entra-only / on-prem-only gap&lt;/h3&gt;
&lt;p&gt;PRT-over-RDP requires both endpoints to be Microsoft-Entra-joined or hybrid-joined [@msl-prtrdp-mstsc, @msl-avdsso]. Restricted Admin and Remote CG require Kerberos and on-premises Active Directory. The two architectures do not compose: a non-hybrid Entra-joined estate cannot deploy Restricted Admin or Remote CG; an on-prem-AD estate cannot deploy PRT-over-RDP. Hybrid join is the bridging primitive, but it has its own configuration cost (Entra Connect, device-write-back, certificate trust, password hash sync), and many estates have hybrid-join enabled for only a subset of devices.&lt;/p&gt;

The five RDP modes occupy different points on a four-axis Pareto frontier: (no-credential-leak × SSO × universality × Kerberos-compatibility). No mode dominates any other on all four axes simultaneously.&lt;ul&gt;
&lt;li&gt;Classic credential delegation gives universality and SSO and Kerberos-compatibility, at the cost of credential-leak protection.&lt;/li&gt;
&lt;li&gt;NLA via CredSSP adds pre-auth-RCE gating, but the credential-leak axis is identical to classic.&lt;/li&gt;
&lt;li&gt;Restricted Admin gives credential-leak protection and Kerberos-compatibility, at the cost of SSO and the universality of the &quot;any user&quot; property (because of the Administrators-group requirement).&lt;/li&gt;
&lt;li&gt;Remote Credential Guard gives credential-leak protection and SSO, at the cost of universality (Kerberos-only).&lt;/li&gt;
&lt;li&gt;PRT-over-RDP gives credential-leak protection and SSO and modern phishing-resistant authentication, at the cost of Kerberos-compatibility and the Entra-joined-everywhere requirement.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The operator&apos;s job is composition: pick the mode that matches each RDP pair&apos;s constraints, accept that two of the four axes will fail for that pair, and use the other modes for the other pairs. A typical 2026 enterprise pool runs (at least) NLA-mandatory classic for legacy, Restricted Admin for admin-tier, Remote CG for user-tier domain RDP, and PRT-over-RDP for AVD. Four authentication modes on one estate is the normal state.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Three of the four limits are bounded: they may shrink as Microsoft deprecates NTLM, ships VBS-trustlet protection for CloudAP on session hosts, or unifies the Entra and on-prem identity surfaces. One is architectural and applies to every authentication protocol ever proposed: &lt;code&gt;SYSTEM&lt;/code&gt; on the target equals the user&apos;s identity for as long as the user stays connected. The next section walks the active research where the bounded limits are still moving.&lt;/p&gt;
&lt;h2&gt;11. Open Problems: Where Research and Operations Are Still Moving&lt;/h2&gt;
&lt;p&gt;Five open problems sit on the RDP authentication stack right now. Three are research-class. Two are operational-class. None has a &quot;just ship a patch&quot; answer.&lt;/p&gt;
&lt;h3&gt;Open Problem 1: PRT extraction at the session host&lt;/h3&gt;
&lt;p&gt;A session host that serves N concurrent RDP-in connections with PRT-over-RDP caches at least N CloudAP entries. A SYSTEM adversary on the session host can dump all of them. Dirk-jan Mollema&apos;s August 2020 follow-up to his original PRT abuse research [@mollema-prt2] describes the underlying primitive in collaboration with Benjamin Delpy (Mimikatz author). The verbatim quote is decisive:&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. Interesting enough, it turns out that 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* (2020) [@mollema-prt2]
&lt;p&gt;That property -- the PRT and session key are recoverable from CloudAP &lt;code&gt;lsass.exe&lt;/code&gt; memory irrespective of TPM protection -- holds on the &lt;em&gt;receiving&lt;/em&gt; session host the same way it holds on the &lt;em&gt;issuing&lt;/em&gt; device. This is the 2026 mirror of the 2008 &quot;RDP into the Citrix jump server and dump credentials&quot; problem.&lt;/p&gt;
&lt;p&gt;The architectural answer is to run CloudAP inside a VBS trustlet (analogous to &lt;code&gt;LsaIso.exe&lt;/code&gt; for NTLM and Kerberos) on every session host. Microsoft has not publicly committed to that work. The original PRT post [@mollema-prt1] notes that &quot;if there is no TPM the keys are stored in software... If a TPM is present, the keys required to request or use the PRT are protected by the TPM and can&apos;t be extracted under normal circumstances&quot; -- but &quot;under normal circumstances&quot; excludes the &lt;code&gt;SYSTEM&lt;/code&gt;-on-target adversary the session-host scenario assumes.&lt;/p&gt;
&lt;h3&gt;Open Problem 2: CredSSP is not deprecable&lt;/h3&gt;
&lt;p&gt;MS-CSSP revision 21.0 (April 23, 2024) [@mscssp-index] is a maintained protocol; no Microsoft roadmap deprecates it. The role transitions from &quot;the authentication layer for RDP and WinRM&quot; to &quot;the compatibility shim for everything that does not speak RDS-AAD-Auth,&quot; but compatibility shims do not retire in the absence of a forcing function. Every CredSSP CVE in the next decade lands on a still-deployed surface. The &lt;code&gt;AllowEncryptionOracle&lt;/code&gt; deployment pattern [@msl-kb4093492] is not the last of its kind.&lt;/p&gt;
&lt;h3&gt;Open Problem 3: Remote CG NTLM exclusion and the hybrid-estate user experience&lt;/h3&gt;
&lt;p&gt;Remote Credential Guard is Kerberos-only [@msl-rcg]. The &lt;code&gt;RestrictedRemoteAdministration&lt;/code&gt; GPO mode 3 is the composite &quot;Restrict credential delegation&quot; policy that prefers Remote CG and falls back to Restricted Admin when Remote CG cannot complete [@msl-rcg].&lt;/p&gt;
&lt;p&gt;The result is a fragmented user experience: on Monday a user RDPs to &lt;code&gt;server01&lt;/code&gt; and gets Remote CG (SSO works); on Tuesday the user RDPs to &lt;code&gt;server02&lt;/code&gt; whose DC trust path has a transient routing problem and gets Restricted Admin (SSO does not work). The user observes &quot;RDP to server02 is broken&quot; and files a ticket; the platform team observes &quot;the GPO fall-back is working as designed.&quot; This pattern persists until NTLM is universally removed from the estate, which is itself an open multi-year project. See the companion &lt;em&gt;NTLMless&lt;/em&gt; article on this site for the wider deprecation arc.&lt;/p&gt;
&lt;h3&gt;Open Problem 4: The Entra / on-prem composition gap&lt;/h3&gt;
&lt;p&gt;Real enterprise estates are a Venn diagram of Entra-only desktops, hybrid-joined Windows 11 laptops, and on-prem-AD-only servers. PRT-over-RDP works between Entra-joined and hybrid-joined endpoints [@msl-prtrdp-mstsc]; Restricted Admin and Remote CG work between Kerberos-routable endpoints; the four cells in the 2x2 ({client-Entra, client-AD} x {target-Entra, target-AD}) have different authentication paths. Hybrid join bridges the two architectures for devices that support it. A conjecture worth stating plainly: the two architectures will not fully converge before 2030. The intermediate state -- four authentication modes running on the same estate at the same time -- is the steady state, not a transition.&lt;/p&gt;
&lt;h3&gt;Open Problem 5: Windows 11 24H2 KIR as a deployment-fault recovery surface&lt;/h3&gt;
&lt;p&gt;In early 2025, Windows 11 24H2 shipped an authentication-stack change that broke CredSSP-mediated RDP in a subset of configurations, manifesting as session hangs at the login screen or 65-second disconnects mid-session. Microsoft rolled out a Known Issue Rollback (&quot;KIR&quot;) via Group Policy in March 2025; the policy name is widely attributed in industry press as &quot;Windows 11 24H2 and Windows Server 2025 KB5053598 250314_20401 Known Issue Rollback.&quot; The Windows 11 24H2 release-health page now reads &quot;There are no active known issues at this time&quot; as of March 27, 2025 [@msl-24h2-status], indicating the KIR cycle has resolved.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Known Issue Rollback is now a primary operational tool for managing authentication-stack regressions in Windows. When a feature update breaks CredSSP, RDP, or any other load-bearing authentication primitive, the response is no longer &quot;wait for the next monthly patch&quot;; it is &quot;push the KIR-disable Group Policy through your management plane.&quot; Operators should be familiar with the KIR mechanism &lt;em&gt;before&lt;/em&gt; the next regression cycle. The 2025 24H2 RDP regression [@msl-24h2-status] is the worked example.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Open Problem 6: QUIC transport and the network-layer detection surface&lt;/h3&gt;
&lt;p&gt;AVD RDP Shortpath for public networks has been GA since late 2022 [@tc-shortpath-blog, @msl-shortpath]; the TURN-relayed variant is GA from late 2024. QUIC is specified in RFC 9000 [@rfc-9000] and replaces TCP/3389 + TLS with UDP/&amp;lt;ephemeral&amp;gt; + QUIC. The IOC surface for &quot;RDP session in progress&quot; changes from a TLS handshake plus CredSSP TS Request/Response on TCP/3389 to a QUIC handshake plus STUN/ICE candidate exchange on a UDP port assigned at runtime.&lt;/p&gt;
&lt;p&gt;Network-detection engineering for this surface has not finished re-tuning. A reasonable conjecture: the QUIC detection surface stabilises by 2027 around per-tenant Conditional Access app-ID telemetry (sign-in log entries for &lt;code&gt;a4a365df-50f1-4397-bc59-1a1564b8bb9c&lt;/code&gt; [@msl-prtrdp-mstsc]) rather than network-layer packet signatures.&lt;/p&gt;
&lt;p&gt;These open problems share a common shape. They are all about &lt;em&gt;composition&lt;/em&gt;. The five modes have to interoperate; the credential-isolation has to extend to the session host; the detection has to span TCP and QUIC. None of them has a feature-shaped answer. The next section walks the practical guide for making the existing primitives work in your environment today.&lt;/p&gt;
&lt;h2&gt;12. Practical Guide, FAQ, and Closing&lt;/h2&gt;
&lt;p&gt;Here is what to do with this stack this week, depending on which side of the wire you live on.&lt;/p&gt;
&lt;h3&gt;For the administrator / platform engineer&lt;/h3&gt;
&lt;p&gt;The four configurations below are the universal baseline. Set them everywhere; then choose a higher-level mode per RDP pair.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enforce NLA.&lt;/strong&gt; GPO: &lt;em&gt;Computer Configuration -&amp;gt; Administrative Templates -&amp;gt; Windows Components -&amp;gt; Remote Desktop Services -&amp;gt; Remote Desktop Session Host -&amp;gt; Security -&amp;gt; Require user authentication for remote connections by using Network Level Authentication&lt;/em&gt;. Verify with PowerShell: &lt;code&gt;(Get-WmiObject -Class Win32_TSGeneralSetting -Namespace root\CIMV2\TerminalServices -Filter &quot;TerminalName=&apos;RDP-Tcp&apos;&quot;).UserAuthenticationRequired&lt;/code&gt; returns &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enforce &lt;code&gt;AllowEncryptionOracle = 0&lt;/code&gt;.&lt;/strong&gt; Set &quot;Encryption Oracle Remediation&quot; to &quot;Force Updated Clients&quot; under &lt;em&gt;Computer Configuration -&amp;gt; Administrative Templates -&amp;gt; System -&amp;gt; Credentials Delegation&lt;/em&gt;. Verify with &lt;code&gt;Get-ItemProperty &apos;HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters&apos;&lt;/code&gt; -- the &lt;code&gt;AllowEncryptionOracle&lt;/code&gt; value should be &lt;code&gt;0&lt;/code&gt; [@msl-kb4093492].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deploy Restricted Admin or Remote CG.&lt;/strong&gt; Set the &lt;code&gt;RestrictedRemoteAdministration&lt;/code&gt; GPO mode under &quot;Restrict delegation of credentials to remote servers&quot; to &lt;code&gt;1&lt;/code&gt; (Require Restricted Admin), &lt;code&gt;2&lt;/code&gt; (Require Remote Credential Guard), or &lt;code&gt;3&lt;/code&gt; (Restrict credential delegation -- the composite that prefers Remote CG and falls back to Restricted Admin when Remote CG cannot complete). Pair with the target-side &quot;Remote host allows delegation of nonexportable credentials&quot; GPO [@msl-rcg].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enable PRT-over-RDP for Entra-joined estates.&lt;/strong&gt; Distribute &lt;code&gt;.rdp&lt;/code&gt; files with &lt;code&gt;enablerdsaadauth:i:1&lt;/code&gt; [@msl-rdp-files]; gate sign-in via Conditional Access policy on the application &lt;code&gt;a4a365df-50f1-4397-bc59-1a1564b8bb9c&lt;/code&gt; [@msl-prtrdp-mstsc]; pair with Windows Hello for Business or FIDO2 for phishing-resistant primary authentication.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Before enabling Remote CG on any target, inventory the NTLM-only paths into it. Workgroup machines, machines whose target SPN registration is incomplete, machines reachable only across DC-isolating firewall rules -- all of them will refuse the Remote CG negotiation when Kerberos cannot complete.&lt;/p&gt;

The exact GPO and registry settings for the four-baseline configuration:&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NLA&lt;/strong&gt;: &lt;code&gt;Computer Configuration -&amp;gt; Administrative Templates -&amp;gt; Windows Components -&amp;gt; Remote Desktop Services -&amp;gt; Remote Desktop Session Host -&amp;gt; Security -&amp;gt; Require user authentication for remote connections by using Network Level Authentication&lt;/code&gt;. Registry: &lt;code&gt;HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\UserAuthentication = 1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AllowEncryptionOracle&lt;/strong&gt;: &lt;code&gt;Computer Configuration -&amp;gt; Administrative Templates -&amp;gt; System -&amp;gt; Credentials Delegation -&amp;gt; Encryption Oracle Remediation -&amp;gt; Force Updated Clients&lt;/code&gt;. Registry: &lt;code&gt;HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters\AllowEncryptionOracle = 0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Restricted Admin / Remote CG&lt;/strong&gt;: &lt;code&gt;Computer Configuration -&amp;gt; Administrative Templates -&amp;gt; System -&amp;gt; Credentials Delegation -&amp;gt; Restrict delegation of credentials to remote servers&lt;/code&gt;. Registry: &lt;code&gt;HKLM\Software\Policies\Microsoft\Windows\CredentialsDelegation\RestrictedRemoteAdministration = 1|2|3&lt;/code&gt; (1 = Require Restricted Admin; 2 = Require Remote Credential Guard; 3 = Restrict credential delegation -- the composite that prefers Remote CG and falls back to Restricted Admin when Remote CG cannot complete) [@msl-rcg].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Target-side trust&lt;/strong&gt;: &lt;code&gt;Computer Configuration -&amp;gt; Administrative Templates -&amp;gt; System -&amp;gt; Credentials Delegation -&amp;gt; Remote host allows delegation of nonexportable credentials -&amp;gt; Enabled&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Apply via Group Policy, Intune ADMX, or local policy. Reboot is not required for these settings to take effect, but new RDP connections must be opened after the policy applies for the negotiation to reflect the new state.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;For the security researcher&lt;/h3&gt;
&lt;p&gt;The wire-level distinction between modes is observable. Capture an RDP handshake with Wireshark (the RDP dissector is built-in). The &lt;code&gt;RDP_NEG_REQ&lt;/code&gt; and &lt;code&gt;RDP_NEG_RSP&lt;/code&gt; packets show the &lt;code&gt;requestedProtocols&lt;/code&gt; and &lt;code&gt;selectedProtocol&lt;/code&gt; fields and the Restricted Admin / Remote CG flag bits. &lt;code&gt;PROTOCOL_HYBRID = 0x02&lt;/code&gt; plus &lt;code&gt;RESTRICTED_ADMIN_MODE_SUPPORTED = 0x08&lt;/code&gt; in the response indicates the negotiated CredSSP sub-mode.&lt;/p&gt;
&lt;p&gt;{&lt;code&gt;// MS-RDPBCGR selectedProtocol bitmask: see learn.microsoft.com/.../b2975bdc function decodeNegRsp(selectedProtocol, flags) {   const protocols = [];   if ((selectedProtocol &amp;amp; 0x01) !== 0) protocols.push(&quot;PROTOCOL_SSL (TLS)&quot;);   if ((selectedProtocol &amp;amp; 0x02) !== 0) protocols.push(&quot;PROTOCOL_HYBRID (CredSSP)&quot;);   if ((selectedProtocol &amp;amp; 0x04) !== 0) protocols.push(&quot;PROTOCOL_RDSTLS&quot;);   if ((selectedProtocol &amp;amp; 0x08) !== 0) protocols.push(&quot;PROTOCOL_HYBRID_EX&quot;);   if ((selectedProtocol &amp;amp; 0x10) !== 0) protocols.push(&quot;PROTOCOL_RDSAAD (Entra)&quot;);   if (protocols.length === 0) protocols.push(&quot;PROTOCOL_RDP (classic)&quot;);   const subModes = [];   if ((flags &amp;amp; 0x08) !== 0) subModes.push(&quot;Restricted Admin supported&quot;);   if ((flags &amp;amp; 0x10) !== 0) subModes.push(&quot;Remote Credential Guard supported&quot;);   console.log(&quot;Protocols:&quot;, protocols.join(&quot; + &quot;));   console.log(&quot;Sub-modes:&quot;, subModes.length ? subModes.join(&quot;, &quot;) : &quot;none&quot;); } // Example: PROTOCOL_HYBRID + Remote CG flag decodeNegRsp(0x02, 0x10); // Example: PROTOCOL_RDSAAD (PRT-over-RDP) decodeNegRsp(0x10, 0x00);&lt;/code&gt;}&lt;/p&gt;
&lt;p&gt;On the target, the distinction between Restricted Admin and the other modes shows up in the Windows event log. Event 4624 (logon-type 10, RemoteInteractive) records the subject; for Restricted Admin the subject is &lt;code&gt;TARGET$&lt;/code&gt; (the machine account) while for classic, Remote CG, and PRT-over-RDP it is the user&apos;s account. A quick check: open an elevated &lt;code&gt;cmd&lt;/code&gt; inside the RDP session and run &lt;code&gt;whoami&lt;/code&gt;. Returns &lt;code&gt;&amp;lt;target&amp;gt;$&lt;/code&gt; under Restricted Admin; returns the user&apos;s domain or Entra account otherwise.&lt;/p&gt;
&lt;p&gt;{`&lt;/p&gt;
Mirrors four PowerShell checks an operator runs on a Windows target.
&lt;p&gt;checks = {
    &quot;NLA required&quot;: &quot;(Get-WmiObject Win32_TSGeneralSetting -Namespace root/CIMV2/TerminalServices -Filter \&quot;TerminalName=&apos;RDP-Tcp&apos;\&quot;).UserAuthenticationRequired&quot;,
    &quot;AllowEncryptionOracle == 0&quot;: &quot;(Get-ItemProperty &apos;HKLM:/Software/Microsoft/Windows/CurrentVersion/Policies/System/CredSSP/Parameters&apos;).AllowEncryptionOracle&quot;,
    &quot;Restricted Admin GPO&quot;: &quot;(Get-ItemProperty &apos;HKLM:/Software/Policies/Microsoft/Windows/CredentialsDelegation&apos;).RestrictedRemoteAdministration&quot;,
    &quot;PRT-over-RDP opt-in&quot;: &quot;Select-String -Pattern &apos;enablerdsaadauth:i:1&apos; (Get-ChildItem -Recurse -Filter *.rdp)&quot;,
}
expected = {&quot;NLA required&quot;: 1, &quot;AllowEncryptionOracle == 0&quot;: 0,
            &quot;Restricted Admin GPO&quot;: &quot;1, 2, or 3&quot;, &quot;PRT-over-RDP opt-in&quot;: &quot;present in .rdp file&quot;}
for label, cmd in checks.items():
    print(f&quot;{label}: expect {expected[label]}; run -&amp;gt; {cmd}&quot;)
`}&lt;/p&gt;
&lt;p&gt;For PRT-over-RDP detection, the highest-fidelity signal lives in Microsoft Entra ID&apos;s sign-in logs: a successful sign-in entry against the application ID &lt;code&gt;a4a365df-50f1-4397-bc59-1a1564b8bb9c&lt;/code&gt; [@msl-prtrdp-mstsc] indicates an RDP session was authenticated using the Entra path. Correlate with the target&apos;s local event log for the same user / timestamp to verify session establishment.&lt;/p&gt;
&lt;h3&gt;For the red-team operator&lt;/h3&gt;
&lt;p&gt;The post-exploitation pivots differ by mode, as the four &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; dumps in §1 illustrated:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Classic / NLA&lt;/strong&gt;: Pass-the-Hash against the target&apos;s &lt;code&gt;lsass.exe&lt;/code&gt; cache is trivial. &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; returns user&apos;s NT-OWF.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Restricted Admin&lt;/strong&gt;: PtH yields the target&apos;s machine account (&lt;code&gt;TARGET$&lt;/code&gt;), not the user. Pivot: RBCD against &lt;code&gt;TERMSRV&lt;/code&gt; via the Wagging-the-Dog chain [@shamir-wagging] or KrbRelayUp [@krbrelayup].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remote Credential Guard&lt;/strong&gt;: PtH yields nothing useful for the user; the credential never reached the target. Pivot: in-session impersonation via SYSTEM-on-target while the user is connected; use &lt;code&gt;OpenProcessToken&lt;/code&gt; against a user-session process.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PRT-over-RDP&lt;/strong&gt;: No NTLM hash, no Kerberos ticket. Pivot: PRT extraction (&lt;code&gt;sekurlsa::cloudap&lt;/code&gt;) from the target&apos;s CloudAP cache; the Dirk-jan Mollema PRT-cookie-mint flow [@mollema-prt2] applies.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;For the detection engineer&lt;/h3&gt;
&lt;p&gt;Five signal sources, ranked by fidelity:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;selectedProtocol&lt;/code&gt; and &lt;code&gt;flags&lt;/code&gt; fields in the &lt;code&gt;RDP_NEG_RSP&lt;/code&gt; packet identify the negotiated mode at the wire.&lt;/li&gt;
&lt;li&gt;Event 4624 (logon-type 10) on the target identifies the session principal: machine-account name under Restricted Admin, user name otherwise.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational&lt;/code&gt; Event ID 1149 records successful RDP session connections.&lt;/li&gt;
&lt;li&gt;RDS Gateway connection logs, if a Gateway is in the path.&lt;/li&gt;
&lt;li&gt;Microsoft Entra ID sign-in logs for the application ID &lt;code&gt;a4a365df-50f1-4397-bc59-1a1564b8bb9c&lt;/code&gt; [@msl-prtrdp-mstsc] for PRT-over-RDP sessions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For BlueKeep-class detection on patched estates: the &lt;code&gt;MS_T120&lt;/code&gt; channel name appearing in an RDP &lt;code&gt;Erect Domain Request&lt;/code&gt; or &lt;code&gt;Attach User Request&lt;/code&gt; is a high-fidelity IOC. Legitimate clients do not request that channel by name [@wiki-bluekeep].&lt;/p&gt;

No. NLA is the *policy* on the RDP server that requires authentication before the RDP session is established (before the basic-settings exchange and virtual-channel binding). NLA is *implemented by* CredSSP -- the Credential Security Support Provider, specified in MS-CSSP [@mscssp-index] -- running over TLS. When operators say &quot;we require NLA,&quot; they mean &quot;we accept only `requestedProtocols = PROTOCOL_HYBRID` or `PROTOCOL_HYBRID_EX`,&quot; both of which select CredSSP under the hood [@rdpbcgr-credssp].

No. NLA prevents pre-authentication remote code execution in the RDP channel-setup code (mitigating BlueKeep [@wiki-bluekeep]) and reduces denial-of-service exposure. NLA does not change what the target&apos;s `lsass.exe` ends up holding at the end of the CredSSP exchange. A CredSSP `TSPasswordCreds` exchange ends with the user&apos;s password or NT-OWF cached on the target. Mimikatz `sekurlsa::logonpasswords` works against a 2012-era NLA-authenticated target identically to a 1998-era classic-RDP target.

No. Restricted Admin makes the target act as *itself*: the user&apos;s session runs as the target&apos;s machine account, the target sees no user credentials, but the connecting user must already be a local Administrator on the target [@msl-rcg]. Remote Credential Guard makes the target forward operations *back to the caller*: the session runs as the user, SSO works, the connecting user only needs Remote Desktop Users group membership on the target, but the path is Kerberos-only [@msl-rcg]. Restricted Admin gave up SSO to gain universality. Remote CG kept SSO at the cost of NTLM compatibility.

Partly. Remote Credential Guard always redirects Kerberos challenges to the caller&apos;s `lsass.exe`. The long-lived signing material lives in the caller&apos;s VTL1 `LsaIso.exe` trustlet *only if* the caller has local Credential Guard enabled. Without local Credential Guard, the material is in regular user-mode `lsass.exe` on the caller. The protocol works in both cases; the protection from a post-compromise of the caller is stronger with local Credential Guard on.

No. BlueKeep (CVE-2019-0708) is a use-after-free in the `MS_T120` virtual-channel binding inside `termdd.sys`, reachable in the RDP channel-setup phase *before* NLA gating completes [@wiki-bluekeep, @nvd-2019-0708]. NLA shipped natively in every BlueKeep-affected operating system from Windows Vista onward (Windows 7, Server 2008, Server 2008 R2); Windows XP and Server 2003 did not ship NLA natively but could be retrofitted via KB951608 (March 2009). The mitigation guidance &quot;enable NLA&quot; worked because NLA *gates* that pre-auth code path behind a successful CredSSP handshake. BlueKeep is &quot;a vulnerability in the channel-setup code reachable when NLA is not enforced,&quot; not &quot;a vulnerability in an era predating NLA.&quot;

No. Microsoft Entra single sign-on for Remote Desktop shipped in the October 11, 2022 cumulative updates: KB5018418 for Windows 11, KB5018410 for Windows 10 20H2 and later, and KB5018421 for Windows Server 2022 [@msl-prtrdp-mstsc, @msl-kb5018418]. The 2025 angles are the Windows 11 24H2 broad GA wave (October 2024) and the March 2025 Known Issue Rollback for a 24H2 RDP regression [@msl-24h2-status]. The Entra-PRT-backed RDP authentication mode itself has been generally available since late 2022.

Only for Azure Virtual Desktop and Windows 365. On-premises RDP defaults to TCP/3389 with TLS. RDP-over-QUIC is implemented in AVD&apos;s RDP Shortpath feature, with four variants documented in Microsoft Learn covering managed networks, ICE/STUN traversal, public networks via ICE/STUN, and TURN-relayed paths [@msl-shortpath]. Public-networks GA was announced in late 2022 [@tc-shortpath-blog]; the TURN-relayed variant is GA in late 2024. The QUIC transport itself is RFC 9000 [@rfc-9000]. The authentication stack above the transport is unchanged from TCP-based RDP.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The five modes coexist because each makes a different Pareto trade-off, and no estate has the luxury of running just one. The matrix is the artifact you live with.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;From password-in-the-pipe to cloud-issued session, every generation of RDP authentication has closed exactly the failure mode that motivated the next. Classic delegation made the credential-aggregation problem visible; NLA gated the pre-auth channel and inadvertently introduced its own CVE class. Restricted Admin gave up the user&apos;s identity to stop delivering credentials; Remote Credential Guard recovered the identity at the cost of Kerberos-only routing; PRT-over-RDP abandoned both Kerberos and NTLM in favour of Entra-issued cookies bound to per-application Conditional Access policies.&lt;/p&gt;
&lt;p&gt;The residual classes -- RBCD against &lt;code&gt;TERMSRV&lt;/code&gt;, PRT extraction at the session host, the in-session SYSTEM-on-target floor -- are what is left, and at least one of them is architectural rather than fixable.&lt;/p&gt;
&lt;p&gt;The four &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; dumps in §1 are no longer four mysteries. They are four readings of a single matrix: which &lt;code&gt;requestedProtocols&lt;/code&gt; byte the client offered, which &lt;code&gt;flags&lt;/code&gt; bits the server accepted, and which credential payload (or which absence of a credential payload) the target received before it built the user&apos;s session. The protocol selectors are public. The trade-offs are public. The matrix is yours to compose, RDP pair by RDP pair, with full knowledge of what each choice puts on the wire and what it leaves in &lt;code&gt;lsass.exe&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;rdp-security-nla-restricted-admin-remote-credential-guard-and-the-prt-over-rdp-pivot&quot; keyTerms={[
  { term: &quot;NLA&quot;, definition: &quot;Network Level Authentication: the server-side policy that requires the client to authenticate via CredSSP before the RDP session is established.&quot; },
  { term: &quot;CredSSP&quot;, definition: &quot;Credential Security Support Provider, the wire protocol that NLA uses: TLS + SPNEGO + Kerberos or NTLM + TSCredentials.&quot; },
  { term: &quot;TSPasswordCreds&quot;, definition: &quot;The CredSSP payload carrying the user&apos;s password or NT-OWF to the target; empty in Restricted Admin mode.&quot; },
  { term: &quot;TSRemoteGuardCreds&quot;, definition: &quot;The CredSSP payload used by Remote Credential Guard, carrying a redirect handle rather than a credential.&quot; },
  { term: &quot;Restricted Admin&quot;, definition: &quot;CredSSP sub-mode that sends empty credentials and runs the user&apos;s session as the target&apos;s machine account.&quot; },
  { term: &quot;Remote Credential Guard&quot;, definition: &quot;CredSSP sub-mode that forwards every Kerberos operation back to the caller&apos;s lsass via RPC, keeping credentials off the target.&quot; },
  { term: &quot;PRT&quot;, definition: &quot;Primary Refresh Token, the long-lived Entra refresh token bound to a Microsoft-Entra-joined device, signed by a TPM-protected key where possible.&quot; },
  { term: &quot;PROTOCOL_RDSAAD&quot;, definition: &quot;RDP_NEG_REQ.requestedProtocols value 0x10 selecting the RDS-AAD-Auth protocol used by PRT-over-RDP.&quot; },
  { term: &quot;RBCD&quot;, definition: &quot;Resource-Based Constrained Delegation; lets a target&apos;s computer object specify which principals can delegate to it via the msDS-AllowedToActOnBehalfOfOtherIdentity attribute.&quot; },
  { term: &quot;BlueKeep&quot;, definition: &quot;CVE-2019-0708, a pre-auth RCE in the MS_T120 virtual-channel handler in termdd.sys, reachable when NLA is not enforced.&quot; }
]} questions={[
  { q: &quot;Why does enabling NLA not prevent Pass-the-Hash?&quot;, a: &quot;Because NLA controls when authentication happens, not what is delivered. The CredSSP exchange still ends with the user&apos;s NT-OWF in the target&apos;s lsass.&quot; },
  { q: &quot;What is the central trade-off between Restricted Admin and Remote Credential Guard?&quot;, a: &quot;Restricted Admin gives up SSO and multi-hop in exchange for universality (any negotiable authentication); Remote CG keeps SSO and multi-hop in exchange for Kerberos-only routing and an extra RPC per downstream hop.&quot; },
  { q: &quot;Why does PRT-over-RDP not need CredSSP?&quot;, a: &quot;Because RDS-AAD-Auth replaces the CredSSP exchange with TLS plus RDS-AAD-Auth PDUs carrying an Entra-issued PRT-cookie; there is no SPNEGO, no Kerberos, and no NTLM on the wire.&quot; },
  { q: &quot;What is the residual attack class for Restricted Admin?&quot;, a: &quot;RBCD against TERMSRV: any principal that can write msDS-AllowedToActOnBehalfOfOtherIdentity on the target&apos;s computer object can S4U2self+S4U2proxy a TERMSRV ticket and RDP in as anyone.&quot; },
  { q: &quot;What is the SYSTEM-on-target floor?&quot;, a: &quot;The architectural property that any RDP mode preserving the user&apos;s identity on the target permits a SYSTEM adversary on the target to impersonate the user via OpenProcessToken and ImpersonateLoggedOnUser for the connection&apos;s duration.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>rdp</category><category>credssp</category><category>remote-credential-guard</category><category>restricted-admin</category><category>entra-id</category><category>pass-the-hash</category><category>windows-security</category><category>authentication</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>Fuzzy Extractors and the One Inequality That Explains Why Windows Hello Doesn&apos;t Use One</title><link>https://paragmali.com/blog/fuzzy-extractors-windows-hello/</link><guid isPermaLink="true">https://paragmali.com/blog/fuzzy-extractors-windows-hello/</guid><description>Fuzzy extractors turn noisy biometrics into stable cryptographic keys. A single 2004 inequality explains why Windows Hello deliberately does not use one.</description><pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate><content:encoded>
A fuzzy extractor turns a noisy, low-entropy biometric reading into a stable, uniformly random cryptographic key, with a public helper string that leaks negligibly little about the key. The Dodis-Reyzin-Smith 2004 construction is the canonical primitive: a secure sketch composed with a strong randomness extractor, governed by a single security inequality that bounds the extractable key length by the source min-entropy, minus the code redundancy, minus twice the security parameter. For consumer face and fingerprint at realistic noise levels, that inequality forbids a cryptographically useful key. Windows Hello -- and Apple Face ID -- consequently use a *match-then-unwrap-TPM-sealed-key* architecture instead, in which the biometric is a gate, not an input to key derivation.
&lt;h2&gt;1. Why can&apos;t a fingerprint just be a password?&lt;/h2&gt;
&lt;p&gt;A developer building a login system writes &lt;code&gt;key = SHA256(fingerprint_image)&lt;/code&gt;, ships it, and never logs in again. Two scans of the same finger produce two slightly different images, the hash is avalanche-sensitive by design, and the cryptographic key is unrecoverable on every authentication after the first. The fix is not a bigger hash. The fix is a new cryptographic primitive.&lt;/p&gt;
&lt;p&gt;The mistake is universal because the temptation is universal. A fingerprint feels like a password: it identifies you, it is hard to forge, and you carry it everywhere. So why not just hash it into a 256-bit key the way every developer has hashed a password for thirty years? The answer is mechanical. SHA-256 is an avalanche function: flipping a single input bit flips, on average, half the output bits. A fingerprint sensor returns a slightly different image every time you press your finger to the glass; one stray dust mote, one degree of rotation, one pixel of pressure variation, and the input has changed in thousands of bits. The hash is statistically independent of the previous one. The key is gone.&lt;/p&gt;
&lt;p&gt;{&lt;code&gt;// Two near-identical 128-bit &quot;fingerprint readings&quot; differing in just 5 bits const enc = new TextEncoder(); async function sha256Hex(bytes) {   const h = await crypto.subtle.digest(&apos;SHA-256&apos;, bytes);   return [...new Uint8Array(h)].map(b =&amp;gt; b.toString(16).padStart(2,&apos;0&apos;)).join(&apos;&apos;); } const w1 = new Uint8Array(16); for (let i = 0; i &amp;lt; 16; i++) w1[i] = (i * 37) &amp;amp; 0xff; const w2 = w1.slice(); w2[3] ^= 0x01; w2[7] ^= 0x10; w2[11] ^= 0x02; w2[12] ^= 0x40; w2[15] ^= 0x80; const h1 = await sha256Hex(w1), h2 = await sha256Hex(w2); let diff = 0; for (let i = 0; i &amp;lt; 64; i++) if (h1[i] !== h2[i]) diff++; console.log(&apos;reading 1 hash:&apos;, h1); console.log(&apos;reading 2 hash:&apos;, h2); console.log(&apos;hex digits that differ:&apos;, diff, &apos;/ 64&apos;); console.log(&apos;the second hash shares nothing with the first&apos;);&lt;/code&gt;}&lt;/p&gt;
&lt;p&gt;Any biometric authentication scheme has to confront two simultaneous problems. The first is that biometric readings are &lt;em&gt;noisy&lt;/em&gt;: two scans of the same finger differ in many bits, two photos of the same face under different lighting differ in millions. The second is that biometric distributions are &lt;em&gt;low-entropy&lt;/em&gt;: fingerprints, faces, and even irises are far from uniformly random bitstrings; they cluster heavily, and a clever guesser can do much better than brute force.&lt;/p&gt;
&lt;p&gt;The Dodis-Reyzin-Smith framing of these two facts, in the introduction of their 2004 paper, is precise: &quot;strings that are neither uniformly random nor reliably reproducible seem to be more plentiful&quot; than the well-behaved strings classical cryptography assumes [@dors-2008-siamjc]. Hao, Anderson, and Daugman put the engineering version of the problem in one sentence: &quot;the main obstacle to algorithmic combination is that biometric data are noisy; only an approximate match can be expected to a stored template. Cryptography, on the other hand, requires that keys be exactly right, or protocols will fail&quot; [@hao-anderson-daugman-2005-tr].&lt;/p&gt;

A pair of algorithms $(\text{Gen}, \text{Rep})$ such that $\text{Gen}(w) \to (R, P)$ produces a uniformly random key $R \in \{0,1\}^\ell$ and a public helper string $P$, while $\text{Rep}(w&apos;, P) \to R$ recovers the same key $R$ for any $w&apos;$ within distance $t$ of $w$. The helper $P$ may be public; it must leak only negligibly about $R$ under any source $W$ of sufficient min-entropy [@dors-2008-siamjc].
&lt;p&gt;A fuzzy extractor is the primitive built to solve exactly this design problem. Given a noisy source $w$ with at least $m$ bits of min-entropy, $\text{Gen}$ produces a stable key $R$ and a public helper $P$; given any reading $w&apos;$ within Hamming distance $t$ of the original, $\text{Rep}$ recovers $R$ identically. The helper $P$ is allowed to be public; the security guarantee says $P$ leaks at most $\varepsilon$ bits about $R$ in statistical distance. This primitive is the right answer to the developer&apos;s mistake at the top of the section, and it has been the subject of twenty years of beautiful cryptographic theory.&lt;/p&gt;
&lt;p&gt;So here is the puzzle the rest of the article will solve. Every major consumer biometric authentication product -- &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; (2015), Apple Touch ID (2013), Apple Face ID (2017) -- has explicitly avoided this primitive. None of them derives a cryptographic key from your biometric. Why? The answer takes nine more sections, and it bottoms out on one inequality.&lt;/p&gt;
&lt;h2&gt;2. Historical origins: the 1990s problem statement&lt;/h2&gt;
&lt;p&gt;By the late 1990s the smartcard-and-PKI deployment wave had forced an uncomfortable question on the cryptographic community: how do you bind a long-lived private key to a &lt;em&gt;person&lt;/em&gt; rather than a &lt;em&gt;device&lt;/em&gt;? Smartcards were cheap to mass-produce, but they were also cheap to steal, and PINs got shared the moment any user found them inconvenient. Tying the key to a fingerprint or an iris reading promised a way out, but the underlying mathematics had not yet been written down.&lt;/p&gt;
&lt;p&gt;Two foundational tools were already in the cryptographic toolkit and would later become load-bearing pieces of the fuzzy extractor. The first was the 1979 Carter-Wegman construction of &lt;em&gt;universal hash functions&lt;/em&gt;: a family ${h_s}$ such that for any two distinct inputs $x \ne y$, $\Pr_s[h_s(x) = h_s(y)] \le 1/|\text{range}|$ [@carter-wegman-1979]. The second was the 1989 Impagliazzo-Levin-Luby Leftover Hash Lemma (LHL), which proved that applying a randomly chosen universal hash to any min-entropy source yields an output statistically indistinguishable from uniform, up to a precise entropy budget [@ill-1989]. Together, these two results were a randomness-extraction toolkit waiting for an application.Carter-Wegman 1979 is the deepest ancestor of every information-theoretic fuzzy extractor. The strong extractor at the heart of the Dodis-Reyzin-Smith construction is, mechanically, a Carter-Wegman universal hash with a random seed -- the LHL is what proves its output is uniform.&lt;/p&gt;

The min-entropy of a random variable $W$ is $H_\infty(W) = -\log_2 \max_w \Pr[W = w]$. It is the entropy measure that captures *worst-case* guessing difficulty: a source with $m$ bits of min-entropy cannot be guessed correctly with probability greater than $2^{-m}$ in one try. Min-entropy is the right measure for cryptographic key derivation because Shannon entropy is too generous when the distribution is peaked [@dors-2008-siamjc].
&lt;p&gt;In May 1998, at the IEEE Symposium on Security and Privacy, Davida, Frankel, and Matt published the first formal-cryptographic proposal for binding a private signing key to a biometric. Their scheme used majority-decoding with a BCH error-correcting code to absorb the noise in repeated iris readings, then used the corrected reading to release a stored long-lived signing key [@davida-frankel-matt-1998], [@dblp-davida-frankel-matt-1998]. The construction worked, in the sense that it ran end-to-end on test data. But the paper had no notion of a &lt;em&gt;strong extractor&lt;/em&gt;, no parameter inequality bounding the extractable key length, and no security theorem against a generic adversary. The reader was asked to trust the construction by inspection.&lt;/p&gt;
&lt;p&gt;That same period saw the rise of a completely different approach. In 2001, Ratha, Connell, and Bolle of IBM proposed &lt;em&gt;cancelable biometrics&lt;/em&gt;: instead of trying to derive a cryptographic key from the biometric, apply a non-invertible application-specific transformation $T_i$ to the feature vector before storage, so that a compromised template can be revoked and re-issued under a fresh $T_j$ [@ratha-connell-bolle-2001]. The goal was &lt;em&gt;template protection&lt;/em&gt;, not key derivation.&lt;/p&gt;
&lt;p&gt;The three properties Ratha et al. demanded of $T_i$ -- &lt;em&gt;irreversibility&lt;/em&gt; (the transform cannot be inverted to recover the original feature vector), &lt;em&gt;unlinkability&lt;/em&gt; (two transforms of the same biometric cannot be matched), and &lt;em&gt;renewability&lt;/em&gt; (a compromised transform can be replaced) -- would two decades later be codified verbatim by ISO/IEC 24745:2022 as the universal properties of any biometric template protection scheme [@iso-iec-24745-2022], [@rathgeb-uhl-2011]. Cancelable biometrics partitions the design space alongside fuzzy extractors: the former &lt;em&gt;transforms&lt;/em&gt; a biometric template, the latter &lt;em&gt;derives&lt;/em&gt; a cryptographic key from it.&lt;/p&gt;
&lt;p&gt;Davida, Frankel, and Matt had shipped a working construction without a unifying primitive. Juels and Wattenberg, within twelve months, would publish a cleaner construction with the same gap; and within seven years Dodis, Reyzin, and Smith would close it. The next section is the story of those precursors, and the structural defect they share.&lt;/p&gt;
&lt;h2&gt;3. Early approaches: fuzzy commitment and fuzzy vault&lt;/h2&gt;
&lt;p&gt;Two precursor constructions, six years apart, get most of the way to a fuzzy extractor without naming the primitive. They are simultaneously the foundation everything later builds on and the ad-hoc constructions the 2004 Dodis-Reyzin-Smith paper would retroactively classify as &lt;em&gt;components&lt;/em&gt; of a real abstraction rather than a complete one.&lt;/p&gt;
&lt;h3&gt;3.1 Juels-Wattenberg 1999: fuzzy commitment&lt;/h3&gt;
&lt;p&gt;Ari Juels and Martin Wattenberg, at the 1999 ACM Conference on Computer and Communications Security, introduced the &lt;strong&gt;fuzzy commitment scheme&lt;/strong&gt; [@juels-wattenberg-1999-pdf]. The construction is short enough to write on a napkin. Fix a binary error-correcting code $\mathcal{C} \subseteq {0,1}^n$ that corrects up to $t$ errors. To commit to a noisy biometric reading $w \in {0,1}^n$:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pick a random codeword $c \stackrel{R}{\leftarrow} \mathcal{C}$.&lt;/li&gt;
&lt;li&gt;Publish the commitment blob $(h(c), \delta)$ where $\delta := w \oplus c$ and $h$ is a cryptographic hash.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To decommit with a fresh reading $w&apos;$ within Hamming distance $t$ of $w$, compute $c&apos; := D(w&apos; \oplus \delta)$ where $D$ is the code&apos;s decoder; check $h(c&apos;) \stackrel{?}{=} h(c)$. If the check passes, the commitment opens. The argument that the scheme is &lt;em&gt;binding&lt;/em&gt; (the committer cannot later open to a different value) and &lt;em&gt;hiding&lt;/em&gt; (the commitment leaks nothing about $w$) goes through in the random-oracle model.&lt;/p&gt;

sequenceDiagram
    participant U as User (commit)
    participant S as Storage
    participant V as Verifier (decommit)
    U-&amp;gt;&amp;gt;U: Pick random codeword c
    U-&amp;gt;&amp;gt;U: Compute delta = w XOR c
    U-&amp;gt;&amp;gt;U: Compute t = hash(c)
    U-&amp;gt;&amp;gt;S: Publish (t, delta)
    Note over V: Time passes, user re-scans
    V-&amp;gt;&amp;gt;S: Fetch (t, delta)
    V-&amp;gt;&amp;gt;V: Read fresh w&apos; near w
    V-&amp;gt;&amp;gt;V: Compute c&apos; = Decode(w&apos; XOR delta)
    V-&amp;gt;&amp;gt;V: Check hash(c&apos;) == t
    V--&amp;gt;&amp;gt;V: Open commitment to c
&lt;p&gt;Fuzzy commitment is elegant, but it has three structural gaps that DRS 2004 will later expose.&lt;/p&gt;
&lt;p&gt;First, the construction is a &lt;em&gt;commitment&lt;/em&gt;, not an &lt;em&gt;extractor&lt;/em&gt;: it binds a hash of a codeword, not a uniformly random key, and it cannot be plugged directly into a key-derivation pipeline. Second, it assumes Hamming-distance noise, which fits iris codes (Daugman&apos;s IrisCodes are fixed-length bitstrings whose pairwise distance is fractional binomial) but does not fit fingerprint minutiae sets or face embeddings. Third, and most damagingly, the construction leaks under correlated re-enrolment. In 2009, Simoens, Tuyls, and Preneel demonstrated &quot;how to link and reverse protected templates produced by code-offset and bit-permutation sketches&quot; [@simoens-tuyls-preneel-2009]; if a user enrols twice with two slightly different readings $w_1, w_2$ of the same finger, the helper pair $(\delta_1, \delta_2)$ leaks $w_1 \oplus w_2$, which is closer to zero than uniform and reveals the noise distribution.&lt;/p&gt;
&lt;h3&gt;3.2 Juels-Sudan 2002 / 2006: fuzzy vault&lt;/h3&gt;
&lt;p&gt;Three years later, Ari Juels and Madhu Sudan extended the same idea to &lt;em&gt;unordered sets&lt;/em&gt;, the natural metric for fingerprint minutiae [@juels-sudan-2002-pdf], [@juels-sudan-2006-dcc]. The &lt;strong&gt;fuzzy vault&lt;/strong&gt; locks a secret $\kappa$ in a vault as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Encode $\kappa$ as the coefficients of a polynomial $p$ of degree $k$ over a finite field.&lt;/li&gt;
&lt;li&gt;For each element $a_i$ of the genuine biometric set $A$, publish the point $(a_i, p(a_i))$.&lt;/li&gt;
&lt;li&gt;Add many &lt;em&gt;chaff points&lt;/em&gt; $(x_j, y_j)$ with $y_j \ne p(x_j)$ to drown the genuine points in noise.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A user whose set $B$ overlaps sufficiently with $A$ identifies enough true points to Reed-Solomon-decode $p$, recovers $\kappa$, and unlocks the vault. The construction handles set-difference noise naturally and was widely deployed in fingerprint authentication research between 2002 and 2010.Watch the citation. The conference version is IEEE ISIT 2002 (single-page proceedings extended abstract; full author PDF is the canonical text). The journal version is &lt;em&gt;Designs, Codes and Cryptography&lt;/em&gt; 38(2):237-257, February 2006 -- not IEEE Transactions on Information Theory as one widely-circulated secondary source claims.&lt;/p&gt;
&lt;p&gt;But the fuzzy vault inherits and amplifies the precursor&apos;s defects. Walter Scheirer and Terrance Boult, in 2007, enumerated three concrete attacks: &lt;em&gt;Attack via Record Multiplicity&lt;/em&gt; (ARM), &lt;em&gt;Surreptitious Key Inversion&lt;/em&gt; (SKI), and &lt;em&gt;Blended Substitution&lt;/em&gt; [@scheirer-boult-2007]. The Attack via Record Multiplicity exploits exactly the same correlated-re-enrolment weakness fuzzy commitment has: two vaults locking the same biometric under different polynomials reveal the underlying set $A$ by intersecting the published points. The Scheirer-Boult paper opens with a sentence that is, in retrospect, the diagnosis of the entire pre-DRS literature: &quot;while many PETs for biometrics have attempted a formal analysis of their security, a significant oversight has been the issue of the risk from attacks that use multiple records&quot; [@scheirer-boult-2007].&lt;/p&gt;
&lt;h3&gt;3.3 The structural defect both constructions share&lt;/h3&gt;
&lt;p&gt;Stand back. Both constructions handle noise tolerance via an error-correcting code, and both produce a security argument by hashing or hiding the result. Neither construction separates these two responsibilities. The noise-tolerance layer (the code) and the uniformity layer (the hash) are entangled in the same blob of public data. That entanglement is structurally why neither can prove a generic security theorem against a generic adversary: every security argument is tied to specific assumptions about the source distribution, the code, and the random oracle, and slight changes to any of them break the analysis. The fix is not a better code or a better hash. The fix has a name: &lt;em&gt;decomposition&lt;/em&gt;.&lt;/p&gt;

A pair of algorithms $(\text{SS}, \text{Rec})$ such that $\text{SS}(w) \to s$ produces a public sketch $s$, and $\text{Rec}(w&apos;, s) \to w$ recovers the original $w$ for any $w&apos;$ within distance $t$ of $w$. The sketch is allowed to leak some information about $w$, but the residual *average min-entropy* $\tilde H_\infty(W \mid \text{SS}(W))$ must remain at least some target $\tilde m$ [@dors-2008-siamjc].
&lt;p&gt;That word -- decomposition -- is what Dodis, Reyzin, and Smith would deliver, on Thursday May 6, 2004, in Interlaken, Switzerland, at EUROCRYPT.&lt;/p&gt;
&lt;h2&gt;4. Evolution: five generations at a glance&lt;/h2&gt;
&lt;p&gt;Before walking through the DRS 2004 decomposition in detail, it helps to see where it sits in the family tree. Every construction the rest of this article mentions belongs to one of five generations, ordered by what failure of the previous generation it closes.&lt;/p&gt;

flowchart LR
    G0[&quot;Gen 0&lt;br /&gt;hash(w)&lt;br /&gt;fails on noise&quot;] --&amp;gt; G1[&quot;Gen 1&lt;br /&gt;Juels-Wattenberg 1999&lt;br /&gt;fuzzy commitment&quot;]
    G1 --&amp;gt; G15[&quot;Gen 1.5&lt;br /&gt;Juels-Sudan 2002/2006&lt;br /&gt;fuzzy vault&quot;]
    G15 --&amp;gt; G2[&quot;Gen 2&lt;br /&gt;Dodis-Reyzin-Smith 2004&lt;br /&gt;fuzzy extractor&quot;]
    G2 --&amp;gt; G3a[&quot;Gen 3a&lt;br /&gt;Boyen 2004&lt;br /&gt;reusable&quot;]
    G2 --&amp;gt; G3b[&quot;Gen 3b&lt;br /&gt;BDKOS 2005 / DKKRS 2012&lt;br /&gt;tamper-resilient&quot;]
    G2 --&amp;gt; G4[&quot;Gen 4&lt;br /&gt;Fuller-Meng-Reyzin 2013&lt;br /&gt;computational, LWE-based&quot;]
    G2 --&amp;gt; G5[&quot;Gen 5&lt;br /&gt;CFPRS 2016&lt;br /&gt;reusable low-entropy&quot;]
&lt;p&gt;The table below names each generation, its central insight, and the new failure mode it exposes that motivates the next generation. Read it top to bottom; each row solves a problem the row above raised.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gen&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Authors / venue&lt;/th&gt;
&lt;th&gt;Central insight&lt;/th&gt;
&lt;th&gt;New failure exposed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;folk&lt;/td&gt;
&lt;td&gt;$\text{key} = h(w)$&lt;/td&gt;
&lt;td&gt;Avalanche destroys key on every re-scan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1999&lt;/td&gt;
&lt;td&gt;Juels-Wattenberg, CCS [@juels-wattenberg-1999-pdf]&lt;/td&gt;
&lt;td&gt;Code-offset: hide $w$ inside $\delta = w \oplus c$ for random codeword $c$&lt;/td&gt;
&lt;td&gt;Hamming-only; no extractor; leaks under re-enrol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.5&lt;/td&gt;
&lt;td&gt;2002 / 2006&lt;/td&gt;
&lt;td&gt;Juels-Sudan, ISIT / DCC [@juels-sudan-2002-pdf], [@juels-sudan-2006-dcc]&lt;/td&gt;
&lt;td&gt;Polynomial-on-set with chaff points; handles set-difference&lt;/td&gt;
&lt;td&gt;Vulnerable to record-multiplicity and key-inversion attacks [@scheirer-boult-2007]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2004 / 2008&lt;/td&gt;
&lt;td&gt;Dodis-Reyzin-Smith, EUROCRYPT / SIAM JC [@drs-2004-eurocrypt], [@dors-2008-siamjc]&lt;/td&gt;
&lt;td&gt;Decomposition: secure sketch + strong extractor; one inequality&lt;/td&gt;
&lt;td&gt;Forbids construction at consumer biometric entropy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3a&lt;/td&gt;
&lt;td&gt;2004&lt;/td&gt;
&lt;td&gt;Boyen, CCS [@boyen-2004-ccs-eprint]&lt;/td&gt;
&lt;td&gt;Reusable fuzzy extractors; chosen-perturbation security&lt;/td&gt;
&lt;td&gt;Outsider model needs XOR-homomorphic sketch; insider model needs RO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3b&lt;/td&gt;
&lt;td&gt;2005 / 2012&lt;/td&gt;
&lt;td&gt;Boyen-Dodis-Katz-Ostrovsky-Smith, EUROCRYPT [@bdkos-2005-eurocrypt]; DKKRS, IEEE TIT [@dkkrs-2012-ieeetit]&lt;/td&gt;
&lt;td&gt;Tamper-resilient fuzzy extractors; helper-data integrity against active adversary&lt;/td&gt;
&lt;td&gt;Active-adversary lower bound: $\Omega(\log(1/\varepsilon))$ extra entropy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2013 / 2020&lt;/td&gt;
&lt;td&gt;Fuller-Meng-Reyzin, ASIACRYPT / I&amp;amp;C [@fmr-2013-asiacrypt-eprint], [@fmr-2020-iandc]&lt;/td&gt;
&lt;td&gt;Skip the sketch; LWE-based computational construction extracts key length equal to source min-entropy&lt;/td&gt;
&lt;td&gt;Negative result: every computational HILL secure sketch still implies an ECC with $2^{m-2}$ codewords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;2016&lt;/td&gt;
&lt;td&gt;Canetti-Fuller-Paneth-Reyzin-Smith, EUROCRYPT [@cfprs-2016-eurocrypt]&lt;/td&gt;
&lt;td&gt;Per-bit digital lockers; sample-then-extract; reusable for low-entropy sources&lt;/td&gt;
&lt;td&gt;Depends on digital-locker idealisation; restricted source class&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Read this way, the family tree tells a story. Each successor generation closes a real defect: Boyen 2004 closes the multi-enrolment leak that Simoens-Tuyls-Preneel would later make concrete; BDKOS 2005 closes the helper-data tampering problem; FMR 2013 attacks the min-entropy floor itself by trading information-theoretic security for an LWE assumption; CFPRS 2016 chases the low-entropy regime where every prior generation gave up. None of them dethrones the foundational decomposition. They all live inside the framework DRS established.Watch two attribution traps. Boyen 2004 is a sole-author paper -- &quot;Reusable Cryptographic Fuzzy Extractors&quot; by Xavier Boyen [@boyen-2004-ccs-eprint], not &quot;Boyen and Reyzin&quot; or &quot;Boyen et al.&quot; And Fuller-Meng-Reyzin 2013 appeared at &lt;em&gt;ASIACRYPT&lt;/em&gt; 2013, not EUROCRYPT 2013; the misattribution is widespread in secondary sources [@fmr-2013-asiacrypt-eprint].&lt;/p&gt;
&lt;p&gt;Generation 2 is the load-bearing entry. Every later claim about what a fuzzy extractor can and cannot do traces back to it. The next section walks through the construction in mechanical detail, because the inequality at its centre is the artefact every later section will reference.&lt;/p&gt;
&lt;h2&gt;5. The breakthrough: Dodis-Reyzin-Smith 2004 in detail&lt;/h2&gt;
&lt;p&gt;May 6, 2004. Interlaken, Switzerland. Session 16 (&quot;New Applications&quot;). Yevgeniy Dodis (NYU), Leonid Reyzin (Boston University), and Adam Smith (then MIT) present a paper that will be widely cited as the foundational work of the area [@drs-2004-eurocrypt]. The journal version, published in 2008 in &lt;em&gt;SIAM Journal on Computing&lt;/em&gt; with Rafail Ostrovsky added as a fourth author, is the canonical reference text for every formal definition the field uses [@dors-2008-siamjc].The conference paper is three-author Dodis-Reyzin-Smith; the 2008 SIAM Journal on Computing version is four-author and adds Ostrovsky. Cite whichever fits your context, but get the author count right.&lt;/p&gt;
&lt;p&gt;The paper&apos;s contribution is not a new algorithm. It is a &lt;em&gt;decomposition&lt;/em&gt; and a &lt;em&gt;security inequality&lt;/em&gt;. The two halves of the decomposition are the secure sketch and the strong randomness extractor, and the inequality bounds the extractable key length in terms of source min-entropy, code redundancy, and security parameter.&lt;/p&gt;
&lt;h3&gt;5.1 The secure sketch: information reconciliation&lt;/h3&gt;
&lt;p&gt;A secure sketch is the noise-tolerance layer. Formally, an $(\mathcal{M}, m, \tilde m, t)$-secure sketch is a pair of functions $(\text{SS}, \text{Rec})$ over a metric space $(\mathcal{M}, \text{dis})$ such that, for any $w, w&apos;$ with $\text{dis}(w, w&apos;) \le t$, $\text{Rec}(w&apos;, \text{SS}(w)) = w$, and for any source $W$ with min-entropy $H_\infty(W) \ge m$, the &lt;em&gt;average min-entropy&lt;/em&gt; $\tilde H_\infty(W \mid \text{SS}(W)) \ge \tilde m$ [@dors-2008-siamjc].&lt;/p&gt;

Average min-entropy, also called conditional min-entropy, generalises min-entropy to the case where partial information $Y$ about $W$ is public. Formally, $\tilde H_\infty(W \mid Y) = -\log_2 \mathbb{E}_{y \leftarrow Y}\!\left[\max_w \Pr[W = w \mid Y = y]\right]$. It is the right entropy measure for sketches because the sketch $\text{SS}(W)$ is public and an adversary&apos;s best guess of $W$ averages over the possible sketch values [@dors-2008-siamjc].
&lt;p&gt;Two canonical sketch constructions matter. The &lt;strong&gt;code-offset sketch&lt;/strong&gt; picks a random codeword $c$ from an $[n, k, 2t+1]$ binary error-correcting code and publishes $s = w \oplus c$. To recover, compute $c&apos; = D(w&apos; \oplus s)$ where $D$ is the code&apos;s decoder; then return $w = s \oplus c&apos;$. The entropy loss is at most $n - k$ bits. The &lt;strong&gt;syndrome sketch&lt;/strong&gt; publishes $s = H \cdot w^T$ where $H$ is the parity-check matrix of the same code; recovery solves a coset-leader problem. The entropy loss is identical; the syndrome variant just publishes a shorter helper. PinSketch, the canonical sketch for &lt;em&gt;set-difference&lt;/em&gt; metrics, lives in section 6 of the journal paper [@dors-2008-siamjc].&lt;/p&gt;
&lt;p&gt;{&lt;code&gt;// Simulate a tiny [16, 11, 3] code: 11 data bits, 5 parity bits via a fixed generator. // Real code-offset uses BCH/Reed-Solomon; this is a toy that shows the structure. function parity(w, mask) { let p = 0; for (let i = 0; i &amp;lt; 16; i++) if ((mask&amp;gt;&amp;gt;i)&amp;amp;1) p ^= (w&amp;gt;&amp;gt;i)&amp;amp;1; return p; } const masks = [0b1111111111100000, 0b1111110000011110, 0b1111000011111101, 0b1100111111111011, 0b0011111111110111]; function encode(data11) {   let cw = data11 &amp;amp; 0x7FF;   for (let i = 0; i &amp;lt; 5; i++) cw |= parity(data11, masks[i]) &amp;lt;&amp;lt; (11 + i);   return cw; } // Sketch: pick a random codeword c, publish s = w XOR c const w = 0b0110110010110101; // imagine this is the user&apos;s first reading const data = Math.floor(Math.random() * 2048); const c = encode(data); const s = w ^ c; console.log(&apos;First reading w =&apos;, w.toString(2).padStart(16,&apos;0&apos;)); console.log(&apos;Random codeword c =&apos;, c.toString(2).padStart(16,&apos;0&apos;)); console.log(&apos;Public sketch s = w XOR c =&apos;, s.toString(2).padStart(16,&apos;0&apos;)); // Re-scan: the user reads w&apos; with one bit flipped const wp = w ^ (1 &amp;lt;&amp;lt; 7); console.log(&apos;Re-scan reading w\\&apos; =&apos;, wp.toString(2).padStart(16,&apos;0&apos;)); const cp = wp ^ s; console.log(&apos;Decoder input c + e =&apos;, cp.toString(2).padStart(16,&apos;0&apos;)); console.log(&apos;The decoder sees the noisy codeword and corrects it back to c -- so Rec recovers w from w\\&apos; and s.&apos;);&lt;/code&gt;}&lt;/p&gt;
&lt;h3&gt;5.2 The strong randomness extractor: from sketch-residual to uniform key&lt;/h3&gt;
&lt;p&gt;A strong randomness extractor is the uniformity layer. The relevant formal statement is the average-case form of the &lt;strong&gt;Leftover Hash Lemma&lt;/strong&gt;.&lt;/p&gt;

A function $\text{Ext}: \{0,1\}^n \times \{0,1\}^d \to \{0,1\}^\ell$ is an *average-case* $(n, \tilde m, \ell, \varepsilon)$-strong extractor if, for every joint distribution $(W, I)$ over $\{0,1\}^n \times \{0,1\}^*$ with $\tilde H_\infty(W \mid I) \ge \tilde m$, the statistical distance $\text{SD}((\text{Ext}(W; S), S, I), (U_\ell, S, I)) \le \varepsilon$ where $S$ is the (public) extractor seed and $U_\ell$ is uniform [@dors-2008-siamjc].

Let $H$ be a universal hash family with output length $\ell$. For any source $W$ with $\tilde H_\infty(W \mid I) \ge \tilde m$, the distribution $(S, H_S(W), I)$ is $\varepsilon$-close in statistical distance to $(S, U_\ell, I)$ whenever $\ell \le \tilde m - 2 \log(1/\varepsilon) + 2$ [@ill-1989], [@dors-2008-siamjc]. The Leftover Hash Lemma is therefore the single inequality that powers every information-theoretic strong extractor used in practice.
&lt;p&gt;The LHL says: take any min-entropy source, hash it with a randomly chosen universal hash, and what comes out is statistically indistinguishable from uniform, up to a precise budget. Pay $2 \log(1/\varepsilon) - 2$ bits of entropy at the door; everything left over is uniform.&lt;/p&gt;
&lt;h3&gt;5.3 Composition&lt;/h3&gt;
&lt;p&gt;The composition is the whole point. Define $\text{Gen}(w) := (R, P)$ where $P = (\text{SS}(w), \text{seed})$ and $R = \text{Ext}(w; \text{seed})$. To recover, $\text{Rep}(w&apos;, P)$ runs $w = \text{Rec}(w&apos;, \text{SS}(w))$ and recomputes $R = \text{Ext}(w; \text{seed})$. The composition is an $(\mathcal{M}, m, \ell, t, \varepsilon)$-fuzzy extractor, and the security proof is now algebraic.&lt;/p&gt;

The helper data $P$ in a fuzzy extractor is the public part of the output of $\text{Gen}$. It consists of the secure sketch $\text{SS}(w)$ plus the extractor seed. It must be available at recovery time, but it need not be secret. The security guarantee says that even an adversary who sees $P$ in full learns at most $\varepsilon$ bits about the extracted key $R$ in statistical distance [@dors-2008-siamjc].

flowchart TD
    W[&quot;Noisy reading w&quot;] --&amp;gt; SS[&quot;Secure sketch SS&quot;]
    W --&amp;gt; EXT[&quot;Strong extractor Ext&quot;]
    SEED[&quot;Random seed&quot;] --&amp;gt; EXT
    SS --&amp;gt; P[&quot;Public helper P = (sketch, seed)&quot;]
    SEED --&amp;gt; P
    EXT --&amp;gt; R[&quot;Uniform key R&quot;]
    P --&amp;gt; REP[&quot;Rep at recovery&quot;]
    WP[&quot;Noisy reading w&apos;&lt;br /&gt;(within distance t)&quot;] --&amp;gt; REP
    REP --&amp;gt; R2[&quot;Same uniform key R&quot;]
&lt;h3&gt;5.4 The load-bearing inequality&lt;/h3&gt;
&lt;p&gt;Compose the two entropy budgets. The sketch starts with $H_\infty(W) \ge m$ bits of min-entropy and leaks at most $n - k$ to its public sketch; what remains is $\tilde H_\infty(W \mid \text{SS}(W)) \ge m - (n - k)$. Feed that residual into the LHL with security parameter $\varepsilon$, and the extractor delivers a uniform key of lengthThe constant $+2$ at the end of the inequality is an artefact of how DORS 2008 states the average-case Leftover Hash Lemma in Lemma 2.4; the conference paper writes it as $-O(1)$.&lt;/p&gt;

$$\ell \;\le\; H_\infty(W) - (n - k) - 2\log(1/\varepsilon) + 2.$$
&lt;p&gt;This inequality is the artefact every later section will reference. Walk it term by term. The first term is the source min-entropy: the actual information content of the biometric. The second term is the code redundancy: the entropy paid to absorb noise. The third term is the security parameter cost: every halving of the adversary&apos;s distinguishing advantage costs two bits. The final $+2$ is a small constant.&lt;/p&gt;
&lt;p&gt;{&lt;code&gt;function extractableKeyLen(m, codeRedundancy, epsilon) {   const securityCost = 2 * Math.log2(1 / epsilon);   return m - codeRedundancy - securityCost + 2; } // Iris source (Daugman 2003: ~249 dof = effective bits), 128-bit security, BCH [255,131,37] console.log(&apos;iris @ eps=2^-80:&apos;, extractableKeyLen(249, 124, 2 ** -80).toFixed(1), &apos;bits&apos;); // Fingerprint at the upper end of Pankanti-Prabhakar-Jain 2002 (~70 effective bits) console.log(&apos;fingerprint @ eps=2^-80:&apos;, extractableKeyLen(70, 124, 2 ** -80).toFixed(1), &apos;bits&apos;); // Face embedding under correlated illumination noise (~30-50 effective bits) console.log(&apos;face @ eps=2^-80:&apos;, extractableKeyLen(40, 124, 2 ** -80).toFixed(1), &apos;bits&apos;); // Loosen security to eps=2^-40 and see if fingerprint recovers console.log(&apos;fingerprint @ eps=2^-40:&apos;, extractableKeyLen(70, 124, 2 ** -40).toFixed(1), &apos;bits&apos;);&lt;/code&gt;}&lt;/p&gt;
&lt;p&gt;Run that calculator on realistic numbers. At a security parameter of $\varepsilon = 2^{-80}$, the third term alone eats 160 bits. A standard $[255, 131, 37]$ BCH code (which corrects up to 18 errors in 255 bits) burns another 124 bits. To extract a 128-bit AES key, the source must supply at least 410 bits of min-entropy.&lt;/p&gt;

Set $m = 70$ (fingerprint upper bound per Pankanti et al. 2002), $n - k = 124$ (BCH redundancy), and $\varepsilon = 2^{-80}$. The extractable key length becomes $70 - 124 - 160 + 2 = -212$ bits. A negative bound means the construction is not slow or expensive: it is *infeasible* at any parameter setting. Try loosening security to $\varepsilon = 2^{-40}$: still $70 - 124 - 80 + 2 = -132$. Even pushing the security parameter all the way down to $\varepsilon = 2^{-10}$ (laughably weak by OS-authenticator standards) leaves you at \$70 - 124 - 20 + 2 = -72$ bits. The fingerprint source simply does not have the entropy budget for the construction at any meaningful security level.
&lt;p&gt;The iris, at Daugman&apos;s 249 statistical degrees of freedom [@daugman-2003-pdf], [@daugman-2004-csvt], is just barely enough -- and only because Hao, Anderson, and Daugman engineered a careful two-layer Hadamard-then-Reed-Solomon code that exploits the block structure of iris noise to achieve a high error-correction rate per information bit, sufficient to extract 140 bits from the 2048-bit iris code at 99.5% recovery success [@hao-anderson-daugman-2005-tr]. The fingerprint, at 40 to ~70 effective bits per Pankanti, Prabhakar, and Jain [@pankanti-prabhakar-jain-2002], is not even close. The face embedding, at 30 to 50 raw bits and considerably less under correlated illumination and pose noise, is further still.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The DRS 2004 key-length inequality is the article&apos;s load-bearing artefact. Every later claim that a fuzzy extractor cannot work on consumer biometrics traces back to it. The construction is not slow or expensive on these sources -- it is &lt;em&gt;mathematically forbidden&lt;/em&gt;, in the sense that the extractable key length is negative at the security parameter an operating-system authenticator demands.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is the inequality that forbids the construction on consumer-grade face or fingerprint at the security bar an operating system authenticator demands. The rest of the article is the four-generation effort to escape the forbidding, and the architectural choice every shipped consumer product made instead.&lt;/p&gt;
&lt;h2&gt;6. State of the art: by metric space and by successor generation&lt;/h2&gt;
&lt;p&gt;The DRS 2004 framework is parameterised by metric space and source class. To navigate the field, think of every fuzzy-extractor instantiation as a pair of choices: pick a sketch suited to the source&apos;s metric, then pick an extractor suited to the source&apos;s entropy profile. The state of the art is best read as a two-axis table.&lt;/p&gt;
&lt;h3&gt;6.1 Sketches by metric space&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric space&lt;/th&gt;
&lt;th&gt;Sketch construction&lt;/th&gt;
&lt;th&gt;Code or technique&lt;/th&gt;
&lt;th&gt;Where it fits&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Hamming distance&lt;/td&gt;
&lt;td&gt;Code-offset / syndrome [@dors-2008-siamjc]&lt;/td&gt;
&lt;td&gt;$[n,k,2t+1]$ BCH&lt;/td&gt;
&lt;td&gt;Iris codes; SRAM PUFs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set difference&lt;/td&gt;
&lt;td&gt;PinSketch (DORS 2008 section 6) [@dors-2008-siamjc], [@reyzin-lab-home]&lt;/td&gt;
&lt;td&gt;Symmetric-difference syndrome decoding; sublinear in universe size&lt;/td&gt;
&lt;td&gt;Fingerprint minutiae sets; many-out-of-many tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edit distance&lt;/td&gt;
&lt;td&gt;Embed into Hamming via low-distortion encoding&lt;/td&gt;
&lt;td&gt;Ostrovsky-Rabani-style embeddings&lt;/td&gt;
&lt;td&gt;DNA sequences, typed passwords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Continuous (face / fingerprint embeddings)&lt;/td&gt;
&lt;td&gt;Quantise then Hamming&lt;/td&gt;
&lt;td&gt;Lloyd-Max or learned quantisers&lt;/td&gt;
&lt;td&gt;Face deep-features; the worst empirical entropy profile&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The continuous-source case is where the consumer biometric story gets ugly: quantising a learned embedding loses entropy in proportion to the quantiser&apos;s resolution, and the residual is the entropy budget the sketch has to work with.&lt;/p&gt;
&lt;h3&gt;6.2 Generation 3a: Boyen 2004 reusable fuzzy extractors&lt;/h3&gt;
&lt;p&gt;Xavier Boyen, about five months after the DRS conference paper, attacked the multi-enrolment problem head on [@boyen-2004-ccs-eprint]. A &lt;em&gt;reusable&lt;/em&gt; fuzzy extractor remains secure when the same source is enrolled multiple times under correlated but different readings $w_1, w_2, \ldots, w_q$. Boyen formalises two threat models. The &lt;em&gt;outsider chosen-perturbation&lt;/em&gt; attack allows the adversary to choose the noise patterns between enrolments; Boyen shows that fuzzy extractors built from XOR-homomorphic sketches (code-offset is one) are secure against outsider adversaries with bounded perturbations. The &lt;em&gt;insider chosen-perturbation&lt;/em&gt; attack additionally gives the adversary access to the extracted keys $R_1, \ldots, R_q$; this stronger model requires a random-oracle assumption. The Canetti-Fuller-Paneth-Reyzin-Smith 2016 paper would later argue that the outsider model&apos;s perturbation class is &quot;unlikely to hold for a practical source,&quot; quoting the paper directly [@cfprs-2016-eprint].&lt;/p&gt;
&lt;h3&gt;6.3 Generation 3b: BDKOS 2005 / DKKRS 2012 tamper-resilient fuzzy extractors&lt;/h3&gt;
&lt;p&gt;A different defect of the DRS construction: the public helper $P$ is not authenticated. If an active adversary can rewrite $P$ on its way to the verifier, the verifier reconstructs the wrong key, and the security analysis falls apart. Xavier Boyen, Yevgeniy Dodis, Jonathan Katz, Rafail Ostrovsky, and Adam Smith addressed this in 2005 with the &lt;strong&gt;tamper-resilient&lt;/strong&gt; fuzzy extractor [@bdkos-2005-eurocrypt]. Their Theorem 1 builds a tamper-detecting secure sketch in the random-oracle model: publish $(\text{pub}^&lt;em&gt;, h)$ where $\text{pub}^&lt;/em&gt;$ is a standard sketch and $h = H(w, \text{pub}^*)$; at recovery, recompute the tag and reject on mismatch. The full tamper-resilient fuzzy extractor (BDKOS §3.2) then composes this tamper-detecting sketch with a strong extractor. The standard-model construction came later, in 2012, from Dodis, Kanukurthi, Katz, Reyzin, and Smith, by replacing the random oracle with an &lt;em&gt;algebraic manipulation detection&lt;/em&gt; (AMD) code, with entropy loss $O(\log(1/\varepsilon))$ above the passive bound [@dkkrs-2012-ieeetit], [@cdfpw-2008-eurocrypt].&lt;/p&gt;
&lt;h3&gt;6.4 Generation 4: Fuller-Meng-Reyzin 2013 computational fuzzy extractors&lt;/h3&gt;
&lt;p&gt;By 2013 the field had hit a wall. The DRS inequality forbids information-theoretic constructions on low-entropy consumer biometrics. Fuller, Meng, and Reyzin asked the obvious next question: does the wall come down if you trade information-theoretic security for computational security? Their answer, in &lt;em&gt;Computational Fuzzy Extractors&lt;/em&gt; at ASIACRYPT 2013, is half negative and half positive [@fmr-2013-asiacrypt-eprint], [@fmr-2020-iandc].&lt;/p&gt;
&lt;p&gt;The negative half: &quot;for every secure sketch that retains $m$ bits of computational entropy, there is an error-correcting code with $2^{m-2}$ codewords&quot; [@fmr-2013-asiacrypt-eprint]. The coding-theory lower bound survives the relaxation to computational HILL pseudoentropy. The positive half: skip the sketch entirely. Treat the biometric reading as an LWE error vector, use a random linear code, and base security on the Learning With Errors problem. The construction extracts a key length equal to the source min-entropy, with security under standard LWE assumptions.&lt;/p&gt;
&lt;h3&gt;6.5 Generation 5: Canetti-Fuller-Paneth-Reyzin-Smith 2016 reusable low-entropy&lt;/h3&gt;
&lt;p&gt;The final piece of the contemporary state of the art is CFPRS 2016 [@cfprs-2016-eurocrypt], [@cfprs-2016-eprint]. Ran Canetti, Benjamin Fuller, Omer Paneth, Leonid Reyzin, and Adam Smith built a fuzzy extractor that is reusable, handles low-entropy distributions, and works under realistic correlated noise. The key technique is &lt;em&gt;per-bit digital lockers&lt;/em&gt;: for each bit of the source, store a digital locker keyed on a random subset of input bits. Recovery samples subsets, queries the lockers, and majority-votes. The construction depends on a digital-locker idealisation, but CFPRS show that any reusable fuzzy extractor for low-entropy sources requires either the random-oracle model or an equivalent strong assumption, which limits the room to remove the idealisation.&lt;/p&gt;
&lt;h3&gt;6.6 The one consumer-biometric construction that ever cleared the bar&lt;/h3&gt;
&lt;p&gt;Across two decades of theoretical work, exactly one published consumer-biometric fuzzy extractor has cleared the DRS bar at production-grade parameters. Hao, Anderson, and Daugman, in a 2005 Cambridge tech report and a 2006 IEEE Transactions on Computers paper, presented an iris fuzzy extractor that &quot;can generate up to 140 bits of biometric key, more than enough for 128-bit AES&quot; with &quot;a 99.5% success rate&quot; on 70 eyes [@hao-anderson-daugman-2005-tr], [@hao-anderson-daugman-2006-ieeetc]. The construction layers a Hadamard code (handles single-bit errors) with a Reed-Solomon code (handles burst errors) inside the code-offset sketch, then runs LHL.The Hao-Anderson-Daugman code is a two-layer Hadamard-then-Reed-Solomon composition. The inner Hadamard layer is HC(6) at rate $7/64 \approx 1/9$ (7 bits encoded into 64 bits per block, 32 blocks per 2048-bit iris code), and absorbs noise within each block; the outer RS(32, 20) over $\text{GF}(2^7)$ tolerates up to six block errors across the 32 blocks. The composition costs more redundancy than a single BCH code but matches the iris noise statistics better. The iris is the only common biometric where the entropy budget is generous enough to absorb that much redundancy and still leave 140 bits over.&lt;/p&gt;
&lt;p&gt;The state of the art, taken together, is wide and mature. Every successor either requires the source to have an entropy profile most consumer biometrics lack, or uses idealisations (random oracle, digital locker, LWE-with-specific-error-distribution) that no production cryptosystem wants to depend on. The next two sections make that boundary precise.&lt;/p&gt;
&lt;h2&gt;7. Competing approaches: six paradigms&lt;/h2&gt;
&lt;p&gt;Step back from the fuzzy-extractor lineage and put it in competitive context. There are at least six distinct approaches to binding cryptographic operations to a biometric, and only two of them &lt;em&gt;derive&lt;/em&gt; a key from the biometric. The other four use the biometric as a &lt;em&gt;gate&lt;/em&gt; on a key generated elsewhere. ISO/IEC 24745:2022 codifies three protection properties -- irreversibility, unlinkability, and renewability -- that any biometric template protection scheme should provide [@iso-iec-24745-2022], and the Rathgeb-Uhl 2011 survey is the open-access reference that maps each approach to the three properties [@rathgeb-uhl-2011].&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Representative work&lt;/th&gt;
&lt;th&gt;Derives key?&lt;/th&gt;
&lt;th&gt;Irreversibility&lt;/th&gt;
&lt;th&gt;Unlinkability&lt;/th&gt;
&lt;th&gt;Renewability&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Information-theoretic fuzzy extractor&lt;/td&gt;
&lt;td&gt;Dodis-Reyzin-Smith 2004 family [@dors-2008-siamjc]&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (under min-entropy)&lt;/td&gt;
&lt;td&gt;Hard under correlated re-enrol&lt;/td&gt;
&lt;td&gt;Yes (rotate seed and sketch)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Computational fuzzy extractor&lt;/td&gt;
&lt;td&gt;Fuller-Meng-Reyzin 2013 / CFPRS 2016 [@fmr-2013-asiacrypt-eprint], [@cfprs-2016-eurocrypt]&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (under LWE / digital locker)&lt;/td&gt;
&lt;td&gt;Improved over information-theoretic&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cancelable biometrics&lt;/td&gt;
&lt;td&gt;Ratha-Connell-Bolle 2001 [@ratha-connell-bolle-2001]&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (by transform design)&lt;/td&gt;
&lt;td&gt;Yes (transform key)&lt;/td&gt;
&lt;td&gt;Yes (re-enrol under fresh transform)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Homomorphic encryption biometric matching&lt;/td&gt;
&lt;td&gt;Engelsma-Jain-Boddeti HERS [@engelsma-jain-boddeti-hers-arxiv]&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Yes (under HE)&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;Secure-element match-on-chip&lt;/td&gt;
&lt;td&gt;Apple Secure Enclave [@apple-platform-security], [@apple-secure-enclave]&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Hardware-anchored&lt;/td&gt;
&lt;td&gt;Yes (per-device)&lt;/td&gt;
&lt;td&gt;Yes (hardware key rotation)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Match-then-unwrap-TPM-sealed-key&lt;/td&gt;
&lt;td&gt;Windows Hello ESS [@ms-learn-ess], [@ms-learn-hello-business]&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Hardware-anchored&lt;/td&gt;
&lt;td&gt;Yes (per-device)&lt;/td&gt;
&lt;td&gt;Yes (rotate TPM-sealed key)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

A class of biometric template protection schemes in which a non-invertible, application-specific transformation $T_i$ is applied to the feature vector before storage. The stored template is then $T_i(\text{features})$; matching is performed in the transformed space; and a compromised template can be revoked by re-enrolling under a fresh transform $T_j$. The goal is *template protection*, not cryptographic key derivation: no uniformly random key falls out of the construction. ISO/IEC 24745 names three properties such a transform must satisfy: irreversibility, unlinkability, and renewability [@ratha-connell-bolle-2001], [@rathgeb-uhl-2011].

The international standard *Information security, cybersecurity and privacy protection -- Biometric information protection* (ISO/IEC 24745:2022 Edition 2, 63 pages, published February 2022 [@iso-iec-24745-2022]) defines three properties of any biometric protection scheme -- irreversibility, unlinkability, renewability -- without prescribing any specific cryptographic primitive. The standard is paywalled at CHF 204, which is why most academic and engineering treatments cite the open-access Rathgeb-Uhl 2011 survey [@rathgeb-uhl-2011] as a proxy for the property definitions. The three properties are deliberately neutral: a fuzzy extractor, a cancelable transform, a homomorphic-encryption matcher, and a hardware-anchored secure element can all in principle satisfy them, and the standard is silent on which is best.
&lt;p&gt;The two &lt;em&gt;derive&lt;/em&gt; approaches (rows 1 and 2 in the table) follow the genealogy this article has been tracing. The remaining four are &lt;em&gt;gate&lt;/em&gt; approaches: each generates the cryptographic key by some independent means -- 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;-sealed asymmetric key, a Secure Enclave-bound key, a homomorphic-encryption keypair -- and uses the biometric only to decide whether to release the key. The cancelable-biometrics approach is even more conservative: it does not even tie a key to the biometric at all; it only protects the template against compromise.&lt;/p&gt;
&lt;p&gt;Why is the &lt;em&gt;derive&lt;/em&gt; versus &lt;em&gt;gate&lt;/em&gt; distinction so deep? Because it determines who is responsible for the key&apos;s secrecy. In a &lt;em&gt;derive&lt;/em&gt; model, the biometric &lt;em&gt;is&lt;/em&gt; the secret; if the biometric leaks (a photo of your face, a latent print on a glass), the cryptographic key is at risk. In a &lt;em&gt;gate&lt;/em&gt; model, the secret is independent of the biometric -- usually a hardware-anchored private key that never leaves the secure element -- and the biometric is just a soft second factor that decides whether the user is allowed to &lt;em&gt;use&lt;/em&gt; the secret.&lt;/p&gt;
&lt;p&gt;Hardware-anchored &lt;em&gt;gate&lt;/em&gt; schemes also get to rely on attestation: a TPM or Secure Enclave can prove to a remote relying party that the key it just used is bound to a specific device, by a specific user, in a specific authentication ceremony. A pure software fuzzy extractor cannot make any of those claims.&lt;/p&gt;
&lt;p&gt;This is the decisive architectural distinction in the field. Every shipped consumer biometric authenticator on the planet picks &lt;em&gt;gate&lt;/em&gt;. The next two sections explain why: section 8 walks through three theoretical lower bounds that draw the perimeter inside which any fuzzy extractor can live, and section 10 walks through the Windows Hello architecture as the concrete embodiment of &lt;em&gt;gate&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;8. Theoretical limits&lt;/h2&gt;
&lt;p&gt;Three lower-bound results, taken together, draw the perimeter inside which any fuzzy extractor can live. The section 5 inequality was the first. Two more come from later papers, and they are sharper than the basic inequality suggests.&lt;/p&gt;
&lt;h3&gt;8.1 The min-entropy floor&lt;/h3&gt;
&lt;p&gt;The DRS section 5 inequality already gives a floor: $\ell \le H_\infty(W) - (n-k) - 2\log(1/\varepsilon) + 2$. Fuller, Reyzin, and Smith in 2020 sharpened this with an impossibility result for &lt;em&gt;universal&lt;/em&gt; information-theoretic fuzzy extractors.&lt;/p&gt;
&lt;p&gt;They define a stronger notion they call &lt;em&gt;fuzzy min-entropy&lt;/em&gt;, $H^{\text{fuzz}}&lt;em&gt;{t,\infty}(W) := -\log \max&lt;/em&gt;{w_0} \Pr[W \in \mathcal{B}&lt;em&gt;t(w_0)]$, and prove that the gap between the universal-construction bound $H&lt;/em&gt;\infty(W) - \log|\mathcal{B}&lt;em&gt;t|$ and the optimal bound $H^{\text{fuzz}}&lt;/em&gt;{t,\infty}(W)$ can be a large fraction of $n$ bits. For Daugman&apos;s iris parameters ($n = 2048$, $H_\infty \approx 249$, $\log|\mathcal{B}_t| \approx 1024$), the universal bound sits more than 1000 bits below the fuzzy-min-entropy upper bound -- a gap of $\approx 0.5n$ -- and Theorem 5.1&apos;s impossibility region pushes the worst-case gap up toward $h_2(\tau) \cdot n$ for higher noise rates [@frs-2020-ieeetit]. The implication: a single universal construction cannot extract the optimal key length from every high-fuzzy-min-entropy source; some sources require source-specific constructions to close the gap, and the DRS bound is essentially tight in the worst case.&lt;/p&gt;
&lt;p&gt;Plug realistic numbers into the floor. The table below is the empirical perimeter the cryptographic community has lived inside for two decades.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Approx. raw entropy&lt;/th&gt;
&lt;th&gt;Effective entropy under correlated noise&lt;/th&gt;
&lt;th&gt;Clears DRS bar at $\varepsilon = 2^{-80}$ for 128-bit key?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Iris [@daugman-2003-pdf], [@daugman-2004-csvt]&lt;/td&gt;
&lt;td&gt;~249 dof&lt;/td&gt;
&lt;td&gt;~249 dof (matched-illumination scans)&lt;/td&gt;
&lt;td&gt;Yes (demonstrated [@hao-anderson-daugman-2006-ieeetc])&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fingerprint minutiae [@pankanti-prabhakar-jain-2002]&lt;/td&gt;
&lt;td&gt;~70 bits at best image quality&lt;/td&gt;
&lt;td&gt;40-70 bits depending on sensor&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Face deep-feature embeddings&lt;/td&gt;
&lt;td&gt;30-50 bits raw&lt;/td&gt;
&lt;td&gt;Often much less under illumination / pose&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SRAM PUF [@intrinsic-id-sram-puf], [@tuyls-skoric-kevenaar-2007-springer]&lt;/td&gt;
&lt;td&gt;thousands of bits (entire SRAM page)&lt;/td&gt;
&lt;td&gt;thousands of bits (controlled noise)&lt;/td&gt;
&lt;td&gt;Yes (deployed in over a billion devices)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Watch Daugman&apos;s 249 figure carefully. It is the number of degrees of freedom in the &lt;em&gt;Hamming distance distribution&lt;/em&gt; between IrisCodes from different irises, fit to a fractional binomial with $N = 249$ and $p = 0.5$. It is not the raw min-entropy of an iris image: an iris sensor returning 249 bits of high-quality iris data is &lt;em&gt;not&lt;/em&gt; the same as 249 bits of min-entropy. Daugman&apos;s 2003 Pattern Recognition paper makes the distinction explicitly [@daugman-2003-pdf].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Across every consumer biometric the industry has deployed, the iris is unique in clearing the DRS bar at production parameters. Daugman&apos;s 249 statistical degrees of freedom give the iris a budget more than three times the budget of fingerprint, and an order of magnitude more than face. Hao, Anderson, and Daugman 2006 demonstrate a 140-bit iris key with 99.5% success on 70 eyes [@hao-anderson-daugman-2006-ieeetc] -- the only published consumer-biometric fuzzy extractor ever to clear the DRS bar at production parameters. The catch: iris sensors are intrusive, expensive, and rarely shipped in consumer phones or laptops.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;8.2 Reusability impossibility&lt;/h3&gt;
&lt;p&gt;Boyen&apos;s 2004 insider chosen-perturbation game is unconditionally insecure for adversaries who can choose enough perturbations [@boyen-2004-ccs-eprint]. CFPRS 2016 cite this impossibility result and work around it by restricting attention to a digital-locker-amenable source class [@cfprs-2016-eprint]. The practical implication is that any fuzzy extractor that wants to be reusable across many enrolments has to either (a) restrict the source class (CFPRS&apos;s path) or (b) accept a security degradation per re-enrol. Neither option is appealing for a consumer device that may see its user re-enrol after every kernel update, every sensor recalibration, or every routine credential rotation.&lt;/p&gt;
&lt;h3&gt;8.3 Active-adversary lower bound&lt;/h3&gt;
&lt;p&gt;A passive adversary sees the helper $P$ but does not modify it; an active adversary can rewrite $P$ between enrolment and recovery. BDKOS 2005 and DKKRS 2012 prove that protecting against active adversaries requires either a one-time setup secret (a shared seed established out of band), an authenticated channel between enrolment and recovery, or a min-entropy surplus of $\Omega(\log(1/\varepsilon))$ above the passive bound [@bdkos-2005-eurocrypt], [@dkkrs-2012-ieeetit]. For $\varepsilon = 2^{-80}$, the active-adversary surcharge is 80 bits.&lt;/p&gt;
&lt;h3&gt;8.4 Combining the three bounds&lt;/h3&gt;
&lt;p&gt;Stack the three bounds on top of each other for a consumer face / fingerprint source. The min-entropy floor is the hardest barrier: with 40 to 80 effective bits and 160 bits of security-parameter cost plus 100-plus bits of code redundancy, the extractable key length is negative. The reusability impossibility forecloses the workaround of pretending that re-enrolments are uncorrelated -- they are not, because real biometric drift is highly correlated. The active-adversary bound forecloses the workaround of pretending the helper data is safe in transit. A software-only fuzzy extractor cannot meet a consumer-OS security bar at consumer biometric quality. What you do &lt;em&gt;instead&lt;/em&gt; is the next section.&lt;/p&gt;
&lt;h2&gt;9. Open problems&lt;/h2&gt;
&lt;p&gt;Four problems remain, ordered by how directly each one blocks deployment in a Windows Hello-class product.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; 1. &lt;strong&gt;Deployable face / fingerprint fuzzy extractors under realistic correlated noise.&lt;/strong&gt; Engelsma, Cao, and Jain&apos;s 2019 &lt;em&gt;DeepPrint&lt;/em&gt; reduces intra-user fingerprint variance via learned representations [@engelsma-cao-jain-2019-arxiv], but no published construction has cleared the DRS bar on a realistic test set under correlated noise. 2. &lt;strong&gt;Reusable computational fuzzy extractors without idealisations.&lt;/strong&gt; CFPRS 2016 uses digital lockers, which require either a random oracle or an equivalent strong assumption [@cfprs-2016-eurocrypt]. Eliminating that idealisation is open. 3. &lt;strong&gt;Post-quantum information-theoretic fuzzy extractors.&lt;/strong&gt; Fuller-Meng-Reyzin&apos;s LWE-based construction is already post-quantum on the computational side [@fmr-2013-asiacrypt-eprint], [@fmr-2020-iandc], but an information-theoretic construction tailored to PQ-style noise distributions is open. 4. &lt;strong&gt;The PUF-to-biometric architectural gap.&lt;/strong&gt; Fuzzy extractors are deployed &lt;em&gt;only&lt;/em&gt; for PUFs (Synopsys PUF IP (including QuiddiKey), over a billion devices [@intrinsic-id-sram-puf]) where the noise model is controlled. Closing the architectural gap to consumer biometrics, where the noise model is adversarial and environmental, is open.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Each of these is hard, and none has a credible path to a consumer-OS-grade deployment in the next product cycle. Take them one at a time.&lt;/p&gt;
&lt;p&gt;The first is the most obviously blocking. Even if every fingerprint sensor in the world tomorrow began returning DeepPrint embeddings instead of minutiae sets, the entropy budget would still be tens of bits below the DRS bar. The bottleneck is the source distribution, not the encoder. Improving the encoder helps -- a learned representation with lower intra-user variance shifts the noise distribution toward zero, which lets you use a code with less redundancy -- but the inequality still bites. The community&apos;s working belief is that no consumer fingerprint sensor will ever ship enough min-entropy to clear the bar at the security parameter an OS authenticator demands.&lt;/p&gt;
&lt;p&gt;The second is more nuanced. Digital lockers are &lt;em&gt;useful&lt;/em&gt; in practice -- they are the central tool that lets CFPRS 2016 handle reusability for low-entropy sources -- but they depend on the random-oracle model. The random-oracle model is fine for theoretical work; it is uncomfortable for a production cryptosystem that has to survive an FIPS evaluation and a NIST audit. The hope is that &lt;em&gt;non-malleable extractors&lt;/em&gt; or &lt;em&gt;correlation-resistant universal hash families&lt;/em&gt; can replace digital lockers in the CFPRS construction without losing the reusability guarantee. Promising directions exist; none has matured into a deployable construction.&lt;/p&gt;
&lt;p&gt;The third sounds esoteric but matters. The information-theoretic DRS construction has been quietly post-quantum since 2004: the LHL holds against quantum adversaries up to a constant factor, and BCH decoding is classical [@dors-2008-siamjc]. But once you move to the &lt;em&gt;computational&lt;/em&gt; fuzzy extractors of FMR 2013 or CFPRS 2016, the security argument depends on a hardness assumption (LWE or digital-locker-as-RO) that one wants to be confident survives the post-quantum transition. LWE is widely believed to be PQ-secure; digital lockers are not yet rigorously analysed against quantum adversaries.&lt;/p&gt;
&lt;p&gt;The fourth, &lt;strong&gt;the PUF-to-biometric gap&lt;/strong&gt;, is where the theoretical and engineering communities meet most uncomfortably. The fuzzy extractor &lt;em&gt;works&lt;/em&gt; in practice: Synopsys PUF IP (including QuiddiKey) embeds a code-offset / syndrome-based fuzzy extractor in over a billion devices, &quot;deployed and proven in over a billion devices certified by EMVCo, Visa, CC EAL6+, PSA, ioXt, and governments across the globe&quot; per the vendor [@intrinsic-id-sram-puf]. The SRAM PUF has thousands of bits of min-entropy and a controlled noise model: powering up the SRAM gives a startup pattern that is reliable across temperature and voltage swings to within a few percent of bits. The signal-to-noise ratio is dramatically better than any consumer biometric.Pierre-Alain Dupont, Julia Hesse, David Pointcheval, Leonid Reyzin, and Sophia Yakoubov&apos;s 2018 EUROCRYPT paper &lt;em&gt;Fuzzy Password-Authenticated Key Exchange&lt;/em&gt; [@dupont-hesse-pointcheval-reyzin-yakoubov-2018] is a recent direction that decouples fuzzy extraction from key agreement: rather than extract a key once and use it, two parties run a password-authenticated key exchange whose &quot;password&quot; is a noisy biometric. Fuzzy PAKE sidesteps the helper-data leakage problem because the helper is consumed inside an interactive protocol that does not commit it to long-term storage.&lt;/p&gt;

The bright line between PUF and biometric is the *noise model*. An SRAM PUF lives in a single device, sees temperature and voltage variation between $-40^\circ$C and $+85^\circ$C, and operates against an adversary who can read the SRAM but cannot rewrite the silicon. The noise distribution is empirically measurable, and the entropy budget is enormous -- thousands of bits per page. A consumer fingerprint sensor, by contrast, lives outside the trust boundary: the noise distribution depends on skin moisture, sensor cleanliness, finger angle, and an adversary who can lift a latent print from a glass. The fuzzy-extractor framework is the right answer for the PUF case and the wrong answer for the consumer biometric case, and the difference is the noise model, not the cryptography.
&lt;p&gt;Each of these problems is interesting on its own merits, but none of them has a credible path to a consumer-OS-grade deployment in the next product cycle. So what does a consumer OS &lt;em&gt;actually&lt;/em&gt; do? That is the punchline.&lt;/p&gt;
&lt;h2&gt;10. The punchline: why Windows Hello does not use a fuzzy extractor&lt;/h2&gt;
&lt;p&gt;State the claim flatly. Windows Hello, in every shipping configuration since Enhanced Sign-in Security was introduced with Windows 11, performs &lt;strong&gt;match-then-unwrap&lt;/strong&gt;, not &lt;strong&gt;derive-from-biometric&lt;/strong&gt;. The biometric is a gate, not an input to key derivation. The cryptographic credential a Windows Hello user authenticates with is a TPM-bound asymmetric keypair generated independently during provisioning; the biometric matcher merely decides whether to authorise the TPM to use that key. The full architecture is documented verbatim in Microsoft Learn&apos;s Enhanced Sign-in Security and Windows Hello for Business pages [@ms-learn-ess], [@ms-learn-hello-business].&lt;/p&gt;
&lt;h3&gt;10.1 Enrolment&lt;/h3&gt;
&lt;p&gt;When a Windows user enrols a face or a fingerprint, the biometric data path runs inside a Virtualisation-Based Security (VBS) &lt;a href=&quot;https://paragmali.com/blog/vbs-trustlets-what-actually-runs-in-the-secure-kernel/&quot; rel=&quot;noopener&quot;&gt;trustlet&lt;/a&gt;, not in the kernel and not in the camera driver. Microsoft&apos;s documentation is explicit:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;When ESS is enabled, the face algorithm is protected using VBS ... The hypervisor allows the face camera to write to these memory regions providing an isolated pathway to deliver face data from the camera to the face matching algorithm&quot; [@ms-learn-ess].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The face image never lands in regular kernel memory. It is delivered by the hypervisor into a memory region readable only by the VBS-resident face-matching trustlet, which extracts a feature template, encrypts it with VBS-only keys, and writes the encrypted blob to disk. For fingerprint, ESS supports only sensors with on-device matching: &quot;ESS is only supported on fingerprint sensors with match on sensor capabilities&quot; [@ms-learn-ess]. The sensor itself runs the matcher and never exposes the template to the host operating system.&lt;/p&gt;

A user-mode process that runs inside Virtual Trust Level 1 (VTL 1) on Windows, isolated from the normal-world kernel (VTL 0) by the Hyper-V hypervisor. Trustlets are the unit of code that the Secure Kernel hosts and that VBS-protected operations execute inside. Examples include the LSA Isolated process (Credential Guard) and the biometric matcher (Windows Hello with Enhanced Sign-in Security) [@ms-learn-ess].
&lt;p&gt;In parallel, the &lt;em&gt;credential&lt;/em&gt; the user will actually authenticate with is generated. Microsoft Learn&apos;s Windows Hello for Business page describes this verbatim: &quot;The provisioning flow requires a second factor of authentication before it can generate a public/private key pair. The public key is registered with the IdP, mapped to the user account&quot; [@ms-learn-hello-business]. The private key never leaves the TPM. It is sealed against a TPM policy that requires the boot integrity to be intact, the user account to be the same, and the VBS-resident biometric matcher to have signalled a match success. The keypair is a per-user, per-device, per-IdP credential; nothing about it is a function of the user&apos;s biometric.&lt;/p&gt;
&lt;h3&gt;10.2 Authentication&lt;/h3&gt;
&lt;p&gt;At authentication time, the user presents a face or a finger; the VBS-resident matcher compares the live template to the stored template; on success, the matcher signals the TPM via a secure channel to unwrap the asymmetric private key for use in an IdP challenge response. The Microsoft documentation states the architecture in two sentences:&lt;/p&gt;

The Windows biometric components running in VBS establish a secure channel to the TPM ... When a matching operation is a success, the biometric components in VBS use the secure channel to authorize the usage of Windows Hello keys for authenticating the user with their identity provider, applications, and services. -- Microsoft Learn, Windows Hello Enhanced Sign-in Security [@ms-learn-ess]
&lt;p&gt;The authentication ceremony itself is described in the Windows Hello for Business page: &quot;Regardless of the gesture used, authentication occurs using the private portion of the Windows Hello for Business credential. The IdP validates the user identity by mapping the user account to the public key registered during the provisioning phase&quot; [@ms-learn-hello-business]. The IdP sees a cryptographic proof that the user-registered TPM-bound key signed the challenge; it never sees anything that depends on the biometric.&lt;/p&gt;

flowchart LR
    subgraph &quot;DRS fuzzy extractor (theoretical)&quot;
        D1[&quot;Read biometric w&quot;] --&amp;gt; D2[&quot;Gen(w) -&amp;gt; (R, P)&quot;]
        D2 --&amp;gt; D3[&quot;Store helper P on disk&quot;]
        D2 --&amp;gt; D4[&quot;Use R as key&quot;]
        D5[&quot;Re-read w&apos; near w&quot;] --&amp;gt; D6[&quot;Rep(w&apos;, P) -&amp;gt; R&quot;]
        D6 --&amp;gt; D7[&quot;Use R as key&quot;]
    end
    subgraph &quot;Windows Hello (production)&quot;
        W1[&quot;Read biometric w in VBS&quot;] --&amp;gt; W2[&quot;Compute template T&quot;]
        W2 --&amp;gt; W3[&quot;Encrypt and store T with VBS-only key&quot;]
        W4[&quot;Generate TPM-bound keypair (sk, pk)&quot;] --&amp;gt; W5[&quot;Register pk with IdP&quot;]
        W4 --&amp;gt; W6[&quot;Seal sk to TPM with policy&quot;]
        W7[&quot;Re-read w&apos; in VBS&quot;] --&amp;gt; W8[&quot;Match w&apos; against T&quot;]
        W8 --&amp;gt; W9[&quot;Authorise TPM unwrap via secure channel&quot;]
        W6 --&amp;gt; W9
        W9 --&amp;gt; W10[&quot;TPM signs IdP challenge with sk&quot;]
    end
&lt;h3&gt;10.3 Why this is the right design&lt;/h3&gt;
&lt;p&gt;Map each architectural choice to a fuzzy-extractor limit from section 8.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The min-entropy gap is real.&lt;/strong&gt; Face and fingerprint min-entropy under correlated real-world noise is below the DRS bar for any cryptographically meaningful key length at the security parameter an OS authenticator must hit. Section 5&apos;s inequality forbids the construction; no amount of clever engineering moves the constants. Microsoft&apos;s engineers, when faced with the choice between deriving a 128-bit key from a 40-bit source and binding the key to a TPM, made the only choice the math allows.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Helper-data leakage compounds under re-enrolment.&lt;/strong&gt; Every time a user re-enrols (new device, sensor recalibration, post-incident credential refresh), a new helper string would be published. Simoens, Tuyls, and Preneel established that correlated code-offset helpers link and reverse [@simoens-tuyls-preneel-2009]. Hardware-anchored match-then-unwrap rotates the TPM-sealed asymmetric key under standard key-management rules instead, sidestepping the cryptographic reusability problem entirely. Key rotation under a hardware root of trust is a solved problem; reusability in a software fuzzy extractor remains an active research area.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reusability across user-account-rebuild scenarios.&lt;/strong&gt; PIN reset, device wipe-and-restore, and credential rotation become &lt;em&gt;key-management&lt;/em&gt; problems (rotate the TPM-sealed key) rather than &lt;em&gt;cryptographic-reusability&lt;/em&gt; problems (rotate the fuzzy extractor and trust the CFPRS bound). The former has thirty years of operational practice behind it; the latter has none.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hardware-anchored attestation is easier to reason about.&lt;/strong&gt; TPM seal-policy binding gives a hardware-anchored security argument that a relying party can verify: the trustlet measurement, the biometric-match-success signal, and the boot integrity all have to match before the key unwraps. A software-only fuzzy extractor cannot match this attestation chain. The IdP at the other end of an authentication ceremony can ask the TPM for a quote attesting that the key was used inside a specific code module on a specific device; no software construction makes that proof.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; In every shipped consumer biometric authenticator on the planet, the biometric is a gate, not an input. The cryptographic key is generated separately during provisioning -- as a TPM-bound asymmetric keypair on Windows Hello, as a Secure-Enclave-bound key on Apple Face ID, as a StrongBox-bound key on Android [@android-keystore] -- and unwrapped on match success. The key is never derived from the biometric.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;10.4 The sibling case: Apple Face ID and Touch ID&lt;/h3&gt;
&lt;p&gt;Apple&apos;s Secure Enclave Processor performs the same architectural pattern, with the Secure Enclave playing the role Windows assigns to the trustlet-plus-TPM pair. The Apple Platform Security guide is explicit:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Apple&apos;s biometric security architecture relies on a strict separation of responsibilities between the biometric sensor and the Secure Enclave, and a secure connection between the two. The sensor captures the biometric image and securely transmits it to the Secure Enclave. During enrollment, the Secure Enclave processes, encrypts, and stores the corresponding Optic ID, Face ID, and Touch ID template data. During matching, the Secure Enclave compares incoming data from the biometric sensor against the stored templates to determine whether to unlock the device or respond that a match is valid&quot; [@apple-platform-security], [@apple-secure-enclave].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Two vendors, independently, converged on the same architecture. Both vendors hire the strongest cryptographers in the world. Neither built a fuzzy extractor. The architectural pattern is now the consensus answer to the consumer biometric authentication problem.&lt;/p&gt;

Apple&apos;s Secure Enclave Processor is the architectural sibling of the Windows VBS trustlet plus TPM combination. The Secure Enclave is an ARM-based coprocessor with its own kernel, its own memory, and its own boot chain, physically isolated on the Application Processor die. During Face ID or Touch ID enrolment, the biometric sensor transmits its raw image directly to the Secure Enclave over a hardware-isolated link; the Secure Enclave extracts the template, encrypts it under a per-device key sealed to the Secure Enclave&apos;s UID, and stores it. During matching, the Secure Enclave compares the live template against the stored template inside its own memory, and on success authorises the use of cryptographic keys held in the same coprocessor. The pattern is identical to the Windows Hello pattern: derive nothing from the biometric; gate a hardware-bound key on the match decision [@apple-platform-security].
&lt;p&gt;Twenty years of theoretical work; zero production consumer-OS biometric authenticators on the planet use any of it for face or fingerprint key derivation; and the engineers who said no were right, for reasons traceable to a single load-bearing inequality at the heart of the 2004 EUROCRYPT paper.&lt;/p&gt;
&lt;h2&gt;11. Frequently asked questions&lt;/h2&gt;

No. Both perform match-then-unwrap rather than derive. Windows Hello generates a TPM-bound asymmetric keypair during provisioning [@ms-learn-hello-business]; the biometric matcher, running inside a VBS trustlet, authorises the TPM to use that key on a match-success signal [@ms-learn-ess]. Apple Face ID and Touch ID follow the same pattern with a Secure-Enclave-bound key in place of a TPM-bound one [@apple-platform-security]. In neither case is the cryptographic key a function of your biometric reading.

Yes -- in SRAM PUFs. Synopsys PUF IP (including QuiddiKey), built on Intrinsic ID SRAM PUF technology, is &quot;deployed and proven in over a billion devices certified by EMVCo, Visa, CC EAL6+, PSA, ioXt, and governments across the globe&quot; [@intrinsic-id-sram-puf]. The PUF noise distribution is controlled and the entropy budget is enormous, so the DRS construction works exactly as advertised. Consumer face and fingerprint biometrics are a different regime: the noise model is adversarial, the entropy budget is small, and the construction&apos;s inequality forbids the key length an OS authenticator needs.

Because the hash is avalanche-sensitive by design: a single-bit input change flips, on average, half the output bits. Two scans of the same finger differ in many bits, so two hashes differ in roughly half their bits. The cryptographic key is statistically independent of the previous one, and the user can never log in again after their first authentication. This is the failure mode that motivates the fuzzy-extractor primitive in section 1 [@hao-anderson-daugman-2005-tr].

Because of the load-bearing inequality at the heart of the EUROCRYPT 2004 paper. For consumer face and fingerprint biometrics at the security parameter an operating system authenticator demands ($\varepsilon = 2^{-80}$ or stronger), the extractable key length is negative: the source min-entropy is too low to absorb the cost of code redundancy plus the security parameter [@dors-2008-siamjc], [@frs-2020-ieeetit]. No amount of clever engineering moves the constants.

Yes. The iris is the only common biometric that comfortably clears the DRS bar. Daugman&apos;s 2003 Pattern Recognition paper reports 249 statistical degrees of freedom across 9.1 million iris-to-iris comparisons [@daugman-2003-pdf]; Hao, Anderson, and Daugman in 2006 demonstrated a 140-bit iris key with 99.5% recovery success on 70 eyes [@hao-anderson-daugman-2006-ieeetc]. But iris sensors are expensive, intrusive, and rarely shipped in consumer phones or laptops, so the result has not generalised to mainstream consumer authentication.

Deep-learning encoders such as Engelsma-Cao-Jain&apos;s DeepPrint reduce intra-user variance by mapping noisy raw biometric readings into compact embeddings [@engelsma-cao-jain-2019-arxiv]. That reduces the noise the secure sketch has to absorb and lets the code use less redundancy. But the deep encoder does not add min-entropy to the source: the underlying fingerprint is still a 40-to-80-bit source. No published construction has been shown to clear the DRS bar on a realistic correlated-noise test set for any consumer biometric other than iris.

Unlikely without one of two changes. Either (a) the sensor stack would have to gain entropy -- for instance, adding an iris camera to a future Surface device would put the source above the DRS bar -- or (b) a CFPRS-style reusable computational fuzzy extractor would have to mature past the digital-locker idealisation [@cfprs-2016-eurocrypt]. Even then, the operational advantages of hardware-bound asymmetric keys (TPM-anchored attestation, IdP-friendly key rotation, no helper-data leakage on re-enrolment) are large enough that a fuzzy extractor would have to clear a high bar to displace the current architecture.
&lt;p&gt;The fuzzy extractor is the right primitive for the right source. SRAM PUFs are that source; consumer face and fingerprint biometrics are not. The 2004 inequality drew the line, two decades of theory have refined the line, and every shipped consumer biometric authenticator on the planet has chosen to live on the other side of it.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;fuzzy-extractors-windows-hello&quot; keyTerms={[
  { term: &quot;Fuzzy extractor&quot;, definition: &quot;A pair (Gen, Rep) producing a stable key R from a noisy source w plus a public helper P; defined by Dodis-Reyzin-Smith 2004.&quot; },
  { term: &quot;Secure sketch&quot;, definition: &quot;The noise-tolerance half of a fuzzy extractor; SS publishes a sketch s, Rec recovers w from any w&apos; within distance t given s.&quot; },
  { term: &quot;Strong randomness extractor&quot;, definition: &quot;The uniformity half of a fuzzy extractor; turns a high-min-entropy source into a uniform key, via universal hashing and the Leftover Hash Lemma.&quot; },
  { term: &quot;Leftover Hash Lemma (LHL)&quot;, definition: &quot;Impagliazzo-Levin-Luby 1989: a universal hash applied to a min-entropy source is statistically close to uniform, with budget ell &amp;lt;= m - 2 log(1/epsilon) + 2.&quot; },
  { term: &quot;Min-entropy (H_infinity)&quot;, definition: &quot;Worst-case guessing-difficulty entropy measure; the right measure for cryptographic key derivation from a peaked distribution.&quot; },
  { term: &quot;Average min-entropy&quot;, definition: &quot;Conditional min-entropy that averages an adversary&apos;s best guess over the values of a public side-channel; the right measure for secure-sketch composition.&quot; },
  { term: &quot;Helper data (P)&quot;, definition: &quot;The public part of a fuzzy extractor&apos;s output: the sketch plus the extractor seed. Available at recovery time; leaks at most epsilon bits about R.&quot; },
  { term: &quot;Trustlet (VBS)&quot;, definition: &quot;A Virtual Trust Level 1 user-mode process on Windows, isolated from the normal kernel by Hyper-V; Windows Hello runs its biometric matcher inside a trustlet.&quot; }
]} questions={[
  { q: &quot;Why does SHA-256(fingerprint_image) fail as a cryptographic key?&quot;, a: &quot;SHA-256 is avalanche-sensitive: a single-bit input change flips half the output bits. Two scans of the same finger differ in many bits, so two hashes are statistically independent. The key is unrecoverable on the second scan.&quot; },
  { q: &quot;What does the DRS 2004 inequality bound, and what are its three terms?&quot;, a: &quot;It bounds the extractable key length ell &amp;lt;= H_infinity(W) - (n-k) - 2 log(1/epsilon) + 2. The three terms are the source min-entropy, the code redundancy paid to absorb noise, and the security parameter cost paid to the Leftover Hash Lemma.&quot; },
  { q: &quot;What is the architectural difference between deriving a key from a biometric and gating a key on a biometric?&quot;, a: &quot;Deriving makes the biometric itself the secret; if the biometric leaks, the key is at risk. Gating generates a key independently and uses the biometric only to decide whether to release it; the key&apos;s secrecy is anchored in hardware (TPM, Secure Enclave) and is independent of the biometric.&quot; },
  { q: &quot;Why does Windows Hello not use a fuzzy extractor?&quot;, a: &quot;Because the DRS inequality forbids a useful key on consumer face or fingerprint at security parameters an OS demands; because helper-data leakage compounds under re-enrolment; and because hardware-anchored match-then-unwrap gives TPM-backed attestation that no software fuzzy extractor can match.&quot; },
  { q: &quot;Where are fuzzy extractors actually deployed in production?&quot;, a: &quot;In SRAM PUFs. Synopsys PUF IP (including QuiddiKey) embeds a DRS-style fuzzy extractor in over a billion devices certified by EMVCo, Visa, CC EAL6+, PSA, ioXt, and governments. The PUF noise model is controlled and the entropy budget is large enough.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>cryptography</category><category>biometrics</category><category>fuzzy-extractors</category><category>windows-hello</category><category>tpm</category><category>authentication</category><category>information-theory</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>WebAuthn and Passkeys on Windows: From CTAP to the Credential Provider Model</title><link>https://paragmali.com/blog/webauthn-and-passkeys-on-windows-from-ctap-to-the-credential/</link><guid isPermaLink="true">https://paragmali.com/blog/webauthn-and-passkeys-on-windows-from-ctap-to-the-credential/</guid><description>The know/have/are taxonomy collapses against modern phishing kits. Passkeys, WebAuthn Level 3, CTAP 2.x, and Windows 11 24H2 third-party providers score against the criteria that actually matter -- and recovery is the load-bearing column.</description><pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate><content:encoded>
**Password plus push-notification MFA is no longer a strong authenticator.** 2024-2026 adversary-in-the-middle phishing kits walk straight through it. WebAuthn and passkeys are strong -- but only if you score them against the right axes (phishing resistance, verifier-compromise resistance, replay/relay resistance, step-up, recovery), not the inherited know/have/are taxonomy. This article walks the five-axis criteria framework, the WebAuthn Level 3 plus CTAP 2.x protocol layer, and the Windows-specific stack: `webauthn.dll`, Windows Hello as the user-verification gesture, the Windows 11 24H2 third-party passkey provider plug-in model, hybrid transport from a phone, and the seven attestation conveyance formats. The thesis the article lands on: every passkey deployment in production is exactly as strong as the weakest path back into the account, and that path is universally weaker than the authentication ceremony itself.
&lt;h2&gt;1. Two factors, no security&lt;/h2&gt;
&lt;p&gt;A junior engineer at a mid-size firm types her Microsoft 365 credentials into what looks exactly like the real &lt;code&gt;login.microsoftonline&lt;/code&gt; page, approves the push notification on her phone, and an hour later the security team is reading her inbox -- because the attacker was, too. The kit is Tycoon 2FA, the technique is reverse-proxy adversary-in-the-middle, and the marketing claim that &quot;password plus MFA is two factors&quot; just lost to a commodity off-the-shelf service. The same class of phishing-as-a-service kit (Evilginx, Caffeine, EvilProxy, Tycoon 2FA) is the dominant phishing toolset in 2024-2026; the kit sits between the user and the real Microsoft login page, captures the credentials and the post-MFA session cookie in flight, and hands a live session to the attacker [@sekoia-tycoon-2fa].&lt;/p&gt;
&lt;p&gt;Replay the exact same attack against a colleague whose only authenticator is a WebAuthn passkey. The kit serves the look-alike page; the page hands the browser a WebAuthn &lt;code&gt;PublicKeyCredentialRequestOptions&lt;/code&gt; blob with a fresh challenge. The browser builds &lt;code&gt;clientDataJSON&lt;/code&gt; with &lt;code&gt;type: &quot;webauthn.get&quot;&lt;/code&gt;, the actual origin the user is on (the look-alike domain &lt;code&gt;login-microsoft0nline.example&lt;/code&gt;, protocol scheme included), and the challenge. The authenticator computes the RP-ID hash from that origin, looks up its stored credential, and finds nothing -- it never registered a passkey for that domain. There is no signature to relay. The kit gets bytes that the real Microsoft server will reject on the first verification step. Microsoft&apos;s own documentation puts it bluntly: passkeys &quot;use origin-bound public key cryptography, ensuring credentials can&apos;t be replayed or shared with malicious actors&quot; [@ms-entra-passwordless].&lt;/p&gt;
&lt;p&gt;The know/have/are taxonomy ranks these two ceremonies as the same. Password plus push is &quot;something you know&quot; plus &quot;something you have,&quot; and so is password plus a passkey on a YubiKey. The taxonomy predicts that both ceremonies are roughly twice as strong as one factor alone. The phishing kit demolishes one and bounces off the other. &lt;em&gt;The taxonomy is wrong.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The right question is not &quot;how many factors did the user produce?&quot; It is &quot;what does the attacker have to defeat?&quot; The know/have/are buckets group authenticators by what the user &lt;em&gt;feels&lt;/em&gt; they are producing. The criteria framework groups them by &lt;em&gt;what an attacker has to defeat&lt;/em&gt;. Only the second taxonomy predicts the outcome of a real-world attack. The phishing kit walks through password plus push because nothing in that ceremony binds the user&apos;s secret to a specific origin. It bounces off the passkey because the passkey signs over the origin the browser is actually on, and no amount of reverse proxying changes that string.&lt;/p&gt;
&lt;p&gt;If the taxonomy is wrong, what is the right one? That is the question §2 answers.&lt;/p&gt;
&lt;h2&gt;2. The criteria framework: five axes that actually predict outcomes&lt;/h2&gt;
&lt;p&gt;The replacement for know/have/are is a five-row table. The rows are &lt;em&gt;what an attacker has to defeat&lt;/em&gt;, not &lt;em&gt;what the user thinks they are producing&lt;/em&gt;. The spine of the table is taken from NIST SP 800-63-4 (final, August 2025) [@sp80063-4-final], NIST SP 800-63B-4 [@sp80063b4-html], the FIDO Alliance Authenticator Certification Levels [@fido-certification-levels], and the IETF channel-binding lineage that runs from RFC 5056 (Williams, November 2007) [@rfc5056] through RFC 9266 (Whited, July 2022) [@rfc9266].&lt;/p&gt;

An authenticator whose protocol prevents a relying party impersonator (an adversary-in-the-middle) from inducing the authenticator to release a usable credential value. NIST SP 800-63B-4 formalises the requirement as *verifier-impersonation resistance*. The practitioner formulation, courtesy of Yubico, is verbatim: an authenticator is phishing-resistant if it binds its output to a communication channel or a verifier name [@yubico-nist-guidance].
&lt;h3&gt;Axis 1: phishing resistance&lt;/h3&gt;
&lt;p&gt;The criterion: can a look-alike domain induce the user (or the user&apos;s authenticator) to release a credential value that the look-alike then replays to the real verifier? Password plus any unbound second factor (SMS-OTP, TOTP, push) fails the criterion -- the kit just forwards every value the user produces. WebAuthn passes it by construction: the authenticator signs over &lt;code&gt;clientDataJSON&lt;/code&gt;, which the &lt;em&gt;browser&lt;/em&gt; fills in with the actual origin the user is on, and the signature is computed jointly over a hash of the RP identifier derived from that origin. The RP refuses any signature whose RP-ID hash does not match the registered &lt;code&gt;rpId&lt;/code&gt;.&lt;/p&gt;

The mechanism by which WebAuthn enforces phishing resistance: the browser writes the user&apos;s actual origin into `clientDataJSON.origin`, the authenticator signs over the SHA-256 hash of the canonical RP identifier (`rpIdHash` in `authenticatorData`), and the relying party validates that `rpIdHash` matches the RP identifier under which the credential was registered. The cryptography is trivial. The value is in the binding.
&lt;p&gt;Microsoft&apos;s Entra documentation states the criterion verbatim: passkeys &quot;provide verifier impersonation resistance, which ensures an authenticator only releases secrets to the Relying Party (RP) the passkey was registered with and not an attacker pretending to be that RP&quot; [@ms-entra-passwordless].&lt;/p&gt;
&lt;h3&gt;Axis 2: verifier-compromise resistance&lt;/h3&gt;
&lt;p&gt;The criterion: if the relying party&apos;s authentication database is exfiltrated, can the attacker use the stolen material to log in? Passwords fail this criterion in the worst possible way -- a salted hash is replayable after offline cracking, and a billion-row password dump is the standard primary input to credential stuffing. The public-key model passes the criterion definitionally. The relying party stores only the credential&apos;s public key; no signature is ever made by the relying party. Even a complete database leak gives the attacker zero authenticators.&lt;/p&gt;
&lt;p&gt;This criterion is older than WebAuthn by half a century. Morris and Thompson&apos;s 1979 password paper made the verifier-compromise case for hashing passwords on a multi-user UNIX system [@morris-thompson-1979]; the WebAuthn move is the realisation that even bcrypt&apos;d password databases lose this criterion eventually, because the work factor that protects them today is one Moore&apos;s-law decade away from being trivial.&lt;/p&gt;
&lt;h3&gt;Axis 3: replay and relay resistance&lt;/h3&gt;
&lt;p&gt;The criterion: can an attacker who observes one successful authentication replay it later, or relay it to a different verifier? OTP-based ceremonies (HOTP [@rfc4226], TOTP [@rfc6238]) provide partial replay resistance via a per-instance counter or timestamp, but they offer almost no relay resistance: the AitM kit forwards the OTP through its proxy within the OTP&apos;s validity window.&lt;/p&gt;
&lt;p&gt;WebAuthn passes the criterion with three layered mechanisms. The first is a fresh challenge issued by the RP for every ceremony, which the authenticator signs over. The second is a per-credential signature counter included in &lt;code&gt;authenticatorData&lt;/code&gt;, monotonically increasing on each use (the relying party rejects any assertion whose counter is not strictly greater than the previous one, modulo the synced-passkey carve-out we will reach in §7). The third is channel binding -- the structurally correct answer to relay attacks, which sits at the TLS layer rather than the application layer.The IETF Token Binding stack (RFC 8471, RFC 8473, both October 2018) [@rfc8471] [@rfc8473] was the most ambitious attempt at the channel-binding criterion at the application layer. Both RFCs remain Proposed Standard at the IETF -- the datatracker history pages record no Historic reclassification event for either [@rfc8471-history] [@rfc8473-history] -- but Chromium removed support in version 70 in October 2018, the same month the RFCs were published, and no major browser has implemented them since [@wiki-token-binding]. The &lt;code&gt;clientDataJSON.tokenBinding&lt;/code&gt; field is therefore a no-op in 2026 production. WebAuthn solves the criterion above the channel by signing the origin into the assertion itself.&lt;/p&gt;
&lt;p&gt;The cleaner channel-binding answer is RFC 9266 &lt;code&gt;tls-exporter&lt;/code&gt; for TLS 1.3 (Whited, July 2022) [@rfc9266], which extends RFC 5056&apos;s channel-binding framework into the TLS 1.3 world -- but no major browser wires &lt;code&gt;tls-exporter&lt;/code&gt; into WebAuthn out of the box as of January 2026. The current WebAuthn deployment treats the origin string in &lt;code&gt;clientDataJSON&lt;/code&gt; as the primary channel binding, with HTTPS itself providing the underlying TLS guarantee.&lt;/p&gt;
&lt;h3&gt;Axis 4: step-up and session continuity&lt;/h3&gt;
&lt;p&gt;The criterion: can the relying party demand a &lt;em&gt;fresh&lt;/em&gt; authentication for a high-value action (transfer money, change password, invite a user), and can it tell the difference between a session that was authenticated with strong factors and one that was authenticated with weak factors? WebAuthn answers this with two flag bits in &lt;code&gt;authenticatorData&lt;/code&gt;. &lt;code&gt;UP&lt;/code&gt; (user present) is set when the authenticator detected a presence test -- a touch, a click, an NFC tap. &lt;code&gt;UV&lt;/code&gt; (user verified) is set when the authenticator additionally verified the user via PIN, biometric, or other gesture. A relying party that demands &lt;code&gt;userVerification: &quot;required&quot;&lt;/code&gt; can force &lt;code&gt;UV=1&lt;/code&gt; on the assertion; an RP that issues a fresh challenge for a high-value action gets a fresh signature tied to that challenge.&lt;/p&gt;
&lt;p&gt;Generic transactional confirmation -- &quot;sign a description of &lt;em&gt;this specific transaction&lt;/em&gt;&quot; -- was attempted in WebAuthn&apos;s earliest drafts via the &lt;code&gt;txAuthSimple&lt;/code&gt; and &lt;code&gt;txAuthGeneric&lt;/code&gt; extensions [@webauthn-fpwd]. Neither extension was ever implemented by browsers, and both are absent from the Level 3 specification surface as of January 2026 [@webauthn-l3-cr-dated]. The Secure Payment Confirmation flow in WebAuthn Level 3 [@webauthn-l3-cr] is the productised replacement for payment transactions; general transactional authorisation remains an open problem.&lt;/p&gt;
&lt;h3&gt;Axis 5: recovery and lifecycle&lt;/h3&gt;
&lt;p&gt;The heretical thesis: this is the only axis that matters in production, and it is the axis on which every modern platform still bottoms out at a single-factor primitive. We will foreshadow it here and land on it in §17. A passkey ceremony that scores AAL3 phishing-resistant at the authentication moment can be a single-factor SMS-OTP at the recovery moment -- and the &lt;em&gt;system&apos;s&lt;/em&gt; AAL is the recovery flow&apos;s AAL, not the authentication ceremony&apos;s. Microsoft&apos;s Entra documentation already flags account recovery as a load-bearing deployment cost: FIDO2 keys &quot;can increase costs for equipment, training, and helpdesk support -- especially when users lose their physical keys and need account recovery&quot; [@ms-entra-passwordless].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The single most predictive question about an authentication system is not &quot;what factor does the user produce at sign-in?&quot; but &quot;what factor produces the credential when the user has lost the original one?&quot; We come back to this in §17.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;The criteria table as a spine&lt;/h3&gt;
&lt;p&gt;The five axes give the article its spine. Every later section fills in a row of the same five-column table. The columns are the strongest authenticators we have shipped: password, password plus SMS-OTP, password plus TOTP, password plus push with number matching, device-bound FIDO2 hardware key, synced passkey, and a hypothetical &quot;recovery-flow-aware&quot; composite. The criteria-aware ranking (§13) re-orders that table in a way the know/have/are taxonomy cannot.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The know/have/are taxonomy groups authenticators by what the user feels they are producing. The criteria framework groups them by what an attacker has to defeat. Only the second taxonomy predicts the outcome of a real-world attack.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If these are the right axes, when did we figure that out?&lt;/p&gt;
&lt;h2&gt;3. Where the taxonomy came from&lt;/h2&gt;
&lt;p&gt;The know/have/are taxonomy did not appear all at once. The 1970s and 1980s operating-systems literature already grouped authentication factors into &quot;something the user knows,&quot; &quot;something the user has,&quot; and &quot;something the user is&quot; -- it was a way of talking about the design space, not a regulatory criterion. The taxonomy entered U.S. federal procurement via the Department of Defense&apos;s &lt;em&gt;Trusted Computer System Evaluation Criteria&lt;/em&gt; in December 1985 -- the Orange Book, DOD 5200.28-STD [@wiki-orange-book] -- which required identification and authentication at every assurance class above D and made passwords the canonical &lt;em&gt;something you know&lt;/em&gt; in federal IT. The Orange Book did not invent the taxonomy; it codified it.&lt;/p&gt;
&lt;p&gt;Two decades later, in June 2004, NIST canonised the same taxonomy as the U.S. federal regulatory framework. NIST SP 800-63 &lt;em&gt;Electronic Authentication Guideline&lt;/em&gt; -- by William Burr, Donna Dodson, and W. Timothy Polk -- defined four assurance levels and tied each to a combination of authenticator categories that the levels could accept [@sp80063-2004-v1] [@sp80063-2004-pdf]. Burr&apos;s framework absorbed two decades of accumulated practice with hardware OTP tokens. The canonical commercial OTP product, RSA SecurID, had shipped in 1986 -- a key fob that produced a fresh code each minute using a built-in clock and a factory-encoded seed [@wiki-rsa-securid] -- and SP 800-63 explicitly accepted SecurID-class authenticators at the higher assurance levels. The four-level structure (later AAL1 through AAL3 in the post-2017 redesign) lasted through SP 800-63-1 (2011), -2 (2013), -3 (2017), and -4 (2025); every revision is recognisably the same shape [@nist-sp80063-3-final].The CSRC bibliographic page for the 2004 first edition renders the leading author as a blank entry preceded by a stray comma, an artefact of Burr&apos;s retirement from NIST after publication. The actual cover-page authorship is Burr, Dodson, and Polk -- the citation in the references list above uses the correct three-name form.&lt;/p&gt;
&lt;p&gt;In parallel, the cryptographic protocol literature was building the &lt;em&gt;criteria&lt;/em&gt; taxonomy that would eventually displace know/have/are. Bellcore&apos;s Neil Haller published RFC 1760 in February 1995 -- the S/KEY one-time password system, a Lamport hash chain that produced a fresh login secret each time and that an eavesdropper could not replay [@rfc1760]. Haller&apos;s text already says the technique was first suggested by Leslie Lamport, which makes 1995 the first IETF standardisation of replay-resistance as a design criterion. RFC 4226 (HOTP, December 2005) [@rfc4226] and RFC 6238 (TOTP, May 2011) [@rfc6238] generalised the same idea into the synchronised counter and time-based variants the world now calls &quot;authenticator app&quot; codes.&lt;/p&gt;
&lt;p&gt;The verifier-impersonation criterion got its first IETF expression in November 2007. Nico Williams&apos; RFC 5056 &lt;em&gt;On the Use of Channel Bindings to Secure Channels&lt;/em&gt; defined the concept that &quot;the two end-points of a secure channel at one network layer are the same as at a higher layer,&quot; and bound authentication at the higher layer to the channel at the lower layer [@rfc5056]. RFC 5056 was the protocol-literature acknowledgement that authentication needed to be tied to &lt;em&gt;something the network attacker could not change&lt;/em&gt; -- the channel itself, not just the user&apos;s typing.&lt;/p&gt;
&lt;p&gt;Kim Cameron&apos;s &lt;em&gt;The Laws of Identity&lt;/em&gt;, published on identityblog.com in May 2005, captured the same idea from a higher-level perspective. The seven Laws are a framework for federated identity on the open Internet; Laws 2 (&quot;minimal disclosure for a constrained use&quot;) and 4 (&quot;directed identity&quot;) are the conceptual ancestors of WebAuthn&apos;s &lt;em&gt;origin binding&lt;/em&gt; and &lt;em&gt;per-RP key pair&lt;/em&gt; design [@identityblog-laws]. Cameron was Microsoft&apos;s Chief Architect of Identity through this period, and the Laws shaped a generation of Microsoft thinking on identity. The Laws preceded the consortium that would actually ship the protocol by eight years.&lt;/p&gt;

The criteria framework was *available* in the literature by 2007: replay resistance from S/KEY (1995), channel binding from RFC 5056 (2007), origin binding from Cameron&apos;s Laws of Identity (2005). It did not displace know/have/are in regulatory documents until NIST SP 800-63-3 in 2017 (which introduced the &quot;phishing-resistant authenticator&quot; term) and SP 800-63-4 in 2025 (which made verifier-impersonation resistance a first-class criterion). Why the gap? The know/have/are taxonomy is *legible to procurement* -- it produces neat checkboxes. The criteria taxonomy is *cryptographically meaningful* but produces fewer neat checkboxes. Regulation prefers checkboxes until breach data forces a change.

gantt
    title Authentication standards lineage, 1985-2026
    dateFormat YYYY
    axisFormat %Y
    section Regulatory codification
    Orange Book DOD 5200.28-STD :1985, 5y
    NIST SP 800-63 v1 :2004, 7y
    NIST SP 800-63-3 (phishing-resistant) :2017, 8y
    NIST SP 800-63-4 final :2025, 2y
    section Criteria origin (IETF/W3C)
    RFC 1760 S/KEY :1995, 10y
    RFC 4226 HOTP :2005, 6y
    RFC 5056 Channel binding :2007, 4y
    RFC 6238 TOTP :2011, 7y
    RFC 8471 Token Binding :2018, 1y
    RFC 9266 tls-exporter :2022, 4y
    section Identity literature
    Cameron Laws of Identity :2005, 8y
    section FIDO and W3C
    FIDO Alliance launch :2013, 1y
    FIDO U2F 1.0 :2014, 5y
    WebAuthn FPWD :2016, 3y
    WebAuthn L1 + CTAP 2.0 :2019, 2y
    WebAuthn L2 + CTAP 2.1 :2021, 1y
    Passkey commitment May 2022 :2022, 1y
    WebAuthn L3 CR :2023, 3y
    CTAP 2.2 PS :2025, 1y
    section Windows
    Windows 10 1903 webauthn.dll :2019, 3y
    Windows 11 22H2 ECC :2022, 2y
    Windows 11 24H2 plug-in model :2024, 2y
&lt;p&gt;By 2007 the criteria framework was on paper. By 2013 there was a consortium for it: the FIDO Alliance launched on 12 February 2013 [@fido-launch-pdf], with six founding members [@wiki-fido-alliance]. Earlier identity-layer attempts -- Mozilla Persona / BrowserID, launched July 2011, with decommissioning announced January 2016 and the service shut down on 30 November 2016 [@wiki-mozilla-persona] -- had tried to build a browser-mediated identity layer at the HTTP level and failed to achieve traction. The FIDO consortium took a different bet: solve the authentication ceremony first, leave the identity-layer above it to OIDC and SAML. What happened first in a browser?&lt;/p&gt;
&lt;h2&gt;4. U2F: the first browser ceremony designed against phishing&lt;/h2&gt;
&lt;p&gt;December 2014. Yubico, Google, and NXP Semiconductors publish FIDO 1.0 / Universal 2nd Factor (U2F) [@fido-u2f-overview]; U2F 1.0 reached Proposed Standard status on 9 October 2014, with the broader FIDO 1.0 announcement window running through December [@wiki-u2f]. The Universal 2nd Factor Wikipedia article catalogues the design tradeoffs explicitly: U2F&apos;s challenge-response is &quot;signed (encoding originating domain/website) to prevent interception and reuse&quot; [@wiki-u2f]. This was the first time a browser ceremony was designed against the phishing-resistance criterion as a &lt;em&gt;primary&lt;/em&gt; goal rather than as an afterthought.&lt;/p&gt;
&lt;p&gt;The U2F ceremony has five field-level moving parts. An &lt;em&gt;AppID&lt;/em&gt; string identifies the relying party, derived from the page&apos;s origin so a phisher&apos;s domain cannot produce a U2F signature for the real bank. A &lt;em&gt;challenge&lt;/em&gt; is a per-ceremony nonce the relying party generates. A &lt;em&gt;key handle&lt;/em&gt; is an opaque blob the authenticator returns at registration and supplies on every later assertion; the relying party uses it to address the right credential on the next challenge. A &lt;em&gt;signature counter&lt;/em&gt; increments monotonically on every assertion, letting the relying party detect simple cloning. And the &lt;em&gt;signature&lt;/em&gt; itself is an ECDSA P-256 signature over the AppID hash, the challenge, the counter, and a presence flag.&lt;/p&gt;
&lt;p&gt;The AppID rule is the load-bearing piece. The browser computes the AppID from the actual origin the user is on; the authenticator signs over its hash; the relying party compares it to the AppID under which the credential was registered. A look-alike domain produces a different AppID, which produces a different signature, which the real verifier rejects. This is the same trick WebAuthn will later generalise as &lt;code&gt;rpId&lt;/code&gt; binding -- and it is the trick that makes U2F structurally immune to the AitM kits that will demolish password plus push a decade later.&lt;/p&gt;
&lt;p&gt;The canonical deployment paper is &lt;em&gt;Security Keys: Practical Cryptographic Second Factors for the Modern Web&lt;/em&gt;, by Juan Lang, Alexei Czeskis, Dirk Balfanz, Marius Schilder, and Sampath Srinivas, in the Financial Cryptography 2016 preproceedings [@lang-fc2016-pdf]. The paper documents Google&apos;s internal rollout: a hardware second factor for every employee, replacing the company&apos;s previous OTP-based MFA. The empirical scoreboard for the criteria framework gets its first data point here -- after the rollout, Google reported zero phishing-related account takeovers on employee accounts during the deployment period. This is not a controlled study; it is the largest natural experiment in deployed phishing resistance the industry had seen.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; U2F is the moment the authentication community made a structural design choice: phishing resistance is a property of the &lt;em&gt;protocol&lt;/em&gt;, not of &lt;em&gt;user training&lt;/em&gt;. No amount of &quot;look for the lock icon&quot; advice closes the phishing gap; a protocol that signs over the origin closes it by construction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;U2F&apos;s limitation is that it is, by design, a &lt;em&gt;second&lt;/em&gt; factor. The password under it remains the load-bearing weak link: a credential-stuffer can reuse the password against a service that does not require U2F, and a phisher can still capture the password even if they cannot capture the U2F signature. The AppID idea was correct; what was missing was the willingness to make the strong factor &lt;em&gt;the&lt;/em&gt; factor, not a layer on top of a weak one. The bridge from U2F to FIDO2 is exactly that move.&lt;/p&gt;
&lt;p&gt;The other piece U2F got right and FIDO2 inherited is the principle that the credential is &lt;em&gt;device-bound&lt;/em&gt; by default. The U2F Wikipedia summary captures the consequence: &quot;no recovery of the key is possible&quot; if the device is lost [@wiki-u2f]. This is the same property that makes synced passkeys, when they arrive in May 2022, a &lt;em&gt;productisation&lt;/em&gt; rather than a &lt;em&gt;cryptographic&lt;/em&gt; move. The bytes are the same. The lifecycle is different.&lt;/p&gt;
&lt;p&gt;If the second factor is doing all the work, why not make it &lt;em&gt;the&lt;/em&gt; factor?&lt;/p&gt;
&lt;h2&gt;5. FIDO2 + CTAP 2.0 + WebAuthn Level 1: the spec lands&lt;/h2&gt;
&lt;p&gt;March 4, 2019. The World Wide Web Consortium and the FIDO Alliance announced that the Web Authentication specification was an official W3C Recommendation [@w3c-fido-press-release]; the dated Recommendation slug is &lt;code&gt;REC-webauthn-1-20190304&lt;/code&gt; [@webauthn-l1-rec]. Same day, with January 30, 2019 as the underlying CTAP 2.0 Proposed Standard date [@ctap-2-0-ps]. The pair is what the industry markets as &lt;em&gt;FIDO2&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The reframe was decisive. A &lt;em&gt;platform authenticator&lt;/em&gt; -- Windows Hello on Windows, Touch ID on macOS, the Android Keystore on Android -- was now a first-class FIDO authenticator. The user&apos;s laptop or phone could be the authenticator. The browser did not need a separate USB device; it could call into the OS instead. This is the move that made FIDO2 a consumer technology, not just a security-team technology.&lt;/p&gt;

The *relying party* is the web service that owns the user&apos;s account. The *rpId* is a string identifying that party for credential scoping; it must be a registrable suffix of the page&apos;s origin (so `login.bank.com` may use `bank.com` as its `rpId`, but `evil.com` may not). All WebAuthn signatures are made over the SHA-256 hash of the `rpId`, which the browser derives from the actual origin and writes into `clientDataJSON`. The relying party validates the signature against the public key registered for that `rpId`. Phishing resistance is `rpId` binding, full stop [@webauthn-l3-cr].
&lt;p&gt;The Web IDL surface that WebAuthn Level 1 standardised is small. &lt;code&gt;navigator.credentials.create({publicKey: ...})&lt;/code&gt; registers a new credential; &lt;code&gt;navigator.credentials.get({publicKey: ...})&lt;/code&gt; produces an assertion. Both return &lt;code&gt;PublicKeyCredential&lt;/code&gt; objects. The complexity is not in the API; it is in the byte-level structures the API exchanges.&lt;/p&gt;
&lt;p&gt;A registration ceremony looks like this. The relying party generates a &lt;code&gt;PublicKeyCredentialCreationOptions&lt;/code&gt; blob containing a fresh challenge, the &lt;code&gt;rpId&lt;/code&gt;, the user&apos;s account identifier, the list of algorithms the RP supports, the desired user verification, and an optional list of credentials the user already has. The browser passes this to the authenticator and gets back two byte blobs. The first is &lt;code&gt;clientDataJSON&lt;/code&gt; -- a UTF-8 JSON blob containing &lt;code&gt;type: &quot;webauthn.create&quot;&lt;/code&gt;, the origin the browser was actually on, and the challenge. The second is &lt;code&gt;authenticatorData&lt;/code&gt; -- a binary blob containing the &lt;code&gt;rpIdHash&lt;/code&gt; (SHA-256 of the canonical &lt;code&gt;rpId&lt;/code&gt;), the flags byte (with &lt;code&gt;UP&lt;/code&gt;, &lt;code&gt;UV&lt;/code&gt;, &lt;code&gt;AT&lt;/code&gt;, &lt;code&gt;ED&lt;/code&gt; bits), the signature counter (initially zero, sometimes non-zero), the new credential&apos;s identifier, the AAGUID identifying the authenticator model, and the credential&apos;s public key in COSE_Key format. An optional &lt;em&gt;attestation statement&lt;/em&gt; binds those bytes to a hardware root of trust.&lt;/p&gt;

A 16-byte identifier the authenticator includes in `authenticatorData` to identify its make and model. Some authenticators emit an all-zeros AAGUID for privacy. Microsoft&apos;s Entra ID hardware-vendor matrix lists dozens of FIDO2 keys with their AAGUIDs and supported transports [@ms-entra-fido2-hardware]; the FIDO Metadata Service is the authoritative directory.

sequenceDiagram
    participant U as User
    participant B as Browser
    participant A as Authenticator
    participant R as Relying Party
    R-&amp;gt;&amp;gt;B: PublicKeyCredentialCreationOptions {challenge, rpId, user, pubKeyAlgs}
    B-&amp;gt;&amp;gt;B: build clientDataJSON {type:create, origin, challenge}
    B-&amp;gt;&amp;gt;A: authenticatorMakeCredential(clientDataHash, rpId, user, ...)
    A-&amp;gt;&amp;gt;U: prompt for user gesture (UV)
    U-&amp;gt;&amp;gt;A: present gesture (PIN, fingerprint, face)
    A-&amp;gt;&amp;gt;A: generate (pubKey, privKey) and sign attestation
    A-&amp;gt;&amp;gt;B: clientDataJSON, authenticatorData, attestationStatement
    B-&amp;gt;&amp;gt;R: attestationResponse {clientDataJSON, attestationObject}
    R-&amp;gt;&amp;gt;R: verify origin, rpIdHash, signature, then store pubKey, credentialId
    R-&amp;gt;&amp;gt;U: account created
&lt;p&gt;An authentication ceremony is the same shape with one structural change: the RP supplies &lt;code&gt;PublicKeyCredentialRequestOptions&lt;/code&gt; with a fresh challenge, the authenticator finds the credential matching the &lt;code&gt;rpId&lt;/code&gt;, prompts the user for a gesture (if &lt;code&gt;userVerification&lt;/code&gt; is requested), and produces an &lt;em&gt;assertion&lt;/em&gt; -- a signature over &lt;code&gt;authenticatorData || SHA-256(clientDataJSON)&lt;/code&gt; with the credential&apos;s private key. The relying party verifies the signature against the stored public key.&lt;/p&gt;
&lt;p&gt;The Windows-side surface debuts in the same window. Microsoft Learn states verbatim that Microsoft &quot;introduced the W3C/Fast IDentity Online 2 (FIDO2) Win32 WebAuthn platform APIs in Windows 10 (version 1903)&quot; [@ms-learn-webauthn-apis]. May 2019. &lt;code&gt;webauthn.dll&lt;/code&gt; ships. From that moment on, every browser on Windows -- Edge, Chrome, Firefox, Brave -- talks WebAuthn through one Win32 surface. The Microsoft Learn passkey overview makes the underlying architecture explicit: &quot;When these APIs are in use, Windows 10 browsers or applications don&apos;t have direct access to the FIDO2 transports for FIDO-related messaging&quot; [@ms-learn-webauthn-apis]. The OS is the dispatcher.&lt;/p&gt;
&lt;p&gt;The W3C/FIDO press release named the launch implementations: Windows 10, Android, Chrome, Firefox, Edge, and Safari (in preview) [@w3c-fido-press-release]. Microsoft, Google, Mozilla, and Apple all shipped within the same year. WebAuthn became the most-implemented strong-authentication standard on the consumer web inside eighteen months.&lt;/p&gt;
&lt;p&gt;{`
// A reader can paste in their own clientDataJSON and authenticatorData
// (base64url-encoded as Microsoft returns them) to see how the parser
// walks the bytes. Origin binding is one SHA-256 invocation away from
// being a one-liner; the value is in the binding, not the cryptography.&lt;/p&gt;
&lt;p&gt;const clientDataB64 = &quot;eyJ0eXBlIjoid2ViYXV0aG4uZ2V0Iiwib3JpZ2luIjoiaHR0cHM6Ly9sb2dpbi5taWNyb3NvZnRvbmxpbmUuY29tIiwiY2hhbGxlbmdlIjoiUk5KU2V6NjFqdyJ9&quot;;
const authDataB64 = &quot;Y9JZsAcVeQOLgxs9Ux7QYZpyTaB-OkpdyPwQk7P9YsoFAAAAFw&quot;;&lt;/p&gt;
&lt;p&gt;function b64urlDecode(s) {
  s = s.replace(/-/g,&apos;+&apos;).replace(/_/g,&apos;/&apos;);
  while (s.length % 4) s += &apos;=&apos;;
  return Uint8Array.from(atob(s), c =&amp;gt; c.charCodeAt(0));
}&lt;/p&gt;
&lt;p&gt;const clientDataBytes = b64urlDecode(clientDataB64);
const clientData = JSON.parse(new TextDecoder().decode(clientDataBytes));
console.log(&quot;clientDataJSON.type     =&quot;, clientData.type);
console.log(&quot;clientDataJSON.origin   =&quot;, clientData.origin);
console.log(&quot;clientDataJSON.challenge=&quot;, clientData.challenge);&lt;/p&gt;
&lt;p&gt;const authData = b64urlDecode(authDataB64);
const rpIdHash = authData.slice(0, 32);
const flags = authData[32];
const signCount = (authData[33]&amp;lt;&amp;lt;24) | (authData[34]&amp;lt;&amp;lt;16) | (authData[35]&amp;lt;&amp;lt;8) | authData[36];
console.log(&quot;authenticatorData rpIdHash =&quot;, Array.from(rpIdHash).map(b=&amp;gt;b.toString(16).padStart(2,&apos;0&apos;)).join(&apos;&apos;));
console.log(&quot;authenticatorData flags    = 0x&quot; + flags.toString(16),
            &quot;UP=&quot;+(flags&amp;amp;1), &quot;UV=&quot;+((flags&amp;gt;&amp;gt;2)&amp;amp;1), &quot;BE=&quot;+((flags&amp;gt;&amp;gt;3)&amp;amp;1), &quot;BS=&quot;+((flags&amp;gt;&amp;gt;4)&amp;amp;1), &quot;AT=&quot;+((flags&amp;gt;&amp;gt;6)&amp;amp;1));
console.log(&quot;authenticatorData signCount=&quot;, signCount);
`}&lt;/p&gt;
&lt;p&gt;The credential&apos;s public key is encoded as a COSE_Key map -- a CBOR object whose algorithm identifier is one of the entries in the IANA COSE Algorithms registry [@iana-cose-registry]. As of the registry&apos;s 2026-03-04 update, no post-quantum algorithm is in WebAuthn-recommended status; ECDSA P-256 and EdDSA Ed25519 remain the workhorses. The companion &lt;em&gt;Post-Quantum Cryptography on Windows&lt;/em&gt; article walks the algorithm-side rollout.&lt;/p&gt;
&lt;p&gt;Level 1 settled the field-level shape. What did the next two years sharpen?&lt;/p&gt;
&lt;h2&gt;6. CTAP 2.1: the wire protocol every security key is speaking&lt;/h2&gt;
&lt;p&gt;15 June 2021. The FIDO Alliance published CTAP 2.1 as a Proposed Standard [@ctap-2-1-ps]. CTAP 2.1 is the CBOR-on-the-wire version most security keys in 2024-2026 are running; CTAP 2.2 (Proposed Standard, 14 July 2025) [@ctap-2-2-ps] refines a few corners, and CTAP 2.3 is the Proposed Standard the FIDO Alliance lists alongside it [@fido-specs-download]. Each version adds capability without breaking the previous one&apos;s commands.&lt;/p&gt;

The Client-to-Authenticator Protocol -- the wire format the browser speaks to a roaming authenticator over USB-HID, NFC, or BLE. CTAP1 (the original U2F messages) carries APDU-style binary structures; CTAP2 carries CBOR-encoded commands. A *CTAP2 authenticator* (also called a FIDO2 or WebAuthn authenticator) implements the CTAP2 command set; modern keys also implement CTAP1 for backwards compatibility [@ctap-2-0-ps].
&lt;p&gt;The CTAP2 command-byte table is the surface a browser actually dispatches to. Each command is a single byte followed by a CBOR-encoded request map. The table below names the commands in order and the criterion-table cell each one strengthens.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command byte&lt;/th&gt;
&lt;th&gt;Command name&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Criterion strengthened&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;0x01&lt;/td&gt;
&lt;td&gt;&lt;code&gt;authenticatorMakeCredential&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Registration: generate a fresh keypair bound to &lt;code&gt;(rpId, user.id)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Phishing resistance (origin binding)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x02&lt;/td&gt;
&lt;td&gt;&lt;code&gt;authenticatorGetAssertion&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Authentication: sign the challenge with the credential&apos;s private key&lt;/td&gt;
&lt;td&gt;Phishing + replay + verifier-compromise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x04&lt;/td&gt;
&lt;td&gt;&lt;code&gt;authenticatorGetInfo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Capability discovery: list supported algorithms, extensions, transports, &lt;code&gt;UV&lt;/code&gt; modes&lt;/td&gt;
&lt;td&gt;Step-up (lets RP know what&apos;s available)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x06&lt;/td&gt;
&lt;td&gt;&lt;code&gt;authenticatorClientPIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Manage the PIN, issue &lt;code&gt;pinUvAuthToken&lt;/code&gt; with permissions bitmap and &lt;code&gt;rpId&lt;/code&gt; scoping&lt;/td&gt;
&lt;td&gt;Step-up + replay&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x07&lt;/td&gt;
&lt;td&gt;&lt;code&gt;authenticatorReset&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Wipe all resident credentials on the device&lt;/td&gt;
&lt;td&gt;Lifecycle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x09&lt;/td&gt;
&lt;td&gt;&lt;code&gt;authenticatorBioEnrollment&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;On-token fingerprint enrolment (CTAP 2.1)&lt;/td&gt;
&lt;td&gt;Step-up (&lt;code&gt;UV=1&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x0A&lt;/td&gt;
&lt;td&gt;&lt;code&gt;authenticatorCredentialManagement&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List, enumerate, and delete resident credentials per RP&lt;/td&gt;
&lt;td&gt;Lifecycle / recovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x0B&lt;/td&gt;
&lt;td&gt;&lt;code&gt;authenticatorSelection&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&quot;Pick this device&quot; prompt when multiple authenticators are present&lt;/td&gt;
&lt;td&gt;UX (no criterion change)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x0C&lt;/td&gt;
&lt;td&gt;&lt;code&gt;authenticatorLargeBlobs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Per-credential blob store under the credential&lt;/td&gt;
&lt;td&gt;Step-up (extension data)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x0D&lt;/td&gt;
&lt;td&gt;&lt;code&gt;authenticatorConfig&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enable enterprise attestation, toggle &lt;code&gt;alwaysUv&lt;/code&gt;, set minimum PIN length&lt;/td&gt;
&lt;td&gt;Verifier-compromise + lifecycle&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Three pieces of CTAP 2.1 are worth pulling out because they meaningfully change the criteria-table cells.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;pinUvAuthToken&lt;/code&gt; and permissions.&lt;/strong&gt; CTAP 2.0&apos;s PIN-protocol let the browser obtain a &lt;code&gt;pinAuthToken&lt;/code&gt; and use it across any command. CTAP 2.1 introduced a &lt;em&gt;permissions bitmap&lt;/em&gt; and &lt;em&gt;rpId scoping&lt;/em&gt; on the token so that a token issued for &lt;em&gt;one&lt;/em&gt; relying party&apos;s ceremony cannot be replayed against a different relying party&apos;s ceremony on the same authenticator [@ctap-2-1-ps]. This closes a class of host-side mischief: an attacker who got the PIN out of one ceremony could not previously be stopped from spending it on a different &lt;code&gt;rpId&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;credProtect&lt;/code&gt;.&lt;/strong&gt; A new extension that lets the RP request a higher protection level on the resident credential -- specifically, that the authenticator should refuse to list the credential without a &lt;code&gt;UV=1&lt;/code&gt; gesture. The first generation of WebAuthn discoverable credentials were enumerable by any host that could speak CTAP2 to the connected key; &lt;code&gt;credProtect&lt;/code&gt; lets the RP say &quot;don&apos;t show this credential&apos;s existence to anything that doesn&apos;t pass user verification first.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Enterprise attestation.&lt;/strong&gt; CTAP 2.1 added an explicit &lt;em&gt;enterprise attestation&lt;/em&gt; mode in which the authenticator binds its attestation statement to a list of relying parties the device&apos;s enrolling organisation has pre-approved. This is the bridge that makes vendor attestation useful in managed enterprises without leaking the user&apos;s specific device identity to every relying party.The largeBlob extension (CTAP 2.1, command 0x0C) gives each credential a small per-credential blob store. RPs use it for things like cached short-lived tokens or per-user policy. The 2024 release notes for the Windows &lt;code&gt;webauthn.dll&lt;/code&gt; API surface flagged largeBlob support as one of the additions in Windows 11 22H2 [@ms-learn-webauthn-apis]; a March 2023 Review Draft [@ctap-2-2-rd] foreshadowed the 2.2 refinements that landed in July 2025.&lt;/p&gt;
&lt;p&gt;All of this is for experts. When did this stop being a security-team conversation and start being a consumer product? What changed in May 2022?&lt;/p&gt;
&lt;h2&gt;7. Passkeys: the productisation moment&lt;/h2&gt;
&lt;p&gt;5 May 2022. Apple, Google, and Microsoft jointly committed at the FIDO Alliance to a common passwordless sign-in standard [@fido-aav-passkey-commitment]. The press release is short on protocol detail and long on user-facing language. The headline commitment, verbatim: &quot;Allow users to automatically access their FIDO sign-in credentials (referred to by some as a &apos;passkey&apos;) on many of their devices, even new ones, without having to reenroll every account&quot; [@fido-aav-passkey-commitment]. &lt;em&gt;Passkey&lt;/em&gt; entered the public lexicon. Andrew Shikiar, the FIDO Alliance&apos;s executive director and CMO at the time, named it in the press call.&lt;/p&gt;

Allow users to automatically access their FIDO sign-in credentials (referred to by some as a &apos;passkey&apos;) on many of their devices, even new ones, without having to reenroll every account. -- Apple, Google, and Microsoft, joint FIDO Alliance announcement, 5 May 2022 [@fido-aav-passkey-commitment]
&lt;p&gt;The &lt;em&gt;cryptographic&lt;/em&gt; move in May 2022 was small. The protocol bytes are the same FIDO2 / WebAuthn / CTAP2 bytes that shipped in March 2019. What changed was twofold: (a) the three platform vendors aligned their sync fabrics so that a passkey created on a user&apos;s phone would appear on the user&apos;s laptop, and (b) the user-facing terminology consolidated from a confusing menagerie (&quot;discoverable credential,&quot; &quot;resident key,&quot; &quot;client-side discoverable credential&quot;) onto a single product term -- &lt;em&gt;passkey&lt;/em&gt;.&lt;/p&gt;

A WebAuthn credential whose `user.id` and account metadata are stored *on the authenticator*, so the authenticator can produce an assertion without the relying party first supplying a credential identifier. The CTAP 2.0 spec calls these *resident keys* [@ctap-2-0-ps]; the WebAuthn Level 2 spec calls them *client-side discoverable credentials* [@webauthn-l2-latest]; the May 2022 vendor commitment rebranded them as *passkeys* [@fido-aav-passkey-commitment]. All three terms refer to the same on-the-wire object.
&lt;p&gt;Discoverable credentials unlock &lt;em&gt;usernameless&lt;/em&gt; sign-in. The relying party does not need to tell the authenticator which credential to use; the authenticator looks up its own resident credentials for the supplied &lt;code&gt;rpId&lt;/code&gt;, shows the user the matching account, and asks for the user-verification gesture. This is the UX primitive every consumer-passkey flow leans on.&lt;/p&gt;
&lt;p&gt;WebAuthn Level 3 (W3C Candidate Recommendation, latest snapshot dated 13 January 2026 [@webauthn-l3-cr] [@webauthn-l3-cr-dated]) is the spec generation that productises passkeys. Level 3 standardises:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;hybrid transport&lt;/strong&gt; (formerly known as caBLE), §6.3.3 of the L3 spec, which lets a phone act as a roaming authenticator for a nearby laptop via QR code plus ephemeral ECDH plus BLE proximity. We cover hybrid in §12.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JSON-serialisation helpers&lt;/strong&gt; -- &lt;code&gt;PublicKeyCredentialCreationOptionsJSON&lt;/code&gt; and &lt;code&gt;PublicKeyCredentialRequestOptionsJSON&lt;/code&gt; -- that make WebAuthn easier to drive from a server SDK without manual base64url juggling.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;getClientCapabilities()&lt;/code&gt;&lt;/strong&gt; so the relying party can probe what the client supports before issuing the ceremony.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;&lt;code&gt;credProps&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;prf&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;largeBlob&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;credProtect&lt;/code&gt;&lt;/strong&gt;, and &lt;strong&gt;Secure Payment Confirmation&lt;/strong&gt; extensions, each of which sharpens one cell of the criteria table.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The mid-2025 cadence picked up: CTAP 2.2 Proposed Standard on 14 July 2025 [@ctap-2-2-ps] refined hybrid-transport semantics and tightened &lt;code&gt;credProtect&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The synced-vs-bound distinction is the structural new thing about passkeys. Before May 2022 a FIDO2 credential lived in one secure element; lose the YubiKey, lose the credential. Synced passkeys put the private key into a sync fabric -- Apple iCloud Keychain (originally 2013) [@wiki-icloud], Google Password Manager (Chrome password sync, late 2000s onward), Microsoft Authenticator (originally 2015) [@wiki-ms-authenticator], and Microsoft Account passkey sync (general availability for consumer accounts on 2 May 2024) [@ms-security-passkeys-consumer] -- and let it appear on every device the user signs into. The mechanism is end-to-end encryption against a sync-fabric key that the platform vendor cannot read; Apple&apos;s Advanced Data Protection model is the strongest current public realisation [@apple-adp-kb].&lt;/p&gt;
&lt;p&gt;The price: the long-term private key has &lt;em&gt;left&lt;/em&gt; the original authenticator. NIST is unambiguous about the consequence. The April 2024 supplement &lt;em&gt;Incorporating Syncable Authenticators into NIST SP 800-63B&lt;/em&gt; [@sp80063sup1] -- since absorbed into NIST SP 800-63B-4 final, July 2025 [@sp80063b4-html] -- classifies synced passkeys at AAL2, not AAL3, because the key is no longer pinned to a single tamper-resistant element. Yubico&apos;s commentary captures the dichotomy verbatim: &quot;FIDO passkeys that are not synced -- device-bound passkeys like YubiKeys -- and are properly stored in dedicated hardware have an AAL3 rating&quot; [@yubico-nist-guidance].&lt;/p&gt;
&lt;p&gt;The WebAuthn spec made the distinction &lt;em&gt;observable&lt;/em&gt;. Two new flag bits in &lt;code&gt;authenticatorData&lt;/code&gt; -- &lt;code&gt;BE&lt;/code&gt; (Backup Eligible) and &lt;code&gt;BS&lt;/code&gt; (Backup State) -- tell the relying party whether the credential is in principle syncable (&lt;code&gt;BE=1&lt;/code&gt;) and whether it is currently backed up (&lt;code&gt;BS=1&lt;/code&gt;) [@webauthn-l3-cr]. The RP can decide policy from those flags: a banking RP can require &lt;code&gt;BE=0&lt;/code&gt; (device-bound) credentials for AAL3 transactions, while accepting &lt;code&gt;BS=1&lt;/code&gt; (synced) credentials for AAL2 sign-in.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s own numbers tell the productisation story in raw counts. The May 2024 Microsoft Security blog announcing passkey support for consumer accounts notes that Microsoft was &quot;detecting around 115 password attacks per second&quot; when Windows Hello first shipped in 2015; &quot;less than a decade later, that number has surged 3,378% to more than 4,000 password attacks per second&quot; [@ms-security-passkeys-consumer]. The 1 May 2025 World Passkey Day post escalates again: &quot;we observed a staggering 7,000 password attacks per second (more than double the rate from 2023). [...] now we see nearly a million passkeys registered every day.&quot; It also reports that &quot;passkey sign-ins are eight times faster than a password and multifactor authentication,&quot; and that &quot;more than 99% of people who sign into their Windows devices with their Microsoft account do so using Windows Hello&quot; [@ms-security-world-passkey-day].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Passkeys are not a new cryptographic primitive. They are a productisation moment in which discoverable credentials became consumer-grade UX. The protocol moves were two years earlier; the product move is what changed the criteria-table scoreboard.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Passkeys are a &lt;em&gt;productisation&lt;/em&gt; moment. On Windows specifically, what does the platform actually do between &lt;code&gt;navigator.credentials.create&lt;/code&gt; and the TPM?&lt;/p&gt;
&lt;h2&gt;8. The Windows platform authenticator: &lt;code&gt;webauthn.dll&lt;/code&gt; end-to-end&lt;/h2&gt;
&lt;p&gt;May 2019. Windows 10 version 1903. The Win32 platform WebAuthn API shipped, and from that moment on every browser and every native application on Windows that wants to do WebAuthn calls &lt;code&gt;webauthn.dll&lt;/code&gt;. The header file &lt;code&gt;webauthn.h&lt;/code&gt; is in the Windows SDK and is also published on GitHub at &lt;code&gt;github.com/microsoft/webauthn&lt;/code&gt; [@github-ms-webauthn]. The reference page on Microsoft Learn enumerates every function the API surfaces [@ms-learn-win32-webauthn]. The 1903 ship date and the subsequent feature additions are documented verbatim by Microsoft Learn: &quot;Microsoft has long been a proponent of passwordless authentication, and has introduced the W3C/Fast IDentity Online 2 (FIDO2) Win32 WebAuthn platform APIs in Windows 10 (version 1903). Starting in &lt;strong&gt;Windows 11, version 22H2&lt;/strong&gt;, WebAuthn APIs support ECC algorithms and starting in &lt;strong&gt;Windows 11 version 24H2&lt;/strong&gt; WebAuthn APIs support plugin passkey managers&quot; [@ms-learn-webauthn-apis].&lt;/p&gt;

When these APIs are in use, Windows 10 browsers or applications don&apos;t have direct access to the FIDO2 transports for FIDO-related messaging. -- Microsoft Learn, *WebAuthn APIs for password-less authentication on Windows* [@ms-learn-webauthn-apis]
&lt;p&gt;That sentence is the entire architectural premise. The OS dispatches FIDO2 ceremonies. The browser does not own the CTAP2 stack, the USB-HID transport, the NFC reader, the BLE pairing, or the Hello UV gesture. It hands &lt;code&gt;webauthn.dll&lt;/code&gt; a request and gets back an assertion.&lt;/p&gt;
&lt;p&gt;The API surface is a small set of functions. The ceremony surface is two functions, the management surface is the remainder.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNAuthenticatorMakeCredential&lt;/code&gt;&lt;/strong&gt; -- the registration entry point. Caller supplies origin / &lt;code&gt;rpId&lt;/code&gt; / user / algorithms / attestation preference / authenticator-selection criteria. Returns an attestation object.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNAuthenticatorGetAssertion&lt;/code&gt;&lt;/strong&gt; -- the authentication entry point. Caller supplies origin / &lt;code&gt;rpId&lt;/code&gt; / allowed credential IDs (or empty for usernameless) / user-verification preference / mediation (Conditional UI, see §9). Returns an assertion.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNGetApiVersionNumber&lt;/code&gt;&lt;/strong&gt; -- a monotonically increasing integer that lets callers feature-detect. Version 1 is Windows 10 1903; versions step up as Windows adds ECC algorithms (22H2), the plugin model (24H2), and the EXPERIMENTAL_*2 surface (Insider builds via KB5072046 [@github-ms-webauthn]).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNGetCancellationId&lt;/code&gt;&lt;/strong&gt; / &lt;strong&gt;&lt;code&gt;WebAuthNCancelCurrentOperation&lt;/code&gt;&lt;/strong&gt; -- cooperative cancellation; the browser asks &lt;code&gt;webauthn.dll&lt;/code&gt; to drop the active ceremony.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNGetPlatformCredentialList&lt;/code&gt;&lt;/strong&gt; / &lt;strong&gt;&lt;code&gt;WebAuthNDeletePlatformCredential&lt;/code&gt;&lt;/strong&gt; -- resident-credential management for synced passkeys held by the OS provider.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable&lt;/code&gt;&lt;/strong&gt; -- the &lt;code&gt;isUVPAA&lt;/code&gt; capability probe; the RP uses this to decide whether to offer a passkey enrolment flow at all.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNFreeAssertion&lt;/code&gt;&lt;/strong&gt; / &lt;strong&gt;&lt;code&gt;WebAuthNFreeCredentialAttestation&lt;/code&gt;&lt;/strong&gt; / &lt;strong&gt;&lt;code&gt;WebAuthNFreePlatformCredentialList&lt;/code&gt;&lt;/strong&gt; -- caller-side memory release; the OS allocates on the heap and the caller is responsible for &lt;code&gt;Free&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNGetErrorName&lt;/code&gt;&lt;/strong&gt; / &lt;strong&gt;&lt;code&gt;WebAuthNGetW3CExceptionDOMError&lt;/code&gt;&lt;/strong&gt; -- translate the Win32 &lt;code&gt;HRESULT&lt;/code&gt; into a WebAuthn-spec error string.&lt;/li&gt;
&lt;/ul&gt;

flowchart TD
    A[Browser or native app] --&amp;gt; B[webauthn.dll: WebAuthNAuthenticatorMakeCredential]
    B --&amp;gt; C[Windows Hello UI: prompt for PIN, fingerprint, or face]
    C --&amp;gt; D[Windows Hello / Hello for Business: verify gesture]
    D --&amp;gt; E[CNG NCRYPT: keypair generation request]
    E --&amp;gt; F[TPM 2.0: generate keypair inside the TPM]
    F --&amp;gt; G[TPM 2.0: TPM2_Certify over the new credential public key]
    G --&amp;gt; H[webauthn.dll: build attestation object with packed or tpm format]
    H --&amp;gt; B
    B --&amp;gt; A
    A --&amp;gt; I[Relying party: verify attestation, store credential public key]
&lt;p&gt;The criteria-framework consequence of that call graph is that &lt;em&gt;the private key never leaves the TPM&lt;/em&gt;. Microsoft Learn states the property verbatim: &quot;The private keys can only be used after they&apos;re unlocked by the user using the Windows Hello unlock factor (biometrics or PIN)&quot; [@ms-learn-passkeys]. The TPM enforces use through its own access-control rules; even kernel malware on the host cannot exfiltrate the raw private key, only request operations gated on the user&apos;s gesture. This is what gets a Windows-platform-bound passkey on a TPM to AAL3 even when synced passkeys are bounded at AAL2.&lt;/p&gt;
&lt;p&gt;The API version sentinel tells a clean feature-evolution story.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Windows release&lt;/th&gt;
&lt;th&gt;API version (approx.)&lt;/th&gt;
&lt;th&gt;Notable additions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Windows 10 1903 (May 2019)&lt;/td&gt;
&lt;td&gt;v1&lt;/td&gt;
&lt;td&gt;Initial Win32 surface: make/get credential, isUVPAA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows 10 1909 / 20H1&lt;/td&gt;
&lt;td&gt;v2&lt;/td&gt;
&lt;td&gt;UV preference, signal-handling refinements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows 11 21H2 (Oct 2021)&lt;/td&gt;
&lt;td&gt;v3&lt;/td&gt;
&lt;td&gt;Hybrid transport (caBLE) entrypoints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows 11 22H2 (Sep 2022)&lt;/td&gt;
&lt;td&gt;v4-v5&lt;/td&gt;
&lt;td&gt;ECC algorithms (ECDSA P-256 platform credentials), Conditional UI mediation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows 11 23H2 (Oct 2023)&lt;/td&gt;
&lt;td&gt;v6&lt;/td&gt;
&lt;td&gt;largeBlob, credProps, refined cancellation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows 11 24H2 (Oct 2024)&lt;/td&gt;
&lt;td&gt;v7&lt;/td&gt;
&lt;td&gt;Plug-in passkey managers (&lt;code&gt;WebAuthNPlugin*&lt;/code&gt;), redesigned Hello UX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insider builds (KB5072046)&lt;/td&gt;
&lt;td&gt;v7+&lt;/td&gt;
&lt;td&gt;EXPERIMENTAL_WebAuthNPluginAddAuthenticator2, EXPERIMENTAL_WebAuthNPluginPerformUserVerification2, EXPERIMENTAL_WebAuthNPluginUpdateAuthenticatorDetails2 [@github-ms-webauthn]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The three &lt;code&gt;EXPERIMENTAL_*2&lt;/code&gt; APIs in &lt;code&gt;github.com/microsoft/webauthn&lt;/code&gt; are Insider-only and will lose the &lt;code&gt;EXPERIMENTAL_&lt;/code&gt; prefix as they stabilise. The naming convention is the standard Windows SDK signal for &quot;we want feedback before this becomes load-bearing public API.&quot;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; On Windows, do not roll your own CTAP2 stack. &lt;code&gt;webauthn.dll&lt;/code&gt; handles USB-HID, NFC, BLE, hybrid transport, Conditional UI, plug-in dispatch, and Windows Hello user verification in a single call. The Win32 reference at &lt;code&gt;learn.microsoft.com/en-us/windows/win32/api/webauthn/&lt;/code&gt; is the source of truth, the header file is at &lt;code&gt;github.com/microsoft/webauthn&lt;/code&gt;, and the YubiKey 5 series [@yubikey5-overview] plus the Entra-listed FIDO2 vendors [@ms-entra-fido2-hardware] are the supported keys.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The criterion-table consequence of dispatching FIDO2 through one OS surface is that &lt;em&gt;every browser is automatically as strong as the OS&lt;/em&gt;. Edge does not need its own attestation logic; neither does Chrome, Firefox, or Brave. They all call the same &lt;code&gt;webauthn.dll&lt;/code&gt;, which routes the registration to the TPM (for platform-bound passkeys), to USB-HID (for roaming security keys), or to a plug-in (for Windows 11 24H2 third-party providers, §10).&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;webauthn.dll&lt;/code&gt; surface answers one half of the question. The other half is: what does the user actually &lt;em&gt;see&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;{`
// Origin binding is computationally trivial. The value is in the binding,
// not the cryptography. This snippet computes SHA-256 of an origin&apos;s
// effective rpId and compares against the rpIdHash a real authenticator
// would have signed. Paste in a clientDataJSON.origin and the
// authenticatorData.rpIdHash from the earlier snippet to verify.&lt;/p&gt;
&lt;p&gt;async function rpIdHash(rpId) {
  const enc = new TextEncoder().encode(rpId);
  const hash = await crypto.subtle.digest(&quot;SHA-256&quot;, enc);
  return Array.from(new Uint8Array(hash)).map(b =&amp;gt; b.toString(16).padStart(2,&apos;0&apos;)).join(&apos;&apos;);
}&lt;/p&gt;
&lt;p&gt;(async () =&amp;gt; {
  const goodOrigin = &quot;login.microsoftonline.example&quot;;
  const badOrigin  = &quot;login-microsoft0nline.example&quot;;
  const goodRpId   = &quot;login.microsoftonline.example&quot;;
  const badRpId    = &quot;login-microsoft0nline.example&quot;;
  console.log(&quot;rpIdHash(&quot;, goodRpId, &quot;) =&quot;, await rpIdHash(goodRpId));
  console.log(&quot;rpIdHash(&quot;, badRpId,  &quot;) =&quot;, await rpIdHash(badRpId));
  // The two hashes differ in every byte. A passkey registered against
  // login.microsoftonline.example cannot be induced to sign for the look-alike
  // because the authenticator computes the second hash from clientDataJSON.origin
  // and refuses to use the credential bound to the first one.&lt;/p&gt;
&lt;p&gt;  // Replay resistance illustration: a signCount of 0x10 followed by 0x0F
  // is illegal (counter regressed). RPs reject this for BS=0 credentials.
  const oldCount = 0x10, newCount = 0x0F;
  console.log(&quot;signCount regression (BS=0)?&quot;, newCount &amp;lt;= oldCount ? &quot;REJECT&quot; : &quot;ACCEPT&quot;);
})();
`}&lt;/p&gt;
&lt;h2&gt;9. Conditional UI: passkey autofill that looks like password autofill&lt;/h2&gt;
&lt;p&gt;The bridge between users&apos; password-trained mental model and the new asymmetric-crypto reality is a UX primitive called Conditional Mediation -- the spec name -- or &lt;em&gt;Conditional UI&lt;/em&gt; in informal use. The relying party renders a normal-looking username field. The browser sees that the page has called &lt;code&gt;navigator.credentials.get({mediation: &quot;conditional&quot;, publicKey: {...}})&lt;/code&gt; and quietly offers the user&apos;s passkey as one of the autofill suggestions, alongside whatever the user has typed and whatever the password manager remembers. The user clicks the passkey suggestion, completes a Windows Hello gesture, and they are signed in. No popup. No modal. No &quot;do you want to use a passkey?&quot; dialog.&lt;/p&gt;

A WebAuthn invocation mode in which the browser offers the user&apos;s discoverable credentials *inside* the same autofill UI it uses for saved passwords, rather than via a modal credential picker. The relying party calls `navigator.credentials.get({mediation: &quot;conditional&quot;, publicKey: {...}})`; the browser silently consults the platform authenticator (and, on Windows 11 24H2, the plug-in passkey providers) for credentials matching the `rpId`. The capability is probed via `PublicKeyCredential.isConditionalMediationAvailable()` [@webauthn-l3-cr].
&lt;p&gt;The canonical engineer-perspective walkthrough is Adam Langley&apos;s &lt;em&gt;Passkeys&lt;/em&gt; post on imperialviolet.org, dated 22 September 2022 [@imperialviolet-passkeys]. Langley walks the flag-page invocation needed on early Chrome Canary builds -- &lt;code&gt;chrome://flags#webauthn-conditional-ui&lt;/code&gt; -- and the capability surface: &lt;code&gt;isUserVerifyingPlatformAuthenticatorAvailable()&lt;/code&gt; to decide whether to offer enrolment, &lt;code&gt;isConditionalMediationAvailable()&lt;/code&gt; to decide whether to render the autofill hint at all. The post is the first time most working engineers saw what passkeys would actually look like at the page level.&lt;/p&gt;
&lt;p&gt;On Windows the browser calls &lt;code&gt;WebAuthNAuthenticatorGetAssertion&lt;/code&gt; with the Conditional mediation flag set; &lt;code&gt;webauthn.dll&lt;/code&gt; consults its resident credential store, finds passkeys matching the &lt;code&gt;rpId&lt;/code&gt;, and surfaces a small in-line affordance for each. The full-screen Windows Hello modal becomes a small in-place gesture acquisition. From the user&apos;s perspective the password-manager metaphor is unchanged; from the cryptography&apos;s perspective the work product is a public-key signature over an origin-bound challenge.&lt;/p&gt;
&lt;p&gt;The L3 spec section 5.1.4 is the normative reference for the mediation modes [@webauthn-l3-cr]. The four modes are: &lt;code&gt;silent&lt;/code&gt; (no user interaction), &lt;code&gt;optional&lt;/code&gt; (browser decides), &lt;code&gt;conditional&lt;/code&gt; (autofill), and &lt;code&gt;required&lt;/code&gt; (modal). Conditional is the one that makes passkeys feel like passwords -- and that is precisely why it took the consumer-passkey rollout off the security-team conversation and into product reviews.&lt;/p&gt;
&lt;p&gt;The Microsoft Learn passkey overview ties the UX to the Windows ship vehicle: &quot;Starting in Windows 11, version 22H2 with KB5030310, Windows provides a native experience for passkey management&quot; [@ms-learn-passkeys]. The Settings -&amp;gt; Accounts -&amp;gt; Passkeys page is the management UI; Conditional Mediation surfaces those passkeys at sign-in time. The passkeys.dev developer directory [@passkeys-dev] is the FIDO Alliance&apos;s collected resource for relying parties implementing the flow.&lt;/p&gt;
&lt;p&gt;The UX implication is the one Adam Langley underlined in the September 2022 post: the password-autofill metaphor is the load-bearing UX primitive that makes passkeys consumer-ready. The cryptography was solved in 2014. The UX took eight more years.&lt;/p&gt;
&lt;p&gt;But what if the user&apos;s passkey lives in 1Password or Bitwarden, not in Windows itself?&lt;/p&gt;
&lt;h2&gt;10. The Windows 11 24H2 third-party passkey provider model&lt;/h2&gt;
&lt;p&gt;8 October 2024. Microsoft published the Windows Developer Blog post &lt;em&gt;Passkeys on Windows: authenticate seamlessly with passkey providers&lt;/em&gt; [@ms-windev-passkeys-blog] as a pre-conference announcement ahead of the FIDO Alliance&apos;s Authenticate 2024 conference (14-16 October 2024 in Carlsbad, California). The post announced three deliverables: &quot;1. A plug-in model for third-party passkey providers. 2. Enhanced native UX for passkeys. 3. A Microsoft synced passkey provider.&quot; 1Password and Bitwarden were the named launch partners; Dashlane joined the roster shortly thereafter. The post says verbatim: &quot;Microsoft is partnering closely with 1Password, Bitwarden and others on integrating this capability&quot; [@ms-windev-passkeys-blog].&lt;/p&gt;
&lt;p&gt;The plug-in model is the first OS-level passkey-provider API on a major desktop platform. macOS Sonoma and iOS 17 had shipped a parallel design (&lt;code&gt;ASCredentialIdentityStore&lt;/code&gt; plus &lt;code&gt;ASCredentialProviderExtension&lt;/code&gt;) [@apple-ascredentialprovider]; Android 14 had added Credential Manager support [@android-credman]; Windows 11 24H2 is the desktop OS that matches the mobile platforms. The mechanism is a COM interface called &lt;code&gt;IPluginAuthenticator&lt;/code&gt;, declared in &lt;code&gt;pluginauthenticator.idl&lt;/code&gt; [@github-ms-webauthn]. A passkey-manager vendor ships a packaged Windows app that registers a COM object implementing the interface, supplies an AAGUID and a friendly name, and lets the OS dispatch ceremonies to it.&lt;/p&gt;
&lt;p&gt;The Plugin API surface is six functions on the OS side and one COM interface on the vendor side. From &lt;code&gt;webauthnplugin.h&lt;/code&gt; and the Microsoft Learn reference [@ms-learn-webauthn-apis]:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNPluginAddAuthenticator&lt;/code&gt;&lt;/strong&gt; -- register the plug-in with the OS. The vendor app calls this on first run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNPluginAuthenticatorAddCredentials&lt;/code&gt;&lt;/strong&gt; -- supply the OS with the credentials the plug-in currently has, so the OS can render them in pickers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNPluginAuthenticatorRemoveCredentials&lt;/code&gt;&lt;/strong&gt; -- the inverse; remove credentials the plug-in no longer holds.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNPluginPerformUserVerification&lt;/code&gt;&lt;/strong&gt; -- request Windows Hello UV on behalf of the plug-in. The plug-in does &lt;em&gt;not&lt;/em&gt; take the UV gesture itself; Windows Hello does, so the gesture-to-credential trust path is OS-mediated.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNPluginRemoveAuthenticator&lt;/code&gt;&lt;/strong&gt; -- the vendor&apos;s uninstall path.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WebAuthNPluginGetAuthenticatorList&lt;/code&gt;&lt;/strong&gt; -- enumerate which plug-ins the OS knows about.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Three additional &lt;code&gt;EXPERIMENTAL_*2&lt;/code&gt; functions ship in Insider build KB5072046 and refine the registration, UV, and update flows. The list, verbatim from the &lt;code&gt;github.com/microsoft/webauthn&lt;/code&gt; README: &lt;code&gt;EXPERIMENTAL_WebAuthNPluginAddAuthenticator2&lt;/code&gt;, &lt;code&gt;EXPERIMENTAL_WebAuthNPluginPerformUserVerification2&lt;/code&gt;, &lt;code&gt;EXPERIMENTAL_WebAuthNPluginUpdateAuthenticatorDetails2&lt;/code&gt; [@github-ms-webauthn].&lt;/p&gt;
&lt;p&gt;The Microsoft-authored reference implementation is the Contoso Passkey Manager sample in &lt;code&gt;microsoft/Windows-classic-samples&lt;/code&gt; [@github-ms-passkey-sample]. The sample&apos;s build manifest is explicit: &quot;Windows SDK version 10.0.26100.7175 or higher. Operating system requirements: Windows 11 version 25H2. Build Major Version = 26200 and Minor Version &amp;gt;= 6725. Windows 11 version 24H2. Build Major Version = 26100 and Minor Version &amp;gt;= 6725&quot; [@github-ms-passkey-sample]. The Microsoft Learn tutorial &lt;em&gt;Third-party passkey providers on Windows&lt;/em&gt; walks the same sample step by step [@ms-learn-thirdparty].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Microsoft Learn third-party tutorial carries an explicit disclaimer: &quot;Contoso Passkey Manager is designed for passkey creation and usage testing only. Don&apos;t use the app for production passkeys&quot; [@ms-learn-thirdparty]. The sample illustrates the COM contract; it does not replace a vetted vendor&apos;s credential vault.&lt;/p&gt;
&lt;/blockquote&gt;

flowchart TD
    A[Browser or native app] --&amp;gt; B[webauthn.dll]
    B --&amp;gt; C{&quot;Provider picker&quot;}
    C --&amp;gt;|Windows Hello / platform| D[CNG + TPM 2.0]
    C --&amp;gt;|Roaming hardware| E[USB-HID / NFC / BLE]
    C --&amp;gt;|Third-party plug-in| F[COM: IPluginAuthenticator]
    F --&amp;gt; G[1Password / Bitwarden / Dashlane vault]
    F --&amp;gt; H[WebAuthNPluginPerformUserVerification]
    H --&amp;gt; I[Windows Hello UI]
    I --&amp;gt; H
    G --&amp;gt; F
    F --&amp;gt; B
    B --&amp;gt; A
&lt;p&gt;The user-facing flow follows the same logic as the macOS / iOS / Android equivalents. The user installs 1Password or Bitwarden from the Microsoft Store. The vendor app calls &lt;code&gt;WebAuthNPluginAddAuthenticator&lt;/code&gt; on first launch. The user enables the provider in Settings -&amp;gt; Accounts -&amp;gt; Passkeys -&amp;gt; Advanced options [@ms-windev-passkeys-blog]. From that point on, when any browser or native app on Windows starts a WebAuthn ceremony, &lt;code&gt;webauthn.dll&lt;/code&gt; presents the user with a picker -- &quot;use a passkey from Windows Hello, from 1Password, from Bitwarden, from a hardware security key, or from your phone&quot; -- and routes the ceremony to the selected provider. The plug-in itself returns an attestation object and an assertion; Windows Hello handles user verification on the plug-in&apos;s behalf via &lt;code&gt;WebAuthNPluginPerformUserVerification&lt;/code&gt;. The Windows trust boundary still owns the gesture acquisition.&lt;/p&gt;

The plug-in model adds credential-store choice; it does not change the lock-screen credential. The plug-in cannot replace Windows Hello at the lock screen; lock-screen sign-in remains the platform authenticator. The plug-in cannot proxy domain credentials -- Kerberos and NTLM are unaffected. The plug-in is *not* a replacement for the legacy `CredMan` (Credential Manager) generic-credential surface; that surface is still where Windows applications stash Basic-Auth-style credentials. The plug-in model is, specifically, a WebAuthn credential store. Everything else stays where it was.
&lt;p&gt;The criterion-table consequence is mixed. The plug-in model strengthens &lt;em&gt;user choice&lt;/em&gt; and &lt;em&gt;recovery&lt;/em&gt;, because a user with an existing 1Password / Bitwarden vault can reuse the recovery primitives they already know. It weakens &lt;em&gt;verifier-compromise resistance&lt;/em&gt; relative to a pure platform-bound passkey, because the long-term key now lives in the vendor&apos;s vault rather than the TPM -- and the vendor&apos;s vault becomes another point of compromise. It does not change phishing resistance, replay resistance, or step-up, because those are properties of the WebAuthn ceremony and the plug-in still produces a WebAuthn-shaped assertion.&lt;/p&gt;
&lt;p&gt;What 1Password, Bitwarden, and Dashlane each ship in their plug-in implementations follows the same template: registration requests get either a &lt;code&gt;packed&lt;/code&gt; attestation statement (for vendor-signed batch attestation keys) or a &lt;code&gt;none&lt;/code&gt; attestation (most consumer flows), and authentication assertions come back the same shape as any other WebAuthn assertion. The plug-in itself decides whether the credential is &lt;code&gt;BE=1, BS=1&lt;/code&gt; (synced in the vendor&apos;s cloud) or &lt;code&gt;BE=0, BS=0&lt;/code&gt; (device-bound to the local install).&lt;/p&gt;
&lt;p&gt;A plug-in supplies the credential. But the &lt;em&gt;attestation statement&lt;/em&gt; on registration tells the relying party &lt;em&gt;what kind of credential it is&lt;/em&gt;. That&apos;s a separate API surface -- what shapes does it come in?&lt;/p&gt;
&lt;h2&gt;11. The seven attestation conveyance formats&lt;/h2&gt;
&lt;p&gt;The IANA WebAuthn registry lists seven format identifiers for the &lt;em&gt;attestation statement&lt;/em&gt; a registration ceremony can produce [@iana-webauthn-registry]. The registry is reachable via RFC 8809 (Hodges, Mandyam, M.B. Jones, August 2020) [@rfc8809] and the canonical normative definitions are in WebAuthn Level 2 §§8.2-8.8 [@webauthn-l2-latest], whose dated Recommendation is at &lt;code&gt;REC-webauthn-2-20210408&lt;/code&gt; [@webauthn-l2-rec]. The seven, in registry order: &lt;code&gt;packed&lt;/code&gt;, &lt;code&gt;tpm&lt;/code&gt;, &lt;code&gt;android-key&lt;/code&gt;, &lt;code&gt;android-safetynet&lt;/code&gt;, &lt;code&gt;fido-u2f&lt;/code&gt;, &lt;code&gt;apple&lt;/code&gt;, and &lt;code&gt;none&lt;/code&gt;. Each is one option a relying party can require, accept, or ignore.&lt;/p&gt;

The mechanism by which a WebAuthn registration ceremony optionally produces a signature over the new credential&apos;s public key (and `authenticatorData` containing the `rpIdHash`), chained to a vendor or platform root. The relying party validates the chain to establish that the new credential&apos;s private key is held by a specific authenticator model or certification level. Attestation is distinct from authentication; attestation runs once at registration, authentication runs every sign-in. The WebAuthn `attestation` parameter on registration controls whether the RP asks for an attestation statement at all (values: `none`, `indirect`, `direct`, `enterprise`).
&lt;p&gt;The table below summarises what each format teaches the relying party.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;What the RP verifies&lt;/th&gt;
&lt;th&gt;Trust anchor required&lt;/th&gt;
&lt;th&gt;Criterion strengthened&lt;/th&gt;
&lt;th&gt;Current adoption&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;packed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Signature over &lt;code&gt;authenticatorData || clientDataHash&lt;/code&gt; by batch attestation key or self-attestation key&lt;/td&gt;
&lt;td&gt;Vendor X.509 cert chain or none (self)&lt;/td&gt;
&lt;td&gt;Verifier-compromise (model identity), optional anti-fraud&lt;/td&gt;
&lt;td&gt;Default for most CTAP2 keys; dominant in production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tpm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TPM 2.0 &lt;code&gt;TPM2_Certify&lt;/code&gt;-style quote over the new credential public key&lt;/td&gt;
&lt;td&gt;AIK / EK chain to TPM vendor root&lt;/td&gt;
&lt;td&gt;Verifier-compromise + device-bound storage&lt;/td&gt;
&lt;td&gt;Windows platform-bound passkeys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;android-key&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Android Keystore attestation chain&lt;/td&gt;
&lt;td&gt;Google-rooted hardware-attestation CA&lt;/td&gt;
&lt;td&gt;Verifier-compromise + StrongBox / TEE residency&lt;/td&gt;
&lt;td&gt;Android platform passkeys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;android-safetynet&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SafetyNet API-derived attestation token&lt;/td&gt;
&lt;td&gt;Google SafetyNet CA&lt;/td&gt;
&lt;td&gt;Legacy; declining&lt;/td&gt;
&lt;td&gt;Legacy Android; SafetyNet deprecation announced June 2022; migration deadline end of January 2024; complete shutdown end of January 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fido-u2f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ECDSA P-256 signature with vendor X.509 cert&lt;/td&gt;
&lt;td&gt;Vendor U2F-era cert&lt;/td&gt;
&lt;td&gt;Verifier-compromise (legacy)&lt;/td&gt;
&lt;td&gt;Legacy U2F-era hardware keys; declining&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;apple&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Anonymous Apple-issued attestation chain&lt;/td&gt;
&lt;td&gt;Apple anonymous-attestation CA&lt;/td&gt;
&lt;td&gt;Verifier-compromise without device de-anonymisation&lt;/td&gt;
&lt;td&gt;Apple platform passkeys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;none&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No attestation; credential public key plus AAGUID only&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;The default for synced-passkey consumer flows&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;A few of these deserve a paragraph each.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;packed&lt;/code&gt;&lt;/strong&gt; is the spec default and the most widely deployed. The authenticator emits one signature over the concatenation of &lt;code&gt;authenticatorData&lt;/code&gt; and a hash of &lt;code&gt;clientDataJSON&lt;/code&gt;, using one of three keys: (a) a per-authenticator-model &lt;em&gt;batch attestation key&lt;/em&gt; whose X.509 chain anchors to the vendor&apos;s attestation root (the privacy-vs-anti-fraud trade-off -- the cert reveals the device model, but not which specific user owns which device); (b) an &lt;em&gt;Anonymisation CA&lt;/em&gt; or Enterprise Attestation key, which lets a managed enterprise distinguish its own devices without leaking that information to consumer relying parties; or (c) a &lt;em&gt;self-attestation&lt;/em&gt; key derived from the credential itself, which proves only that the private key signs and makes no identity claim.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;tpm&lt;/code&gt;&lt;/strong&gt; is the format the Windows platform authenticator emits when the user has a TPM 2.0. The signing object is a TPM &lt;code&gt;TPM2_Quote&lt;/code&gt;-style structure with the TPM&apos;s Attestation Identity Key (AIK), chained back to the TPM vendor&apos;s Endorsement Key (EK) root certificate. This is the most cryptographically opinionated attestation in the registry: it proves the credential is held by a specific TPM vendor&apos;s part. The Windows TPM article in this series walks the AIK / EK chain end to end.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;apple&lt;/code&gt;&lt;/strong&gt; is Apple&apos;s anonymous-attestation design. The X.509 chain ends in an Apple anonymous-attestation CA; cryptographically the relying party can verify the cert chain back to Apple&apos;s root, but the cert itself is engineered to not reveal the user&apos;s specific device. This is the privacy-vs-anti-fraud trade-off resolved in favour of privacy: a relying party gets &quot;this came from a real Apple device&quot; without learning &lt;em&gt;which&lt;/em&gt; Apple device.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;android-safetynet&lt;/code&gt;&lt;/strong&gt; is the legacy format that lots of installed-base Android passkeys still use. Google announced the SafetyNet Attestation API&apos;s deprecation in June 2022 in favour of Play Integrity; the migration deadline was extended to end of January 2024, with complete shutdown landing end of January 2025 [@android-safetynet-deprecation]. Any new Android passkey registered in 2025 or later uses &lt;code&gt;android-key&lt;/code&gt; or &lt;code&gt;none&lt;/code&gt; instead. Relying parties with old &lt;code&gt;android-safetynet&lt;/code&gt; credentials in their database must accept both formats during the transition window; new credentials use the new path.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;fido-u2f&lt;/code&gt;&lt;/strong&gt; is the U2F-era legacy format, descended directly from the December 2014 U2F design [@fido-u2f-overview]. ECDSA P-256 signing key plus a vendor X.509 cert. Modern keys still emit it for U2F-mode CTAP1 ceremonies, but every modern CTAP2 ceremony uses &lt;code&gt;packed&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;none&lt;/code&gt;&lt;/strong&gt; is the most-deployed format in &lt;em&gt;consumer&lt;/em&gt; flows -- and the recommended default for any relying party that does not have a specific anti-fraud requirement. The RP asks for &lt;code&gt;attestation: &quot;none&quot;&lt;/code&gt;; the authenticator returns just the credential public key and the AAGUID, with no signature chain. The privacy benefit is real: attestation deanonymises the user&apos;s device by model, and a relying party that does not need that information should not collect it. The 2024-2026 best practice is &lt;code&gt;attestation: &quot;none&quot;&lt;/code&gt; for consumer passkey flows. NIST SP 800-63B-4 (final) inherits this caution [@sp80063b4-html].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Use &lt;code&gt;attestation: &quot;none&quot;&lt;/code&gt; for consumer flows; the privacy cost of &lt;code&gt;direct&lt;/code&gt; outweighs the anti-fraud benefit for low-value accounts. Use &lt;code&gt;attestation: &quot;direct&quot;&lt;/code&gt; only when (a) you have a documented anti-fraud requirement, (b) you can verify the chain against the FIDO Metadata Service, and (c) you accept that the cert reveals the authenticator model. Use &lt;code&gt;attestation: &quot;enterprise&quot;&lt;/code&gt; only inside a managed enterprise where the user&apos;s device is corporately enrolled.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;All seven formats assume the authenticator is &lt;em&gt;on the same device&lt;/em&gt; as the browser. What happens when it isn&apos;t?&lt;/p&gt;
&lt;h2&gt;12. Hybrid transport: a phone authenticator for a laptop browser&lt;/h2&gt;
&lt;p&gt;A user on a borrowed Windows laptop with no Windows passkey signs in to their bank by scanning a QR code with their iPhone. The phone is the authenticator. The laptop is the WebAuthn client. The protocol that ties them together is &lt;em&gt;hybrid transport&lt;/em&gt;, formerly known as caBLE (Cloud-Assisted Bluetooth Low Energy), standardised in W3C WebAuthn Level 3 §6.3.3 [@webauthn-l3-cr].&lt;/p&gt;

A WebAuthn transport in which a roaming authenticator (typically a mobile phone) cooperates with a WebAuthn client on a nearby device (typically a laptop) via three concurrent channels: an out-of-band channel (QR code) for one-time setup, BLE for proximity, and HTTPS to a discoverable cloud tunnel relay for the actual ceremony bytes. The cryptographic binding is an ephemeral ECDH key exchanged through the QR code; the BLE proves proximity, not identity; the tunnel relay carries the encrypted ceremony [@webauthn-l3-cr-dated].
&lt;p&gt;The ceremony, simplified: the laptop&apos;s browser asks the user to use a phone, generates an ephemeral ECDH keypair, and renders a QR code containing the Tunnel Service URL the phone should connect to, the laptop&apos;s ephemeral public key, and a derived HMAC key. The phone&apos;s camera scans the QR code and derives a shared secret with the laptop via ECDH. The phone then advertises its presence over BLE, the laptop listens for the BLE beacon to confirm physical proximity, and both endpoints connect to the Tunnel Service URL over HTTPS. From that point on, the laptop and the phone exchange CTAP2 ceremony messages, encrypted under the ECDH-derived key, through the tunnel relay. The phone produces a WebAuthn assertion locally using whatever authenticator is on the phone (the Secure Enclave on iPhone, the Android Keystore on Android), encrypts it for the laptop, and the laptop forwards it to the relying party.&lt;/p&gt;

sequenceDiagram
    participant U as User
    participant L as Laptop browser
    participant P as Phone authenticator
    participant T as Tunnel Service
    participant R as Relying Party
    L-&amp;gt;&amp;gt;R: navigator.credentials.get
    R-&amp;gt;&amp;gt;L: PublicKeyCredentialRequestOptions
    L-&amp;gt;&amp;gt;L: generate ephemeral ECDH keypair
    L-&amp;gt;&amp;gt;U: display QR code (tunnel URL, ephem pubkey, HMAC seed)
    U-&amp;gt;&amp;gt;P: scan QR code
    P-&amp;gt;&amp;gt;P: derive shared secret via ECDH
    P-&amp;gt;&amp;gt;L: BLE advertisement (proximity proof)
    L-&amp;gt;&amp;gt;L: confirm BLE advertisement
    P-&amp;gt;&amp;gt;T: HTTPS connect to tunnel URL
    L-&amp;gt;&amp;gt;T: HTTPS connect to tunnel URL
    T-&amp;gt;&amp;gt;L: relay encrypted CTAP2 traffic
    T-&amp;gt;&amp;gt;P: relay encrypted CTAP2 traffic
    P-&amp;gt;&amp;gt;U: prompt for user verification
    U-&amp;gt;&amp;gt;P: present gesture
    P-&amp;gt;&amp;gt;P: produce WebAuthn assertion (origin-bound)
    P-&amp;gt;&amp;gt;T: encrypted assertion
    T-&amp;gt;&amp;gt;L: encrypted assertion
    L-&amp;gt;&amp;gt;R: assertion
    R-&amp;gt;&amp;gt;U: signed in
&lt;p&gt;The criterion-table consequence is precise. Phishing resistance is preserved because the &lt;em&gt;origin&lt;/em&gt; in &lt;code&gt;clientDataJSON&lt;/code&gt; is the laptop&apos;s actual browser origin, which the phone signs over the same way it would for its own browser. The QR code is the cryptographic binding, not the BLE advertisement; the BLE advertisement is a proximity signal that proves the phone is physically near the laptop, but it does not authenticate the phone. The Tunnel Service is a &lt;em&gt;relay&lt;/em&gt;, not a trust anchor; even if the tunnel were compromised, the encrypted ceremony bytes would be unreadable without the ECDH-derived key.&lt;/p&gt;
&lt;p&gt;The design is attributed in the WebAuthn L3 spec to the W3C WebAuthn-3 editor masthead -- Jeff Hodges, J.C. Jones, Michael B. Jones, Akshay Kumar, and Emil Lundberg as current editors, with Dirk Balfanz as a previous editor [@wiki-webauthn]. The original caBLE design and the L3 §6.3.3 productisation were led by Google&apos;s Chrome security and Android Identity teams; the canonical reference is W3C WebAuthn Level 3 §6.3.3 itself.&lt;/p&gt;
&lt;p&gt;Hybrid transport is the only competitor to the Windows platform authenticator that involves no Windows-side credential storage. The Windows laptop holds nothing -- no key, no recovery state, no cached credential. Every ceremony round-trips to the phone. This is the use case the bank-on-a-borrowed-laptop story illustrates: you can sign in to your accounts on a machine you do not own without leaving a credential behind.&lt;/p&gt;
&lt;p&gt;How do other authentication approaches score on the criteria framework?&lt;/p&gt;
&lt;h2&gt;13. Competing approaches scored against the criteria&lt;/h2&gt;
&lt;p&gt;The criteria-framework table makes the competitive field legible. Five rows, six competing columns: password alone, password plus SMS-OTP, password plus TOTP, password plus push with number matching, smart card / PIV, and device-bound or synced passkey. The NIST SP 800-63B-4 AAL grading [@sp80063b4-html] and the NIST syncable-authenticator supplement [@sp80063sup1] anchor the right edge of the table; Yubico&apos;s commentary corroborates the dichotomy between device-bound (AAL3) and synced (AAL2) passkeys [@yubico-nist-guidance].&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criterion&lt;/th&gt;
&lt;th&gt;Password&lt;/th&gt;
&lt;th&gt;Password + SMS-OTP&lt;/th&gt;
&lt;th&gt;Password + TOTP&lt;/th&gt;
&lt;th&gt;Password + Push (number match)&lt;/th&gt;
&lt;th&gt;Smart Card / PIV&lt;/th&gt;
&lt;th&gt;Device-bound passkey&lt;/th&gt;
&lt;th&gt;Synced passkey&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Phishing resistance&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None (AitM relays the OTP)&lt;/td&gt;
&lt;td&gt;None (AitM relays the TOTP)&lt;/td&gt;
&lt;td&gt;Partial (number match defeats most kits)&lt;/td&gt;
&lt;td&gt;Strong (origin-bound via TLS client auth)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Strong&lt;/strong&gt; (&lt;code&gt;rpId&lt;/code&gt; binding)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Strong&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verifier-compromise resistance&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None (SMS infra leaks)&lt;/td&gt;
&lt;td&gt;Partial (TOTP seed on server)&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Strong (public-key only)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Strong&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Strong&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replay / relay resistance&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Weak (OTP relay in 30-60 s)&lt;/td&gt;
&lt;td&gt;Weak (TOTP relay in 30 s)&lt;/td&gt;
&lt;td&gt;Strong (number match per challenge)&lt;/td&gt;
&lt;td&gt;Strong (per-handshake nonce)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Strong&lt;/strong&gt; (challenge + counter)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Strong&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Step-up / continuity&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Strong (PIN re-prompt)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Strong&lt;/strong&gt; (&lt;code&gt;UV=1&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Strong&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recovery floor&lt;/td&gt;
&lt;td&gt;Reset via SMS&lt;/td&gt;
&lt;td&gt;SMS-OTP all the way down&lt;/td&gt;
&lt;td&gt;TOTP seed reset via SMS&lt;/td&gt;
&lt;td&gt;SMS / password&lt;/td&gt;
&lt;td&gt;Admin re-issue&lt;/td&gt;
&lt;td&gt;RP-dependent backup key&lt;/td&gt;
&lt;td&gt;Sync-fabric recovery (Recovery Key + Recovery Contact)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NIST AAL ceiling&lt;/td&gt;
&lt;td&gt;AAL1&lt;/td&gt;
&lt;td&gt;AAL2 nominal (SMS-OTP RESTRICTED in 800-63-3 [@nist-sp80063-3-final]; deprecated in 800-63-4 [@sp80063-4-final])&lt;/td&gt;
&lt;td&gt;AAL2&lt;/td&gt;
&lt;td&gt;AAL2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;AAL3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;AAL3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;AAL2&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Push MFA needs a paragraph of nuance. Vanilla push -- &quot;tap to approve&quot; -- is phishable by default because the attacker can simply trigger the push at the moment they have the password, and a fatigued user taps. Number matching (the user types a code shown on the laptop into the phone, or vice versa) defeats most kits because it ties the push to a specific session. &lt;em&gt;Location binding&lt;/em&gt; (the push is rejected unless the phone is geographically near the laptop) adds another layer. The net is &quot;partial&quot; phishing resistance -- much better than vanilla push, not as strong as origin binding.&lt;/p&gt;
&lt;p&gt;Smart cards and PIV deserve their own paragraph because they are not historically associated with WebAuthn but score well on the criteria. A PIV card with a PIN provides strong phishing resistance via TLS client authentication (origin-bound at the TLS layer), strong verifier-compromise resistance via the public-key model, and strong replay resistance via per-handshake nonces. The weakness is &lt;em&gt;recovery&lt;/em&gt;: a lost card requires an administrative reissue, which scales poorly for consumer flows. The companion &lt;em&gt;App Identity in Windows&lt;/em&gt; article in this series walks the Windows smart-card stack end to end.&lt;/p&gt;
&lt;p&gt;OATH-TOTP is interesting in the criteria table because it is phishing-vulnerable by construction. The TOTP code is the same on the legitimate origin and the look-alike; the AitM kit forwards the code through. Google Authenticator&apos;s cloud-sync feature additionally broke the verifier-compromise property in a subtle way: if the user&apos;s Google account is compromised, the synced TOTP seeds give the attacker a complete second-factor toolkit [@google-auth-sync-2023].&lt;/p&gt;
&lt;p&gt;SAML and OIDC federation are not competitors to WebAuthn in the criteria table -- they are &lt;em&gt;transport layers above&lt;/em&gt; WebAuthn. A SAML or OIDC identity provider does the WebAuthn ceremony for the user; the IdP then issues a SAML assertion or an OIDC ID token to the relying party. WebAuthn underneath is the strong primitive; SAML and OIDC are the enterprise transport for the resulting assertions.&lt;/p&gt;
&lt;p&gt;WebAuthn wins decisively on four of five rows. What&apos;s left in row five? The recovery row.&lt;/p&gt;
&lt;h2&gt;14. Theoretical limits: the corners WebAuthn cannot reach&lt;/h2&gt;
&lt;p&gt;Even with everything from §§4-12 in place, WebAuthn has corners it cannot defend. The relevant impossibility results are well-known in the protocol literature; they are worth naming because they tell a practitioner where defence-in-depth has to come from.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Coerced consent.&lt;/strong&gt; WebAuthn cannot distinguish a willing user from a coerced one. The protocol&apos;s only signal is &quot;the user performed the gesture&quot; -- a fingerprint, a PIN, a face match. No protocol whose only observable is gesture completion can tell whether the user was free at the moment of the gesture. NIST SP 800-63B-4 does not classify physical coercion among the attacks it defends against [@sp80063b4-html]; this is a general impossibility, not a WebAuthn-specific weakness.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A user under duress can be made to present a gesture. WebAuthn cannot detect this. The compensating control is &lt;em&gt;transactional&lt;/em&gt; -- step-up authentication with a fresh challenge for high-value actions, and out-of-band confirmation for transactions above a risk threshold. The protocol cannot solve coercion; the application layer must.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Kernel-level malware on the client.&lt;/strong&gt; Malware with kernel privilege on the user&apos;s device can race the legitimate user. If the malware can call into &lt;code&gt;webauthn.dll&lt;/code&gt; and trigger a Hello UV prompt the user blindly approves, it can extract assertions. The mitigation is TPM-bound keys plus the Hello ESS trustlet (covered in the companion &lt;em&gt;Windows Hello&lt;/em&gt; and &lt;em&gt;Credential Guard&lt;/em&gt; articles), not WebAuthn itself. WebAuthn protects against &lt;em&gt;network&lt;/em&gt; attackers; defending against a kernel-mode attacker on the same device requires the OS&apos;s secure-kernel architecture.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sync-fabric compromise.&lt;/strong&gt; Compromise of Apple iCloud, Google account recovery, or Microsoft&apos;s recovery-key service effectively compromises every passkey held there. Apple&apos;s Advanced Data Protection model [@apple-adp-kb] is the strongest currently-shipped consumer realisation of the end-to-end-encrypted sync invariant, and even it depends on the user retaining their Recovery Contact or Recovery Key in some form. The NIST April 2024 supplement classifies synced passkeys at AAL2 for exactly this reason: the private key leaves the original authenticator [@sp80063sup1]. Yubico&apos;s commentary makes the practitioner consequence explicit: device-bound is AAL3, synced is AAL2 [@yubico-nist-guidance].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Username enumeration and discoverable-credential privacy.&lt;/strong&gt; Discoverable credentials let an authenticator answer &quot;do you have a credential for this &lt;code&gt;rpId&lt;/code&gt;?&quot; without further information. A relying party that asks the question maliciously can enumerate which of its users have set up a passkey. The &lt;code&gt;credProtect&lt;/code&gt; extension introduced in CTAP 2.1 [@ctap-2-1-ps] requires &lt;code&gt;UV=1&lt;/code&gt; to even list the credential, which closes most of the leak; it is not universally deployed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Counter-regression false positives on synced passkeys.&lt;/strong&gt; The per-credential signature counter is per-authenticator. A passkey synced across two devices will see the counter desynchronise between them. WebAuthn L3 §6.1.1 explicitly permits a &lt;em&gt;zero-counter&lt;/em&gt; for synced passkeys; relying parties that treat any counter regression as evidence of cloning will produce false positives. Treat counter regression as evidence of cloning &lt;em&gt;only&lt;/em&gt; for &lt;code&gt;BS=0&lt;/code&gt; (device-bound) credentials. This is a deployment foot-gun, not a protocol flaw.&lt;/p&gt;

flowchart LR
    A[rpId binding / origin in clientDataJSON] --&amp;gt; P[Phishing resistance]
    B[Public-key model / no shared secret] --&amp;gt; V[Verifier-compromise resistance]
    C[Per-RP challenge + signCount + BS=0] --&amp;gt; RR[Replay / relay resistance]
    D[UP and UV flags + freshness] --&amp;gt; S[Step-up / continuity]
    E[BE / BS flags + sync fabric] --&amp;gt; AV[Availability]
    F[Recovery Key + Recovery Contact] --&amp;gt; RC[Recovery]
    G[TPM 2.0 / hardware secure element] --&amp;gt; AAL[AAL3 device-bound]
    H[End-to-end encrypted sync fabric] --&amp;gt; AAL2[AAL2 synced]
&lt;p&gt;These are the &lt;em&gt;protocol&lt;/em&gt; limits. The biggest practical limit is one the protocol cannot fix at all -- recovery. The protocol can specify what factor produces the credential at sign-in; it cannot specify what factor produces the credential when the original one is lost. That is the application-layer question every relying party answers differently, and it is the question §17 will land on.&lt;/p&gt;
&lt;h2&gt;15. Open problems: what&apos;s still moving in late 2025 / early 2026&lt;/h2&gt;
&lt;p&gt;Standardisation is not done. Several major surfaces are still in active draft.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WebAuthn Level 3&lt;/strong&gt; is currently a W3C Candidate Recommendation [@webauthn-l3-cr]; the dated CR snapshot is 13 January 2026 [@webauthn-l3-cr-dated]. The expected progression is Candidate Recommendation to Proposed Recommendation to Recommendation through 2026, with no major spec-breaking changes expected at this point in the process. The active editor masthead is Hodges, J.C. Jones, M.B. Jones, Kumar, and Lundberg [@wiki-webauthn].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CTAP 2.2&lt;/strong&gt; is a FIDO Proposed Standard as of 14 July 2025 [@ctap-2-2-ps]; &lt;strong&gt;CTAP 2.3&lt;/strong&gt; is also listed at FIDO&apos;s specifications download page [@fido-specs-download]. The 2.2 and 2.3 revisions refine hybrid transport, &lt;code&gt;credProtect&lt;/code&gt;, and PIN-protocol handling without breaking 2.1&apos;s command-byte table.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cross-vendor passkey portability.&lt;/strong&gt; The FIDO Alliance &lt;em&gt;Credential Exchange Protocol&lt;/em&gt; (CXP) and &lt;em&gt;Credential Exchange Format&lt;/em&gt; (CXF) Working Drafts, dated 3 October 2024 [@fido-cxp-wd], are the standards effort. The draft text identifies the problem: &quot;the transfer of credentials between two different providers has traditionally been an infrequent occurrence... As it becomes more common for users to have multiple credential providers that they use to create [and] manage credentials, it becomes important to address some of the security concerns with regard to migration&quot; [@fido-cxp-wd]. Apple has signalled CXP-based import for iOS; Bitwarden has signalled support. The likely 2026 trajectory is CXP becoming a Proposed Standard and Windows / Android / iOS implementing it as the OS-level import-export passkeys surface.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Transactional authorisation.&lt;/strong&gt; The earliest WebAuthn drafts included &lt;code&gt;txAuthSimple&lt;/code&gt; and &lt;code&gt;txAuthGeneric&lt;/code&gt; extensions [@webauthn-fpwd]; neither was ever implemented by browsers, and both are absent from L3. The productised path is Secure Payment Confirmation (a sibling spec to WebAuthn), but it covers only payment transactions. General &quot;sign a description of &lt;em&gt;this transaction&lt;/em&gt;&quot; remains an open problem. Conjecture: payment-confirmation becomes the template that gets generalised in WebAuthn Level 4.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Quantum-safe attestation.&lt;/strong&gt; The IANA COSE algorithm registry (last updated 2026-03-04) currently has no PQC algorithm in WebAuthn-recommended status [@iana-cose-registry]. ECDSA P-256, EdDSA Ed25519, RSA-PKCS1.5, and RSA-PSS are the registered options, all quantum-breakable in principle. A long-lived TPM AIK signed today is forgeable to a quantum-capable adversary at any future date. The companion &lt;em&gt;Post-Quantum Cryptography on Windows&lt;/em&gt; article in this series walks the algorithm-side rollout; the WebAuthn deployment side is open. The most plausible trajectory is ML-DSA (FIPS 204) entering the WebAuthn COSE registry by 2027 and existing TPM AIKs receiving a parallel ML-DSA enrolment.&lt;/p&gt;
&lt;p&gt;Standards are still moving. What should a practitioner do &lt;em&gt;today&lt;/em&gt;?&lt;/p&gt;
&lt;h2&gt;16. Practical guide: what to do this week&lt;/h2&gt;
&lt;p&gt;Six pieces of operational advice, each tied to a primary source.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Windows developers: use &lt;code&gt;webauthn.dll&lt;/code&gt;, do not roll your own.&lt;/strong&gt; The Win32 reference at &lt;code&gt;learn.microsoft.com/en-us/windows/win32/api/webauthn/&lt;/code&gt; [@ms-learn-win32-webauthn] is the only surface you should be calling. The OS handles USB-HID, NFC, BLE, hybrid transport, Conditional Mediation, plug-in dispatch, and Windows Hello UV in one call. The header is at &lt;code&gt;github.com/microsoft/webauthn&lt;/code&gt; [@github-ms-webauthn]; the Microsoft Learn overview is at &lt;code&gt;learn.microsoft.com/.../hello-for-business/webauthn-apis&lt;/code&gt; [@ms-learn-webauthn-apis].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Relying parties: default to &lt;code&gt;attestation: &quot;none&quot;&lt;/code&gt;, &lt;code&gt;userVerification: &quot;required&quot;&lt;/code&gt;, &lt;code&gt;residentKey: &quot;preferred&quot;&lt;/code&gt;.&lt;/strong&gt; This is the 2024-2026 consumer-flow baseline. &lt;code&gt;attestation: &quot;none&quot;&lt;/code&gt; preserves user privacy and interoperates with every authenticator type. &lt;code&gt;userVerification: &quot;required&quot;&lt;/code&gt; forces &lt;code&gt;UV=1&lt;/code&gt; and the gesture acquisition. &lt;code&gt;residentKey: &quot;preferred&quot;&lt;/code&gt; enables usernameless sign-in on platforms that support it without burning a credential slot on older authenticators that don&apos;t. The Microsoft Entra passwordless documentation [@ms-entra-passwordless] and the WebAuthn Level 3 spec [@webauthn-l3-cr] are the references.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Enterprise IT: device-bound FIDO2 keys for AAL3 (admin, finance, tier 0); synced passkeys for AAL2 workforce.&lt;/strong&gt; NIST SP 800-63B-4 [@sp80063b4-html] formalises the dichotomy via the syncable-authenticator supplement [@sp80063sup1]. Yubico&apos;s enterprise commentary makes the operational point: device-bound passkeys on dedicated hardware are AAL3; synced passkeys are AAL2 [@yubico-nist-guidance]. For admin accounts use FIDO Alliance L3-certified hardware [@fido-certification-levels] -- YubiKey Bio, Feitian BioPass, the Entra-listed vendors at &lt;code&gt;learn.microsoft.com/.../concept-fido2-hardware-vendor&lt;/code&gt; [@ms-entra-fido2-hardware].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Windows 11 24H2 end users: enable third-party passkey providers in Settings.&lt;/strong&gt; Settings -&amp;gt; Accounts -&amp;gt; Passkeys -&amp;gt; Advanced options. Toggle the provider on for any vendor you trust (1Password, Bitwarden, Dashlane) [@ms-windev-passkeys-blog]. The Microsoft Learn third-party tutorial walks the flow [@ms-learn-thirdparty]. If you do not use a third-party vault, the Microsoft synced passkey provider is enabled by default on 24H2 systems signed in with a Microsoft Account.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. Security architects: write down your recovery flow first.&lt;/strong&gt; Score it against the five-axis criteria table from §2 before you design the authentication factors. The recovery row&apos;s strength is the system&apos;s ceiling, not the floor; the authentication ceremony cannot raise it. Microsoft Entra&apos;s own guidance flags account recovery as a deployment risk: FIDO2 keys &quot;can increase costs for equipment, training, and helpdesk support -- especially when users lose their physical keys and need account recovery&quot; [@ms-entra-passwordless]. §17 lands this argument.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. Incident responders: collect ETW events from the WebAuthn provider.&lt;/strong&gt; Plug-in authenticator registration events on managed devices are a high-signal indicator -- a newly enrolled &lt;code&gt;IPluginAuthenticator&lt;/code&gt; on a privileged user&apos;s machine should be treated as a credential-store change requiring review. The companion &lt;em&gt;ETW on Windows&lt;/em&gt; article in this series walks the WebAuthn provider events end to end.&lt;/p&gt;

Open PowerShell as the signed-in user (no admin needed for your own credentials) and call into the `webauthn.dll` `WebAuthNGetPlatformCredentialList` API via a managed wrapper, or use the Settings -&amp;gt; Accounts -&amp;gt; Passkeys page directly. There is no first-class `Get-WebAuthnCredential` cmdlet as of Windows 11 25H2; the Settings page is the supported management surface. The Microsoft Learn passkey overview is the canonical reference [@ms-learn-passkeys].
&lt;p&gt;Most of this is engineering. One row of the table has resisted engineering for fifty years. That&apos;s where the article lands.&lt;/p&gt;
&lt;h2&gt;17. Recovery: your weakest factor is always your recovery flow&lt;/h2&gt;
&lt;p&gt;The thesis surfaced in §2 and deferred through twelve sections is the one the article lands on. The argument is direct, almost embarrassingly so: every authentication system that admits any external recovery primitive is, in the formal sense, at most as strong as that primitive. Strong authentication ceremonies coexist with weaker recovery ceremonies in every consumer platform in production, and the &lt;em&gt;system&apos;s&lt;/em&gt; assurance level is the minimum of the two, not the maximum.&lt;/p&gt;

*Your weakest factor is always your recovery flow.*
&lt;p&gt;To make the claim concrete, score every major platform&apos;s recovery flow against the same five-axis criteria table.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Apple iCloud Keychain (with Advanced Data Protection).&lt;/strong&gt; Apple&apos;s published model has three recovery primitives [@apple-adp-kb]: (a) a &lt;em&gt;trusted device&lt;/em&gt; the user previously signed into; (b) an &lt;em&gt;iCloud Recovery Contact&lt;/em&gt; -- another Apple ID owner the user has nominated to attest their identity; and (c) an &lt;em&gt;iCloud Recovery Key&lt;/em&gt; -- a 28-character string the user must retain [@apple-recovery-key]. Apple&apos;s published architecture is the strongest current consumer realisation of the end-to-end-encrypted invariant: the recovery primitives unlock an HSM-backed escrow cluster that holds the user&apos;s iCloud Keychain encryption material, but Apple itself does not hold the keys in plaintext. The fundamental dependency is the Apple ID password plus, originally, SMS-OTP at device-trust establishment.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Google Password Manager (with Google Account end-to-end encrypted passkey sync).&lt;/strong&gt; Trusted-device fallback, security-key fallback, recovery code, recovery phone, recovery email. The recovery floor reduces, in the worst case, to SMS-OTP via the recovery phone. Google&apos;s architecture is end-to-end encrypted in the steady state but the trust establishment depends on Google account recovery, which depends on out-of-band verification primitives the user enrolled at account creation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Microsoft Account.&lt;/strong&gt; The October 2024 Windows Developer Blog states the recovery primitive verbatim: &quot;you will be prompted to save a recovery key that will be used to verify your identity and protect your passkeys through end-to-end encryption&quot; [@ms-windev-passkeys-blog]. The recovery key is a high-entropy string the user retains; if they lose it, the recovery flow falls back to the secondary factors the user enrolled (alternate email or SMS-OTP via the recovery phone). As with Google, the worst-case recovery floor is the weakest of the secondary factors the user enrolled.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Microsoft Entra ID (enterprise).&lt;/strong&gt; Entra&apos;s Temporary Access Pass (TAP) is the strongest enterprise recovery primitive currently shipped: an administrator issues a time-bound passwordless TAP that the user redeems to bootstrap a new authenticator. TAP is stronger than consumer flows because of &lt;em&gt;accountability&lt;/em&gt; -- the admin&apos;s identity is on the issuance -- but weaker than the authentication ceremony itself because the admin is socially engineerable. Microsoft documents the TAP issuance and redemption flow in detail [@ms-entra-tap].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1Password, Bitwarden, Dashlane under the 24H2 plug-in model.&lt;/strong&gt; Each vendor&apos;s master password and secondary recovery primitive becomes the &lt;em&gt;de facto&lt;/em&gt; floor of the entire passkey ceremony when the plug-in is the credential store. 1Password&apos;s master password plus Secret Key, Bitwarden&apos;s master password plus 2FA recovery code, and Dashlane&apos;s device trust plus master password -- each is the recovery floor for every passkey the vault holds. The Microsoft Learn third-party tutorial reinforces the warning, in context: &quot;Contoso Passkey Manager is designed for passkey creation and usage testing only. Don&apos;t use the app for production passkeys&quot; [@ms-learn-thirdparty].&lt;/p&gt;

flowchart TD
    A[Apple iCloud Keychain ADP] --&amp;gt; A1[Recovery Contact]
    A --&amp;gt; A2[Recovery Key 28 chars]
    A --&amp;gt; A3[Trusted device]
    A3 --&amp;gt; A4[Apple ID password + SMS-OTP at trust establishment]
    B[Google Password Manager] --&amp;gt; B1[Recovery code]
    B --&amp;gt; B2[Recovery phone]
    B --&amp;gt; B3[Recovery email]
    B2 --&amp;gt; B4[SMS-OTP]
    C[Microsoft Account] --&amp;gt; C1[Recovery Key]
    C --&amp;gt; C3[Alternate email]
    C --&amp;gt; C4[Recovery phone -&amp;gt; SMS-OTP]
    D[Entra ID enterprise] --&amp;gt; D1[Temporary Access Pass]
    D1 --&amp;gt; D2[Admin: socially engineerable]
    E[1Password / Bitwarden / Dashlane vault] --&amp;gt; E1[Master password + Secret Key / 2FA recovery code]
    A4 --&amp;gt; Z[Weak shared-knowledge or SMS-OTP floor]
    B4 --&amp;gt; Z
    C4 --&amp;gt; Z
    D2 --&amp;gt; Z
    E1 --&amp;gt; Z
&lt;p&gt;The diagram looks busy because it is. Every major platform&apos;s recovery flow is a different combination of trusted-device fallback, recovery code or key, recovery contact, and an out-of-band primitive (SMS-OTP, email, or admin attestation). Every one of those out-of-band primitives is weaker than origin-bound public-key cryptography. The cryptographic ceremony scores AAL3 phishing-resistant at the authentication moment; the recovery primitive scores AAL1 or AAL2 at the recovery moment. &lt;em&gt;The system&apos;s AAL is the minimum.&lt;/em&gt;&lt;/p&gt;

NIST SP 800-63B-4&apos;s AAL2 / AAL3 split makes the recovery story explicit. Section 5.1 of SP 800-63B-4 enumerates permitted recovery primitives; every one is at most as strong as its underlying factor. The April 2024 supplement [@sp80063sup1] caps synced passkeys at AAL2 because the long-term private key has left the original authenticator -- the same logic that caps the recovery row applies to the sync fabric. Auditors who care about AAL3 for tier-zero accounts will require *both* a device-bound authenticator and a documented recovery flow whose own strength is at AAL3. The current best-practice composition is two device-bound hardware authenticators in different physical locations, each registered as primary for the other&apos;s recovery.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Every passkey platform in production in 2026 -- Apple, Google, Microsoft, Entra, 1Password, Dashlane, Bitwarden -- bottoms out, in its recovery flow, in some combination of trusted-device fallback and SMS-OTP-equivalent shared knowledge. That floor is the AAL ceiling for the entire system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The protocol literature has been clear about this for fifty years and the regulatory literature has been catching up since 2017. NIST SP 800-63-3 introduced &quot;phishing-resistant authenticator&quot; as a first-class term; SP 800-63-4 (2025) [@sp80063-4-final] makes verifier-impersonation resistance a normative criterion. Neither standard solves recovery; both standards explicitly enumerate what counts as a recovery primitive without specifying how to &lt;em&gt;compose&lt;/em&gt; them into an AAL-graded flow. There is no IETF or FIDO Alliance standard that says &quot;here is a recovery flow whose strength is AAL3.&quot; There may never be -- recovery is application-specific, and the only general protocol is &quot;social attestation&quot; (multiple human witnesses), which does not scale.&lt;/p&gt;
&lt;p&gt;The same WebAuthn ceremony that scores AAL3 phishing-resistant at the authentication moment can be a single-factor SMS-OTP at the recovery moment. &lt;em&gt;Your weakest factor is always your recovery flow.&lt;/em&gt; That is the line. It is the line every working security architect should write down, score against, and design recovery against -- &lt;em&gt;before&lt;/em&gt; designing the authentication factors.&lt;/p&gt;
&lt;h2&gt;18. FAQ&lt;/h2&gt;

No. A password is a shared secret -- the user types a string, the server stores a hash of the same string, and an eavesdropper who captures the string in flight or compromises the server&apos;s database has a credential they can replay. A passkey is one half of an asymmetric keypair: the private key lives in the authenticator (TPM, secure enclave, hardware key, or end-to-end-encrypted sync fabric), and only its public key reaches the server. An eavesdropper who captures a passkey ceremony in flight has nothing they can replay; a server-database leak yields public keys that authenticate no one. WebAuthn Level 3 [@webauthn-l3-cr] and the Microsoft Entra &quot;origin-bound public key cryptography&quot; framing [@ms-entra-passwordless] are the references.

Insecure relative to device-bound; secure relative to passwords. The NIST syncable-authenticator supplement (April 2024) [@sp80063sup1] and SP 800-63B-4 (July 2025) [@sp80063b4-html] cap synced passkeys at AAL2, because the long-term private key has left the original authenticator. Device-bound passkeys on dedicated hardware -- &quot;FIDO passkeys that are not synced ... and are properly stored in dedicated hardware have an AAL3 rating&quot; [@yubico-nist-guidance] -- can reach AAL3. The right answer is to use device-bound keys for tier-zero accounts and synced passkeys for the bulk of consumer flows.

Hello *uses* biometrics but provides the *user-verification gesture* for WebAuthn; the credential itself is asymmetric and lives in the TPM. Microsoft Learn states the property verbatim: &quot;The private keys can only be used after they&apos;re unlocked by the user using the Windows Hello unlock factor (biometrics or PIN)&quot; [@ms-learn-passkeys]. The biometric is one mode of the Hello UV gesture, not the credential. If you disable face or fingerprint, your PIN still unlocks the passkey.

No. Attestation is privacy-leaking for synced passkeys; `attestation: &quot;none&quot;` is the 2024-2026 default for consumer flows. Use `attestation: &quot;direct&quot;` only when you have a documented anti-fraud requirement and can verify the chain against the FIDO Metadata Service. Use `attestation: &quot;enterprise&quot;` only inside a managed enterprise where the user&apos;s device is corporately enrolled. The relevant references are WebAuthn Level 2 §§8.2-8.8 [@webauthn-l2-latest] and the IANA WebAuthn registry [@iana-webauthn-registry].

No. The cryptographic binding is the QR-code-encoded ephemeral ECDH key. Bluetooth is a transport and a proximity signal; it is not a trust anchor. The QR code transfers the laptop&apos;s ephemeral public key plus a derived HMAC seed; the phone derives the shared secret via ECDH; the BLE advertisement merely proves the phone is physically close to the laptop. The encrypted CTAP2 ceremony bytes travel over HTTPS through a discoverable tunnel relay. WebAuthn Level 3 §6.3.3 is the normative description [@webauthn-l3-cr].

No. A Windows passkey can be used with PIN-only user verification; the biometric is one mode of the Hello UV gesture, not the credential. The credential is in the TPM, indexed under your Microsoft Account container, and the PIN is one valid unlock factor. If you use a third-party passkey provider via the 24H2 plug-in model, that provider may use its own master password as the UV gesture; the OS still mediates the gesture acquisition through `WebAuthNPluginPerformUserVerification` [@ms-learn-webauthn-apis].

Microsoft cannot see your TPM-sealed Windows Hello private key; the TPM does not expose the raw key material to the OS, let alone to Microsoft. Apple&apos;s iCloud Keychain with Advanced Data Protection [@apple-adp-kb] and Google&apos;s end-to-end-encrypted passkey sync mean the sync provider cannot see the plaintext keys either. *But* the recovery path can still expose them under specific conditions: an attacker who compromises your recovery contact, recovery key, or your account&apos;s out-of-band recovery primitives (SMS-OTP, recovery email) effectively defeats the end-to-end encryption invariant. The plaintext keys are not what gets exfiltrated; the recovery primitives are.
&lt;p&gt;This article is one of a series on Windows authentication primitives. &lt;em&gt;NTLMless: The Death of NTLM in Windows&lt;/em&gt; (2026-05-10) covers the legacy authentication protocol passkeys are displacing. &lt;em&gt;Windows Hello, Demystified&lt;/em&gt; covers the user-verification gesture WebAuthn leans on. &lt;em&gt;Adminless: Administrator Protection in Windows&lt;/em&gt; (2026-05-10) and &lt;em&gt;App Identity in Windows&lt;/em&gt; (2026-05-08) cover the privilege-escalation and code-identity primitives that surround the authentication stack. The companion &lt;em&gt;Kerberos on Windows&lt;/em&gt; (2026-05-11) covers the enterprise transport for the resulting assertions; &lt;em&gt;ETW on Windows&lt;/em&gt; (2026-05-11) covers the telemetry surface for incident responders.&lt;/p&gt;
&lt;p&gt;The Windows passkey stack is the productisation moment for a forty-year-old protocol-literature insight: authentication should be tied to &lt;em&gt;something the network attacker cannot change&lt;/em&gt;. WebAuthn ties it to the origin in &lt;code&gt;clientDataJSON&lt;/code&gt;, signed by a credential whose private key never reaches the wire. Windows 10 1903 made it a Win32 surface; Windows 11 24H2 made it a plug-in surface; Authenticate 2024 made it a default. The protocol bytes are FIDO2; the consumer experience is autofill. The Windows part is the dispatcher between them.&lt;/p&gt;
&lt;p&gt;The criteria framework is the diagnostic kit. Use it on every authentication system you ship. Score it against five axes, not three. Write down the recovery flow first. Match the authentication ceremony to the recovery flow you can actually defend. And remember the line: &lt;em&gt;your weakest factor is always your recovery flow.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;webauthn-and-passkeys-on-windows-from-ctap-to-the-credential-provider-model&quot; keyTerms={[
  { term: &quot;Phishing-resistant authenticator&quot;, definition: &quot;An authenticator whose protocol prevents a relying party impersonator from inducing the authenticator to release a usable credential value. NIST SP 800-63B-4 calls this verifier-impersonation resistance.&quot; },
  { term: &quot;Origin binding&quot;, definition: &quot;The mechanism by which WebAuthn enforces phishing resistance: the browser writes the origin into clientDataJSON; the authenticator signs over the SHA-256 hash of the canonical rpId; the RP rejects any signature whose rpIdHash does not match the registered rpId.&quot; },
  { term: &quot;rpId&quot;, definition: &quot;A string identifying the WebAuthn relying party for credential scoping. Must be a registrable suffix of the page&apos;s origin. All WebAuthn signatures are made over its SHA-256 hash.&quot; },
  { term: &quot;CTAP 2.x&quot;, definition: &quot;The Client-to-Authenticator Protocol: the wire format browser to roaming authenticator over USB-HID, NFC, or BLE. CTAP1 is APDU-based; CTAP2 is CBOR-based. Modern keys speak CTAP 2.1 (June 2021) or 2.2 (July 2025).&quot; },
  { term: &quot;Discoverable credential (resident key, passkey)&quot;, definition: &quot;A WebAuthn credential whose account metadata is stored on the authenticator, enabling usernameless sign-in. CTAP 2.0 called these resident keys; the May 2022 vendor commitment branded them passkeys.&quot; },
  { term: &quot;Attestation conveyance&quot;, definition: &quot;The mechanism by which a registration ceremony optionally produces a signature over the credential public key, chained to a vendor or platform root. Seven IANA-registered formats: packed, tpm, android-key, android-safetynet, fido-u2f, apple, none.&quot; },
  { term: &quot;Hybrid transport (caBLE)&quot;, definition: &quot;A WebAuthn transport in which a phone acts as a roaming authenticator for a nearby laptop. QR code carries an ephemeral ECDH key; BLE proves proximity; HTTPS tunnel relay carries encrypted CTAP2 bytes.&quot; },
  { term: &quot;AAGUID&quot;, definition: &quot;A 16-byte Authenticator Attestation GUID identifying the authenticator make and model. Some authenticators emit all-zeros for privacy; the FIDO Metadata Service is the authoritative directory.&quot; },
  { term: &quot;Conditional UI / Conditional Mediation&quot;, definition: &quot;A WebAuthn invocation mode in which the browser offers discoverable credentials inside the autofill UI rather than via a modal picker. RP calls navigator.credentials.get with mediation: &apos;conditional&apos;.&quot; },
  { term: &quot;BE / BS flags&quot;, definition: &quot;Backup Eligible and Backup State bits in authenticatorData. BE=1 means the credential is in principle syncable; BS=1 means it is currently backed up. NIST SP 800-63B-4 caps BS=1 credentials at AAL2.&quot; },
  { term: &quot;AAL1 / AAL2 / AAL3&quot;, definition: &quot;NIST SP 800-63B-4 authentication assurance levels. AAL1 is single-factor; AAL2 is multi-factor or phishing-resistant; AAL3 is hardware-bound non-syncable authentication.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows-security</category><category>webauthn</category><category>passkeys</category><category>fido2</category><category>ctap</category><category>phishing-resistance</category><category>windows-hello</category><category>authentication</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>No Secrets to Steal: How Windows Hello Eliminated the Shared Secret</title><link>https://paragmali.com/blog/your-face-is-not-your-password-inside-windows-hellos-hardwar/</link><guid isPermaLink="true">https://paragmali.com/blog/your-face-is-not-your-password-inside-windows-hellos-hardwar/</guid><description>How Windows Hello replaced passwords with TPM-backed biometrics, survived a decade of attacks, and helped make passwordless the default.</description><pubDate>Tue, 28 Apr 2026 00:00:00 GMT</pubDate><content:encoded>
**Windows Hello replaces passwords with biometric authentication backed by hardware cryptography.** Your face or fingerprint unlocks a private key sealed inside a TPM chip -- no biometric data ever leaves your device, and no shared secret crosses the network. After a decade of enterprise growing pains and a cat-and-mouse security arms race, Microsoft made passwordless the default for new accounts in May 2025, with passkeys now achieving a 98% sign-in success rate. The password&apos;s 64-year reign is ending -- but open problems in biometric spoofing, credential portability, and quantum-resistant cryptography mean the replacement is still under construction.
&lt;h2&gt;Why Passwords Must Die&lt;/h2&gt;
&lt;p&gt;In 2024, Microsoft observed 7,000 password attacks every second [@ms-passkeys] -- more than double the rate from 2023. Picture this: a user types their carefully memorized 16-character password into what looks like a corporate login page. The page is a phishing replica. In under a second, that password -- the one they have been rotating every 90 days for three years -- belongs to someone else.&lt;/p&gt;

Microsoft observed 7,000 password attacks per second in 2024. The password Corbato invented as a quick fix in 1961 had become the single greatest attack surface in computing.
&lt;p&gt;The problem is not weak passwords. The problem is passwords themselves. They are shared secrets -- a piece of information that both you and the server know. Anything a server stores can be stolen. Anything you type can be intercepted. Anything you memorize can be phished. These are not implementation bugs. They are design properties.&lt;/p&gt;
&lt;p&gt;It was not supposed to be this way. In 1961, Fernando Corbato [@wiki-password] introduced computer passwords at MIT as a quick fix for multi-user mainframes. Users needed separate file spaces on the Compatible Time-Sharing System (CTSS), and a secret string was the simplest way to provide per-user isolation. It was a temporary measure for a specific engineering constraint.&lt;/p&gt;
&lt;p&gt;That temporary measure lasted 64 years.&lt;/p&gt;
&lt;p&gt;What if authentication did not require a secret at all? What if your face unlocked a cryptographic key -- and that key never left your device? That is the promise of Windows Hello. But the story of how we got here passes through a gelatin finger, a low-cost USB device, and a near-infrared camera that shattered assumptions about what &quot;secure&quot; really means.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;The Password&apos;s 64-Year Reign: A Brief History of Authentication Failure&lt;/h2&gt;
&lt;p&gt;In 1966, a software bug in MIT&apos;s CTSS printed the master password file to every user&apos;s terminal -- the first known password breach [@wiki-password].The 1966 CTSS incident was not a hack. A system administrator accidentally swapped the login message file with the master password file. Every user who logged in that day saw everyone else&apos;s password on screen.&lt;/p&gt;
&lt;p&gt;It was a sign of things to come. For the next six decades, every generation of authentication would solve one problem -- and reveal a deeper one.&lt;/p&gt;

gantt
    title Authentication Evolution
    dateFormat YYYY
    axisFormat %Y
    section Passwords
    Plaintext passwords on CTSS       :1961, 1979
    section Hashed
    UNIX crypt / hashed passwords     :1979, 1993
    section Network Auth
    NTLM challenge-response           :1993, 2000
    Kerberos / Windows AD             :2000, 2015
    section Biometrics
    Software biometrics via WBF       :2009, 2015
    section Windows Hello
    Hello + TPM asymmetric auth       :2015, 2021
    ESS + VBS + Cloud Trust           :2021, 2024
    Passkeys and passwordless default :2024, 2026
&lt;h3&gt;Generation 0: Plaintext passwords (1961)&lt;/h3&gt;
&lt;p&gt;Corbato&apos;s CTSS stored passwords in plaintext [@wiki-password] in a file accessible to administrators. The model was simple: the user enters a string, the system compares it to a stored copy, and access is granted on match. The key assumption -- that only the legitimate user knows the password -- held exactly as long as the system remained uncompromised. Which was about five years.&lt;/p&gt;
&lt;h3&gt;Generation 1: Hashed passwords (1970s)&lt;/h3&gt;
&lt;p&gt;The obvious fix: do not store passwords in plaintext. In 1979, Robert Morris and Ken Thompson published the design behind UNIX&apos;s &lt;code&gt;crypt()&lt;/code&gt; function [@wiki-crypt], a one-way hash based on a modified DES algorithm with a 12-bit salt. Even if an attacker stole the hash file, they could not directly read the passwords. They would have to try every possible password and compare hashes -- a brute-force attack.&lt;/p&gt;
&lt;p&gt;For a while, that was computationally infeasible. Then Moore&apos;s Law caught up. By the late 1990s, EFF&apos;s DES Cracker and distributed.net had reduced 56-bit DES keysearch to &lt;strong&gt;22 hours and 15 minutes&lt;/strong&gt; [@eff-des], making DES-based &lt;code&gt;crypt()&lt;/code&gt; increasingly untenable against well-funded attackers. Users also chose weak, predictable passwords, and attackers built rainbow tables that mapped common passwords to their hashes instantly.&lt;/p&gt;
&lt;p&gt;Windows made this worse. LAN Manager (LM) hashes [@ms-lm-hash] uppercased every password, limited them to 14 characters, and split them into two 7-byte halves hashed independently.The LM hash design was spectacularly bad. By splitting a 14-character password into two 7-character halves, it reduced the brute-force search space from 95^14 to 2 x 95^7 -- a reduction of over 34 trillion times. An attacker could crack each half separately.&lt;/p&gt;
&lt;p&gt;Rainbow tables could crack LM hashes in seconds. Microsoft eventually disabled LM hashing by default in Windows Vista, but the damage to enterprise networks had been done.&lt;/p&gt;
&lt;h3&gt;Generation 2: Network challenge-response (1990s)&lt;/h3&gt;
&lt;p&gt;The next insight: stop transmitting passwords over the network. NTLM [@ms-lm-hash] used a challenge-response protocol -- the server sends a random nonce, the client computes a response using the nonce and the password hash, and the server verifies the response. The password never crosses the wire.&lt;/p&gt;
&lt;p&gt;Kerberos [@ms-kerberos], adopted in Windows 2000, improved further with mutual authentication, time-limited tickets, and single sign-on. It was elegant protocol engineering.&lt;/p&gt;
&lt;p&gt;But the fundamental problem remained: shared secrets. NTLM was vulnerable to pass-the-hash attacks [@mitre-pth] -- an attacker who obtains the password hash can authenticate without ever knowing the password. Kerberos tickets could be stolen (Golden Ticket, Silver Ticket attacks). Both systems still depended on users choosing strong passwords, which they consistently failed to do.&lt;/p&gt;
&lt;h3&gt;Generation 3: First software biometrics (2000s)&lt;/h3&gt;
&lt;p&gt;By the early 2000s, fingerprint readers appeared on Windows laptops. The idea was appealing: replace &quot;something you know&quot; with &quot;something you are.&quot; No password to remember, no password to steal.&lt;/p&gt;
&lt;p&gt;Microsoft introduced the Windows Biometric Framework (WBF) [@ms-wbf] in Windows 7 (2009), standardizing the API and driver interface. Before WBF, each fingerprint reader vendor -- AuthenTec, Validity, UPEK -- shipped proprietary middleware that injected into the Windows logon process. The result was inconsistent security, driver conflicts, and no centralized management.&lt;/p&gt;
&lt;p&gt;But WBF solved the wrong problem. It standardized the API while leaving the security model unchanged: biometric templates stored with weak encryption in user-accessible files, matching running in OS user space, and no hardware isolation whatsoever.&lt;/p&gt;
&lt;p&gt;In 2002, Tsutomu Matsumoto at Yokohama National University demonstrated the &quot;gummy finger&quot; attack -- creating gelatin replicas of fingerprints that fooled approximately 80% of commercial readers [@gummy-finger]. The materials cost just a few dollars. Without liveness detection and hardware protection, biometrics were security theater.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The pattern was unmistakable.&lt;/strong&gt; Each generation protected a different layer -- plaintext storage, hash computation, network transmission, biometric convenience -- but each left the next layer exposed. By 2013, passwords were fundamentally broken, and software-only biometrics were not the answer. Then Apple proved something nobody expected.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;The Catalyst: How Touch ID Changed Everything&lt;/h2&gt;
&lt;p&gt;September 2013. Apple unveils the iPhone 5S [@apple-touchid] with a fingerprint sensor embedded in the home button. It was not the first phone with a fingerprint reader -- Motorola&apos;s ATRIX 4G shipped with a biometric fingerprint reader in 2011 [@motorola-atrix]. But it was the first one that hundreds of millions of people actually used.&lt;/p&gt;
&lt;p&gt;What made Touch ID different was not the sensor. It was the Secure Enclave -- a dedicated secure subsystem integrated into Apple&apos;s system-on-chip and isolated from the main processor [@apple-secure-enclave]. The enclave runs its own microkernel, stores biometric material in protected memory, and keeps the matching pipeline outside the reach of normal iOS processes. Apple designed it so the biometric path stayed inside the enclave boundary rather than becoming just another app-visible API.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Apple controlled the sensor, the SoC, the Secure Enclave hardware, and iOS. This vertical integration meant the entire biometric pipeline -- from sensor capture through template matching to key release -- could be designed as a single trust chain. No Windows OEM could match this in 2013 because the sensor, CPU, and OS came from three different vendors with no unified security model.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That architecture established a pattern that Windows Hello would later follow with the TPM. Both isolate secrets in hardware, but they do different jobs: the Secure Enclave is a richer coprocessor that protects both biometric processing and keys, while the TPM is a narrower trust anchor for key storage, signing, and attestation. Apple&apos;s newer Secure Enclave documentation also emphasizes encrypted enclave memory, whereas Windows later needed ESS and &lt;a href=&quot;https://paragmali.com/blog/the-windows-secure-kernel/&quot; rel=&quot;noopener&quot;&gt;VBS&lt;/a&gt; to give its broader PC system a comparable isolation boundary [@apple-secure-enclave; @ms-ess].&lt;/p&gt;
&lt;p&gt;Touch ID proved two things simultaneously: that consumer biometrics could be both secure and delightful, and that the key to secure biometrics was hardware isolation, not better algorithms.&lt;/p&gt;
&lt;p&gt;The FIDO Alliance had already been working on the standards side. Founded in July 2012 [@fido-launch] by Michael Barrett (PayPal&apos;s CISO), Ramesh Kesanupalli (Nok Nok Labs), and partners including Lenovo, Validity Sensors, and Infineon, the Alliance set out to create open standards for strong authentication that would replace passwords. Its first protocols split the problem in two: UAF defined a passwordless flow where a device-local biometric or PIN unlocks a per-service key pair [@fido-uaf], while U2F defined a hardware-token second factor that signs a challenge after the user taps the device [@fido-u2f]. FIDO2 later unified these ideas into the WebAuthn + CTAP stack used for passkeys today [@fido-how].&lt;/p&gt;
&lt;p&gt;The convergence was forming: consumer demand (Apple proved people wanted biometrics), open standards (FIDO defined how it should work), and enterprise need (Microsoft tracked thousands of password attacks per second). Apple showed &lt;em&gt;what&lt;/em&gt; was possible. The FIDO Alliance defined &lt;em&gt;how&lt;/em&gt; it should work. Microsoft was about to show how to do it at the scale of an entire operating system.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;The Breakthrough: Windows Hello&apos;s Architecture&lt;/h2&gt;
&lt;p&gt;On March 17, 2015, Joe Belfiore announced Windows Hello. The key insight was not an algorithm -- it was an architecture. What if the biometric never leaves the device, and the authentication secret is a cryptographic key that even the server never sees?&lt;/p&gt;

A dedicated security chip soldered to a computer&apos;s motherboard (or implemented in firmware) that generates, stores, and manages cryptographic keys. The TPM can create key pairs where the private key is physically bound to the chip and cannot be exported -- even the operating system cannot extract it. Windows Hello uses TPM 2.0 to seal authentication keys.

A cryptographic system using two mathematically related keys: a public key (shared openly) and a private key (kept secret). Data encrypted with one key can only be decrypted with the other. In Windows Hello, the TPM holds the private key and signs authentication challenges; the server holds only the public key, which is useless to an attacker.
&lt;p&gt;Here is how Windows Hello authentication [@ms-whfb] works:&lt;/p&gt;

sequenceDiagram
    participant U as User
    participant B as Biometric Sensor
    participant D as Device OS
    participant T as TPM Chip
    participant S as Identity Server
    U-&amp;gt;&amp;gt;B: Present face or fingerprint
    B-&amp;gt;&amp;gt;D: Capture biometric sample
    D-&amp;gt;&amp;gt;D: Match against stored template
    Note over D: Local verification only
    D-&amp;gt;&amp;gt;T: Request private key release
    T-&amp;gt;&amp;gt;T: Verify TPM-bound policy
    T--&amp;gt;&amp;gt;D: Private key available for signing
    S-&amp;gt;&amp;gt;D: Send challenge nonce
    D-&amp;gt;&amp;gt;D: Sign nonce with private key
    D-&amp;gt;&amp;gt;S: Return signed assertion
    S-&amp;gt;&amp;gt;S: Verify signature with public key
    S-&amp;gt;&amp;gt;D: Authentication success
&lt;p&gt;&lt;strong&gt;Step 1: Enrollment.&lt;/strong&gt; The TPM generates an asymmetric key pair -- RSA-2048 or ECDSA P-256. The private key is sealed inside the TPM and cannot be exported. The public key is registered with the identity provider (Azure AD, Entra ID, or on-premises AD) [@ms-whfb].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2: Biometric enrollment.&lt;/strong&gt; The user registers their face (via a near-infrared camera) or fingerprint. The biometric template is stored locally on the device, protected by the OS.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3: Authentication.&lt;/strong&gt; The user presents their biometric gesture. The device verifies it locally against the stored template. If the match succeeds, the TPM releases the private key. The identity server sends a random challenge nonce; the device signs it with the private key and returns the signed assertion. The server verifies the signature using the stored public key. No shared secret ever crosses the network.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Windows Hello&apos;s breakthrough was architectural, not algorithmic. By pairing biometrics with hardware-backed asymmetric cryptography, it eliminated shared secrets entirely. No biometric data ever leaves the device. No password hash sits on a server waiting to be stolen. Each authentication is a fresh, unreplayable cryptographic signature.&lt;/p&gt;
&lt;/blockquote&gt;

The probability that a biometric system incorrectly accepts an unauthorized person. Windows Hello requires a facial recognition FAR below 0.001% (1 in 100,000) [@ms-biometric-reqs]. Apple&apos;s Face ID is documented at less than 0.0001% (1 in 1,000,000) for a single enrolled face [@apple-faceid-security]. Lower is better -- but zero is theoretically impossible.

A camera technology that captures light in the 700--1000 nanometer wavelength range, invisible to the human eye. Windows Hello uses NIR cameras because infrared illumination works regardless of ambient lighting and is harder to spoof with printed photos or screens -- standard displays do not emit near-infrared light. Or so everyone assumed until 2025.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Without a TPM, Windows Hello falls back to software key storage, dramatically weakening the security model. The private key becomes a file protected by the OS rather than a secret sealed in tamper-resistant silicon. Always verify TPM 2.0 is present and active before relying on Hello&apos;s security properties.&lt;/p&gt;
&lt;/blockquote&gt;

A Trusted Platform Module is not a general-purpose processor. It is a purpose-built chip (or firmware module) designed for a narrow set of cryptographic operations: key generation, key storage, signing, and attestation.&lt;p&gt;When Windows Hello enrolls a user, the TPM generates a key pair using its internal random number generator. The private key never exists outside the chip&apos;s boundary -- it is generated inside the TPM and stays there. The TPM enforces access policies: it will only release the key for signing after the device OS confirms that the biometric match succeeded. Even a compromised operating system kernel cannot extract the private key from a hardware TPM.&lt;/p&gt;
&lt;p&gt;This is fundamentally different from software key storage, where the key is a file on disk that any sufficiently privileged process can read.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;The PIN paradox&lt;/h3&gt;
&lt;p&gt;Windows Hello also revived the humble PIN -- and made it more secure than a complex password. A Hello PIN [@ms-whfb] is device-bound: it unlocks the TPM-stored private key on that specific device. A stolen PIN is useless without physical access to the hardware. Compare this to a password, which works from any device on earth. A 4-digit PIN on Windows Hello is architecturally more secure than a 20-character password reused across services.Microsoft Passport was briefly announced as a separate product in early 2015 -- the cryptographic key infrastructure behind Windows Hello. By late 2015, the branding was merged. &quot;Microsoft Passport&quot; was retired and its functionality absorbed into &quot;Windows Hello&quot; and &quot;Windows Hello for Business.&quot; The separate brand caused market confusion and was quickly abandoned.&lt;/p&gt;
&lt;p&gt;The biometric FAR can be expressed mathematically. For a face recognition system with $n$ enrolled users and a per-comparison FAR of $p$, the probability of at least one false acceptance across all comparisons is:&lt;/p&gt;
&lt;p&gt;$$P(\text{false accept}) = 1 - (1 - p)^n$$&lt;/p&gt;
&lt;p&gt;For Windows Hello&apos;s required FAR of $10^{-5}$ [@ms-biometric-reqs] and a single user, this gives a 0.001% chance per authentication attempt. With 1,000 attempts, the cumulative probability rises to roughly 1% -- which is why lockout policies and anti-hammering protections exist.&lt;/p&gt;
&lt;p&gt;{`
// This demonstrates the core idea behind Windows Hello&apos;s authentication.
// In the real system, the private key lives in the TPM and never leaves.&lt;/p&gt;
&lt;p&gt;async function simulateHelloAuth() {
  // Step 1: Enrollment -- generate key pair (TPM does this in hardware)
  const keyPair = await crypto.subtle.generateKey(
    { name: &quot;ECDSA&quot;, namedCurve: &quot;P-256&quot; },
    true, // extractable for demo only; TPM keys are NOT extractable
    [&quot;sign&quot;, &quot;verify&quot;]
  );
  console.log(&quot;Key pair generated (simulating TPM enrollment)&quot;);&lt;/p&gt;
&lt;p&gt;  // Step 2: Server sends a challenge nonce
  const challenge = crypto.getRandomValues(new Uint8Array(32));
  console.log(&quot;Server challenge:&quot;, Array.from(challenge.slice(0, 8)).map(b =&amp;gt; b.toString(16).padStart(2, &apos;0&apos;)).join(&apos;&apos;));&lt;/p&gt;
&lt;p&gt;  // Step 3: Device signs the challenge with the private key
  const signature = await crypto.subtle.sign(
    { name: &quot;ECDSA&quot;, hash: &quot;SHA-256&quot; },
    keyPair.privateKey,
    challenge
  );
  console.log(&quot;Signed assertion:&quot;, new Uint8Array(signature).slice(0, 16).join(&apos;,&apos;) + &apos;...&apos;);&lt;/p&gt;
&lt;p&gt;  // Step 4: Server verifies with the public key
  const valid = await crypto.subtle.verify(
    { name: &quot;ECDSA&quot;, hash: &quot;SHA-256&quot; },
    keyPair.publicKey,
    signature,
    challenge
  );
  console.log(&quot;Server verification:&quot;, valid ? &quot;SUCCESS&quot; : &quot;FAILED&quot;);
  console.log(&quot;\nNote: The private key never left the device.&quot;);
  console.log(&quot;The server only has the public key -- useless to an attacker.&quot;);
}&lt;/p&gt;
&lt;p&gt;simulateHelloAuth();
`}&lt;/p&gt;
&lt;p&gt;Windows Hello solved the fundamental password problem: no shared secrets ever traverse the network. But the story does not end here -- because researchers would soon discover that protecting the key was not enough if you could not trust the camera.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;The Enterprise Gambit: Windows Hello for Business&lt;/h2&gt;
&lt;p&gt;Windows Hello delighted consumers. But enterprise IT administrators asked a harder question: how do I deploy this to 50,000 machines managed by Active Directory?&lt;/p&gt;

The W3C Web Authentication API -- a browser standard that lets websites request public-key-based authentication from platform authenticators (like Windows Hello) or roaming authenticators (like security keys). WebAuthn became a W3C Recommendation on March 4, 2019, forming the browser-side component of the FIDO2 standard alongside CTAP (Client-to-Authenticator Protocol).
&lt;p&gt;Windows Hello for Business (WHfB) [@ms-whfb] launched in 2016 with two trust types, each carrying its own infrastructure burden:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Certificate Trust&lt;/strong&gt; required a full Public Key Infrastructure -- a Certificate Authority hierarchy, CRL distribution points, certificate templates, and ADFS (Active Directory Federation Services). For organizations that already had PKI, this was a natural fit. For everyone else, it meant weeks of setup.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key Trust&lt;/strong&gt; required Windows Server 2016+ domain controllers with AD schema extensions. Simpler than Certificate Trust, but still demanded on-premises infrastructure that many cloud-first organizations were trying to eliminate.Yogesh Mehta, Principal Group Program Manager at Microsoft, evangelized Windows Hello for Business at Ignite 2016. He would later be credited as a key figure in the FIDO2 certification effort. The original Belfiore blog post URL announcing Windows Hello is now lost to link rot.&lt;/p&gt;
&lt;p&gt;Two milestones accelerated adoption. In March 2019, WebAuthn became a W3C Recommendation [@w3c-webauthn] -- a universal browser API for public-key authentication. Android had already been FIDO2-certified in February 2019 [@fido-android-certification]; two months after WebAuthn&apos;s recommendation, Windows Hello became one of the first FIDO2-certified platform authenticators built into a desktop operating system [@fido-certification]. Together, these meant that Windows Hello could authenticate not just to Windows, but to any FIDO2-supporting website through any modern browser.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Unless you have specific PKI requirements, Cloud Trust -- announced by Microsoft in 2022 [@ms-cloud-trust-ga] -- eliminates much of the complexity of certificate and key trust deployments. It requires Entra ID configuration and Microsoft Entra Kerberos rather than a full on-prem PKI or ADFS stack, which is why Microsoft now treats it as the default recommendation for many hybrid organizations.&lt;/p&gt;
&lt;/blockquote&gt;


flowchart TD
    A[Choose a WHfB Trust Model] --&amp;gt; B{Cloud-native org using Entra ID?}
    B --&amp;gt;|Yes| C[Cloud Trust -- Recommended]
    B --&amp;gt;|No| D{On-prem AD still required?}
    D --&amp;gt;|Yes| E{Existing PKI infrastructure?}
    D --&amp;gt;|No| C
    E --&amp;gt;|Yes| F[Certificate Trust]
    E --&amp;gt;|No| G[Key Trust]
    C --&amp;gt; H[Simplest deployment: Entra ID only]
    F --&amp;gt; I[Most complex: CA + CRL + ADFS]
    G --&amp;gt; J[Moderate: Server 2016+ DCs required]
&lt;p&gt;&lt;strong&gt;Cloud Trust&lt;/strong&gt; delegates all validation to Entra ID. No on-premises PKI, no ADFS, no certificate templates. Best for organizations that are cloud-native or hybrid with Azure AD.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key Trust&lt;/strong&gt; requires Windows Server 2016+ domain controllers with AD schema extensions. Choose this if you need on-premises AD support but do not have PKI.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Certificate Trust&lt;/strong&gt; requires the full PKI stack -- CA hierarchy, CRL distribution, ADFS. Choose this only if your organization already has PKI infrastructure and needs certificate-based authentication for regulatory compliance.&lt;/p&gt;
&lt;p&gt;Enterprise deployment was painful -- multiple trust models confused administrators, and adoption was slower than hoped. But it was about to get much worse. In July 2021, a researcher with a low-cost USB board would demonstrate that Windows Hello&apos;s most basic assumption was wrong.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;The Security Arms Race: When Researchers Fought Back&lt;/h2&gt;
&lt;p&gt;Omer Tsarfati had a simple question: what happens if you plug in a USB device that &lt;em&gt;claims&lt;/em&gt; to be an IR camera? The answer would force Microsoft to rethink Windows Hello&apos;s entire trust model.&lt;/p&gt;
&lt;h3&gt;The USB camera bypass (CVE-2021-34466)&lt;/h3&gt;
&lt;p&gt;In July 2021, Tsarfati at CyberArk Labs [@cyberark-bypass] revealed that Windows Hello&apos;s facial recognition accepted input from any USB device presenting itself as an IR camera -- with no attestation, no hardware trust verification, and no device identity check.Tsarfati&apos;s attack required only a single IR frame -- not video, not a 3D reconstruction, just one static infrared image of the target&apos;s face. The simplicity of the attack was what made it so alarming.&lt;/p&gt;
&lt;p&gt;Using an NXP evaluation board [@cyberark-bypass], Tsarfati constructed a custom USB device that replayed a single IR frame of a target&apos;s face. Plug it in, and Windows Hello authenticated the attacker as the target. At the time, 85% of Windows 10 users employed Windows Hello [@cyberark-bypass] -- making this a massive attack surface.&lt;/p&gt;
&lt;p&gt;The insight was devastating: the TPM protected the key, but nobody protected the camera. Windows Hello&apos;s threat model assumed trusted camera hardware. The USB specification makes no such guarantee.&lt;/p&gt;

A Windows feature that uses the hardware hypervisor to create an isolated virtual environment (Virtual Trust Level 1, or VTL1) separated from the main OS kernel (VTL0). Even if an attacker gains SYSTEM-level access to the Windows kernel, they cannot read memory in VTL1. Windows Hello&apos;s Enhanced Sign-in Security uses VBS to isolate biometric processing.
&lt;h3&gt;Microsoft&apos;s response: ESS and VBS&lt;/h3&gt;
&lt;p&gt;Microsoft&apos;s answer came with Windows 11: Enhanced Sign-in Security (ESS) [@ms-ess], which moved biometric matching into the VBS-protected enclave described above. Even a compromised Windows kernel cannot access templates or tamper with the comparison pipeline there.&lt;/p&gt;

flowchart TD
    subgraph VTL0[&quot;VTL0: Normal OS Environment&quot;]
        A[Windows Kernel]
        B[Applications]
        C[Standard Drivers]
    end
    subgraph VTL1[&quot;VTL1: Secure World -- ESS&quot;]
        D[Biometric Matching Engine]
        E[Encrypted Template Storage]
        F[Credential Isolation]
    end
    G[Hypervisor] --- VTL0
    G --- VTL1
    H[Secure Biometric Sensor] --&amp;gt; D
    A -.-&amp;gt;|Blocked by Hypervisor| D
    B -.-&amp;gt;|Blocked by Hypervisor| E
&lt;p&gt;Alongside ESS, Microsoft rolled out Cloud Trust in 2022 [@ms-cloud-trust-ga], eliminating the need for on-premises PKI for many deployments. Two problems -- biometric isolation and deployment complexity -- were finally being addressed in parallel.&lt;/p&gt;
&lt;h3&gt;Red Bleed: the NIR assumption shatters (CVE-2025-26644)&lt;/h3&gt;
&lt;p&gt;The arms race was not over. In August 2025, researchers Bowen Hu, Kuo Wang, and Chip Hong Chang at Nanyang Technological University presented &quot;Red Bleed&quot; [@red-bleed] at USENIX Security 2025. Microsoft had already patched CVE-2025-26644 [@wiz-cve] in April 2025, but the full attack was now public.&lt;/p&gt;
&lt;p&gt;Windows Hello&apos;s NIR facial recognition relied on a critical assumption: no commercial display can emit near-infrared light. The researchers shattered this assumption [@nvd-red-bleed] with a custom-built LCD screen costing less than $400 that could display NIR images. They trained a Variational Autoencoder to convert widely available RGB photos -- from social media, video calls, public sources -- into convincing NIR facial videos. The result: a presentation attack that bypassed Windows Hello face authentication and prompted liveness-detection hardening [@red-bleed-pdf]. The Red Bleed attack name references the &quot;red bleed&quot; phenomenon in LCD panels where a small amount of near-infrared light leaks through the color filters -- the researchers amplified this effect with a custom panel.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s April 2025 patch strengthened liveness detection and anti-spoofing measures for NIR authentication.&lt;/p&gt;
&lt;h3&gt;Faceplant: the template swap (CVE-2026-20804)&lt;/h3&gt;
&lt;p&gt;The third major attack came from ERNW Research in August 2025. At Black Hat USA 2025, Baptiste David and Tillmann Oßwald&apos;s official conference briefing &quot;Windows Hell No for Business&quot; [@blackhat-windows-hell-no] detailed the Faceplant template-injection attack, which they later documented technically on ERNW&apos;s research blog [@faceplant].&lt;/p&gt;
&lt;p&gt;In practice, an attacker with local administrator privileges could enroll their own face on one machine, extract the resulting template, and transplant it into the victim&apos;s biometric database on the target device. After injection, Windows Hello accepted the attacker&apos;s face for the victim&apos;s account. ERNW traced the weakness to software-protected templates that a local administrator could extract and replace on non-ESS systems [@faceplant].&lt;/p&gt;
&lt;p&gt;ESS blocks this attack completely -- biometric templates in VTL1 are inaccessible even to local administrators. But many enterprise PCs lack ESS-compatible hardware.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Many enterprise PCs -- particularly those shipped without an ESS-certified built-in biometric sensor, including many AMD-based and older Intel-based machines -- lack ESS capability. On these machines, biometric templates remain in software-protected storage vulnerable to the Faceplant attack. Verify hardware compatibility before assuming biometric isolation is active.&lt;/p&gt;
&lt;/blockquote&gt;

flowchart TD
    A[&quot;2015: Windows Hello Launch&quot;] --&amp;gt; B[&quot;2021: CVE-2021-34466\nUSB Camera Spoofing&quot;]
    B --&amp;gt; C[&quot;Microsoft Response:\nESS + VBS Isolation&quot;]
    C --&amp;gt; D[&quot;2025: CVE-2025-26644\nRed Bleed NIR Attack&quot;]
    D --&amp;gt; E[&quot;Microsoft Response:\nLiveness Detection Update&quot;]
    E --&amp;gt; F[&quot;2025: CVE-2026-20804\nFaceplant Template Injection&quot;]
    F --&amp;gt; G[&quot;Defense: ESS Hardware\nIsolation Blocks Attack&quot;]
    G --&amp;gt; H[&quot;Ongoing: Adversarial ML\nArms Race&quot;]
    classDef fake fill:#7a3030,stroke:#c44b4b,color:#fce8e8
    class B fake,stroke:#333
    class D fake,stroke:#333
    class F fake,stroke:#333
    classDef real fill:#2f5a3a,stroke:#5fa872,color:#dff5e4
    class C real,stroke:#333
    class E real,stroke:#333
    class G real,stroke:#333
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Each generation of authentication protected a new layer -- but every layer revealed the next attack surface. The TPM protected the key. ESS protected the biometric pipeline. Liveness detection hardened NIR authentication. Security is never a single solution. It is a stack, and each layer needs its own defense.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The arms race revealed a humbling truth: biometric authentication is not a silver bullet. It is a layered defense -- and each layer needs its own protection. But while researchers probed Windows Hello&apos;s defenses, the industry was converging on something bigger.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;The Convergence: Passkeys and the Passwordless Future&lt;/h2&gt;
&lt;p&gt;May 5, 2022. Apple, Google, and Microsoft [@passkeys-announcement] -- three companies that agree on almost nothing -- issued a joint announcement: they were all committing to passkeys.&lt;/p&gt;

A FIDO2/WebAuthn credential built on the same public-key model as Windows Hello. Passkeys can be device-bound (like traditional Hello credentials, stored in the TPM) or synced across devices through a credential manager such as iCloud Keychain or Google Password Manager. The local biometric or PIN check stays on-device; the relying party only sees public keys and signatures.
&lt;p&gt;FIDO2 had a usability problem. Credentials were bound to a single device. Lose your laptop, lose your credentials. Passkeys solved this by introducing synced credentials -- private keys encrypted and distributed across a user&apos;s devices through their platform credential manager. The FIDO Alliance&apos;s protocol [@fido-how] maintained the cryptographic guarantees (no shared secrets, phishing resistance) while adding the portability users demanded.&quot;World Password Day&quot; was symbolically renamed &quot;World Passkey Day&quot; in May 2025, when Microsoft announced that new accounts would default to passwordless authentication.&lt;/p&gt;
&lt;h3&gt;The numbers tell the story&lt;/h3&gt;
&lt;p&gt;By May 2025, Microsoft made new accounts passwordless by default [@ms-passkeys]:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nearly 1 million passkey registrations daily [@ms-passkeys]&lt;/li&gt;
&lt;li&gt;98% passkey sign-in success rate [@ms-passkeys] vs. 32% for passwords&lt;/li&gt;
&lt;li&gt;Passkey sign-ins 8x faster [@ms-passkeys] than password + MFA&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How the platforms compare&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Windows Hello (WHfB)&lt;/th&gt;
&lt;th&gt;Apple Face ID / Passkeys&lt;/th&gt;
&lt;th&gt;Google Passkeys&lt;/th&gt;
&lt;th&gt;FIDO2 Hardware Keys&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hardware root of trust&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&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 2.0&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Secure Enclave&lt;/td&gt;
&lt;td&gt;TEE / Titan M&lt;/td&gt;
&lt;td&gt;On-key secure element&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Credential sync&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No (device-bound)&lt;/td&gt;
&lt;td&gt;Yes (iCloud Keychain)&lt;/td&gt;
&lt;td&gt;Yes (Google PM)&lt;/td&gt;
&lt;td&gt;No (hardware-bound)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cross-platform&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Windows only&lt;/td&gt;
&lt;td&gt;Apple + QR/BT bridge&lt;/td&gt;
&lt;td&gt;Android/Chrome + QR/BT&lt;/td&gt;
&lt;td&gt;Universal USB/NFC/BT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FAR (face)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&amp;lt; 0.001%&lt;/td&gt;
&lt;td&gt;&amp;lt; 0.0001%&lt;/td&gt;
&lt;td&gt;Varies by OEM&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Enterprise management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Intune, GP, Conditional Access&lt;/td&gt;
&lt;td&gt;Limited (Apple MDM)&lt;/td&gt;
&lt;td&gt;Android Enterprise&lt;/td&gt;
&lt;td&gt;Manual provisioning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Recovery on device loss&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Re-enroll on new device&lt;/td&gt;
&lt;td&gt;iCloud backup restore&lt;/td&gt;
&lt;td&gt;Google Account restore&lt;/td&gt;
&lt;td&gt;Requires backup key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NIST AAL level&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AAL2&lt;/td&gt;
&lt;td&gt;AAL2&lt;/td&gt;
&lt;td&gt;AAL2&lt;/td&gt;
&lt;td&gt;AAL3-eligible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best suited for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Windows enterprise&lt;/td&gt;
&lt;td&gt;Apple platform&lt;/td&gt;
&lt;td&gt;Android / cross-platform web&lt;/td&gt;
&lt;td&gt;High-assurance regulated&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Sources: Microsoft biometric requirements [@ms-biometric-reqs], Apple passkey security [@apple-passkeys-security], Google passkeys [@google-passkeys], FIDO specifications [@fido-specs]&lt;/p&gt;
&lt;p&gt;Google&apos;s passkey story is centered on Google Password Manager: passkeys created on Android or Chrome sync across Android, ChromeOS, Windows, macOS, Linux, and Chrome browsers where the same account is available [@google-passkeys]. FIDO2 hardware security keys (YubiKey, Google Titan) take the opposite approach: the credential stays on a dedicated secure element, works across platforms via USB/NFC/Bluetooth, and must be provisioned deliberately on each account [@fido-u2f; @fido-how]. That trade-off buys the highest assurance available today; multi-factor cryptographic hardware authenticators are the mainstream route to NIST AAL3 [@nist-aal].&lt;/p&gt;

sequenceDiagram
    participant U as User
    participant B as Browser
    participant A as Platform Authenticator
    participant S as Relying Party Server
    U-&amp;gt;&amp;gt;B: Click Register with Passkey
    B-&amp;gt;&amp;gt;S: Request registration options
    S-&amp;gt;&amp;gt;B: Return challenge + relying party info
    B-&amp;gt;&amp;gt;A: navigator.credentials.create()
    A-&amp;gt;&amp;gt;U: Prompt biometric verification
    U-&amp;gt;&amp;gt;A: Present face / fingerprint / PIN
    A-&amp;gt;&amp;gt;A: Generate key pair in TPM
    A-&amp;gt;&amp;gt;B: Return public key + attestation
    B-&amp;gt;&amp;gt;S: Send credential to server
    S-&amp;gt;&amp;gt;S: Store public key for user
    S-&amp;gt;&amp;gt;B: Registration complete
&lt;p&gt;{`
// This shows the structure of a WebAuthn registration request.
// In production, the challenge comes from your server.&lt;/p&gt;
&lt;p&gt;const registrationOptions = {
  publicKey: {
    // Random challenge from the server (32 bytes)
    challenge: crypto.getRandomValues(new Uint8Array(32)),&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Your service identity
rp: {
  name: &quot;Example Corp&quot;,
  id: &quot;example.com&quot;
},

// User identity
user: {
  id: new Uint8Array([1, 2, 3, 4]),
  name: &quot;alice@example.com&quot;,
  displayName: &quot;Alice&quot;
},

// Acceptable key types (ES256 = ECDSA P-256)
pubKeyCredParams: [
  { type: &quot;public-key&quot;, alg: -7 }  // ES256
],

// Request a resident/discoverable credential (passkey)
authenticatorSelection: {
  residentKey: &quot;required&quot;,
  userVerification: &quot;required&quot;  // Biometric or PIN
},

// 5-minute timeout
timeout: 300000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  }
};&lt;/p&gt;
&lt;p&gt;console.log(&quot;Registration options structure:&quot;);
console.log(JSON.stringify(registrationOptions.publicKey.rp, null, 2));
console.log(&quot;\nKey algorithm: ES256 (ECDSA P-256)&quot;);
console.log(&quot;Resident key: required (discoverable passkey)&quot;);
console.log(&quot;User verification: required (biometric or PIN)&quot;);
console.log(&quot;\nIn production, call: navigator.credentials.create(registrationOptions)&quot;);
`}&lt;/p&gt;
&lt;h2&gt;Deploying Windows Hello Today&lt;/h2&gt;
&lt;p&gt;For consumers, the simplest path is built into Windows: open &lt;strong&gt;Settings &amp;gt; Accounts &amp;gt; Sign-in options&lt;/strong&gt;, create a Windows Hello PIN first, then enroll face or fingerprint if the hardware is present [@ms-whfb]. If Windows only offers PIN, the machine lacks a compatible biometric sensor. On a laptop with an IR camera or certified fingerprint reader, enrollment takes a few minutes and the credential becomes device-bound immediately.&lt;/p&gt;
&lt;p&gt;For enterprises, Microsoft now recommends starting with Cloud Trust unless certificate-based authentication is a hard requirement. A practical rollout checklist is short: confirm devices are Entra joined or hybrid joined, deploy Microsoft Entra Kerberos, verify Windows 10 21H2+/Windows 11 clients and Windows Server 2016+ read-write domain controllers in each site, then push &lt;strong&gt;Use Windows Hello for Business&lt;/strong&gt; plus &lt;strong&gt;Use cloud trust for on-premises authentication&lt;/strong&gt; through Intune or Group Policy [@ms-cloud-trust-ga]. That is dramatically lighter than standing up PKI, ADFS, and certificate templates.&lt;/p&gt;
&lt;p&gt;ESS deserves its own hardware check. A TPM alone is not enough: ESS depends on Windows 11, VBS-capable hardware, and compatible secure biometric sensors [@ms-ess]. Unsupported systems can still use Hello, but they fall back to the older software-protected biometric path. Hardware inventory determines whether you are getting the modern threat model or merely the old UX.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Start with a pilot group, require a Hello PIN for every enrolled user, and issue at least one backup FIDO2 security key to admins and help-desk staff. The cleanest password migration is additive: enroll Hello first, prove recovery works, then remove password prompts from the highest-value workflows last.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For password migration, avoid a flag day. Keep passwords as break-glass recovery while you move device sign-in, Microsoft 365, VPN, and high-value internal apps onto Hello or passkeys first [@ms-entra-passwordless]. Measure enrollment completion, recovery success, and hardware exceptions. Once those numbers stabilize, tighten Conditional Access so phishing-resistant credentials satisfy MFA and passwords become the fallback of last resort.&lt;/p&gt;
&lt;p&gt;After 64 years, the password is finally losing its grip. But the story of Windows Hello is not a triumph -- it is a lesson in the limits of security engineering.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;The Limits: What Remains Unsolved&lt;/h2&gt;
&lt;p&gt;Biometrics fail in a way passwords do not: they are hard to rotate.&lt;/p&gt;

You cannot change your face. This single fact defines the deepest unsolved problem in biometric authentication.
&lt;p&gt;Passwords can be rotated. Security keys can be replaced. But you have one face, ten fingerprints, and two irises. If a biometric template is compromised, there is no &quot;reset&quot; button.&lt;/p&gt;

A technique for generating revocable biometric templates by applying non-invertible mathematical transformations to the original biometric data. If a transformed template is compromised, a new transformation can be applied to create a fresh template from the same biometric trait. In theory, this solves the irrevocability problem. In practice, the trade-off between non-invertibility and matching accuracy remains unresolved.
&lt;h3&gt;The biometric floor&lt;/h3&gt;
&lt;p&gt;The theoretical limit on biometric authentication error is the Bayes error rate [@jain-biometric] -- the minimum achievable error when the genuine-user and impostor score distributions overlap. Per information theory, the error probability is bounded by Fano&apos;s inequality:&lt;/p&gt;
&lt;p&gt;$$P_e \geq \frac{H(X|Y) - 1}{\log |X|}$$&lt;/p&gt;
&lt;p&gt;where $P_e$ is the probability of error, $H(X|Y)$ is the conditional entropy of identity given the biometric sample, and $|X|$ is the number of possible identities. Current systems achieve a FAR of $10^{-5}$ to $10^{-6}$, but the theoretical minimum [@jain-biometric] -- given perfect sensors and optimal classifiers -- could be orders of magnitude lower. The practical gap is driven by sensor noise, environmental variability, and aging of biometric features.&lt;/p&gt;
&lt;h3&gt;Five open problems&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;1. Cross-platform credential portability.&lt;/strong&gt; Passkeys are currently vendor-locked. An Apple passkey does not transfer to a Google account. The FIDO Alliance published draft CXP/CXF specifications [@fido-cxp] in late 2024 for encrypted credential exchange, but full cross-vendor interoperability is not expected before late 2026.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. The adversarial ML arms race.&lt;/strong&gt; Generative AI can create increasingly convincing biometric spoofs -- the Red Bleed attack [@red-bleed] used a VAE to convert RGB photos to NIR facial videos. Discriminative AI tries to detect these spoofs. This is an open-ended arms race with no known endpoint.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Account recovery.&lt;/strong&gt; When all biometric and device-based credentials fail, how does a user recover their account? Most services fall back to email or SMS [@ms-entra-passwordless] -- reintroducing the very phishable factors they were designed to eliminate. Recovery codes are functionally passwords.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Systems that fall back to passwords or SMS for account recovery reintroduce the very vulnerabilities they were designed to eliminate. A truly passwordless system needs passwordless recovery -- and no universal solution exists yet.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;4. The quantum threat.&lt;/strong&gt; Shor&apos;s algorithm [@nist-pqc] on a sufficiently large quantum computer would break all ECDSA and RSA authentication -- including every FIDO2 credential in existence. NIST finalized post-quantum standards [@nist-pqc] (ML-DSA, SLH-DSA, ML-KEM) in 2024, but no FIDO2 authenticator ships with post-quantum support as of 2026.&lt;/p&gt;

All current FIDO2/WebAuthn authentication uses ECDSA P-256, which provides 128-bit classical security. Breaking a single credential requires approximately $2^{128}$ operations -- far beyond any existing computer.&lt;p&gt;Shor&apos;s algorithm changes this equation. A cryptographically relevant quantum computer could factor the elliptic curve discrete logarithm problem in polynomial time, breaking ECDSA entirely. No such computer exists today, but the &quot;harvest now, decrypt later&quot; threat means adversaries may be collecting signed assertions now to verify forged credentials later.&lt;/p&gt;
&lt;p&gt;NIST finalized its first post-quantum cryptography standards in 2024 [@nist-pqc]: ML-DSA (formerly CRYSTALS-Dilithium) for signatures, ML-KEM (formerly CRYSTALS-Kyber) for key encapsulation, and SLH-DSA (formerly SPHINCS+) for hash-based signatures. The FIDO Alliance and W3C are exploring hybrid signature schemes that combine classical ECDSA with post-quantum algorithms, but no timeline for standardization has been published.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. The ESS hardware gap.&lt;/strong&gt; ESS requires specific secure sensors and VBS-capable CPUs [@ms-ess]. Many enterprise PCs -- particularly those shipped without an ESS-certified built-in biometric sensor, including many AMD-based and older Intel-based machines -- lack ESS capability. On these devices, Windows Hello falls back to the pre-ESS security model, leaving them vulnerable to attacks like Faceplant.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. Accessibility and inclusion.&lt;/strong&gt; Biometric authentication creates barriers for people with facial differences, missing fingers, or conditions that affect biometric stability. A passwordless future must ensure that non-biometric alternatives (PINs, hardware keys) remain first-class options, not afterthoughts. Behavioral biometrics -- keystroke dynamics, gait analysis, continuous session verification -- represent an emerging parallel path that may expand authentication options beyond traditional biometric modalities.&lt;/p&gt;

Open PowerShell as administrator and run:&lt;pre&gt;&lt;code&gt;Get-CimInstance -Namespace root/Microsoft/Windows/DeviceGuard -ClassName Win32_DeviceGuard | Select-Object VirtualizationBasedSecurityStatus
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A value of &lt;code&gt;2&lt;/code&gt; means VBS is running. Then check the biometric service:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Get-WinEvent -LogName Microsoft-Windows-Biometrics/Operational -MaxEvents 10 | Format-List
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Look for events indicating ESS-protected biometric operations. If your device lacks ESS, consider disabling biometric sign-in on sensitive accounts and using FIDO2 hardware keys instead.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Biometric traits are permanent and finite. Unlike passwords, they cannot be changed if compromised. This irrevocability is the deepest unsolved challenge in passwordless authentication -- and no amount of better sensors or smarter algorithms can change the fact that you have one face, ten fingerprints, and two irises.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The theoretically ideal system would combine zero-knowledge biometric verification, post-quantum cryptographic authentication, hardware-attested revocable credentials, and cross-platform portability. None of this exists yet.&lt;/p&gt;
&lt;p&gt;The password&apos;s 64-year reign is ending, but its replacement is still under construction. Every generation of authentication solved one problem and revealed a deeper one. The question is not whether passwordless authentication will win -- it is whether we can build it before the attackers catch up.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Frequently Asked Questions&lt;/h2&gt;

No. Biometric data never leaves the device. During enrollment, your face or fingerprint template is stored locally, protected by the operating system (and by VBS on ESS-enabled devices). Only a public key is registered with the identity provider (Azure AD / Entra ID) [@ms-whfb]. Microsoft&apos;s servers never receive, store, or process your biometric data.

Standard photos cannot. Windows Hello uses near-infrared cameras [@ms-biometric-reqs] with anti-spoofing algorithms that distinguish between live faces and flat images. However, researchers have demonstrated advanced attacks: CVE-2021-34466 [@cyberark-bypass] used a custom USB device emulating an IR camera, and the Red Bleed attack [@red-bleed] used a custom NIR-emitting LCD display. Both have been patched, but the arms race continues.

No -- it is more secure. A Windows Hello PIN is device-bound [@ms-whfb]: it unlocks a TPM-stored private key on that specific hardware. A stolen PIN is useless without physical access to the device. A password, by contrast, works from any device on earth and can be phished, reused, or leaked in a breach.

Consumer Windows Hello [@ms-whfb] ties authentication to a personal Microsoft account. Windows Hello for Business integrates with Azure AD / Entra ID with enterprise management capabilities: conditional access policies, Intune deployment, multiple trust models (cloud, key, certificate), and group policy controls. They share the same biometric and TPM technology but have different management and security models.

No. Passkeys build on Hello&apos;s foundation. Windows Hello acts as the platform authenticator for FIDO2 passkeys [@fido-how] on Windows -- your biometric gesture unlocks the passkey stored in the TPM. Passkeys extend Hello&apos;s model to cross-platform and cross-service authentication via the WebAuthn standard [@webauthn-3].

With device-bound credentials (traditional Windows Hello), you re-enroll on the new device using your Microsoft or organizational account. With synced passkeys, credentials restore from your credential manager -- iCloud Keychain [@apple-passkeys-security] for Apple, Google Password Manager [@google-passkeys] for Android/Chrome. Registering a FIDO2 hardware security key [@fido-specs] as a backup authenticator is strongly recommended.

Not indefinitely. The asymmetric cryptography underlying Hello and FIDO2 (ECDSA P-256) is theoretically vulnerable [@nist-pqc] to quantum computers running Shor&apos;s algorithm. No quantum computer can break it today, and the timeline for cryptographically relevant quantum computers remains uncertain. NIST finalized post-quantum cryptography standards in 2024, but no FIDO2 authenticator ships with post-quantum support yet. Migration planning should begin now.
&lt;hr /&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;windows-hello-revolution&quot; keyTerms={[
  { term: &quot;TPM&quot;, definition: &quot;Trusted Platform Module -- hardware chip that generates and stores cryptographic keys&quot; },
  { term: &quot;Asymmetric cryptography&quot;, definition: &quot;Public-key/private-key system where data signed with one key is verified with the other&quot; },
  { term: &quot;FAR&quot;, definition: &quot;False Acceptance Rate -- probability a biometric system accepts an unauthorized person&quot; },
  { term: &quot;NIR&quot;, definition: &quot;Near-infrared imaging -- camera technology used by Windows Hello for anti-spoofing&quot; },
  { term: &quot;WebAuthn&quot;, definition: &quot;W3C standard browser API for public-key-based authentication&quot; },
  { term: &quot;VBS&quot;, definition: &quot;Virtualization-Based Security -- hypervisor isolation for secure processing&quot; },
  { term: &quot;ESS&quot;, definition: &quot;Enhanced Sign-in Security -- VBS-isolated biometric matching in Windows 11&quot; },
  { term: &quot;Passkey&quot;, definition: &quot;FIDO2 credential that can be synced across devices via credential managers&quot; },
  { term: &quot;FIDO2&quot;, definition: &quot;Industry standard for passwordless authentication (WebAuthn + CTAP)&quot; },
  { term: &quot;Cancelable biometrics&quot;, definition: &quot;Revocable biometric templates using non-invertible transformations&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows-hello</category><category>authentication</category><category>biometrics</category><category>fido2</category><category>passkeys</category><category>security</category><category>tpm</category><author>noreply@paragmali.com (Parag Mali)</author></item></channel></rss>