Inside the Primary Refresh Token: The Cryptographic Seam Between Windows Logon and Microsoft Entra ID
How one TPM-bound JWT issued at first sign-in bridges Windows logon and Microsoft Entra ID -- and how Pass-the-PRT taught Microsoft to bind the derivation to the message.
Permalink1. Three sign-ins, one credential
A user signs into a freshly enrolled Entra-joined laptop with Windows Hello for Business. Ten seconds later they open Outlook, which silently authenticates against Microsoft 365. An hour later they type outlook.office.com into Edge -- and they are already signed in there too.
Three sign-ins, one credential. The credential was issued during the Windows logon itself, and the user has never seen it.
This article is about that credential -- the Primary Refresh Token -- and about the cryptographic seam where Windows logon stops being a local NT-style event and becomes a Microsoft Entra ID transaction.
A device-bound JSON Web Token issued by Microsoft Entra ID to the Cloud Authentication Provider in lsass.exe at first interactive sign-in on a Microsoft Entra-registered, Entra-joined, or Entra-hybrid-joined device. The PRT is the artifact every other token broker on the device references to mint app access tokens, browser SSO cookies, and Conditional Access claims for the lifetime of the sign-in session [1].
The questions worth asking are concrete. What does that token actually contain? How did it get from lsass to a browser cookie without the user ever pasting it? Why is the cookie that rides in the browser called x-ms-RefreshTokenCredential when the PRT itself never leaves the device? And -- the question that will define everything in §5 and §6 -- if the credential is bound to a TPM, how did three independent researchers in the summer of 2020 mint cookies anywhere they wanted to?
The plan is to answer those questions in order. We will name every load-bearing primitive in the stack. We will walk a token request end-to-end. We will explain what the July 2021 KDFv2 patch actually changed at the byte level. And we will be honest about what the PRT cannot do -- because the rest of this series is about the identity surfaces that run alongside it, not under it.
Before we can read the PRT itself, we have to understand the problem it was built to solve. That means going back to 2013, before Azure AD Join was a thing.
2. The cloud-identity gap, 2011 to 2014
Windows authentication, in 2011, did not speak cloud. NTLM resolved against a local SAM database. Kerberos resolved against an on-prem Key Distribution Center. Both predate the notion of a cloud identity provider by more than a decade. When a Windows endpoint authenticated, it talked to a domain controller it could see on the network -- and if it could not see a domain controller, it talked to the local SAM and called it a day.
For a cloud-only workload, that left a gap shaped like a question. Where, exactly, does the user's identity live when there is no on-prem domain to resolve it against?
The first answer was OAuth. RFC 6749 had shipped in October 2012, edited by Dick Hardt while at Microsoft, with refresh tokens explicitly modeled as long-lived bearer credentials redeemed at a token endpoint for short-lived access tokens [2]. Microsoft's Active Directory Authentication Library -- ADAL -- took the obvious next step: every application that wanted to talk to Microsoft's cloud APIs got its own client, its own redirect, and its own refresh token. SSO was approximated by sharing the underlying password prompt or, on a domain-joined machine, by hoping Integrated Windows Authentication smuggled the right Kerberos ticket to the right endpoint.
That patchwork held for a while. It also taught Microsoft two things.
The first lesson was about Conditional Access. If every app maintained its own refresh-token cache and re-presented credentials independently, the policy engine could only see what each token request happened to surface. Whether the request came from a managed Surface or from an unmanaged consumer laptop was anyone's guess. The device, in other words, was invisible.
The second lesson was about the user. Ten apps meant ten silent renewal pipelines, ten password prompts when those pipelines broke, and ten different broker components asking "are you sure?" in slightly different language. The user experience and the security posture were on the same side of the ledger: both wanted a single device-bound credential that every broker could reference.
The first move was small. On 28 June 2013, Adam Hall announced Workplace Join as part of Windows Server 2012 R2: a device-registration primitive that put an X.509 certificate from the Device Registration Service into Active Directory, so that "users can register their device using Workplace Join which creates a new device object in Active Directory and installs a certificate on the device, allowing IT to take into account the user's device authentication as part of conditional access policies" [3].
Workplace Join taught the directory that a device existed. It did not make the Windows sign-in itself a cloud event. The artifact it produced was a long-lived certificate, not a session-scoped credential, and it lived on the on-prem AD side of the seam, not the cloud side. For the rest, Microsoft would need a credential the cloud could mint during the sign-in.
That credential arrived in 2015 -- but its design took another year to harden.
3. Workplace Join, Azure AD Join, and the OAuth-refresh-token patchwork
What does it cost a Windows endpoint to authenticate to ten cloud apps if it has no PRT?
Counting tokens is a good way to find out. Each app maintains its own refresh-token cache. Each refresh redeems against the same login.microsoftonline.com endpoint but with a different client_id and a different audience claim. Each app re-asserts the device claim as a separate transaction -- if it can; an app that does not ride a broker can only surface what its own credential flow knows. The architectural failure mode is not that authentication is bad; it is that authentication is redundant, and the policy engine sees a hundred small claims instead of one big one.
Microsoft walked out of that failure mode in three steps.
Step one (June 2013): Workplace Join. A device cert, signed by the Device Registration Service, written to a new device object in Active Directory. Adam Hall's announcement is the load-bearing primary source [3]. Nothing about a session: the certificate lives across reboots, across sign-ins, across user accounts. Microsoft now calls this state Microsoft Entra registered -- the same primitive, renamed [4].
"Workplace Join" was the 2013 marketing name. The same artifact is now called "Microsoft Entra registered" and is the device state used for personal (BYOD) devices that get conditional-access policies applied to corporate workloads. The taxonomy in §3 of the current Microsoft Learn documentation lists three states: Microsoft Entra registered, Microsoft Entra joined, and Microsoft Entra hybrid joined [4].Step two (May 2015): Azure AD Join. On 28 May 2015, Alex Simons and Gary Henderson announced that Windows 10, build 1507, would let a device sign in against a cloud-only Microsoft identity at first boot. "Azure AD join is optimized for users that primarily access cloud resources," the announcement reads -- a quiet way of saying that for the first time, a Windows machine did not need a domain controller on the network to give a user a sign-in surface [5].
This 28 May 2015 Tech Community post is the corrected primary source. An older URL in the same series (.../ba-p/247010) was re-tagged by Microsoft's CMS to a 2010 RemoteFX article and now resolves to unrelated content; the 244005 post is the load-bearing technical announcement.
The Azure AD Join story introduced one more component: CloudAP, the Cloud Authentication Provider, an authentication-package framework hosted inside lsass.exe. CloudAP is the LSASS-resident broker that an enterprise SSO surface talks to from inside the operating system. It is not yet a PRT engine -- in May 2015, it is mostly a routing layer for cloud sign-in primitives. The PRT itself does not exist yet.
A pluggable authentication-package framework introduced inside lsass.exe to host cloud-identity sign-in plugins. The Microsoft Entra ID plugin (aadcloudap.dll) is the canonical implementation; CloudAP is the LSASS-resident broker that, from Windows 10 1607 onward, owns the device-side PRT lifecycle on Entra-joined and Entra-hybrid-joined machines [1].
Step three (August 2016): the first PRT. Windows 10, version 1607 -- the Anniversary Update -- began rolling out on 2 August 2016 [6]. In that build, CloudAP gained an Entra ID plugin that minted a PRT during interactive sign-in, alongside a TPM-bound key pair for proof of possession. From that moment, every other broker on the machine -- the Web Account Manager that backed native apps, Edge for browser SSO, third-party mstsc flows that wanted to redirect a sign-in -- had a single artifact to reference. The architectural gap from §2 closed; the patchwork became a stack.
By the time Microsoft Open Specifications publication MS-OAPXBC went public on 16 October 2015, version 1.0 -- contemporaneous with the Windows 10 1507 release, not three years later -- the protocol scaffolding was already in place [7]. The PRT itself was the credential the scaffolding had been waiting for.
By 2016, Microsoft had a name for the missing primitive: one device-bound, session-scoped, cloud-issued credential that all brokers could reference. The Anniversary Update made it real. The next question is what that credential is cryptographically -- and to answer that, we need to be precise about two key pairs that most descriptions of the PRT conflate.
Diagram source
timeline
title PRT generations, 2013 to 2022
2013 : Workplace Join (Windows Server 2012 R2)
: Device cert in AD; no session credential
2015 : Azure AD Join (Windows 10 1507)
: CloudAP framework in lsass; no PRT yet
2016 : First PRT (Windows 10 1607)
: CloudAP + Entra plugin issue device-bound JWT
2020 : Pass-the-PRT class disclosed
: Christensen + Mollema + Syynimaa
2021 : KDFv2 (CVE-2021-33779)
: SHA256 of payload mixed into derivation
2022 : CAE GA + Cloud Kerberos Trust + TROOPERS 22
: Composition era begins 4. The two-key cryptographic model
Most descriptions of the PRT online say the cookie is "DKey-signed." That phrase has been wrong since July 2021. Here is the actual cryptographic substrate.
When a Windows device joins Microsoft Entra ID -- by way of the Out-of-Box Experience, by dsreg's join command, or by the implicit registration that happens on a personal device -- the registration component generates two key pairs on the device. One pair signs PRT issuance requests. The other unwraps session keys returned with the PRT. Microsoft's own documentation enumerates the two pairs the dsreg component generates at device registration: Device key (dkpub/dkpriv) and Transport key (tkpub/tkpriv) [1].
The first of the two key pairs minted at Microsoft Entra registration. The private half (dkpriv) is TPM-resident on supported hardware (TPM 2.0 from Windows 10 1903 onward) and signs the JWT used to request a Primary Refresh Token from Microsoft Entra ID. The public half (dkpub) is registered with Microsoft Entra ID at join time and is what Entra ID uses to verify that the request originated from the registered device [1].
The second registration-time key pair. Entra ID encrypts the freshly minted PRT session key under tkpub; only tkpriv -- TPM-resident on supported hardware -- can unwrap it. Every downstream signing operation flows through a key derived from that session key, so the transport key is the asymmetric on-ramp to the device's symmetric proof-of-possession surface [1].
The Windows component that performs Microsoft Entra registration -- mints the device and transport key pairs, registers dkpub/tkpub with Entra ID, and produces the device certificate that backs the Microsoft Entra device object. dsregcmd.exe is its operator-facing interrogation tool; dsregcmd /status reports current state including AzureAdPrt, AzureAdPrtUpdateTime, and AzureAdPrtExpiryTime [1].
The two-key model is not a typo, and the second-most-common reading of it is wrong. The device key signs the request for a PRT. The transport key unwraps the session key that arrives with a PRT. Once unwrapped, the session key signs everything from there on -- not the device key.
The eight-step issuance flow makes this explicit.
Diagram source
sequenceDiagram
participant User
participant CloudAP as CloudAP (lsass)
participant TPM
participant Entra as Microsoft Entra ID
participant CA as Conditional Access
participant WAM
User->>CloudAP: 1. Interactive sign-in (Hello, password, FIDO2)
CloudAP->>TPM: 2. Sign authorization JWT with dkpriv
TPM-->>CloudAP: 3. Signed assertion
CloudAP->>Entra: 4. Issuance request (signed assertion)
Entra->>CA: 5. Evaluate device + user + risk claims
CA-->>Entra: 6. Issuance permitted
Entra-->>CloudAP: 7. PRT + session_key encrypted under tkpub
CloudAP->>TPM: 8. Unwrap session_key with tkpriv
Note over CloudAP,WAM: Session key now resident -- WAM, browser SSO, and CAE all derive from it A user provides an interactive credential -- a Hello gesture, a password, a FIDO2 security key. The CloudAP plugin in lsass constructs a JWT carrying the user's authorization material and asks the TPM to sign it with dkpriv. That signed assertion goes to Microsoft Entra ID. Entra evaluates Conditional Access; if the device, the user, and the risk profile pass policy, Entra returns a PRT (a long-lived JWT) and a fresh session key encrypted under tkpub. The TPM unwraps the session key with tkpriv. The session key now lives on the device, in CloudAP's hot path, available for every broker to use.
The symmetric key Microsoft Entra ID generates per PRT mint and returns to the device encrypted under tkpub. After the TPM unwraps it with tkpriv, the session key is the proof-of-possession key for the PRT lifetime: every renewal request, every x-ms-RefreshTokenCredential cookie, and every app-token request signed via the Web Account Manager is HMAC-signed by a key derived from the session key via SP800-108 KDF [1] [8].
The session key is the part the rest of this article keeps coming back to. It is the artifact that, in 2020, three independent researchers would prove the TPM was not protecting in the way Microsoft's documentation implied.
Once the session key is on the device, the Web Account Manager (WAM) -- the user-mode broker process that handles native-app token requests -- and the browser SSO surface used by Edge, Chrome, and Firefox can mint subordinate artifacts. The most interesting one is a cookie.
The Windows user-mode broker that mediates access-token requests from native applications to Microsoft Entra ID. WAM presents each app-token request alongside a PRT-derived signed assertion, eliminating the per-app refresh-token cache that the pre-2016 ADAL design required. WAM is the Windows analogue of the Microsoft Enterprise SSO plug-in for Apple devices [1] [9].
The HTTP cookie Edge, Chrome, and Firefox attach to requests against login.microsoftonline.com and a small set of Microsoft cloud surfaces. It carries a JWT signed with alg: HS256 whose header field kdf_ver indicates whether the cookie used KDFv1 or KDFv2 derivation [8]. The cookie is what makes the third sign-in in the §1 hook -- the silent Edge sign-in to outlook.office.com -- not require a credential prompt.
On supported hardware, both dkpriv and tkpriv are non-extractable TPM 2.0 keys. On a device with Microsoft Pluton (a TPM 2.0 implementation embedded in the SoC), the same model applies; Pluton is a TPM 2.0 implementation, not a replacement. On non-TPM Windows -- a virtual machine without a vTPM, a desktop where the TPM is disabled, certain consumer SKUs -- DPAPI is the fallback. DPAPI-protected keys live in user-profile state and can be unwrapped with the user's credentials, which is a meaningfully weaker contract than TPM non-extractability. We will come back to that distinction in §9.
If both keys live in the TPM and the cookie is signed with a key derived from a TPM-resident session key, the whole architecture should make Pass-the-PRT impossible. In 2020, three independent researchers proved it didn't.
5. When TPM-binding is not enough
In July 2020, two researchers, working independently, asked the same question: if the session key is in the TPM, can I still mint a PRT cookie?
The answer, on the architecture Microsoft shipped at the time, was yes -- and the answer came from three angles in less than two months.
"A Primary Refresh Token can be compared to a long-term persistent Ticket Granting Ticket (TGT) in Active Directory... the Primary Refresh Token however can be used to authenticate to any application, and is thus even more valuable. This is why Microsoft has applied extra protection to this token." -- Dirk-jan Mollema, 21 July 2020
Lee Christensen at SpecterOps, mid-July 2020. Christensen's blog post -- "Requesting Azure AD Refresh Tokens on Azure AD-joined Machines for Browser SSO" -- documented a path through a Component Object Model interface, IProofOfPossessionCookieInfoManager.GetCookieInfoForUri, that returned a fully signed x-ms-RefreshTokenCredential cookie to a user-mode caller [11]. The CLSID is {a9927f85-a304-4390-8b23-a75f1c668600}; the implementation lives in MicrosoftAccountTokenProvider.dll; the workflow rides through BrowserCore.exe over a named pipe. Christensen released the proof-of-concept as RequestAADRefreshToken on GitHub [12]. An attacker -- specifically, a process running as the signed-in user -- could call the COM interface, lift the cookie, and paste it into a browser running anywhere on the planet.
The COM-API path did not require admin. It did not require touching the TPM. It did not need to know anything about the session key. The operating system politely produced a signed cookie because that is what the COM API was built to do, and the contract did not distinguish the legitimate browser from the attacker process.
Dirk-jan Mollema, 21 July 2020. A week later, Mollema published "Abusing Azure AD SSO with the Primary Refresh Token" on dirkjanm.io. Mollema's framing was different: he wanted to understand the PRT as a forensic artifact. The blog opens with the TGT analogy quoted above and explicitly attributes parallel discovery to Christensen [13]. The toolchain he documented, ROADtoken, lived inside the larger ROADtools framework that he was building for offensive Azure AD research [14]. The threat model was the same as Christensen's: an attacker on the live device could mint cookies, and the TPM was not in the way.
Mollema, 5 August 2020. This is the blog that mattered most. In "Digging further into the Primary Refresh Token," Mollema reverse-engineered aadcloudap.dll. He isolated the session-key handling, the cookie-construction routine, the SP800-108 derivation call, the eventual BCryptKeyDerivation-then-HMAC flow. And he wrote the sentence that, in retrospect, defined the next year of Microsoft's response: "despite the session key of the PRT is stored in the TPM whenever possible, this doesn'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" [15].
"despite the session key of the PRT is stored in the TPM whenever possible, this doesn't prevent us from extracting the PRT and the required information to create SSO cookies." -- Dirk-jan Mollema, 5 August 2020
The reason is the most important thing in this article. The session key never left the TPM. But the signing key derived from the session key did. The TPM dutifully performed an SP800-108 derivation -- HMAC-SHA256 with the label AzureAD-SecureConversation and the client-chosen ctx value -- and returned the derived key to caller memory. The TPM was protecting the root of the derivation, not the output of it. Once the derived key materialized in lsass, an admin-with-debug-privilege attacker could simply read it.
Around the same time, Benjamin Delpy -- the author of Mimikatz -- picked up Mollema's "challenge" of recovering PRT data from lsass. Two days after Mollema's 5 August post, that collaboration produced the Mimikatz release tagged 2.2.0-20200807, which added the sekurlsa::cloudap and dpapi::cloudapkd modules [16]. The tag URL itself was later collapsed in GitHub's modern UI -- it returns 404 today, almost certainly because of repeated takedown requests during the Azure-PRT release period -- but a Wayback Machine snapshot from 20 September 2020 preserves the release page and proves the tag existed at the time [17].
https://github.com/gentilkiwi/mimikatz/releases/tag/2.2.0-20200807 returns HTTP 404 in the current GitHub UI; the modern releases list starts at 2.2.0-20210729. The Wayback snapshot at web.archive.org/web/20200920005113/... preserves the release page (including the "prt3" animated demonstration GIF). Nestori Syynimaa's AADInternals post and Mollema's 5 August 2020 blog both reference the same tag URL, which is how we know the artifact was real [17] [18] [15].
Nestori Syynimaa and AADInternals, August through September 2020. Syynimaa's AADInternals PowerShell module shipped Get-AADIntUserPRTToken as part of v0.4.1 alongside the disclosure. On 29 September 2020, AADInternals' blog post about the tool gained an inline update: "It seems that PRT tokens must now include the request_nonce. If not, Azure AD sends a redirect with sso_nonce which must be added to the PRT token. This means that without access to session key, PRT tokens can't be used anymore" [18]. That update is the first observable Microsoft mitigation: Entra ID began demanding that PRT cookies contain a server-issued nonce. It bought time. It did not solve the architectural problem.
Diagram source
sequenceDiagram
participant Attacker
participant LSASS
participant TPM
participant COM as IProofOfPossessionCookieInfoManager
participant Entra as Microsoft Entra ID
Note over Attacker,LSASS: Attacker has user or admin on the live device
Attacker->>LSASS: sekurlsa::cloudap (admin path)
LSASS-->>Attacker: PRT + derived signing key + context
Note over Attacker: Or, parallel user-only path:
Attacker->>COM: GetCookieInfoForUri(target_url)
COM-->>Attacker: Pre-baked x-ms-RefreshTokenCredential
Note over Attacker: Cookie is now portable
Attacker->>Entra: Replay cookie from an attacker-controlled host
Entra-->>Attacker: SSO honored, access token issued The community quickly settled on a name for this class: Pass-the-PRT. By analogy to Pass-the-Hash and Pass-the-Ticket, the attack is "lift a long-lived authentication artifact from one host, present it as your own elsewhere." For a credential that the entire cloud sign-in stack was about to trust, the implications were severe.
By September 2020 Microsoft had bolted a nonce onto the cookie. By July 2021 they had something architecturally different: a single SHA-256 over the cookie's full payload that killed off-device Pass-the-PRT for good.
6. KDFv2 and the death of off-device Pass-the-PRT
The fix Microsoft shipped on 13 July 2021 fits on one line.
The CVE is CVE-2021-33779. NIST's National Vulnerability Database describes it as "Windows AD FS Security Feature Bypass Vulnerability" and provides no further public detail [19]. Microsoft's own KDFv2 documentation ties the patch explicitly to that CVE: "On July 13, 2021, updates were released for AD FS to address token replay attacks, as described in CVE-2021-33779. These updates introduce new settings to enable and control a new, Key Derivation Function (KDF) called KDFv2" [20].
The version-2 key-derivation rule introduced for the x-ms-RefreshTokenCredential cookie on 13 July 2021. Under KDFv2, the SP800-108 KDF context is SHA256(ctx || assertion_payload) rather than the bare client-chosen ctx value. The JWT header field kdf_ver carries the value 2 to indicate that KDFv2 was used. KDFv1 is preserved for backward compatibility but is disabled by default on a service that has been moved to "Enforced" mode [8] [20].
A small subtlety lives in the attribution. NVD names AD FS. The community-side coverage -- blog.3or.de, Mollema's TROOPERS 22 deck, AADInternals -- names PRT-cookie forgery. The Microsoft KDFv2 page sits in the middle: it ties the patch to CVE-2021-33779 and walks through the same derivation change that closed off-device Pass-the-PRT, but it does not use the term "Pass-the-PRT" on the page itself. We will keep the hedge in mind.
The load-bearing rule is one sentence. MS-OAPXBC §3.2.5 puts it like this: "If the client chooses to use KDFv2, the client MUST use SHA256(ctx || assertion payload) instead of ctx as the context for deriving the signing key. The client MUST also add the JWT header field kdf_ver with value set to 2 to communicate that KDFv2 was used for creating the derived signing key" [8].
To see why that line matters, picture what the attacker in §5 was actually copying. The attacker lifted the derived signing key out of lsass. The derived signing key was, under KDFv1, a function of the session key (TPM-resident) and the client-chosen context ctx (any 256 bits the attacker liked). Any cookie the attacker built using the same ctx would verify against the same derived key. The attacker could pick ctx first, derive the key once, and stamp out as many cookies as they wanted.
Under KDFv2, the context is no longer arbitrary. The context is SHA256(ctx || assertion_payload). The assertion_payload is the JWT body the cookie is trying to assert. Change a single claim in the body, and the SHA-256 hash changes, and the SP800-108 derivation produces a different key. A key derived for one cookie cannot sign any other cookie. There is nothing to precompute.
The residual is also explicit. The attacker who is still on the device -- still has a process running as the user or as SYSTEM -- can ask CloudAP to mint a fresh cookie. The TPM happily performs the new SHA-256-bound derivation, because that is its job; CloudAP returns the signed cookie to the calling process, because that is its job. The blog.3or.de reverse-engineering names this class precisely: "This attack, referred to as Pass-the-PRT-Cookie, still works today but requires presence on the targeted device" [10]. Mollema's TROOPERS 22 talk calls the same residual "Cookie-on-Demand" and walks the in-place cookie-minting flow on a fully patched Entra-joined endpoint [21] [22].
The minimal cryptographic statement of the fix is small enough to write down. Let be HMAC-SHA256, be the session key, be the constant label AzureAD-SecureConversation, be the per-cookie context, and be the JWT body to be signed. Under KDFv1, the derived signing key was . Under KDFv2, the derived signing key is . The difference is exactly the hash of the message body inside the derivation context.
// Illustrative; do NOT use as production crypto.
const crypto = require('crypto');
function sha256(buf) { return crypto.createHash('sha256').update(buf).digest(); }
function hmac(key, data) { return crypto.createHmac('sha256', key).update(data).digest(); }
function deriveKdfv2SigningKey(sessionKey, ctx, assertionPayload) {
const label = Buffer.from('AzureAD-SecureConversation', 'utf8');
const boundCtx = sha256(Buffer.concat([ctx, assertionPayload]));
// SP800-108 KDF in counter mode is more involved; one HMAC stands in here.
return hmac(sessionKey, Buffer.concat([label, boundCtx]));
}
// The signing key is now uniquely tied to assertionPayload. Press Run to execute.
A side-by-side flowchart makes the structural shift legible.
Diagram source
flowchart LR
subgraph KDFv1 ["KDFv1 (pre-July 2021)"]
A1[Session key in TPM] --> A2["SP800-108 KDF
label = AzureAD-SecureConversation
context = ctx"]
A2 --> A3[Derived signing key]
A3 --> A4[HMAC over any JWT body]
end
subgraph KDFv2 ["KDFv2 (July 2021+)"]
B1[Session key in TPM] --> B2["SP800-108 KDF
label = AzureAD-SecureConversation
context = SHA256 of ctx || payload"]
B2 --> B3[Derived signing key]
B3 --> B4[HMAC over the specific JWT body]
end KDFv2 killed off-device replay. It did not kill the on-device signing oracle, and it did not shorten the PRT's 90-day lifetime. The next generation tackled both -- not by closing the on-device gap, which is architecturally hard, but by making issued access tokens revocable in seconds.
7. The seam: CAE, Token Protection, Cloud Kerberos Trust
By 2022 the PRT was the credential. The work that remained was to make every artifact issued from it -- every access token, every Kerberos TGT, every Conditional Access claim -- share the same device-binding contract.
That work has three named pieces, and a quiet rename in the middle.
Continuous Access Evaluation
Continuous Access Evaluation entered public preview in late 2020, a few months after Mollema's August blog. By 10 January 2022, Microsoft announced General Availability across Microsoft Entra ID; the announcement post came from Alex Simons, Corporate Vice President for Program Management in the Microsoft Identity Division [23]. CAE is the mechanism by which a long-lived access token issued from a PRT can be invalidated in seconds when something critical changes.
An industry-standard near-real-time revocation channel for OAuth access tokens, implemented by Microsoft Entra ID as a claim-challenge protocol between Entra and CAE-aware resource providers. CAE is anchored in the OpenID Continuous Access Evaluation Profile (CAEP) [24]. CAE-aware resources reject a previously valid access token when Entra signals one of five critical events: user account deletion or disablement, password change, MFA enablement, admin token revocation, or high user-risk classification. Microsoft Learn documents an event-propagation upper bound of 15 minutes, with IP-location enforcement instantaneous [25].
Mechanically: a CAE-aware client requests an access token from Entra ID, and Entra issues a long-lived token -- up to 28 hours rather than the conventional one hour -- with a xms_cc claim signaling that the bearer understands the protocol. The resource provider serves requests against that token. When something changes -- the user gets disabled in HR, the IT admin resets the password, a sign-in trips a high-risk classification -- Entra ID fires a CAEP event. The resource provider receives the event and, on the next request, returns an HTTP 401 with a WWW-Authenticate claim challenge. The client returns to Entra, presents the PRT, and asks for a fresh access token; Entra evaluates Conditional Access at that moment and either issues a new token or refuses. The user sees, at worst, a fast re-authentication; the access window for the revoked credential is on the order of seconds rather than the access token's original lifetime.
Diagram source
sequenceDiagram
participant Admin
participant Entra as Microsoft Entra ID
participant Resource as Exchange Online
participant Client
Admin->>Entra: Force password reset for user
Entra-->>Resource: CAEP event: Credential Change
Client->>Resource: GET /mail (with long-lived token)
Resource-->>Client: 401 WWW-Authenticate (claim challenge)
Client->>Entra: Refresh token + claim challenge
Note over Entra: Re-evaluate Conditional Access against current user state
Entra-->>Client: New short access token (or deny)
Client->>Resource: GET /mail (new token)
Resource-->>Client: 200 OK The initial CAE deployment was constrained: only Exchange Online, SharePoint Online, and Teams understood the claim-challenge protocol at GA [25]. Microsoft Graph followed. Other workloads still honor an access token until natural expiry, which is the open scope of the §9 caveat list.
Token Protection
If CAE is the time dimension, Token Protection is the space dimension. The Conditional Access feature, also referred to as "token binding," demands that an app-token request originate from a device-bound session token -- in practice, a PRT-signed assertion. The Microsoft Learn page defines it as a "Conditional Access session control that attempts to reduce token replay attacks by ensuring only device bound sign-in session tokens, like Primary Refresh Tokens (PRTs), are accepted by Microsoft Entra ID when applications request access to protected resources" [26].
A Microsoft Entra Conditional Access session control that enforces device-bound sign-in for app-token requests against supported resources. Token Protection is the per-app analogue of the PRT's device-binding contract: every access token must originate from a device-bound session token. As of 2026, Token Protection is generally available on Windows for Exchange Online, SharePoint Online, Teams, Azure Virtual Desktop, and Windows 365; it is in preview on iOS/iPadOS and macOS via the Microsoft Enterprise SSO plug-in [26] [9].
The current scope is intentionally narrow. Native applications and the Microsoft Enterprise SSO plug-in for Apple devices both implement the device-bound assertion. Browsers do not. A browser visiting a Microsoft cloud resource still rides the x-ms-RefreshTokenCredential cookie path. Closing that gap is what Device Bound Session Credentials -- the cross-vendor web standard Microsoft co-designed with Google -- exists to do, and we will return to that in §10.
Cloud Kerberos Trust
The third piece bridges the cloud-mediated PRT path back to on-prem Kerberos. The mechanism is simple in framing and intricate in implementation: Microsoft Entra ID provisions a virtual AzureADKerberos read-only domain controller object inside the on-prem Active Directory domain, and an Entra-signed partial Kerberos TGT issued to a Hello-for-Business-signed-in device can be exchanged at any on-prem DC for a fully-formed TGT carrying SID and authorization data.
A Microsoft Entra ID mechanism by which Entra ID can mint Kerberos TGTs for one or more Active Directory domains. An Entra-signed partial TGT carries the user's identity; an on-prem domain controller, holding the cryptographic shared key represented by the virtual AzureADKerberos RODC computer object, completes the TGT with on-prem SID and group claims. The bridge requires Windows 10 21H2 (with KB5010415+) or later, and a Windows Server 2016+ functional level on the domain controller; it shipped in April-June 2022 [27] [28].
The Microsoft Learn deployment guide is explicit about the AzureADKerberos object's role: "When Microsoft Entra Kerberos is enabled in an Active Directory domain, an AzureADKerberos computer object is created in the domain. This object: Appears as a read only domain controller (RODC) object, but isn't associated with any physical servers; Is only used by Microsoft Entra ID to generate TGTs for the Active Directory domain" [27]. The architectural property to notice is that the user's NTLM hash is not the binding key. Microsoft Entra ID never holds the on-prem NTLM hash; the cryptographic root is the AzureADKerberos RODC's keys, which Entra and the on-prem domain controller share without involving any user-side long-term secret.
Cloud Kerberos Trust is the Kerberos PKINIT pattern from RFC 4556 [29], reframed: the cloud identity provider is the public-key initial authenticator, and Entra ID issues the partial TGT exactly as a PKINIT-aware KDC would.
The Azure AD to Microsoft Entra ID rename
In the middle of all this, on 11 July 2023, the brand changed. Microsoft renamed Azure Active Directory to Microsoft Entra ID and consolidated several adjacent products under the Microsoft Entra umbrella [30]. The article uses "Microsoft Entra ID" throughout; in primary sources from before July 2023, the same product is "Azure AD." The rename is real, and it matters when citing older documentation, but it does not change the protocol surface.
The seam restated
With Continuous Access Evaluation, Token Protection, and Cloud Kerberos Trust in place, the picture from §1 fills out. Every cloud-mediated identity feature on a modern Windows endpoint either issues, refreshes, presents, or evaluates a PRT. The PRT itself is the asymmetric handshake that binds the device. CAE makes the time dimension elastic. Token Protection makes the access surface device-bound at the resource-request layer. Cloud Kerberos Trust makes the on-prem Kerberos surface reachable from a PRT-bearing device.
The PRT is the cryptographic seam: a single device-bound credential, issued at first sign-in, that every other identity artifact on the device references. CAE, Token Protection, and Cloud Kerberos Trust are not three different bindings; they are three different ways the same PRT contract reaches three different surfaces -- the revocation surface, the per-resource access-token surface, and the on-prem Kerberos surface.
A small comparison matrix makes the support story explicit.
| Resource / scenario | CAE-aware | Token Protection (Windows GA) | Cloud Kerberos Trust |
|---|---|---|---|
| Exchange Online | Yes | Yes | n/a |
| SharePoint Online | Yes | Yes | n/a |
| Microsoft Teams | Yes | Yes | n/a |
| Microsoft Graph | Yes | Not enforced | n/a |
| Azure Virtual Desktop | Partial | Yes | n/a |
| Windows 365 | Partial | Yes | n/a |
| On-prem file share | n/a | n/a | Yes |
| Browser (any Microsoft cloud) | Indirect via resource | No (native apps only) | n/a |
That is what the PRT does. But four sibling articles in this series describe identity surfaces the PRT does not cover. Before we celebrate the seam, we have to be honest about where it stops.
8. Where PRT is not the answer
The PRT carries device state, MFA state, and Conditional Access claims for the cloud-mediated identity path. There is no clause in that sentence that mentions on-prem Kerberos, NTLM hashes, local admin authorization, or workload identities -- and that is the point.
Five surfaces the PRT does not cover, in the order operators most often confuse them:
On-prem Kerberos via the on-prem KDC. A Windows user signing into a domain-joined or hybrid-joined machine still mints a Kerberos TGT against the on-prem Key Distribution Center on Windows logon. The PRT path is parallel, not replacement. The user's downstream kerberos.dll ticket cache is populated by Kerberos AS_REQ/AS_REP exchanges between the workstation and the on-prem DC; the PRT lives in CloudAP's memory in lsass and does not influence that flow. Cloud Kerberos Trust adds a bridge from PRT to on-prem TGT for users whose primary credential is in Entra; it does not retire the on-prem Kerberos path.
Credential Guard and LSAISO. Credential Guard, introduced on the Enterprise SKU of the original Windows 10 release in 2015, isolates NTLM hashes and Kerberos long-term keys inside the Local Security Authority Isolated Subsystem (LSAISO), which runs in Virtual Trust Level 1 (VTL1) on top of the Hyper-V hypervisor [31] [32]. Credential Guard predates the cloud-identity model entirely; its threat model is on-prem credential theft via long-term-key extraction from lsass. The load-bearing distinction for the threat model is this: PRT material does NOT live in LSAISO. It lives in normal lsass.exe under CloudAP. Mollema's August 2020 extraction worked because the PRT's session-key handling is in the same address space as ordinary user processes that hold debug privilege; LSAISO did not move there. Treat "I have Credential Guard enabled" and "my PRT is hardware-isolated" as independent statements.
krbtgt keys, the kinds of long-term secrets that the 2010s-era "Pass-the-Hash" tooling was designed to extract. The PRT's session key is a per-PRT artifact that lives in CloudAP's memory under normal LSASS. Credential Guard protects you against a different attack class. Get it for those reasons; do not get it expecting PRT-class mitigation.
Adminless and local-admin removal. "Adminless" is an authorization pattern -- removing standing local-admin rights, requiring just-in-time elevation -- not an authentication pattern. It is orthogonal to the PRT. A device can be PRT-bound and still have a thousand local admins; a device can have zero local admins and still mint PRTs. The PRT addresses "who is signing in;" Adminless addresses "what they can do once signed in." Conflating them is a common rhetorical move in Microsoft documentation and a common source of confusion in audits.
App Identity, managed identities, and workload identities. Workloads in Microsoft cloud environments authenticate through a separate broker path: the Azure Instance Metadata Service (IMDS) on VMs, Workload Identity Federation for cross-cloud Kubernetes flows, managed identities on Functions and App Service. None of these always involve a PRT. A managed identity is a non-human principal in Entra ID with a system-issued credential, not a device-bound JWT, and the broker path that produces its access tokens is structurally different. The App Identity sibling article addresses that surface in detail.
Remote Credential Guard versus Azure AD RDP sign-in. These two are often introduced together because both involve credentials over RDP, and conflating them is the load-bearing threat-model error in this section. Remote Credential Guard redirects Kerberos credentials over the RDP hop: the client's TGT is reachable to the remote mstsc session via a CredSSP-mediated redirection mechanism, so that the remote session can fetch downstream service tickets without re-prompting. It does not transport PRT material across the connection. Azure AD RDP sign-in -- the separate scenario where the RDP host itself is Entra-joined and accepts an Entra sign-in at session establishment -- is the PRT-mediated path, and it happens at the host side, not as a redirection from the client.
The pattern across all five is the same. PRT is the cloud-mediated authentication path. Kerberos is the on-prem authentication path. Credential Guard is the on-prem long-term-credential isolation path. Adminless is the local-authorization pattern. App Identity is the workload-authentication path. Remote Credential Guard is an on-prem credential redirection over RDP. They run alongside each other on a modern Windows endpoint; they answer different questions. Mistaking the PRT for any of them is how good threat models go sideways.
9. Theoretical limits
The single most important sentence in the W3C Device Bound Session Credentials draft is also the single most important sentence about the PRT -- and it does not mention the PRT at all.
"DBSC will not prevent temporary access to the browser session while the attacker is resident on the user's device. The private key should be stored as safely as modern operating systems allow, preventing exfiltration of the session private key, but the signing capability will likely still be available for any program running as the user on the user's device." -- W3C Web Application Security Working Group, Device Bound Session Credentials draft
That paragraph is the architectural lower bound. Every device-bound session credential ever proposed inherits it. The PRT is no exception. Five bounded promises follow.
1. The on-device-attacker floor is architectural. A hardware-bound key whose signing surface is reachable by a same-privilege process can be used by that process for the lifetime of its presence. The TPM holds the key; the operating system mediates the signing operation; any process the operating system trusts to talk to CloudAP can ask for a signature. KDFv2 closed off-device replay because the signing key is now uniquely bound to one cookie -- but the on-device process can simply ask for the next signature. The DBSC working draft is explicit that this is the floor for the entire class [33]. The composition argument we will name in §10 is the practical response.
2. Non-TPM Windows reopens the pre-2021 attack class. When the device key and transport key are protected by DPAPI rather than by a TPM 2.0, the key material can be unwrapped with the user's profile credentials. Pre-2021 Pass-the-PRT becomes available again because the attacker is no longer trying to extract a derived signing key from lsass -- they are extracting the root of the derivation from disk. Microsoft Learn names "TPM 2.0 on Windows 10 1903 or higher" as the supported configuration; everything else is best-effort [1]. TPM 2.0 is load-bearing, not optional, for the security claims this article makes.
3. Phishing-resistance inheritance is one-shot. The PRT records the authentication strength of the issuing credential -- whether the user signed in with Hello for Business, a FIDO2 key, a password, or a password plus an MFA factor. The mfa claim on the PRT carries this through to downstream tokens. If the user authenticated with a phishable factor at issuance, every downstream access token transitively trusts that weaker factor for the PRT lifetime. The PRT does not upgrade. To enforce phishing-resistant authentication, the deployer must configure Conditional Access Authentication Strengths at the Entra ID side -- the PRT will record what arrived, but it will not refuse to mint downstream tokens because the issuing factor was weak.
4. CAE coverage is not universal. Continuous Access Evaluation is the time dimension of revocation -- but only for CAE-aware resources. Exchange Online, SharePoint Online, Teams, and Microsoft Graph honor the claim-challenge protocol; many other workloads still treat the access token as valid until its native expiry [25]. If your tenant's risk surface is a CAE-unaware first- or third-party application, the deployment-time guarantee is the access token's natural lifetime, not 15 minutes.
5. The PRT lifetime is 90 days by design. A device offline for more than the PRT lifetime cannot silently refresh; the user will see a re-authentication prompt the next time the device reaches Entra ID. That window is the Conditional Access trade-off: longer windows reduce friction for travelers and offline scenarios; shorter windows reduce the attacker's window after a device compromise. Microsoft chose 90 days; the deployer can tune it via Conditional Access Sign-In Frequency policies but cannot move it independently of the broader refresh-token configuration.
Four of the five limits are bounded -- TPM rollout, claim-strength policy, CAE rollout, offline cadence. They get smaller as Microsoft ships, as administrators tighten policy, as more resources become CAE-aware. One is architectural and applies to every device-bound session credential ever proposed: same-device admin equals access while the admin has it. That is the open problem the next section traces.
10. Open problems
Five open problems sit on the PRT model right now. None of them have a "just ship a patch" answer.
Cross-vendor near-real-time revocation. CAE works inside the Microsoft Entra perimeter. If a user is compromised at Entra and Microsoft revokes the session, the signal does not automatically propagate to Okta-protected resources, Google Workspace, AWS IAM Identity Center, or any other identity provider the same user happens to have a session against. The standardization vehicle exists: the OpenID Shared Signals Framework defines a cross-IdP event-receiver protocol, and the OpenID CAEP specification provides the event taxonomy [24]. The bilateral transmit/receive deployments are sparse. Stage 3 of the research pipeline found no public production cross-vendor CAE deployment that wires Entra revocation events into a non-Microsoft IdP. The standard is ready; the deployments are not.
DBSC and PRT composition for browser SSO. Google's Device Bound Session Credentials began general availability for Chrome 146 on Windows in late 2025, with Microsoft co-designing the standard through the W3C process [34] [33]. The Chrome developer documentation references Chrome 145 as the rollout-start build, and the Google security blog references Chrome 146 as the GA build; the version drift reflects a phased rollout, and the article uses the later figure [35]. The composition question is unresolved: when a browser on Windows visits login.microsoftonline.com, the request will carry both a DBSC-bound short cookie (per-origin) and an x-ms-RefreshTokenCredential cookie from the WAM attachment path. Which binding wins, and how the two bindings are composed in the resource provider's evaluation, has not been publicly documented. The Stage 3 research found no Microsoft engineering blog explaining the contract.
PRT-aware Conditional Access for AI agents and workload identities. As organizations deploy autonomous AI agents that act on behalf of users -- Copilot agents, Office Studio bots, third-party LangGraph-style systems -- the identity story is genuinely unsettled. Some agents authenticate as the user via delegated permissions on a PRT-mediated path. Others authenticate as their own service principal via Workload Identity Federation. Conditional Access policies designed for human users -- "require compliant device, require MFA, require sign-in frequency under four hours" -- do not map cleanly to either. Microsoft Entra Agent ID entered public preview at Ignite 2025 with Conditional Access extended to agent identities via custom security attributes and agent-identity-blueprint policy targeting [36], but the precise PRT-side claim semantics for agent-on-behalf-of-user vs autonomous-agent paths are still settling. The Conditional Access for AI Agents sibling article addresses the evolving model in detail.
PRT across RDP. There is no clean "redirect PRT" primitive analogous to Remote Credential Guard's Kerberos redirection. Inside an RDP session to an Entra-joined host, a user can perform an Azure AD RDP sign-in that mints a new PRT at the host -- but the client's PRT does not transit the RDP hop. Forensic and operational tooling that wants to know "what PRT does this remote user have, and is it the same as the client's?" has to query both endpoints separately. Active Microsoft work in this area is referenced in Mollema's TROOPERS 22 deck, but no public solution has shipped.
11. Practical guide
Here is what you actually do with the PRT this week.
Verifying PRT issuance
The operator-facing surface is dsregcmd /status, which prints the PRT state under the SSO State section. The three fields to read are AzureAdPrt (Yes if a PRT is present), AzureAdPrtUpdateTime (the timestamp of the last refresh), and AzureAdPrtExpiryTime (the absolute expiry on the current PRT, by default 90 days after issuance) [1] [37].
// Models the section of dsregcmd /status output you care about.
// On a real Windows host, you would run: dsregcmd /status | findstr AzureAdPrt
const sampleOutput = `
+----------------------------------------------------------------------+
| SSO State |
+----------------------------------------------------------------------+
AzureAdPrt : YES
AzureAdPrtUpdateTime : 2026-05-12 09:31:14.000 UTC
AzureAdPrtExpiryTime : 2026-08-10 09:31:14.000 UTC
AzureAdPrtAuthority : login.microsoftonline.com/<tenant-id>
EnterprisePrt : NO
`;
const lines = sampleOutput.split('\n').filter(l => l.match(/AzureAdPrt/));
console.log(lines.map(l => l.trim()).join('\n'));
// Healthy: AzureAdPrt=YES and AzureAdPrtUpdateTime within the last 4 hours. Press Run to execute.
If AzureAdPrt is NO on a device that should have one, the most common causes are (a) the device is not actually Entra-joined, (b) the user has never signed in interactively since the last reboot, or (c) the device's TPM is malfunctioning and CloudAP could not complete the issuance handshake. dsregcmd /status will print device-state diagnostics directly above the SSO State section that disambiguate these.
Forcing PRT renewal
The PRT refreshes silently every four hours, driven by CloudAP -- this is the renewal cadence Microsoft Learn documents as the device-side refresh schedule, not a Conditional Access policy [1]. To force an out-of-band renewal, the supported path is to sign the user out and back in with a Hello-for-Business gesture or a strong credential. A locked-and-unlocked session does not generally force a new PRT mint; CloudAP treats unlock as a continuation event, not a fresh issuance.
Hunting PRT-mediated sign-ins in Entra logs
In the Microsoft Entra audit and sign-in logs, the load-bearing fields are authenticationDetails, authenticationProcessingDetails, and the IsCompliantDevice and DeviceDetail claims attached to the sign-in event. A sign-in that rode the PRT path will surface a PRT indicator in authenticationProcessingDetails. In Microsoft Defender XDR's advanced-hunting tables, the corresponding views are IdentityLogonEvents (for on-prem and federated paths) and AADSignInEventsBeta (for native Entra sign-in events) [38]. The latter is the table to query when looking for unusual x-ms-RefreshTokenCredential-driven sign-ins -- specifically, sign-ins from device-claim-bearing tokens whose DeviceId does not match the device's DeviceId in Intune.
Conditional Access patterns
| Pattern | What it enforces | What it cannot enforce |
|---|---|---|
| Require compliant device | Sign-in only from devices Intune (or a partner MDM) reports as compliant | Whether the compliance signal is fresh; an attacker who can spoof an Intune compliance attestation passes |
| Require Microsoft Entra hybrid joined device | Sign-in only from hybrid-joined devices | Personal Entra-registered devices that meet compliance |
| Require MFA at sign-in | A fresh MFA factor at PRT issuance | Whether the MFA factor is phishing-resistant |
| Authentication Strengths (FIDO2-only) | Phishing-resistant credential at issuance, propagated as a strong mfa claim into the PRT | Downstream phishability through cookie theft (KDFv2 fix applies; on-device residual remains) |
| Token Protection for sign-in tokens | Device-bound assertion required for app-token requests | Browser sessions (DBSC is the per-origin counterpart) |
| Sign-in Frequency = 4 hours | Re-authentication every four hours | The 90-day PRT lifetime independent of sign-in cadence |
The right policy stack for most enterprises is: require compliant device (or hybrid-joined), require Authentication Strengths for privileged users, require Token Protection where the resource supports it, and set a Sign-In Frequency policy that matches your risk appetite. CAE is on by default on modern tenants and does not need explicit opt-in.
CAE enablement and tenant configuration
CAE was made the default for all Entra tenants at GA on 10 January 2022; the announcement explicitly noted that Microsoft "auto-enabled it for all tenants" [23]. Microsoft Outlook, Microsoft Teams, and Office on Windows are CAE-aware clients [25]; third-party apps that want to participate need to implement the claim-challenge protocol. Microsoft Graph clients gain CAE participation by including cp1 in the requested client capabilities [39]. If your tenant is a CAE outlier, the cause is almost always a custom OIDC application that has not implemented the claim challenge.
Forensic indicators
Three signals deserve hunting attention:
- Anomalous
x-ms-RefreshTokenCredentialcookie origins. A sign-in where the cookie's IP geolocation does not match the device's last known location -- particularly across time zones -- is a candidate Pass-the-PRT-Cookie signal even after KDFv2, because the on-device class survives. - Device-claim-bearing tokens whose
DeviceIddoes not match Intune state. An attacker who lifted a PRT off-device cannot mint cookies post-KDFv2, but a clonedDeviceIdclaim in a token request is a strong off-the-rails signal in older logs and a useful retrospective hunt for July 2021 and earlier. lsassbroker-process anomalies. Mimikatz-class memory-reading tools typically attach tolsasswith debug privileges. The current EDR generation (Microsoft Defender for Endpoint, CrowdStrike Falcon, SentinelOne) detects the canonical access patterns; deploy that telemetry, then validate the alert-rule coverage withGet-MpComputerStatusand the EDR-specific equivalents.
What NOT to do
A 60-second sanity check for an Entra-joined device
Open an elevated command prompt. Run dsregcmd /status. Confirm AzureAdJoined : YES, DeviceId is populated, and AzureAdPrt : YES with a recent AzureAdPrtUpdateTime. Then in PowerShell, run Get-CimInstance -ClassName Win32_Tpm and confirm the TPM is present, ready, and at spec version 2.0. Finally, in the Entra ID portal, search for the device by DeviceId and confirm the registration state, the OS version, and the compliance posture. Those three checks rule out 90% of "is my PRT working?" questions.
That is the PRT -- what it is, how it broke, how Microsoft fixed it, where it stops. Now the FAQ.
12. FAQ and closing
Frequently asked questions
Is the PRT the same as a Kerberos TGT?
No. They are different protocols, issued by different authorities, with different lifetimes. A Kerberos TGT is issued by an on-prem Key Distribution Center, lives 10 hours by default, and rides the AS_REQ/AS_REP protocol. A PRT is issued by Microsoft Entra ID, lives 90 days by default, and rides the MS-OAPXBC protocol over HTTPS. Cloud Kerberos Trust issues a TGT to a PRT holder via the Microsoft Entra Kerberos partial-TGT mechanism [27], but the two artifacts are distinct and serve different protocol clients.
Does the PRT replace NTLM and Kerberos?
No. The PRT is the cloud-mediated authentication path. On-prem Kerberos still flows through the on-prem KDC for resources protected by the on-prem Active Directory domain. NTLM remains in use for legacy applications until those applications migrate. The PRT, Cloud Kerberos Trust, and the in-progress "NTLM-less" effort together describe a path that reduces reliance on NTLM, but they do not delete the on-prem authentication surface on day one.
Is the PRT cookie 'DKey-signed'?
Not since July 2021. The asymmetric device key (dkpriv) signs the PRT issuance request -- a single asymmetric signature per PRT mint. The x-ms-RefreshTokenCredential cookie, by contrast, is HMAC-signed with alg: HS256 using a symmetric key derived from the PRT session key via the SP800-108 KDF. Under KDFv2, the derivation context binds the cookie's full payload via SHA256(ctx || assertion_payload) [8] [10].
Did dirkjanm.io disclose PRT extraction at DEF CON 2022?
No. Dirk-jan Mollema's seminal PRT-cookie extraction work appeared in two blog posts on dirkjanm.io -- 21 July 2020 and 5 August 2020 [13] [15]. His 2022 conference talk on the same body of research was at TROOPERS 22 in Heidelberg in June 2022, not at DEF CON 30 [22]. Mollema's DEF CON history covers DC 27 (2019), DC 32 (2024), and DC 33 (2025); he did not present at DC 30 (2022) [40]. The "DEF CON 2022" anchor that occasionally appears in summaries of the PRT-attack story is a memory error.
If my user has a PRT, are they still subject to Conditional Access?
Yes. Conditional Access evaluates each token request, including app-token requests via the Web Account Manager and x-ms-RefreshTokenCredential cookie redemptions at login.microsoftonline.com. The PRT carries device-state, MFA, and risk claims; Conditional Access uses those claims plus the resource and request context to allow or deny each request. CAE additionally revokes already-issued long-lived access tokens in near real time when critical events fire [25].
Does Pluton replace the TPM in the PRT model?
No. Microsoft Pluton is a TPM 2.0 implementation -- the same TPM 2.0 contract, embedded in the SoC rather than as a discrete chip. The PRT two-key model is unchanged. dkpriv and tkpriv are TPM 2.0 keys on Pluton just as they are on a discrete TPM 2.0; CloudAP does not branch on TPM provenance in its issuance path.
What is the difference between Entra registered, Entra joined, and Entra hybrid joined for PRT purposes?
All three device states issue PRTs at first interactive sign-in. The differences are about device-management posture and which Conditional Access claims attach. Microsoft Entra registered is the personal-device / BYOD state -- the device has a cloud identity but is not the primary management surface; the PRT exists but the device is not necessarily compliant in the management sense. Microsoft Entra joined is the cloud-primary state -- the device's primary identity authority is Entra ID. Microsoft Entra hybrid joined is the dual state -- the device has both an on-prem AD computer object and an Entra ID device object; both authentication paths are active in parallel. Microsoft documents hybrid join as "an interim step on the road to Microsoft Entra join" for organizations migrating away from on-prem AD [4].
The PRT is not a replacement for Kerberos, NTLM, or Credential Guard. It is the cryptographic seam where Windows logon becomes a Microsoft Entra ID transaction -- and the rest of this series is about what runs alongside it: Hello for Business as the issuing credential, WebAuthn and FIDO2 as the per-relying-party authenticator class, Cloud Kerberos Trust as the on-prem bridge, Credential Guard as the on-prem-credential isolation path, Adminless as the local-authorization pattern, App Identity as the workload broker. Each of those articles starts from a question this one raises, and each closes on a question that connects back. The seam is the part you can name when somebody asks how the three sign-ins from §1 are secretly one event.
Study guide
Key terms
- Primary Refresh Token (PRT)
- Device-bound JWT issued by Microsoft Entra ID to CloudAP at first interactive sign-in; cryptographic seam between Windows logon and Entra-mediated SSO.
- CloudAP
- Cloud Authentication Provider plugin framework in lsass.exe; the Entra ID plugin owns the device-side PRT lifecycle.
- Device key (dkpub/dkpriv)
- TPM-bound key pair that signs PRT issuance requests; registered with Entra ID at join time.
- Transport key (tkpub/tkpriv)
- TPM-bound key pair Entra ID uses to wrap session keys; only tkpriv can unwrap them on-device.
- Session key
- Symmetric proof-of-possession key for the PRT lifetime; signs cookies and app-token requests via SP800-108 KDF derivation.
- x-ms-RefreshTokenCredential
- HMAC-signed JWT cookie that carries PRT-derived authentication to login.microsoftonline.com from supported browsers.
- KDFv2
- Post-CVE-2021-33779 derivation rule that mixes SHA256(ctx || payload) into the cookie's signing-key derivation, closing off-device replay.
- Continuous Access Evaluation (CAE)
- Near-real-time revocation channel for OAuth access tokens; 15-minute event-propagation upper bound; CAEP-anchored claim-challenge protocol.
- Token Protection
- Conditional Access session control that requires device-bound assertions for app-token requests; the per-app analogue of PRT device binding.
- Cloud Kerberos Trust
- Bridge that lets a PRT-bearing device receive on-prem Kerberos TGTs from Entra ID via the AzureADKerberos virtual RODC object.
Comprehension questions
Why is 'the PRT cookie is DKey-signed' wrong?
The device key signs the asymmetric PRT issuance request once per PRT mint. Cookies are HMAC-signed with a symmetric key derived from the session key via SP800-108 KDF; under KDFv2 the derivation context is SHA256(ctx || assertion_payload).
What did CVE-2021-33779 fix, in one sentence?
It introduced KDFv2, which binds the cookie's full payload into the SP800-108 derivation context, so a key derived for one cookie cannot sign another -- killing off-device Pass-the-PRT.
What does the on-device-attacker floor mean for the PRT?
A same-privilege attacker on the live device can ask CloudAP to mint a fresh cookie; the TPM signs it, because that is its job. Off-device replay is closed; on-device Cookie-on-Demand is the architectural residual.
Where does the PRT NOT apply?
On-prem Kerberos via the on-prem KDC, Credential Guard / LSAISO (NTLM/Kerberos long-term keys), Adminless (authorization), App Identity / workload identities, and Remote Credential Guard (which redirects Kerberos, not PRT).
How does CAE revoke an in-flight access token?
Entra fires a CAEP event on a critical change (user deletion, password reset, MFA enable, admin revocation, high user risk). The CAE-aware resource provider issues an HTTP 401 with a claim challenge on the next request; the client re-presents the PRT and Entra evaluates Conditional Access fresh, issuing a new token or denying.
References
- What is a Primary Refresh Token?. Microsoft Learn. https://learn.microsoft.com/en-us/entra/identity/devices/concept-primary-refresh-token - Canonical Microsoft definition of PRT, dsreg two-key model, TPM binding, 90-day lifetime, 4-hour CloudAP renewal, browser SSO. ↩
- (2012). RFC 6749 -- The OAuth 2.0 Authorization Framework. https://datatracker.ietf.org/doc/html/rfc6749 - OAuth 2.0 baseline; refresh token role. ↩
- (2013). Bring Your Own Device (BYOD): New Windows Server 2012 R2 device access and information protection. Microsoft Windows Server Blog. https://www.microsoft.com/en-us/windows-server/blog/2013/06/28/bring-your-own-device-byod-new-windows-server-2012-r2-device-access-and-information-protection/ - 28 June 2013 Workplace Join announcement. ↩
- What is a device identity in Microsoft Entra ID?. Microsoft Learn. https://learn.microsoft.com/en-us/entra/identity/devices/overview - Microsoft devices-state taxonomy: registered, joined, hybrid joined. ↩
- (2015). Azure AD Join on Windows 10 devices. Microsoft Entra Blog (Tech Community). https://techcommunity.microsoft.com/blog/microsoft-entra-blog/azure-ad-join-on-windows-10-devices/244005 - 28 May 2015 announcement of Azure AD Join for Windows 10 1507. ↩
- (2016). How to get the Windows 10 Anniversary Update. Windows Blogs. https://blogs.windows.com/windowsexperience/2016/08/02/how-to-get-the-windows-10-anniversary-update/ - Windows 10 Anniversary Update / 1607 release-date anchor (2 Aug 2016). ↩
- MS-OAPXBC: OAuth 2.0 Protocol Extensions for Broker Clients (index). Microsoft Open Specifications. https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-oapxbc/2f7d8875-0383-4058-956d-2fb216b44706 - First published version 1.0 dated 16 October 2015. ↩
- MS-OAPXBC: Section 3.2.5 -- x-ms-RefreshTokenCredential JWT signing. Microsoft Open Specifications. https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-oapxbc/fa254670-3826-492e-834e-58f739081a55 - KDFv2 derivation rule, kdf_ver=2, AzureAD-SecureConversation label. ↩
- Microsoft Enterprise SSO plug-in for Apple devices. Microsoft Learn. https://learn.microsoft.com/en-us/entra/identity-platform/apple-sso-plugin - Apple SSO plug-in for Microsoft Entra: macOS, iOS, iPadOS. ↩
- (2024). Understanding Primary Refresh Tokens and CVE-2021-33779: how Pass-the-PRT was eliminated. blog.3or.de. https://blog.3or.de/understanding-primary-refresh-tokens-and-cve-2021-33779-how-pass-the-prt-was-eliminated.html - Canonical post-mitigation reverse-engineering analysis; Pass-the-PRT vs Pass-the-PRT-Cookie distinction. ↩
- (2020). Requesting Azure AD Refresh Tokens on Azure AD-joined Machines for Browser SSO. https://posts.specterops.io/requesting-azure-ad-request-tokens-on-azure-ad-joined-machines-for-browser-sso-2b0409caad30 - SpecterOps mid-July 2020 disclosure; CLSID a9927f85-...; x-ms-RefreshTokenCredential cookie extraction. ↩
- RequestAADRefreshToken (leechristensen/RequestAADRefreshToken). https://github.com/leechristensen/RequestAADRefreshToken - COM-API browser-SSO refresh-token-extraction tool. ↩
- (2020). Abusing Azure AD SSO with the Primary Refresh Token. https://dirkjanm.io/abusing-azure-ad-sso-with-the-primary-refresh-token/ - 21 July 2020 seminal disclosure; explicit parallel-discovery attribution to Lee Christensen. ↩
- ROADtools (dirkjanm/ROADtools). https://github.com/dirkjanm/ROADtools - ROADtools framework; roadtx prt sub-command. ↩
- (2020). Digging further into the Primary Refresh Token. https://dirkjanm.io/digging-further-into-the-primary-refresh-token/ - 5 August 2020 follow-up; aadcloudap.dll reverse-engineering; Mimikatz collaboration with Benjamin Delpy. ↩
- mimikatz (gentilkiwi/mimikatz). https://github.com/gentilkiwi/mimikatz - Mimikatz repository home; sekurlsa::cloudap module. ↩
- Wayback Machine: mimikatz release tag 2.2.0-20200807 (snapshot). https://web.archive.org/web/20200920005113/https://github.com/gentilkiwi/mimikatz/releases/tag/2.2.0-20200807 - 20 Sept 2020 snapshot preserving the Mimikatz Azure-PRT tag that is now 404 on GitHub. ↩
- (2020). Get-AADIntUserPRTToken and the 29 September 2020 nonce mitigation. https://aadinternals.com/post/prt/ - AADInternals PRT cookie tooling; 29 Sept 2020 request_nonce binding documented. ↩
- CVE-2021-33779 -- Windows AD FS Security Feature Bypass Vulnerability. NIST National Vulnerability Database. https://nvd.nist.gov/vuln/detail/CVE-2021-33779 - NVD authoritative description (AD FS framing). ↩
- What is KDFv2. Microsoft Learn. https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/operations/what-is-kdfv2 - 13 July 2021 KDFv2 release tied to CVE-2021-33779; KdfV2Support setting modes. ↩
- (2022). Breaking Azure AD joined endpoints in zero-trust environments (slide deck). https://dirkjanm.io/assets/raw/TR22_Mollema_Breaking_Azure_AD_joined_endpoints_in_zero-trust_environments_v1.0.pdf - TROOPERS 22 slide deck PDF. ↩
- (2022). Breaking Azure AD joined endpoints in zero-trust environments (talk abstract). TROOPERS Conference. https://troopers.de/troopers22/agenda/tr22-1055-breaking-azure-ad-joined-endpoints-in-zero-trust-environments/ - TROOPERS 22 abstract; 2020-2022 research arc summary. ↩
- (2022). Continuous access evaluation in Azure AD is now generally available (mirror). thewindowsupdate.com. https://thewindowsupdate.com/2022/01/10/continuous-access-evaluation-in-azure-ad-is-now-generally-available/ - 10 January 2022 CAE GA announcement (mirror of Tech Community post by Alex Simons). ↩
- OpenID Continuous Access Evaluation Profile 1.0 -- Draft 01. OpenID Foundation. https://openid.net/specs/openid-caep-specification-1_0-01.html - CAEP event-type taxonomy that CAE implements. ↩
- Continuous access evaluation in Microsoft Entra ID. Microsoft Learn. https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-continuous-access-evaluation - CAE definition, 5 critical events, 15-minute propagation upper bound, claim-challenge mechanism. ↩
- Token protection in Microsoft Entra Conditional Access. Microsoft Learn. https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-token-protection - Token Protection GA on Windows, preview on iOS/macOS, native-apps-only scope. ↩
- Configure Microsoft Entra hybrid join cloud Kerberos trust. Microsoft Learn. https://learn.microsoft.com/en-us/windows/security/identity-protection/hello-for-business/deploy/hybrid-cloud-kerberos-trust - AzureADKerberos RODC object; partial-TGT issuance; KB5010415+ / Windows 10 21H2 minimum. ↩
- Enable passwordless security key sign-in to on-premises resources. Microsoft Learn. https://learn.microsoft.com/en-us/entra/identity/authentication/howto-authentication-passwordless-security-key-on-premises - Cloud Kerberos Trust PRT-to-on-prem-TGT flow. ↩
- (2006). RFC 4556 -- Public Key Cryptography for Initial Authentication in Kerberos (PKINIT). https://datatracker.ietf.org/doc/html/rfc4556 - Kerberos PKINIT extension used by Cloud Kerberos Trust. ↩
- (2023). Microsoft Entra expands into Security Service Edge and Azure AD becomes Microsoft Entra ID. Microsoft Security Blog. https://www.microsoft.com/en-us/security/blog/2023/07/11/microsoft-entra-expands-into-security-service-edge-and-azure-ad-becomes-microsoft-entra-id/ - 11 July 2023 Azure AD -> Microsoft Entra ID rename. ↩
- Configure Credential Guard. Microsoft Learn. https://learn.microsoft.com/en-us/windows/security/identity-protection/credential-guard/ - Microsoft Learn overview of Credential Guard: VBS-based isolation of NTLM hashes and Kerberos TGTs. ↩
- Protect derived domain credentials with Windows Defender Credential Guard (Windows IT Pro Center, Wayback 2016 snapshot). Microsoft Windows IT Pro Center (Wayback Machine). https://web.archive.org/web/2016/https://docs.microsoft.com/en-us/windows/security/identity-protection/credential-guard/credential-guard - Contemporaneous Microsoft documentation: "Introduced in Windows 10 Enterprise and Windows Server 2016" verbatim; anchors Credential Guard to the Windows 10 Enterprise launch surface (2015). ↩
- Device Bound Session Credentials (W3C Editor's Draft). W3C Web Application Security Working Group. https://w3c.github.io/webappsec-dbsc/ - W3C DBSC draft; on-device-attacker impossibility statement; per-origin keying. ↩
- Protecting cookies with Device Bound Session Credentials. Google Security Blog. https://blog.google/security/protecting-cookies-with-device-bound-session-credentials/ - Chrome 146 GA on Windows; Microsoft co-design partnership. ↩
- Device Bound Session Credentials launches on Windows. Chrome for Developers. https://developer.chrome.com/blog/dbsc-windows-announcement - Developer guidance; cites Chrome 145 as the rollout-start build. ↩
- Conditional Access for agent identities. Microsoft Learn. https://learn.microsoft.com/en-us/entra/identity/conditional-access/agent-id - Microsoft Entra Agent ID + Conditional Access integration introduced at Ignite 2025; documents attribute-driven targeting via custom security attributes and agent-identity-blueprint policy levers. ↩
- Troubleshoot devices by using the dsregcmd command. Microsoft Learn. https://learn.microsoft.com/en-us/entra/identity/devices/troubleshoot-device-dsregcmd - Reference for dsregcmd /status output fields including AzureAdPrt, AzureAdPrtUpdateTime, AzureAdPrtExpiryTime under the SSO state section. ↩
- Advanced hunting schema in Microsoft Defender XDR. Microsoft Learn. https://learn.microsoft.com/en-us/defender-xdr/advanced-hunting-schema-tables - Defender XDR advanced-hunting tables including IdentityLogonEvents and AADSignInEventsBeta. ↩
- How to use Continuous Access Evaluation enabled APIs in your applications. Microsoft Learn. https://learn.microsoft.com/en-us/entra/identity-platform/app-resilience-continuous-access-evaluation - CAE client-capabilities contract; cp1 declaration; claim-challenge response handling for OAuth clients. ↩
- Talks (Dirk-jan Mollema). https://dirkjanm.io/talks/ - Conference talks index; TROOPERS 22 entry; no DC30/2022 appearance. ↩
- Refresh tokens in the Microsoft identity platform. Microsoft Learn. https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens - Non-PRT refresh-token lifetime baseline (24h for SPAs, 90d otherwise). ↩
- Platform SSO for macOS. Apple Platform Deployment. https://support.apple.com/guide/deployment/platform-sso-for-macos-dep7bbb05313/web - Apple Platform SSO; Secure Enclave-backed key authentication. ↩
- (2023). RFC 9449 -- OAuth 2.0 Demonstrating Proof of Possession (DPoP). https://datatracker.ietf.org/doc/html/rfc9449 - DPoP application-level proof of possession; §11.4 attacker-on-device residual. ↩
- (2020). RFC 8705 -- OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens. https://datatracker.ietf.org/doc/html/rfc8705 - mTLS-bound access tokens. ↩
- (2018). RFC 8471 -- The Token Binding Protocol Version 1.0. https://datatracker.ietf.org/doc/html/rfc8471 - The abandoned TLS-exporter binding approach. ↩
- Web Authentication: An API for accessing Public Key Credentials -- Level 3. W3C. https://www.w3.org/TR/webauthn-3/ - WebAuthn Level 3; per-Relying-Party scoping. ↩