This is the deep-dive companion to Passkeys Explained: What They Are and Why They Beat Passwords, which covers the concepts in plain English. Here we open up the machinery: what actually lands on the server when you sign in, how the registration and authentication ceremonies run, and why the phone-based QR flow leans on hardware most people never think about.
A passkey is easy to picture as a single object, but it is more accurate to think of it as a small bundle of related parts. A single passkey is really one half of a pair, plus the rules and processes that make it usable.
A few terms you will need to know before we start
| Term | What it means |
|---|---|
| Authenticator | The thing that stores your private key and checks that it is really you. This can be built into your device (like Windows Hello or Apple Face ID), a physical key you plug in (like a YubiKey), or a password manager that supports passkeys. |
| Relying Party (RP) | A slightly formal name for the website or app you are signing in to. It is the party "relying on" the passkey to confirm your identity. |
| User verification | The quick check that proves you are present and that you are you, usually a biometric scan or a local PIN. Your biometric data never leaves your device and is never sent to the website - the website only learns that the check passed. |
| Origin binding (Relying Party ID) | The security property that ties a passkey to one specific domain. A passkey made for yourbank.moderniam.com simply will not respond to yourbank.modern42.com or any other address. This is the single most important reason passkeys resist phishing, and it is enforced by the browser rather than left to your judgement in the moment. |
| Challenge | The random, one-time puzzle the website sends for your device to sign. Because it is different every time, an attacker cannot record one valid login and replay it later. |
| Credential ID | A unique label the authenticator generates when the passkey is created. The website uses it as a reference to find the right stored public key and match it to your account. Think of it as the serial number that lets the two halves find each other again. |
| User handle | A behind-the-scenes identifier that links the passkey back to your account in the website's system. It is deliberately not your email or username (both of which can change), but a stable internal reference. This is also why a passkey can sign you in without you typing a username at all. |
| Sign counter | A number the authenticator can increment on each use, which a server may track to help spot a cloned authenticator. Worth knowing that it is often 0 and static for synced passkeys, so many relying parties treat it as advisory rather than decisive. |
| Private key | The secret half, sealed inside your authenticator, that signs the challenge at login. It never leaves the device. Everything else in the bundle exists to support it. |
| Public key | Its matching half, handed to the website at sign-up and kept on the server to check the signatures your private key produces. Harmless on its own. |
| Flags | Alongside the credential, each login carries a single status byte of authenticator data, and every bit in it reports one fact the server can check. |
The anatomy of a passkey
As you learnt above, the passkey assertion is just a cryptographic payload that is sent to a relying party (RP). If you are curious what actually lands on the server when you sign in, the diagram below is a labelled reference of the assertion. It lists the JSON the browser posts to the RP, the decoded challenge and origin, the decoded authenticator data with its full flag byte, and the digital signature. Nothing in it is a secret anyone could reuse.
The browser posts a small JSON object holding a credential ID (which tells the server which stored public key to use), the authenticator data, the client data, and a digital signature.
If we decode the client data you find the one-time challenge and, critically, the origin - the real web address that the browser itself filled in rather than the web page. The signature is computed over the authenticator data joined to a SHA-256 hash of the client data, using the private key that never leaves the authenticator. This hashing and cryptography ensures that the sent data has not been changed in transit and can only be verified by the correct private key.
The server verifies the signature against the public key that was stored when you first registered the private key. If it checks out, the server knows the genuine private key signed the challenge for the site, and no reusable secret ever crossed the wire.
A WebAuthn authentication assertion, field by field. None of it is a reusable secret.
Reading the diagram in sections:
-
The PublicKeyCredential posted to the web server contains
id,rawId,type, and aresponseobject withauthenticatorData,clientDataJSON,signatureanduserHandle, plusclientExtensionResults. The signed input is theauthenticatorDataconcatenated with a SHA-256 hash of theclientDataJSON. -
The authenticatorData, when decoded, holds the
rpIdHash, a flag byte, asignCount, attested credential data (present only when the AT flag is 1) and extensions (present only when the ED flag is 1). AT is always 0 in an authentication assertion. -
The flags are a single status byte, and every bit attests one fact the server can check:
- Bit 0 - UP (user present): set when a physical gesture such as a tap took place.
- Bit 1 - RFU: reserved for future use, always 0.
- Bit 2 - UV (user verified): set when a biometric or PIN check passed.
- Bit 3 - BE (backup eligible): set when the credential is allowed to be backed up or synced, which is what makes it a multi-device (syncable) passkey.
- Bit 4 - BS (backup state): set when the credential is currently backed up or synced.
- Bit 5 - RFU: reserved for future use, always 0.
- Bit 6 - AT (attested credential data present): always 0 in an authentication assertion, because attested credential data is only included at registration.
- Bit 7 - ED (extension data present): set only when extensions were used.
The two backup bits are the ones people usually mean when they ask how "syncing" works. BE is a permanent property fixed when the passkey is created - it tells you whether the credential is the kind that can be synced at all. BS can change over time and tells you whether that credential is synced right now. Read together, BE set with BS set describes a synced, multi-device passkey, whereas BE unset describes a single-device, device-bound passkey. One caveat: BE indicates eligibility, not a guarantee that a copy exists elsewhere, and the WebAuthn specification is explicit that the presence of these bits does not let a relying party prove where a key physically lives.
-
The clientDataJSON decodes into
type,challenge,originandcrossOrigin.
So how is a password different from a passkey?
It is worth seeing what a password-based login looks like by contrast. A password login uses an HTTPS POST to send the actual secret across the internet. On the server, where it is stored (hopefully as a salted hash), it is now checked: the server runs an algorithm across the submitted secret and checks whether it matches the saved hash. It carries no binding of which origin asked for it, and it does not know whether it was sent by the owner of the secret. That is what makes passwords - or any shared secret - both breachable and phishable, because a lookalike site gets a secret it can reuse. A password login looks something like this:
A password login posts the username and password directly, with no challenge, origin or signature.
You can see the benefit of the passkey assertion model, which carries a signature instead of a secret and is bound to the origin (the website URL) it can be used with.
WebAuthn - the standard that makes it all work
You will hear the word WebAuthn the moment you start reading about passkeys, so it is worth a plain explanation. WebAuthn, short for Web Authentication, is the open standard that lets a website ask your browser to create and use a passkey. It is maintained by the W3C, the same body responsible for the core standards of the web, and it is already built into every modern browser and operating system.
The neat way to think about it is that WebAuthn is the common language all web systems speak. Before it existed, any website wanting passwordless login had to deal with a patchwork of incompatible, bespoke gadgets and proprietary systems. WebAuthn gave everyone a single agreed set of rules and vernacular, so a passkey created in Chrome on a Windows laptop behaves the same way as one created in Safari on an iPhone. That shared language is the reason passkeys work across the whole industry rather than locking you into one vendor - and why they are being adopted so rapidly.
In practice WebAuthn defines two processes, which the standard calls ceremonies. Registration is when your device creates a new passkey for a site and hands over the public key. Authentication is when you later sign in and your device signs the site's challenge. Both run through the same WebAuthn machinery in your browser, and both come down to that one tap that starts with your face, fingerprint, or PIN unlocking access to your passkey.
Now, WebAuthn does not work entirely alone. It sits inside a larger family of standards from the FIDO Alliance, the industry body whose members include Microsoft, Google, Amazon, Meta, Intel, Yubico, Cisco and Apple. The combination of WebAuthn (the part the browser speaks) and a companion protocol called CTAP (which lets your browser talk to external authenticators such as a phone or a plugged-in security key) is together known as FIDO2. You do not need to know those acronyms, or how their inner workings behave, to use a passkey. The single thing worth remembering is that passkeys rest on open, shared standards rather than any one company's product, which is what gives you interoperability, portability and choice.
And reassuringly, all of this complexity is hidden. You will never interact with WebAuthn directly. It hums away in the background, and all you ever see is the prompt asking you to confirm it is you.
How signing up and signing in actually work
By now you have the pieces, so here are the two ceremonies end to end. The diagrams put all four participants in their own lane, which makes it easy to see who talks to whom and, more to the point, what never moves.
Registration ceremony
Registration is where the key pair is born. Your device creates it for that specific site, sends only the public key, and locks the pair to the site's domain. The private key never appears in a single message.
The passkey registration ceremony across the User, Authenticator, Browser/Client and RP Server lanes. Only the public key is ever sent.
Authentication ceremony
Signing in is the mirror image. The server sends a one-time challenge, you approve with a biometric or PIN, and your device signs the challenge with the private key it has been holding. The signature also proves the request came from the genuine site, and the server checks it against the public key it stored at registration.
The passkey authentication ceremony. No shared secret is ever transmitted.
On many modern sites, your saved passkeys appear right in the login box as autofill suggestions, so you can pick your account and authenticate in a single tap. The industry calls this "conditional UI," but to you it just looks like the site already knows which passkeys you have.
Discoverable credentials and how the authenticator selects them
There is one more structural distinction worth drawing out, because it quietly shapes the login experience.
A discoverable credential (WebAuthn previously called these "resident keys," and the term still appears in the API) stores everything needed to sign in - including the private key material and your user handle - directly on the authenticator. Because the authenticator holds this extra information, the website does not need to know who you are before asking for a login. It can send a request with an empty list of allowed credentials, and your authenticator simply looks up whatever passkeys it holds for that site's domain (origin) and offers them to you. This is what makes a login with no typed username possible, and it is the machinery behind the autofill experience where your passkey appears in the login box before you have entered anything.
A non-discoverable credential works differently under the hood. The authenticator does not store the private key at all. Instead, it retrieves the passkey on demand using the credential ID that the website supplies. That is why the site must identify you first, typically by asking for a username, so it can send back the credential IDs it has stored against your account. Nothing is stored on the authenticator, so it can support an effectively unlimited number of non-discoverable credentials. This design dates from earlier standards when security keys were used as a second factor after a password, where identifying the user first was already part of the flow.
The distinction matters more than it first appears, because in current implementations and usage, a passkey is a discoverable credential. The standards state that relying parties implementing passkey login should always create credentials as discoverable, and the account pickers shown by browsers and operating systems will only ever surface discoverable credentials. For developers, this is the residentKey: "required" setting at registration.
How the discoverable flow differs
The sequence below shows the WebAuthn authentication ceremony as it runs with a discoverable credential. The differences from the basic authentication ceremony above are at the start and the end:
- The server sends an empty allowed-credentials list rather than looking your account up first; the authenticator finds its own matching passkeys by domain; and you pick your account from the browser's list.
- The signed response carries your user reference so the server can work out which account just signed in.
The difference is purely who identifies whom, and in which order. The origin check, the user verification and the signature itself are unchanged, so nothing about the security model is weakened.
A discoverable-credential WebAuthn login: the empty allow-list and the returned user handle are the only real differences.
Support for passkeys
Support is now broad across the mainstream platforms, with the usual caveat that exact behaviour can vary by device maker and version.
Passkey support at a glance: platforms, desktop browsers, the gap between ecosystems, and hardware-key slot limits.
Apple
In the Apple ecosystem, passkeys arrived with iOS and iPadOS 16 and macOS 13 Ventura, stored and synced through iCloud Keychain, with Safari 16 on iOS and 16.1 on macOS carrying the browser side. From iOS 17, third-party password managers can act as the passkey provider. macOS can use passkeys held in iCloud Keychain.
Android
On Android, support runs from Android 9 upwards through the Credential Manager framework with Google Password Manager as the default store, and from Android 14 users can select a third-party password manager as their passkey provider instead. Samsung Internet supports passkeys from version 21 with syncing through Samsung Pass.
Browsers
On the desktop, Chrome and Edge picked up passkey support from version 108. Firefox added passkey support, including the autofill picker, in Firefox 122 in early 2024.
Windows
Windows has supported passkeys from Windows 10, with the full native experience - including passkey management through Windows Hello - arriving in the Windows 11 2023 update (23H2).
Linux
Desktop Linux has no native platform authenticator, so Chrome and Firefox on Linux cannot create passkeys locally. The cross-device QR flow with a phone, or a hardware security key, are the working paths for the OS.
Cross-platform support
Passkeys do not sync between ecosystems - a passkey in iCloud Keychain/Passwords does not sync or appear in Google Password Manager, or vice versa. This is where cross-platform password managers, or the QR-based cross-device flow, come in.
Hardware security keys
Each passkey consumes a small amount of storage on the authenticator, and on hardware security keys that storage is finite. Devices like YubiKeys can hold between 25 and 100 discoverable credentials depending on the version of the key. If you are keeping passkeys on a hardware key for high-assurance accounts, the slot count is worth knowing before you commit to it broadly.
Using your phone as a passkey: the QR code and the Bluetooth handshake
Several times above - on Linux, in the gap between ecosystems, when signing in on a borrowed computer - we leaned on "the cross-device QR flow" without opening it up. It deserves a proper look, because it is the one corner of the passkey story where the tidy "it just works" experience quietly depends on your hardware, and occasionally on configuration an administrator has to get right.
The scenario is this. You are sitting at a computer - call it the host - that does not hold your passkey. Perhaps a Linux box, a hotel PC, a colleague's laptop, or a locked-down virtual desktop. Your passkey lives on your phone, and you want to use the phone to sign in on the host. FIDO calls the machinery that makes this work hybrid transport, though you will still see its old codename, caBLE, in older write-ups. It was standardised in CTAP 2.2, the protocol that lets a browser talk to an external authenticator.
When you pick "use a passkey from another device," the host shows a QR code. You scan it with your phone, approve with your face, fingerprint or PIN, and you are signed in on the host. Simple on the surface. Underneath, that one action uses three completely different channels, each doing exactly one job.
Three channels, three jobs
You, the host and your phone during a QR sign-in. The dotted hop is the QR code (visual, one-way), the thick line is the Bluetooth proximity beacon, and the tunnel underneath carries the encrypted data.
-
The QR code is a one-way visual bootstrap. The host draws it, the phone reads it with its camera, and that is the whole of the QR's job. It is not the login. It carries a short-lived setup bundle - an ephemeral public key and a shared secret - that lets the two devices recognise each other and agree how to talk securely. It travels as light, from one screen into one camera, which is precisely why it never crosses the internet.
-
Bluetooth Low Energy proves the phone is in the room. The instant your phone has read the QR, it broadcasts a small, encrypted BLE advertisement, and the host sits there listening for exactly that beacon. Because the advert is derived from the secret embedded in the QR code, only a phone that has just scanned this host's QR can produce one the host will accept. This is the step most people never realise is happening, and it is the reason the flow will not complete with Bluetooth switched off.
-
An encrypted internet tunnel carries the actual data. This is the part that surprises people. The passkey traffic - the challenge, the signature, the WebAuthn assertion - does not travel over Bluetooth. It flows over the internet through a tunnel service operated by the phone's vendor, such as Google or Apple. That relay shuttles encrypted bytes between the host and the phone but cannot read them, because the two devices stand up an end-to-end encrypted channel over the top of it, keyed partly from material exchanged in the QR and the BLE beacon. Your private key never leaves the phone, exactly as in every other passkey ceremony.
So Bluetooth is not the pipe. It is the proximity sensor. The QR code starts the conversation, Bluetooth proves the two devices are physically together, and the internet carries the load.
Why proximity over Bluetooth is good security
It is fair to ask why the designers bothered with Bluetooth at all, when the data already moves over an encrypted internet tunnel. The answer is that a QR code, on its own, is trivial to relay, and relaying one is a genuine attack.
Picture a phishing page that shows you a QR code and says "scan to sign in." Nothing physically stops an attacker from taking a real QR code generated by their login session on their machine, dropping a screenshot of it onto a page in front of you, and hoping you scan it. If scanning were enough, your phone would cheerfully authorise the attacker's session on the other side of the world.
The BLE beacon shuts that door. After you scan, your phone broadcasts its little encrypted advertisement into the air immediately around it, and the host has to hear that beacon to carry on. Bluetooth Low Energy only reaches a short distance - a handful of metres in practice - so "the host can hear the beacon" is a physical proof that your phone and the host are in the same place. An attacker relaying a QR code from a data centre or another city is nowhere near your phone, hears nothing, and the ceremony stops dead. And because the advert is cryptographically tied to the specific QR you scanned, a stray Bluetooth device nearby cannot forge it either.
This is why the proximity check is more than a box-ticking nicety - it is load-bearing. The material carried in the beacon also feeds the keys that bring up the encrypted tunnel, so a host that never heard a valid, nearby advert cannot finish the handshake in the first place. Proximity is not checked once and then taken on trust. It is baked into the cryptography.
This is why passkeys sometimes need device-level configuration
Here is the practical sting for engineers, and the thing a password-era mental model tends to miss. A password asks nothing of the device but a keyboard. A passkey, and the phone-based QR flow in particular, is coupled to the host's hardware and configuration. On a physical laptop that means a working, switched-on Bluetooth radio. Turn Bluetooth off for policy reasons, or sit at a desktop with no Bluetooth adapter at all, and the QR route to your phone simply will not complete, because the second channel in the diagram above is missing.
The problem sharpens in virtual desktops. In Azure Virtual Desktop, Windows 365 or any RDP session, the "host" running the browser is a virtual machine in a data centre. That VM has no Bluetooth radio, and it is certainly not in the room with your phone, so the QR and BLE flow cannot originate from it. Left to its own devices, in-session passkey sign-in is dead on arrival.
Microsoft's answer is a device-level feature called WebAuthn redirection. With it enabled, WebAuthn calls made inside the remote session are redirected back down the RDP connection to your local device, which then handles them with its own authenticator - Windows Hello, a plugged-in FIDO2 key, or the local machine's Bluetooth radio for the phone flow. The tell that it is working is a Windows Security prompt appearing on your real machine, overlaying the remote session.
The catch is that this is configuration, not magic:
- It is governed by the RDP property
redirectwebauthn:i:1on the host pool, or the Device redirection control in the Azure portal, and it can be independently allowed or blocked by Intune or Group Policy through the Do not allow WebAuthn redirection setting. Where those disagree, the most restrictive setting wins, so a single mismatched policy can silently switch passkey sign-in off for an entire host pool. - The Windows App or Remote Desktop client, and the platform it runs on, have to support redirection in the first place.
Azure Virtual Desktop does enable this redirection by default on new host pools, but "by default" is not "guaranteed." It is one policy toggle away from off, and it is exactly the sort of setting that turns "passkeys don't work on our VDI" into a half-day of head-scratching. The wider lesson holds well beyond Microsoft: because passkeys lean on device hardware - a Bluetooth radio, a secure element, a camera - and on session plumbing like redirection that passwords never touched, rolling them out is partly an endpoint-configuration exercise, not purely an identity one. It is worth auditing Bluetooth policy, VDI redirection settings and client versions before you promise your users a passwordless future.
Common misconceptions
Two comparisons come up whenever passkeys are weighed against a well-run password setup. Each contains a grain of truth, which is what makes them sticky, so it is worth walking through them carefully.
"A strong password in a synced credential manager is about as good as a passkey"
This is the one worth slowing down for, because on the surface it seems fair. The reasoning goes something like this:
My password is long, unique and random, it lives in the same synced vault a passkey would, and I unlock that vault with my fingerprint. Same place, same gesture, so surely they are roughly the same?
They are not, and it has nothing to do with how strong the password is. A password is a bearer secret. Whoever presents the right string is let in, and that string is handed to the server on every login. Strength only changes how hard it is to guess. It does nothing about the fact that the secret is transmitted across the internet and stored on the server, which is what makes even strong passwords phishable and breaches damaging.
A passkey simply does not have that issue. The private key is never sent, and the signature it produces is bound to the real site's origin, checked by the browser on your device rather than by you. That origin binding is the whole difference. A perfect clone of your bank's page can still defraud a careful person out of a password, because the password neither knows nor cares which site it is typed into. A passkey knows.
So this is not two points on one scale; the two work in different ways. A synced vault makes a password nicer to manage, but it cannot hand the password the properties that make a passkey phishing-resistant - origin binding and a non-transmitted cryptographic credential.
"If I keep everything in one vault, a passkey is no safer than a password there anyway"
There is a legitimate point hiding in this one, but it is about a different thing than it first appears. If you store both your passkey and your one-time-code (TOTP) seeds in the same synced vault, then a compromise of that single vault would expose both at once, whereas a separate authenticator app on a different device would give you an independent second anchor. That is a sound observation about not concentrating all your credentials in one basket, and it is worth recognising.
But notice that this is a point about where you store your credentials, not about how strong passkey authentication is compared to password authentication. Spreading your credentials and recovery options across more than one store is good practice whatever technology you use. It does not close the gap between a bearer secret (passwords) and an origin-bound key (passkeys). Keep the two questions separate and the "no safer anyway" conclusion falls away. The storage concern is real, and the authentication advantage of the passkey is still intact.

