Relationship to OAuth 2.0 Device Flow
The first question people ask is whether this restates RFC 8628. It does not — the standard and Veriqa answer different questions and live on different layers.
The overlap is only in the shape of the interaction — “start where typing is awkward, confirm on the
phone”. There is no protocol duplication: a browser sign-in through Veriqa lives entirely inside
authorization_code, and the server-to-server entry point ends in an exchange of its own on the token
endpoint.
What it adds compared with device flow
- It collapses the verification step. In device flow the second device goes through another full sign-in: open the address, type the code, authenticate. Here it is one tap in a messenger where the session already exists. Strictly speaking this is not an improvement on the standard but a method dropped into the hole the standard deliberately left empty.
- It targets code phishing. A known weakness of device flow: the attacker starts the flow on their side and talks the victim into entering their code — the standard does nothing to bind the initiator to the confirming party. On a browser sign-in Veriqa shows the initiator’s context at the moment of confirmation, and that addresses precisely this vector.
- It links a channel in the same step. Outside device flow’s scope entirely: the standard ends at issuing a token.
What exists today
A browser or a webview on the device. If the platform offers a webview, the ordinary sign-in through/connect/authorize works: a page with a QR code, confirmation in a messenger, and the
application receives OIDC tokens.
The server-to-server confirmation entry point — no browser needed. The application calls
POST /api/transaction/confirmation, authenticating with client credentials and naming a declared
action type (action_type), and receives a channel_entry in the response: the address for the
user (url) — the channel’s deep link or the channel-selection page — and the same address as a
ready-made QR image (qr, a PNG data URI) with the moment it stops being valid (valid_until). An
application on any TV SDK can show that image; the device needs no browser for it. The user scans
the QR code with their phone and confirms in the messenger. Send include_channel_entries: true and
the response also carries channel_entries — a deep link with its QR code for every available
channel — so the screen can offer a choice of messengers.
The QR image carries the product attribution: a “Powered by Veriqa” strip under the code, below its
quiet zone, so the picture is taller than it is wide — leave room for the strip rather than fitting
the image into a square frame. The strip is part of what the software renders under its license:
cropping it off is technically possible, and whether you may do so is a licensing matter, not a
setting.
The application reads the outcome with GET /api/transaction/{id}/result: confirmed, declined,
expired or failed, and pending while there is no answer yet. If expected identities
(expected_identities) were passed at creation, the result also tells whether the confirming
person matched the expected one (matched_type).
Signing in without a browser, when the application has a backend. Once the outcome is
confirmed, the application’s server exchanges the transaction for the id_token of the person who
confirmed: POST /connect/token with grant_type=urn:veriqa:params:oauth:grant-type:confirmation,
the transaction_id and a scope that contains openid. The server keeps the sub from the token
next to its own account and opens its own session on the TV. The client needs
AllowClientCredentials, AllowConfirmationTokenGrant and openid in AllowedScopes; the exchange
and its rules are described in
Linking from your server.
How this differs from a browser sign-in:
- No
refresh_token. A transaction is redeemed once; the long-lived session on the TV is the application’s own. - It is a confirmation, not a sign-in. It needs a declared
action_typewith its text, and with the grant enabled the application learns the confirming person’s channel identity in every confirmation of that client. A separate client for the TV scenario is worth considering. - The initiator’s context is what your backend writes. The request comes from your server, not
from the TV, and the QR is a bearer entry: whoever opens it first confirms, and the
subis theirs. Put the device and the place into the action type’s text through slots your backend fills.
Client credentials are the application’s secret. Call the server-to-server entry point from your own
server, not from code on the device: a secret shipped inside a TV application can be extracted.
What does not exist today
- A path for a device with no backend of its own. The client secret cannot live on the device, so a TV application without a server has no way to obtain tokens yet. A full implementation of Device Authorization Grant (RFC 8628) is in progress.
- There are no native SDKs for TV platforms: the server-to-server entry point and the exchange are plain HTTP requests.