samples/dotnet/pseudo-channels sample in the repository
(veriqa.app/source) works. Its README.md explains how to set it up and
run it: you need a public HTTPS address, a Google OAuth client and an Apple Services ID.
When it helps
A device where your users would rather not type their passwords:- someone else’s computer or a shared one;
- a colleague’s workstation;
- a computer in a hotel, a coworking space or a classroom;
- a kiosk or a terminal at a counter.
- a TV or a set-top box, where a password would have to be typed with a remote;
- a kiosk with a touch screen;
- a device with a few buttons;
- a screen in a meeting room.
How it works
- The sign-in device starts an ordinary OpenID Connect sign-in through
/connect/authorize. The Veriqa sign-in page shows a QR code with a hop mode link. - The user scans the QR code with the phone camera. The phone opens the hop page of the node; when both providers are enabled, the user picks Google or Apple.
- The sample host sends the phone to the provider with the authorization code flow. The user picks an account. If they are not yet signed in to Google or Apple on the phone, they sign in now and type the provider password on the phone.
- The provider returns the phone to the sample’s return address, and the host validates the claims it received.
- The host reports the start to the core with a signed webhook. The core asks its question through the adapter, and the adapter keeps the question context for the transaction.
- The phone shows the Confirm the sign-in page: the application being signed in to, the browser and system the sign-in started from, the location, the start time and the account. The user taps Yes, sign me in or No.
- The host passes the answer to the core with a signed webhook: a confirmation or a decline.
- The sign-in device completes the OpenID Connect flow, and the phone shows the outcome.
sub of the form google-id:<the user's identifier at Google> or
apple-id:<the user's identifier at Apple>, along with channel_user_id, channel_type, email
and email_verified.
If the channel link is opened in the browser of the sign-in device itself rather than scanned with a
phone, the flow becomes an ordinary sign-in at the provider followed by the same question page.
Nothing cross-device happens then, and nothing breaks.
Why the Yes/No step
A provider may return a result without asking anything: withoutprompt, Google shows a consent
screen only to a user who has not authorized the application yet, so on a phone signed in to a
single Google account that has authorized it, the request goes through with no screen at all. The sample sends
prompt=select_account so that the account chooser at least shows which account is used
(Google: OpenID Connect).
Choosing an account also says nothing about
whose sign-in it completes. Without step 6, an attacker could show a victim the QR code of the
attacker’s own sign-in, and the victim’s sign-in at Google would silently complete it — on the
attacker’s device, under the victim’s account. The question page names the application and the device the
sign-in started from, so the victim can answer No.
The question and the answer are bound to one sign-in:
- the question page works only in the browser that has just signed in at the provider: the host sets a short-lived cookie in it after the provider’s return;
- a second account that signs in at the provider for the same sign-in sees neither the details nor the buttons;
- a sign-in that was canceled or timed out is not asked about again.
What it is not
Google and Apple are not built-in channels of Veriqa. This is a sample built on the public channel SPI (Build your own channel adapter): oneIChannelAdapter class is
registered twice, as google-id and as apple-id, and depends on Veriqa.Core.Contracts only. The
sample host itself plays the platform behind the channel.
Nor is it a delivery channel. There is no chat or mailbox behind it, so no message can be sent to the
user “in the channel”: the question “is it you signing in?” is asked by a page of the sample on the
phone. Where pseudo-channels sit among the other channels is covered in
Pseudo-channels; a separate
service for signing in with Google, Apple and Huawei is upcoming — see Coming next.
What to keep in mind
- Scan the QR code with the system camera, not inside a messaging app. A QR code or a link opened in
an app’s built-in browser reaches Google in an embedded user agent, and Google refuses the sign-in
with
disallowed_useragent(Google: OAuth 2.0 policies, “Use secure browsers”, Google: authorization errors). - No phone number. The ID token claims Google documents are
sub,email,email_verified,name,given_name,family_name,pictureandlocale(Google: OpenID Connect), and the scopes Apple accepts arenameandemail(Apple: request an authorization). An application that needs a verified phone number needs a channel that has one. - Apple: the email may be a relay address. A user may choose an anonymous address that forwards
to their real one; mail reaches it only from sender domains registered with Apple
(Apple: private email relay service).
Treat
emailas a contact address, not as an identifier: the identifier issub. - Apple: no name. The sample requests
openid emailonly. Apple returns the name in a separateuserfield of the authorization response rather than as an ID token claim (Apple: request an authorization), and only the first time the user signs in (Apple: authenticating users). The display name of an Apple user is therefore their email address. - State lives in memory. The question context and the outcome are kept in the host process for
the lifetime of the transaction (
Veriqa:TransactionEngine:TransactionTtlSeconds). A restart drops every sign-in in progress.
See also
- Sign-in surfaces — where a sign-in can start and how surfaces differ for the integration.
- Smart TV and keyboard-free surfaces — sign-in where there is nothing to type on.
- Build your own channel adapter — the SPI the sample’s adapter is written against.
- Samples — every sample in the repository.