Skip to content

WebAuthn registration fails with PIN-configured CTAP 2.1 authenticator when another security key is already registered #8193

Description

@all-solutions

Steps To Reproduce

  1. Create or use a Bitwarden Cloud account.
  2. Enable WebAuthn/FIDO2 two-step login.
  3. Register a YubiKey as a WebAuthn security key.
  4. Physically disconnect the YubiKey from the computer.
  5. Use a Swissbit iShield Key 2 Pro with a configured FIDO2 PIN.
  6. Attempt to register the iShield Key 2 Pro as an additional WebAuthn security key.
  7. Chrome does not present a FIDO2 PIN prompt.
  8. Touching the iShield does not complete the WebAuthn ceremony.
  9. The operation eventually times out.

The behavior is reproducible.

As a control test:

  1. Remove the registered YubiKey from the Bitwarden account.
  2. Without changing the iShield, its PIN, the browser, or any other setting, attempt to register the iShield again.
  3. Registration now completes successfully without requesting the PIN.

Registering the YubiKey again makes the iShield registration fail again.

The resulting behavior is therefore:

Existing WebAuthn credentials iShield registration
None Succeeds
YubiKey registered Times out
YubiKey removed again Succeeds

Expected Result

The iShield Key 2 Pro should be registrable as an additional WebAuthn two-step-login authenticator when another security key is already registered.

If user verification is appropriate for the authenticator, the browser should be able to request the configured FIDO2 PIN and complete the registration ceremony.

Having another WebAuthn credential registered to the account should not prevent registration of a different compatible authenticator.

Actual Result

When a YubiKey credential is already registered, registration of the PIN-configured Swissbit iShield Key 2 Pro does not complete.

Chrome does not request the iShield's FIDO2 PIN. Touching the key has no effect and the WebAuthn operation eventually times out.

Removing the YubiKey credential from the account immediately makes registration of the same iShield work again.

This reproduces on the official Bitwarden Cloud service and matches behavior previously reproduced with Vaultwarden.

Screenshots or Videos

No response

Additional Context

The Swissbit iShield Key 2 Pro is a CTAP 2.1 authenticator.

Relevant authenticator capabilities reported by the device are:

clientPin:        yes
alwaysUv:         no
makeCredUvNotRqd: yes

The same behavior was previously investigated in Vaultwarden:

dani-garcia/vaultwarden#7437

During that investigation, the failure was narrowed down to a WebAuthn registration request using:

userVerification: discouraged

in combination with an existing credential being supplied through excludeCredentials.

With no existing WebAuthn credential, the iShield successfully performs credential creation without user verification.

When an existing YubiKey credential is present, the same operation no longer completes.

Changing only the WebAuthn user-verification policy from:

discouraged

to:

preferred

was tested as a diagnostic workaround.

With preferred:

  • Chrome presents the iShield FIDO2 PIN dialog
  • PIN verification succeeds
  • registration succeeds
  • subsequent authentication succeeds
  • existing YubiKeys continue to work normally

No other WebAuthn-related changes were necessary.

There is also an existing Vaultwarden pull request that addresses the same interoperability issue by making the WebAuthn 2FA user-verification policy configurable:

dani-garcia/vaultwarden#7500

The pull request keeps discouraged as the default for backward compatibility and allows administrators to opt into preferred.

In my testing, enabling preferred through that implementation resolves the iShield registration/authentication issue while existing YubiKeys and standard Bitwarden clients continue to work normally.

I am not suggesting that Bitwarden should adopt the Vaultwarden implementation directly; I am including it as additional evidence that the behavior is reproducible and that changing the user-verification policy avoids the failing path.

There is also an independent report in the Vaultwarden investigation involving a Google Titan Security Key:

dani-garcia/vaultwarden#7437 (comment)

That user encounters a different variant of the problem with userVerification: discouraged: the Titan can be registered, but subsequent authentication times out.

Registration with user verification performed produces a working credential.

The Titan case does not require multiple registered credentials, so it appears that interoperability problems involving userVerification: discouraged may not be limited to the iShield/excludeCredentials combination.

I understand that userVerification: discouraged is valid WebAuthn behavior and may be intentional for a two-step-login flow. I am therefore not suggesting that using discouraged is itself necessarily a specification violation.

However, the current behavior results in otherwise functional FIDO2/CTAP authenticators being unusable with Bitwarden under reproducible conditions.

Using userVerification: preferred avoids the failing path in testing while still not requiring user verification from authenticators that do not support or need it.

I would be happy to perform additional tests with the iShield Key 2 Pro and YubiKeys, or provide CTAP/WebAuthn traces if they would help identify the exact interaction causing the failure.

Build Version

Bitwarden Cloud – current production version, tested 2026-08-12

Environment

Cloud (bitwarden.com)

Environment Details

  • Bitwarden Cloud
  • Swissbit iShield Key 2 Pro
  • FIDO2 PIN configured
  • CTAP 2.1
  • YubiKey used as the existing WebAuthn credential
  • Chrome on Windows

Issue Tracking Info

  • I understand that work is tracked outside of Github. A PR will be linked to this issue should one be opened to address it, but Bitwarden doesn't use fields like "assigned", "milestone", or "project" to track progress.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions