Skip to main content
This explainer is for developers who have worked with OIDC but not with Veriqa. It shows where exactly Veriqa plugs into a standard flow — and where it stops.

OIDC on one screen

OpenID Connect is a thin identity layer on top of OAuth 2.0. The application receives two tokens: an id_token (who the user is) and an access_token (access to APIs). The app does not check passwords itself — it trusts the issuer (authorization server), which returns signed tokens.

Authorization Code Flow + PKCE

The standard secure flow for web and desktop apps:
  1. The app redirects the user to the issuer’s /authorize (with state, nonce and PKCE parameters).
  2. The user authenticates on the issuer side.
  3. The issuer returns a short-lived code to the registered redirect_uri.
  4. The app exchanges the code (+ PKCE code_verifier) for tokens at /token.
PKCE with the S256 method is mandatory for public clients — it protects the code exchange from interception.

Where Veriqa fits

Veriqa sits between steps 2 and 3 — in place of “the user authenticates”. Instead of a sign-in form, the issuer opens a Veriqa transaction: it shows a QR code / entry point, waits for confirmation in a trusted channel, builds a ClaimsPrincipal from the result and hands it to OpenIddict to issue the code. From there it is plain OIDC (code → /token → tokens).

The full flow, step by step

From starting the transaction to issuing OpenIddict tokens.
The key point: Veriqa does not replace OpenIddict — token issuance, discovery, JWKS and refresh stay with it. Veriqa only supplies user authentication through a trusted channel.

The channel adapter in the flow

The channel adapter (Telegram / WhatsApp / other channels / Email) links the transaction to a specific messaging app: it delivers the confirmation request to the user, receives their response and returns the resolved identity to the transaction. Each channel is a separate adapter, and the set is extensible.

Resolved identity and claims

After confirmation Veriqa builds an identity snapshot and maps it to OIDC claims: channel is a Veriqa-specific scope and it is the gate for the channel claims. If you do not request it, neither claim reaches the access_token, the id_token or the /connect/userinfo response. Add channel to your RP’s requested scopes and to the client’s AllowedScopes if your application reads them. avatar is the other Veriqa-specific scope, and it is the gate for picture. The value is the image itself, a data:image/…;base64,… URI (a channel that exposes a public link may give an https URL instead). It travels only in the access_token and so reaches you only through /connect/userinfo; it is never put into the id_token. Request avatar (and add it to the client’s AllowedScopes), fetch the claims from userinfo (GetClaimsFromUserInfoEndpoint = true in ASP.NET Core), and treat a missing picture as “no avatar”. In ASP.NET Core picture is not mapped into the principal by default, and it should not be: a data URI in the authentication cookie inflates the request headers. Take the image from the userinfo JSON in OnUserInformationReceived and keep it in your own store. /connect/userinfo returns only the claims permitted by scopes and configuration. Override the mapping with your own IClaimsMapper.
preferred_username is a hint, not an identity. On the Email channel (Push mode) it carries the sender display name — a string the sender types into the From header themselves. SPF, DKIM and DMARC do not verify it: they cover the domain and the address, not the displayed name. Veriqa sanitizes the value (bidi overrides and control characters are removed, the length is capped), but it cannot verify it.The user identifier is sub alone; the verified address is email next to email_verified. Never match accounts on preferred_username and never present it as a verified name.

Step-up and confirmation in OIDC terms

2FA and step-up are not separate transaction types but overlays: 2FA over login, step-up over confirmation. It is the same Veriqa transaction model with extra context, so confirming a sensitive action goes through the same trusted channel as a normal sign-in.

What Veriqa is NOT

Veriqa is an OpenID Connect provider, but not an IAM: it does not store or manage user accounts. Veriqa adds a sign-in method and channel linking to your system, and the user base stays with you.

Further reading

.NET quickstart

Wire Veriqa into an ASP.NET Core host.

Preparing for production

The pre-production checklist.