Skip to content

WebAuthn times out with PIN-configured CTAP 2.1 authenticator when user verification is discouraged #7437

Description

@all-solutions

Steps to reproduce

  1. Configure a FIDO2 PIN on a Swissbit iShield Key 2 Pro MIFARE.
  2. Open the Web Vault and navigate to Settings > Security > Two-step login > Passkey.
  3. Attempt to register the security key.
  4. No PIN prompt appears and the WebAuthn operation eventually times out.
  5. Resetting the FIDO2 applet and registering the key before configuring a PIN works, but this is not a complete workaround because authentication is also initiated with userVerification: discouraged.

The same Vaultwarden installation successfully registers YubiKeys that already have a FIDO2 PIN. A PIN prompt appears for those keys.

The iShield also registers and authenticates successfully on webauthn.io with its PIN configured.

Expected result

Vaultwarden should interoperate with the authenticator: either the non-UV operation should complete successfully, or user verification should be requested so the browser presents a PIN prompt.

Actual result

With a FIDO2 PIN configured, no PIN dialog appears and the operation times out. Registration works only while no PIN is configured.

Authenticator information

Product:              Swissbit iShield Key 2 Pro MIFARE
Device version:       1.1.0
FIDO version:         v1.4.0-0-gd69b47b
AAGUID:               7787a482-13e8-4784-8a06-c7ed49a7aaf4
Supported protocols:  U2F, CTAP 2.0, CTAP 2.1
clientPin:            yes
alwaysUv:             no
makeCredUvNotRqd:     yes

The authenticator advertises makeCredUvNotRqd: yes. Therefore, with Vaultwarden requesting userVerification: discouraged, Chrome does not present a PIN dialog. The resulting non-UV makeCredential operation does not complete.

Confirmed diagnostic workaround

I built Vaultwarden 1.36.0 with only the WebAuthn user-verification policy changed from discouraged to preferred for both registration and authentication:

  • registration challenge: Discouraged_DO_NOT_USE > Preferred
  • stored registration state: "discouraged" > "preferred"
  • authentication challenge: Discouraged_DO_NOT_USE > Preferred
  • stored authentication state: "discouraged" > "preferred"

With this test build:

  1. Chrome presents the FIDO2 PIN dialog.
  2. After entering the PIN and touching the key, registration completes.
  3. The key appears in the WebAuthn security-key list.
  4. Authentication in a new Incognito window also succeeds with PIN and touch.

No other source or configuration changes were made.

This indicates that Vaultwarden's explicit userVerification: discouraged policy triggers the incompatible path. The underlying issue may be in the authenticator firmware, Windows WebAuthn, or their interaction, but allowing preferred provides a working interoperability option.

Would the maintainers consider making the WebAuthn 2FA user-verification policy configurable, while keeping discouraged as the default for backward compatibility? I would be willing to prepare a PR once the preferred approach and configuration scope are agreed upon.

Environment

  • Vaultwarden: 1.36.0
  • Successful diagnostic build: 1.36.0-uv-preferred-test
  • Web Vault: 2026.4.1
  • Server: Debian 13, Linux x86_64
  • Database: SQLite 3.51.3
  • Deployment: built from source by the Proxmox VE Community Script
  • Reverse proxy: none; Vaultwarden serves HTTPS directly
  • Client: Web Vault
  • Browser: Google Chrome 150.0.7871.124

Vaultwarden Support String

Your environment (Generated via diagnostics page)

  • Vaultwarden version: v1.36.0-uv-preferred-test
  • Web-vault version: v2026.4.1
  • OS/Arch: linux/x86_64
  • Running within a container: false (Base: Not applicable)
  • Database type: SQLite
  • Database version: 3.51.3
  • Uses config.json: true
  • Uses a reverse proxy: false
  • Internet access: true
  • Internet access via a proxy: false
  • DNS Check: true
  • Browser/Server Time Check: true
  • Server/NTP Time Check: true
  • Domain Configuration Check: false
  • HTTPS Check: true
  • Websocket Check: true
  • HTTP Response Checks: true

Config & Details (Generated via diagnostics page)

Show Config & Details

Environment settings which are overridden: ADMIN_TOKEN

Config:

{
  "_duo_akey": "***",
  "_enable_duo": false,
  "_enable_email_2fa": true,
  "_enable_smtp": true,
  "_enable_yubico": true,
  "_icon_service_csp": "",
  "_icon_service_url": "",
  "_ip_header_enabled": true,
  "_max_note_size": 10000,
  "_smtp_img_src": "***:",
  "admin_ratelimit_max_burst": 3,
  "admin_ratelimit_seconds": 300,
  "admin_session_lifetime": 20,
  "admin_token": "***",
  "allowed_connect_src": "",
  "allowed_iframe_ancestors": "",
  "attachments_folder": "/opt/vaultwarden/data/attachments",
  "auth_request_purge_schedule": "30 * * * * *",
  "authenticator_disable_time_drift": false,
  "data_folder": "/opt/vaultwarden/data",
  "database_conn_init": "",
  "database_idle_timeout": 600,
  "database_max_conns": 10,
  "database_min_conns": 2,
  "database_timeout": 30,
  "database_url": "********************************",
  "db_connection_retries": 15,
  "disable_2fa_remember": false,
  "disable_admin_token": false,
  "disable_icon_download": false,
  "dns_prefer_ipv6": false,
  "domain": "*****://*******************",
  "domain_origin": "*****://*******************",
  "domain_path": "",
  "domain_set": true,
  "duo_context_purge_schedule": "30 * * * * *",
  "duo_host": null,
  "duo_ikey": null,
  "duo_skey": null,
  "duo_use_iframe": false,
  "email_2fa_auto_fallback": false,
  "email_2fa_enforce_on_verified_invite": false,
  "email_attempts_limit": 3,
  "email_change_allowed": true,
  "email_expiration_time": 600,
  "email_token_size": 6,
  "emergency_access_allowed": true,
  "emergency_notification_reminder_schedule": "0 3 * * * *",
  "emergency_request_timeout_schedule": "0 7 * * * *",
  "enable_db_wal": true,
  "enable_websocket": true,
  "enforce_single_org_with_reset_pw_policy": false,
  "event_cleanup_schedule": "0 10 0 * * *",
  "events_days_retain": null,
  "experimental_client_feature_flags": "",
  "extended_logging": true,
  "helo_name": null,
  "hibp_api_key": null,
  "http_request_block_non_global_ips": true,
  "http_request_block_regex": null,
  "icon_blacklist_non_global_ips": true,
  "icon_blacklist_regex": null,
  "icon_cache_folder": "/opt/vaultwarden/data/icon_cache",
  "icon_cache_negttl": 259200,
  "icon_cache_ttl": 2592000,
  "icon_download_timeout": 10,
  "icon_redirect_code": 302,
  "icon_service": "internal",
  "incomplete_2fa_schedule": "30 * * * * *",
  "incomplete_2fa_time_limit": 3,
  "increase_note_size_limit": false,
  "invitation_expiration_hours": 120,
  "invitation_org_name": "Vaultwarden",
  "invitations_allowed": true,
  "ip_header": "X-Forwarded-For",
  "job_poll_interval_ms": 30000,
  "log_file": null,
  "log_level": "info",
  "log_timestamp_format": "%Y-%m-%d %H:%M:%S.%3f",
  "login_ratelimit_max_burst": 10,
  "login_ratelimit_seconds": 60,
  "org_attachment_limit": null,
  "org_creation_users": "",
  "org_events_enabled": false,
  "org_groups_enabled": false,
  "password_hints_allowed": true,
  "password_iterations": 100000,
  "purge_incomplete_sso_auth": "0 20 0 * * *",
  "push_enabled": false,
  "push_identity_uri": "https://identity.bitwarden.com",
  "push_installation_id": "***",
  "push_installation_key": "***",
  "push_relay_uri": "https://push.bitwarden.com",
  "reload_templates": false,
  "require_device_email": false,
  "rsa_key_filename": "/opt/vaultwarden/data/rsa_key",
  "send_purge_schedule": "0 5 * * * *",
  "sendmail_command": null,
  "sends_allowed": false,
  "sends_folder": "/opt/vaultwarden/data/sends",
  "show_password_hint": true,
  "signups_allowed": false,
  "signups_domains_whitelist": "",
  "signups_verify": true,
  "signups_verify_resend_limit": 6,
  "signups_verify_resend_time": 3600,
  "smtp_accept_invalid_certs": false,
  "smtp_accept_invalid_hostnames": false,
  "smtp_auth_mechanism": "\"Login\"",
  "smtp_debug": false,
  "smtp_embed_images": true,
  "smtp_explicit_tls": null,
  "smtp_from": "***********************",
  "smtp_from_name": "*********",
  "smtp_host": "********************",
  "smtp_password": "***",
  "smtp_port": 587,
  "smtp_security": "starttls",
  "smtp_ssl": null,
  "smtp_timeout": 15,
  "smtp_username": "***********************",
  "sso_allow_unknown_email_verification": false,
  "sso_audience_trusted": null,
  "sso_auth_only_not_session": false,
  "sso_authority": "",
  "sso_authorize_extra_params": "",
  "sso_callback_path": "*****://************************************************",
  "sso_client_cache_expiration": 0,
  "sso_client_id": "",
  "sso_client_secret": "***",
  "sso_debug_tokens": false,
  "sso_enabled": false,
  "sso_master_password_policy": null,
  "sso_only": false,
  "sso_pkce": true,
  "sso_scopes": "email profile",
  "sso_signups_match_email": true,
  "templates_folder": "/opt/vaultwarden/data/templates",
  "tmp_folder": "/opt/vaultwarden/data/tmp",
  "trash_auto_delete_days": null,
  "trash_purge_schedule": "0 5 0 * * *",
  "use_sendmail": false,
  "use_syslog": false,
  "user_attachment_limit": null,
  "user_send_limit": null,
  "web_vault_enabled": true,
  "web_vault_folder": "/opt/vaultwarden/web-vault",
  "yubico_client_id": "51567",
  "yubico_secret_key": "***",
  "yubico_server": null
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions