Windows Hello Cloud Trust
Windows Hello Cloud Trust: What is it? Why do you care?
— Steve Syfuhs (@SteveSyfuhs) February 22, 2022
Twitter warning: Like all good things this is mostly correct, with a few details fuzzier than others for reasons: a) details are hard on twitter; b) details are fudged for greater clarity; c) maybe I'm just dumb.
In the early days, Windows Hello for Business came in two deployment flavors: Certificate Trust or Key Trust.
Certificate Trust is basically the answer to the question "what if we made smart cards unlockable with your face?"
This is a surprisingly accurate depiction because under the covers Windows Hello uses certificate logon to get you to the desktop, which in the CT case means spinning up PKI, deploying templates, protecting private keys through hardware binding, etc.
Smart cards require the exact same infrastructure, and the only difference is where the private key is stored. In the Hello case it's stored on disk and protected by your TPM. Smart cards store them in silicon embedded on a plastic card.
This model works about as well as you can expect for a system that is not dependent on the cloud and must coexist with existing PKI within large organizations, and actually: it works well. We cut out teeth on getting the infrastructure right with smart cards over 20 years.
All of this came about in Windows 10, and didn't require changes to Active Directory, which means no Domain Controller deployments. Okay, that actually makes for some reasonable tradeoffs.
But then we had this other mode: Key Trust. This mode doesn't require PKI and gives you some flexibility in deployment, but for all intents and purposes requires The Cloud to do all sorts of orchestration plus enough Server 2016 DCs to handle authentication load. Tradeoffs.
Between the two, for the vast majority of customers Key Trust is a lot easier to deploy as they're already hybrid, or are planning it, don't already have PKI in place, and have no problem standing up a handful of 2016 servers.
But there are some downsides. See, when you log into Windows with Windows Hello the authority with which you authenticate against is determined by your join state. Domain join => Domain Controller. Azure AD Join => Azure AD.
Doing the face thing or the fingerprint thing or the PIN thing unlocks a private key, and that private key is used to authenticate to the machine authority. In DJ land that's a certificate, doing Kerberos PKINIT. In AADJ land that's an OAuth signed assertion.
Certificate trust doesn't need to do anything special, since the PKI is all local to AD and AD fundamentally understands the cert presented to it. The cloud requires something like ADFS to translate the certificate to something AAD understands.
Key trust is the reverse: the cloud natively understands the key and AD needs it translated. Most folks deploy AAD Connect and rely on a backsync where AAD pushes down the Windows Hello certificates to AD.
This backsynced key gets stored in a special location different from where certificate trust or smart cards go For Reasons (good reasons) which necessitates 2016+, but still fundamentally works as a smart card does by authenticating using Kerberos PKINIT.
In principle this is fine since most folks have AAD Connect, but there are problems because this sync can take anywhere from 1 minute to 30 minutes on average, plus however long it takes to replicate from the sync target DC and whichever DC you're authenticating against.
In short: it takes a long time to provision a key trust key on-prem, and you can't use Windows Hello to log into your hybrid machine for... a while. And you can't access on-prem resources on AADJ machines for... a while.
It's not ideal.
Remember FIDO? Remember all that work we did to build Kerberos into the cloud? Remember how when you log into a machine, we immediately give you a TGT from AAD and use it to log you into your machine and get you access to on-prem resources?
So: Cloud Trust.
Cloud Trust gives us the best of both worlds. We get instant provisioning and instant hybrid auth, all without having to deploy any additional infrastructure. Neat.
So, how does this thing work? Well, you start with Key Trust. You do all the same onboarding into AAD, where you generate a key, register it with AAD and voila instant Hello. This part is a little more complicated, but honestly, not by much. Make key, have key, give key, use key.
The heavy lifting is now the backend. In the before-times AAD had to push the key back down to AD, which took fooooreeeevvveerrrr. Now when you log in with the key you registered 5 seconds ago, we generate a partial TGT and return it to your machine.
Sometime before we generated the TGT you also ran a one-line PowerShell command that:
1. Created an Azure AD RODC object on-prem
2. Synced that RODC secret to AAD
The presence of that RODC secret in AAD is what triggers this magic. It tells us you trust AAD to log you in to your on-prem environment.
So, you log in, we generate a partial TGT encrypted to the RODC secret and return it to you. Your Windows client sees this, sends the partial TGT to a nearby domain controller and asks for a real on-prem TGT.
The domain controller understands that this is a partial (RODC) TGT, meaning it contains exactly one piece of information in it: your username. The reason this is interesting is because it *doesn't* contain your group membership information.
This is actually a pretty useful mechanism because folks don't like synchronizing ALL of their group memberships to AAD, and if we returned a TGT with a subset of your memberships you'd be hosed. So, your DC looks you up by name, does some sanity checks, and generates a full TGT.
Cloud trust takes your hybrid Windows Hello deployment from a very complicated and slow process down to a PowerShell command and some Group Policy or Intune futzing to turn the feature on.