Concepts

How Okia login works, and the ideas you need before integrating.

The login model

Okia replaces passwords with two factors, in order of preference:

Method What the user sees When
Passkey Face ID / Touch ID / Android biometric prompt Every login after enrollment. Target: < 5s, zero typing
WhatsApp code 6-digit code delivered to their WhatsApp First-time enrollment, and always available as fallback

All login happens on Okia's hosted pages at auth.okia.io — via popup on desktop or full redirect on mobile (the SDK auto-selects; redirect is the documented baseline). Your site never sees a phone number unless the user consents to the phone scope. There is no cross-origin iframe mode.

First login (enrollment)

  1. User clicks your login button → hosted sheet opens.
  2. Enters phone number → receives a 6-digit code on WhatsApp → verifies.
  3. Offered a passkey ("Sign in with Face ID next time"). Skippable — an OTP-only account still works.
  4. Redirected back to your site with an authorization code; your backend exchanges it for tokens.

Returning login

The user taps the phone field and their passkey appears (WebAuthn conditional UI) — one biometric confirmation, no form. If they have an active Okia session under 24h old, it's a one-tap "Continue as +9•••42".

Fallback

The WhatsApp code path is always one tap away. A fallback login sets amr: ["otp"] in the ID token (see step-up below) and fires a user.otp_fallback webhook. Passkeys are never deleted by an OTP login.

Pairwise subject IDs

The same person has a different sub on every site. This is deliberate.

  • A user enrolls once into a global vault keyed by phone number.
  • Each site receives sub = "pw_" + base64url(HMAC-SHA256(site.pairwiseSalt, endUser.id)) — derived from a per-site random salt.
  • Two sites — even two sites in the same organization — cannot correlate their users, and Okia provides no API to resolve a sub across sites. Lookup is scoped to /v1/sites/{siteId}/users/{sub} only.

Consequences for you:

Do Don't
Store sub as the stable user key for your site Expect the same sub on your other sites
Request the phone scope if you genuinely need the number (a live, verified site only, and the sheet still offers the user "Continue without sharing" — expect some sign-ins to arrive without it) Try to join users across sites by phone or sub

Note: end users have no email in Okia. There is no email scope or claim.

Sessions: yours vs Okia's

Two independent sessions exist after login:

Session Where Lifetime Controlled by
Your site's session Your cookie/backend, minted after the token exchange Whatever you choose You
Okia SSO session __Host-pw_sess cookie on auth.okia.io 30 days, rolling Okia

The SSO session is what makes login on a second connected site instant. Logging out of your site does not end the SSO session; GET /logout on the auth domain does. After a global logout, sites validating JWTs locally may accept an already-issued access token for up to 15 minutes (the access-token lifetime) — that lapse is by design and documented, not a bug.

"Remember this device" on the hosted sheet is the 30-day SSO session — disclosed to the user, not a checkbox.

The amr claim and step-up

Every ID token carries amr (authentication methods reference):

amr Meaning
["webauthn"] Passkey login — phishing-resistant, user-verified
["otp"] WhatsApp-code login — possession of the phone only

If an action on your site is sensitive (payments, changing account details), check amr. When it's ["otp"], send the user back through /authorize with max_age=0 and check amr on the new ID token before proceeding. max_age is the OIDC parameter, in seconds: a sign-in older than that gets no one-tap "Continue", only a fresh ceremony — the passkey first, for anyone who has one. There is no parameter that forbids the WhatsApp code, which is always one tap away, so the answer can come back ["otp"] again; decide what that person may do. auth_time tells you how fresh the authentication is if you need recency, not just method.

Account safety rules worth knowing

  • Passkeys are never wiped by an OTP login, and for 24h after an OTP fallback login no passkey can be deleted at all.
  • If a phone number is recycled to a new owner (account inactive ≥ 180 days), the old account is quarantined — the new owner gets a fresh identity, and the old owner can recover via their passkey. Your site sees a new sub, never a silently transferred one.
Concepts · Okia docs