Hi,
Your findings are consistent and i used claude to help complemente with what's I known about Windows's WebAuthn platform architecture. Here's what I can offer
on each question:
Question 1 — Is this a known limitation?
Yes, this is a known (though not formally documented by Microsoft) platform behavior. The FIDO CTAP2.1 specification
itself is completely transport-agnostic regarding getPinUvAuthTokenUsingUvWithPermissions (subCommand 0x06). The only
prerequisite the spec defines is:
"This subCommand is only applicable when the authenticator supports built-in user verification methods. This
subCommand MUST be implemented if the authenticator returns both uv and pinUvAuthToken option IDs set to true in the
authenticatorGetInfo response."
— CTAP2.1-PS, Section 6.5.5.7.3 [1]
There is no normative or informative text anywhere in the spec restricting this subcommand to any specific transport.
The spec's architecture statement is explicit:
"A FIDO2 Authenticator can be accessed by a CTAP client through a variety of transport mechanisms. This
specification only concerns itself with the logical CTAP messages themselves, not with the physical transport layer."
So the restriction you're observing is a Windows platform implementation decision, not a spec-level prohibition.
Re: Question 2 — Intentional or bug?
Most likely an architectural design decision, not a regression. On Windows, the device stack for FIDO2 authenticators
is bifurcated:
USB HID devices with FIDO usage page are enumerated as FIDO authenticators and receive the full WebAuthn treatment
(including biometric UV flows). CCID devices enter the PC/SC subsystem, which historically serves certificate-based
smart card authentication. The fact that you're seeing CTAP2 commands at all over CCID likely means Windows is using a
credential provider path that supports PIN-based FIDO2 over smart card (for Entra ID / CBA scenarios), but the UV
interaction flow was never implemented for this path.
The UX reasoning likely is: CTAPHID authenticators with built-in biometrics (YubiKey Bio, FEITIAN BioPass) present as
self-contained security keys where the user interacts directly with the device. The Windows UX for "touch your
security key" / "scan your fingerprint on the key" is designed around that HID-enumerated model. CCID-connected
devices, from the platform's perspective, are smart cards in a reader — a form factor where on-device biometric
interaction isn't the expected UX paradigm.
Re: Question 3 — Any workaround?
Based on publicly available information, your options are:
1. Re-expose over USB HID (CTAPHID): As you noted, this is the reliable path. If your hardware supports composite USB
(HID + CCID), exposing a CTAPHID interface with FIDO usage page (0xF1D0) alongside CCID should make Windows enumerate
it as a full FIDO2 authenticator with UV support.
2. Dual-interface approach: Some implementations (e.g., Feitian's JavaCard-based authenticators) expose both a CCID
interface (for certificate/PIV operations) and a HID interface (for FIDO2). The HID interface gets full WebAuthn
platform support.
3. Wait for platform changes: There's no published roadmap from Microsoft indicating CCID UV support is planned, but
Windows Insider builds occasionally expand FIDO2 support.
Other platforms (macOS, Linux via libfido2, ChromeOS) do support full CTAP2.1 UV over CCID — Yubico's libfido2 [2]
implements UV identically across all transports (see src/fido2/dev.c transport dispatch). This confirms your
implementation is spec-compliant; the gap is Windows-specific.
Re: Question 4 — Transport factoring into PIN vs. UV
decision
Your packet captures
confirm this conclusively: Windows queries getUVRetries (0x07) — proving it
reads the
authenticator's UV
capability — then ignores it and proceeds with
getPinUvAuthTokenUsingPinWithPermissions (0x09). The
decision to skip UV
appears to be made after capability discovery, based on transport
classification.
Microsoft's FIDO2
security key provider documentation [3] lists supported transports as
"USB" (meaning HID), NFC (via
the built-in NFC
stack, not PC/SC), and BLE. CCID/PC/SC is conspicuously absent from the
supported transport list for
full FIDO2
operations.
---
Sources:
[1] FIDO CTAP2.1
Proposed Standard (2021-06-15), Section 6.5.5.7.3:
https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html
[2] Yubico libfido2
— CCID transport implementation (full UV parity with HID):
https://github.com/Yubico/libfido2
[3] Microsoft —
FIDO2 security key provider requirements:
https://learn.microsoft.com/en-us/entra/identity/authentication/concept-fido2-hardware-vendor
[4] FIDO Registry of
Predefined Values, Section 3.1 (User Verification Methods / uvModality values):
https://fidoalliance.org/specs/common-specs/fido-registry-v2.2-ps-20220523.html
---
The spec
doesn't restrict UV by transport. Windows's webauthn.dll (and its credential
provider chain)
architecturally
treats CCID-connected authenticators as smart cards with limited CTAP2 support
(PIN only). The most
reliable fix is
exposing a CTAPHID (USB HID, usage page 0xF1D0) interface. All non-Windows
platforms handle this
correctly.