# FIDO Hybrid QR

> Source: https://docs.barcoder.ai/docs/standards/fido-hybrid-qr
> research date 2026-10-30 · extracted at 2026-10-30
> Publisher: Barcoder — encyclopedia of QR, barcode and payment-code standards

Specifications:
- [Client to Authenticator Protocol (CTAP) 2.3, Proposed Standard, 26 February 2026](https://fidoalliance.org/specs/fido-v2.3-ps-20260226/fido-client-to-authenticator-protocol-v2.3-ps-20260226.html)
- [Client to Authenticator Protocol (CTAP) 2.2, Proposed Standard, 14 July 2025](https://fidoalliance.org/specs/fido-v2.2-ps-20250714/fido-client-to-authenticator-protocol-v2.2-ps-20250714.html)
- [IANA provisional registration of the fido URI scheme](https://www.iana.org/assignments/uri-schemes/prov/fido)

## Overview

The **FIDO hybrid QR code** is the [QR Code](https://docs.barcoder.ai/docs/standards/qr-code) a computer shows when a user signs in with a passkey held on another device, usually a phone. Its text is a `FIDO:/` URI followed by digits, which encode a small CBOR map holding a public key and a shared secret <sup>[1][1]</sup> <sup>[2][2]</sup>. The code carries no web address or account data. It only starts the process: the phone must then prove it is physically close over Bluetooth Low Energy (BLE) before the normal CTAP exchange runs <sup>[1][1]</sup>.

The mechanism was first called **caBLE** (cloud-assisted Bluetooth Low Energy), was renamed **hybrid** in 2022 <sup>[7][7]</sup>, and is defined in CTAP 2.2 and 2.3.

## History

- **2019.** TechTarget reports that Google had offered caBLE since 2019 <sup>[10][10]</sup>.
- **2020.** Chromium's `v2_handshake.cc`, which builds and parses today's QR payload, carries a 2020 copyright line <sup>[4][4]</sup>.
- **June 2021.** CTAP 2.1 listed only USB HID, NFC and BLE bindings, with no hybrid section <sup>[13][13]</sup>.
- **3 September 2021.** Adam Langley of Google registered the `fido` URI scheme with IANA for "forthcoming" FIDO Alliance specifications on cross-device authentication <sup>[6][6]</sup>.
- **5 May 2022.** Apple, Google and Microsoft jointly committed to letting users approve a sign-in on a phone for a nearby device, even one running a different operating system or browser <sup>[11][11]</sup>. TechTarget named caBLE as the protocol they would use <sup>[10][10]</sup>.
- **2022.** At WWDC22, Apple described the QR and Bluetooth flow as part of the standards behind passkeys <sup>[12][12]</sup>.
- **24 June 2022.** Langley's WebAuthn change added the transport string `hybrid`, noting that FIDO had chosen the name for "the transport formerly known as caBLE". It was merged on 27 July 2022 <sup>[7][7]</sup> <sup>[8][8]</sup>.
- **14 July 2025.** CTAP 2.2 reached Proposed Standard with the hybrid transports in section 11.5 <sup>[1][1]</sup>.
- **26 February 2026.** CTAP 2.3 added BLE as an optional data channel beside WebSockets <sup>[2][2]</sup> <sup>[14][14]</sup>.

## Technical specification

**Carrier.** An ordinary [QR Code](https://docs.barcoder.ai/docs/standards/qr-code). The hybrid sections reviewed for this page give no symbol size or error-correction level <sup>[1][1]</sup>.

### Payload

The text is `FIDO:/` plus digit-encoded CBOR. The specification writes the scheme in uppercase and requires a single slash, because a double slash would imply an authority, which this scheme does not have <sup>[1][1]</sup>. Chromium's parser accepts the prefix in either case <sup>[4][4]</sup>.

The decoded data is a canonical CBOR map with integer keys <sup>[1][1]</sup> <sup>[2][2]</sup>:

| Key | Type | Required | Meaning |
|---|---|---|---|
| 0 | 33 bytes | yes | Compressed P-256 public key that authenticates the displaying device |
| 1 | 16 bytes | yes | Random QR secret |
| 2 | integer | yes | Number of assigned tunnel server domains the implementation knows (two are listed) |
| 3 | integer | no | Current time, in seconds since the epoch |
| 4 | boolean | no | `true` if the displaying device supports state-assisted transactions |
| 5 | text | yes | Flow hint: `ga` (sign-in), `mc` (credential creation), `dcp` (Digital Credentials presentation) or `dci` (issuance). Unknown values count as `ga` |
| 6 | array | no | Data channels, from CTAP 2.3: 0 is WebSockets, 1 is BLE. If absent, WebSockets only |

The Required column follows the specification's text. Chromium's parser is looser: it insists only on keys 0 and 1 <sup>[4][4]</sup>. Encoders may add a random GREASE key, 65535, so that parsers stay tolerant of unknown keys <sup>[1][1]</sup>. libwebauthn leaves key 6 out for legacy peers, and omits key 4 rather than writing `false` <sup>[25][25]</sup>.

### Digit encoding

The bytes are split into 7-byte chunks. Each chunk is read as a little-endian integer and written as a zero-padded 17-digit decimal number. A trailing 1 to 6 bytes take 3, 5, 8, 10, 13 or 15 digits <sup>[1][1]</sup> <sup>[4][4]</sup>. The specification says only that the encoding is "designed to be efficient when expressed in a QR code" <sup>[1][1]</sup>.

**Why digits fit QR well.** QR numeric mode stores three digits in 10 bits and two digits in 7 <sup>[29][29]</sup>, so a 17-digit chunk costs 57 bits to carry 56 bits of data (our calculation): about 1.8 % overhead.

### Illustrative payload

The CTAP text gives no sample QR string. The string below is **structurally illustrative only**. It was computed for this page with an all-zero X coordinate, a counting secret and a fixed timestamp, so it is not a working key and belongs to no device:

```
FIDO:/000000091493500540000000000000000000000000000000000000000000000000000000000000000000000564050807291904025421010491811870057950297627316200231212771312386107096654083332
```

It decodes to these 69 bytes of CBOR, with keys 0 to 5 in order:

```
a6 00 5821 02 00…00 01 50 000102…0f 02 02 03 1a 6b49d200 04 f5 05 62 6761
```

### Size in a QR code

The figures here are our calculation, not a specification limit.

With keys 0 to 5, the payload is 69 bytes, or 168 digits, for 174 characters of text. Without the optional keys 3 and 4 it is 61 bytes and 155 characters.

| Encoding of the 174 characters | Bits | Smallest version at L |
|---|---|---|
| `FIDO:/` in alphanumeric, digits in numeric | 620 | 4 (33 × 33) |
| All alphanumeric | 970 | 6 (41 × 41) |
| All byte | 1,404 | 8 (49 × 49) |

The calculation uses the mode and count-indicator sizes for versions 1 to 9 <sup>[30][30]</sup>, QR's 11 bits per alphanumeric pair <sup>[31][31]</sup>, and the data-codeword totals <sup>[32][32]</sup>. Every character of `FIDO:/` is in the alphanumeric set, which includes `:` and `/` <sup>[33][33]</sup>. In the mixed form, version 4 fits at level L, version 5 (37 × 37) at M, version 7 at Q and version 8 at H <sup>[32][32]</sup>. Each version adds four modules per side <sup>[34][34]</sup>. This page could not establish which modes or levels shipping browsers use.

### After the scan

1. The phone derives keys from the QR secret with HKDF-SHA256 and broadcasts an encrypted 20-byte BLE advertisement under service UUID `0000fff9-0000-1000-8000-00805f9b34fb` <sup>[1][1]</sup>.
2. The computer, scanning for that UUID, decrypts the advertisement to get a connection nonce, a routing ID and a tunnel server ID <sup>[1][1]</sup>.
3. Both devices join a WebSocket tunnel at `wss://<domain>/cable/connect/<routing ID>/<tunnel ID>`. The assigned domains are `cable.ua5v.com` and `cable.auth.com` <sup>[1][1]</sup>. A third-party library says Google runs the first and Apple the second <sup>[24][24]</sup>.
4. A Noise handshake (KNpsk0, with P-256, SHA-256 and AES-256-GCM) secures the tunnel, and the CTAP messages run inside it <sup>[1][1]</sup>. Apple says the relay server "can't see anything that's going on" <sup>[12][12]</sup>.
5. With CTAP 2.3, the devices may skip the tunnel and use an L2CAP channel over BLE. WebSockets should stay available as a fallback <sup>[2][2]</sup>.

The phone can also send linking data, so later sign-ins from the same computer can start with a state-assisted transaction and no QR code <sup>[1][1]</sup>. Support for this is signalled by key 4.

## Use cases

- **Passkey sign-in across devices.** The core use. On Windows 11 23H2 or later the user picks an iPhone, iPad or Android device, then scans the code. Microsoft requires Bluetooth and internet on both devices <sup>[16][16]</sup>. Google states that the phone must be near the laptop and the user must approve on the phone <sup>[17][17]</sup>.
- **Creating a passkey from another device.** The `mc` hint covers registration <sup>[1][1]</sup>, which Thales documents for its Android SDK <sup>[18][18]</sup>.
- **Third-party passkey providers.** On Android 14 and later, the system camera scans the code and hands the request to the chosen credential provider <sup>[18][18]</sup>. The Microsoft Authenticator camera scans these codes on Android but not on iOS, where the system camera is required <sup>[16][16]</sup>.
- **Digital credentials.** The `dcp` and `dci` hints carry Digital Credentials API presentation and issuance across devices <sup>[1][1]</sup>.
- **Enterprise sign-in.** Microsoft Entra ID documents the flow for passkeys held in Microsoft Authenticator <sup>[16][16]</sup>.

Where a screen is missing, the QR step does not work. Meta has described a method for XR headsets that bypasses QR codes while keeping the proximity requirement <sup>[19][19]</sup>.

## Security

The code is not a credential. Its key pair is single-use, and Apple notes that a code sent by email or generated on a fake website "won't work", because a remote attacker cannot receive the Bluetooth advertisement <sup>[12][12]</sup>. CTAP states that the proximity proof exists "to help prevent attacks" <sup>[1][1]</sup>.

**PoisonSeed (July 2025).** Expel reported that attackers had relayed a real QR code to a phished user to get past a FIDO key. It then retracted the claim on 25 July 2025: the logs showed that all later MFA challenges failed, and it accepted that a properly implemented flow without proximity times out <sup>[20][20]</sup>.

The IETF's draft on cross-device flows, draft 15 of January 2026, says FIDO cross-device authentication proves proximity through BLE advertisements, which greatly reduces exposure to the attacks it catalogues. It recommends the approach where devices support it <sup>[21][21]</sup>.

## Implementations

| Project | Lang | Stars | Last active | Notes |
|---|---|---|---|---|
| [chromium/chromium](https://github.com/chromium/chromium) | C++ | ~25.2k | 2026-10 | `qr::Encode` and `qr::Parse` in `device/fido/cable/v2_handshake.cc` <sup>[4][4]</sup> <sup>[28][28]</sup> |
| [kanidm/webauthn-rs](https://github.com/kanidm/webauthn-rs) | Rust | ~0.7k | 2026-10 | `webauthn-authenticator-rs` implements both roles. Its authors call it incomplete and not crypto-reviewed <sup>[24][24]</sup> <sup>[27][27]</sup> |
| [linux-credentials/libwebauthn](https://github.com/linux-credentials/libwebauthn) | Rust | ~0.6k | 2026-10 | Linux platform library that builds the QR code, with caBLE v2 and CTAP 2.3 BLE-only hybrid <sup>[25][25]</sup> <sup>[26][26]</sup> |

No maintained standalone `FIDO:/` decoder was found, and no Python implementation turned up in this search. Any general QR reader returns the text, but acting on it needs the full protocol.

## Comparison

- **Hybrid QR vs [SMART Health Cards](https://docs.barcoder.ai/docs/standards/smart-health-cards).** Both turn data into digits to use QR numeric mode. SMART Health Cards write each character as two digits, because a JWS character holds about 6 bits <sup>[23][23]</sup>. FIDO packs raw bytes at 17 digits per 7 bytes <sup>[1][1]</sup>. A SMART Health Card is the credential itself, while a FIDO code holds only single-use keys <sup>[12][12]</sup>.
- **Hybrid QR vs OAuth device flow (RFC 8628).** In the device flow, a user approves a request in a browser on another device, and a QR code can carry the verification link <sup>[22][22]</sup>. The IETF draft says pairing FIDO cross-device authentication with the Authorization Code Grant and PKCE avoids the device flow's risks <sup>[21][21]</sup>. Choose hybrid when both devices have BLE and internet access <sup>[21][21]</sup>.
- **Hybrid vs a USB or NFC security key.** Those have their own CTAP bindings <sup>[13][13]</sup>. Hybrid needs no extra hardware when the user already holds a phone with a passkey, but it needs Bluetooth and, usually, internet on both devices <sup>[16][16]</sup>.

## Fun facts

- The `fido` registration names Adam Langley, and its reference field cites an unrelated-looking draft on SSH URIs, `draft-ietf-secsh-scp-sftp-ssh-uri` <sup>[6][6]</sup>. The scheme is still only provisional <sup>[5][5]</sup>.
- The old name survives in today's specification: the WebSocket subprotocol is `fido.cable`, and the state-assisted header is `X-caBLE-Client-Payload` <sup>[1][1]</sup>.
- The `webauthn-authenticator-rs` documentation still says no public specification exists and that Chromium's C++ source is the only reference <sup>[24][24]</sup>, although CTAP 2.2 has since published it <sup>[1][1]</sup>.

## Status

**Active, with a rename pending.** CTAP 2.3 is the current Proposed Standard <sup>[2][2]</sup>. WebAuthn Level 3, a W3C Recommendation of 25 August 2026, defines the `hybrid` transport value <sup>[9][9]</sup>.

Per passkeys.dev (updated 21 September 2026), Android 9+ and iOS/iPadOS 16+ can act as the scanning authenticator. Clients include Windows 23H2+, macOS 13+ with Chrome or Edge, and Chrome OS 108+. The table's flattened layout makes the row alignment slightly ambiguous <sup>[15][15]</sup>.

BLE data transfer in CTAP 2.3 needs support on both the initiating platform and the phone <sup>[14][14]</sup>.

## Sources

[1]: https://fidoalliance.org/specs/fido-v2.2-ps-20250714/fido-client-to-authenticator-protocol-v2.2-ps-20250714.html
[2]: https://fidoalliance.org/specs/fido-v2.3-ps-20260226/fido-client-to-authenticator-protocol-v2.3-ps-20260226.html
[4]: https://chromium.googlesource.com/chromium/src/+/refs/heads/main/device/fido/cable/v2_handshake.cc
[5]: https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml
[6]: https://www.iana.org/assignments/uri-schemes/prov/fido
[7]: https://lists.w3.org/Archives/Public/public-webauthn/2022Jun/0258.html
[8]: https://lists.w3.org/Archives/Public/public-webauthn/2022Jul/0229.html
[9]: https://www.w3.org/TR/webauthn-3/
[10]: https://www.techtarget.com/cybersecurity/feature/Apple-Microsoft-Google-expand-FIDO2-passwordless-support?amp=1
[11]: https://fidoalliance.org/apple-google-and-microsoft-commit-to-expanded-support-for-fido-standard-to-accelerate-availability-of-passwordless-sign-ins/
[12]: https://developer.apple.com/videos/play/wwdc2022/10092/
[13]: https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html
[14]: https://developers.yubico.com/CTAP/CTAP2.3.html
[15]: https://passkeys.dev/device-support/
[16]: https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-sign-in-passkey-authenticator
[17]: https://developers.google.com/identity/passkeys/use-cases
[18]: https://thalesdocs.com/oip/fido2-sdk/fido2-sdk-hybrid-transport/fido2-sdk-hybrid-transport-android/index.html
[19]: https://fidoalliance.org/?p=88419
[20]: https://www.bleepingcomputer.com/news/security/threat-actors-try-to-downgrade-fido2-mfa-auth-in-poisonseed-phishing-attack/
[21]: https://www.ietf.org/archive/id/draft-ietf-oauth-cross-device-security-15.html
[22]: https://www.rfc-editor.org/rfc/rfc8628
[23]: https://spec.smarthealth.cards/
[24]: https://docs.rs/webauthn-authenticator-rs/latest/webauthn_authenticator_rs/cable/index.html
[25]: https://docs.rs/crate/libwebauthn/0.5.0/source/src/transport/cable/qr_code_device.rs
[26]: https://github.com/linux-credentials/libwebauthn
[27]: https://github.com/kanidm/webauthn-rs
[28]: https://github.com/chromium/chromium
[29]: https://www.thonky.com/qr-code-tutorial/numeric-mode-encoding
[30]: https://www.thonky.com/qr-code-tutorial/data-encoding
[31]: https://www.thonky.com/qr-code-tutorial/alphanumeric-mode-encoding
[32]: https://www.thonky.com/qr-code-tutorial/error-correction-table
[33]: https://www.thonky.com/qr-code-tutorial/alphanumeric-table
[34]: https://www.qrcode.com/en/about/version.html

[1] [Client to Authenticator Protocol (CTAP) 2.2, Proposed Standard](https://fidoalliance.org/specs/fido-v2.2-ps-20250714/fido-client-to-authenticator-protocol-v2.2-ps-20250714.html) — FIDO Alliance, 2025
[2] [Client to Authenticator Protocol (CTAP) 2.3, Proposed Standard](https://fidoalliance.org/specs/fido-v2.3-ps-20260226/fido-client-to-authenticator-protocol-v2.3-ps-20260226.html) — FIDO Alliance, 2026
[4] [device/fido/cable/v2_handshake.cc](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/device/fido/cable/v2_handshake.cc) — The Chromium Authors, accessed 2026
[5] [Uniform Resource Identifier (URI) Schemes](https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml) — IANA, accessed 2026
[6] [Provisional URI scheme registration: fido](https://www.iana.org/assignments/uri-schemes/prov/fido) — IANA, 2021
[7] [public-webauthn: commit adding the hybrid transport](https://lists.w3.org/Archives/Public/public-webauthn/2022Jun/0258.html) — W3C mailing list archive, 2022
[8] [public-webauthn: merge of PR #1755](https://lists.w3.org/Archives/Public/public-webauthn/2022Jul/0229.html) — W3C mailing list archive, 2022
[9] [Web Authentication Level 3](https://www.w3.org/TR/webauthn-3/) — W3C, 2026
[10] [Apple, Microsoft, Google expand FIDO2 passwordless support](https://www.techtarget.com/cybersecurity/feature/Apple-Microsoft-Google-expand-FIDO2-passwordless-support?amp=1) — TechTarget, 2022
[11] [Apple, Google and Microsoft commit to expanded support for FIDO standard](https://fidoalliance.org/apple-google-and-microsoft-commit-to-expanded-support-for-fido-standard-to-accelerate-availability-of-passwordless-sign-ins/) — FIDO Alliance, 2022
[12] [Meet passkeys, WWDC22](https://developer.apple.com/videos/play/wwdc2022/10092/) — Apple Developer, 2022
[13] [Client to Authenticator Protocol (CTAP) 2.1, Proposed Standard](https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html) — FIDO Alliance, 2021
[14] [CTAP 2.3: Protocol Refinements and PIN Complexity Improvements](https://developers.yubico.com/CTAP/CTAP2.3.html) — Yubico, accessed 2026
[15] [Device Support](https://passkeys.dev/device-support/) — passkeys.dev, 2026
[16] [Sign in with passkeys in Authenticator for Android and iOS devices](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-sign-in-passkey-authenticator) — Microsoft Learn, 2026
[17] [Passkeys use cases](https://developers.google.com/identity/passkeys/use-cases) — Google for Developers, 2025
[18] [Android hybrid transport](https://thalesdocs.com/oip/fido2-sdk/fido2-sdk-hybrid-transport/fido2-sdk-hybrid-transport-android/index.html) — Thales (vendor), accessed 2026
[19] [No Display? No Problem: Cross-Device Passkey Authentication for XR Devices](https://fidoalliance.org/?p=88419) — Meta Engineering, via FIDO Alliance, 2026
[20] [Threat actors try to downgrade FIDO2 MFA auth in PoisonSeed phishing attack](https://www.bleepingcomputer.com/news/security/threat-actors-try-to-downgrade-fido2-mfa-auth-in-poisonseed-phishing-attack/) — BleepingComputer, 2025
[21] [Cross-Device Flows: Security Best Current Practice, draft 15](https://www.ietf.org/archive/id/draft-ietf-oauth-cross-device-security-15.html) — IETF, 2026
[22] [RFC 8628: OAuth 2.0 Device Authorization Grant](https://www.rfc-editor.org/rfc/rfc8628) — IETF, 2019
[23] [SMART Health Cards Framework](https://spec.smarthealth.cards/) — SMART Health Cards, accessed 2026
[24] [webauthn_authenticator_rs::cable](https://docs.rs/webauthn-authenticator-rs/latest/webauthn_authenticator_rs/cable/index.html) — Kanidm project, accessed 2026
[25] [libwebauthn 0.5.0: qr_code_device.rs](https://docs.rs/crate/libwebauthn/0.5.0/source/src/transport/cable/qr_code_device.rs) — docs.rs, accessed 2026
[26] [linux-credentials/libwebauthn](https://github.com/linux-credentials/libwebauthn) — GitHub, accessed 2026
[27] [kanidm/webauthn-rs](https://github.com/kanidm/webauthn-rs) — GitHub, accessed 2026
[28] [chromium/chromium](https://github.com/chromium/chromium) — GitHub, accessed 2026
[29] [Numeric Mode Encoding](https://www.thonky.com/qr-code-tutorial/numeric-mode-encoding) — Thonky.com, accessed 2026
[30] [Data Encoding](https://www.thonky.com/qr-code-tutorial/data-encoding) — Thonky.com, accessed 2026
[31] [Alphanumeric Mode Encoding](https://www.thonky.com/qr-code-tutorial/alphanumeric-mode-encoding) — Thonky.com, accessed 2026
[32] [Error Correction Code Words and Block Information](https://www.thonky.com/qr-code-tutorial/error-correction-table) — Thonky.com, accessed 2026
[33] [Alphanumeric Table](https://www.thonky.com/qr-code-tutorial/alphanumeric-table) — Thonky.com, accessed 2026
[34] [Information capacity and versions of QR Code](https://www.qrcode.com/en/about/version.html) — Denso Wave, accessed 2026

## Deployments

_No country reports mention this standard by name._

## Regions / aggregations not mapped to a single country

- Universal
