Skip to main content
Signing in through a messaging app is convenient, but the confirmation in the chat is not tied to the browser where the session will open: a person talked into confirming someone else’s QR code hands the sign-in to the attacker. A passkey is bound to your application’s origin and works only near the browser, so a mandatory key protects the users who have one. Users still sign in with Veriqa, which also delivers the button for creating the key, while your application registers and verifies the key.
Veriqa already provides the mechanisms this scenario needs; you implement the logic on top of them on your side, in whatever way suits you — see What you build yourself.

What Veriqa adds to passkeys

On its own, a passkey needs an account to attach to and a way back in when the device that holds the key is lost. When people sign in through Veriqa, both come with the first sign-in:
  • An account without a sign-up form. The first sign-in through the messaging app gives your application the user’s identity, and you create the account from it — no form, no password, no email verification, as in Passwordless sign-in and registration. The key is added to an account that already exists.
  • A backup channel from the first sign-in. The account is already linked to the person’s messaging app. If the device that holds the key is lost, you still have a channel to reach the person; run recovery through it as a separate, stricter procedure (see What to keep in mind).
  • Fewer steps than with a sign-up form. To sign in, the person scans a QR code and taps a button in the chat, and they create the key with one more button in the same chat.

What you build yourself

Veriqa neither creates nor verifies passkeys: a WebAuthn server library for your stack registers and verifies the key. Veriqa provides the sign-in and the button in the messaging app after it.
  1. A button in the messaging app after the sign-in. Set the Redirect post-completion action (or a link item of Menu) to the URL of your key-creation page with {handle} in it — Menu and Redirect:
    Synthetic example: the client ID, the URL and the button label are made up. The settings sit in the client entry, so the button arrives after every sign-in to this application through Telegram, and only in the chat of the person who confirmed the sign-in. Add the other channels that show buttons to the same map.
  2. The key-creation page. The link in the button opens where the person has the messaging app — usually on the phone. Your server exchanges the handle and learns who signed in (POST /api/link-handle/redeem with an application token — see Two bots), gets sub and starts a WebAuthn registration for that sub. The key is created on this device and bound to your application’s origin. The handle is single-use and valid for Veriqa:TransactionEngine:CompletedRetentionSeconds — 600 seconds by default.
  3. Keys only through the button. Do not let a session opened by a Veriqa sign-in create a key: if the sign-in was forwarded, that session belongs to the attacker, who would add their own key to someone else’s account. If the sub already has a key, the key-creation page registers a new one only after a signature with an existing key. Otherwise, an attacker who got the person to confirm a forwarded sign-in could ask them to forward the button’s link too and add their own key.
  4. The key before the session. When Veriqa returns the id_token, check whether that sub has a key. If it does, ask for a signature with the key in the same browser and open the session only after you have verified it. If it does not, follow your own policy: open an ordinary session or point them to the button in the messaging app.
  5. Mandatory mode. For a user who has created a key, turn off sign-in without the key: as long as it remains available, the attacker will use it.

Why this works

The attacker starts a sign-in to your application and forwards the QR code to the victim. The victim confirms in their messaging app, and Veriqa hands the authorization code to the attacker’s browser. Your application then asks that browser for the victim’s key. A fake page on another origin gets no signature for your origin, and signing in to someone else’s computer with a key on the phone requires Bluetooth between them: under RFC 10027 (BCP 247, §6.2.3.3) both devices need BLE. With a mandatory key, and new keys added only with an existing one, the attacker gets no session. In BCP 247 terms, for users with a mandatory key this is proximity over radio (§6.1.1). It is also the phishing-resistant sign-in before a confirmation your server creates (§6.1.15). How this fits the other mitigations is shown on Veriqa, BCP 247 and the threat model.

What to keep in mind

  • Only the mandatory mode protects. A user who has no key, or who can still sign in without one, is no better protected than with an ordinary sign-in through a messaging app.
  • Creating the first key is the weak spot. The link in the button is a bearer link: whoever opens it first creates a key for an account that has none. An attacker who talked the person into confirming someone else’s sign-in can ask them to forward this link too. Once the account has a key, the page adds a new one only after a signature with an existing key (step 3). Tell the user about every new key through a channel you have, and let them remove a key that is not theirs.
  • Bluetooth, or a key on the computer itself. Signing in to a computer with a key on the phone requires Bluetooth on both devices. Where radio is forbidden, a key created on the computer itself works: create the first key there by opening the button, for example, in a desktop messaging app. If the first key is already on the phone, no key can be added on such a computer, because adding one takes a signature with the existing key, and that signature needs Bluetooth too. In that case the place factor fits such a perimeter.
  • Not every channel shows the button. Messaging apps and the sign-in with a provider account show a button after the sign-in. Email shows no buttons, and WhatsApp through Twilio does not send them: these users need another way to create a key, but not from a session opened through Veriqa.
  • A lost device. Account recovery without the key is another way around the key. Run it as a separate procedure, stricter than an ordinary sign-in — see Account recovery.