WordPress

Pure redirect flow, zero JavaScript — immune to caching plugins. Works with stock WordPress and WooCommerce.

Install

  1. Download the plugin zip from your dashboard (any site → Connectors → WordPress), or install it from the command line:

    wp plugin install https://app.okia.io/downloads/okia-login.zip --activate
    
  2. Otherwise: WP admin → Plugins → Add New → Upload Plugin → activate.

Updates arrive on the WordPress Plugins screen like any other plugin: 1.2.0+ checks your Okia domain for a newer build on WordPress's own schedule, so you can click Update — or switch on auto-updates — and never touch a zip again. (One-time: a site still on 1.0.0 or 1.1.0 has no checker yet, so upload the current zip by hand once.)

Connect (~1 min)

  1. WP admin → Settings → Okia Login → Connect to Okia.
  2. You land in your Okia dashboard, signed in if you were not. Approve: create a new site (named after your blog) or link to an existing one.
  3. You are sent back to WordPress with the client ID and secret saved and the callback URL registered. Nothing to copy.
  4. Link your own account before you sign in with it: Users → Profile → Sign in with Face ID. Okia matches WordPress users on that link and nothing else, so without it your first Okia sign-in creates a new user rather than logging you into your administrator account — see Linking an existing account.
  5. Open /wp-login.php. Okia now leads the screen: a full-width Sign in with Face ID button, with the password form behind Use a password instead (?classic=1 always brings it back). Complete the WhatsApp code + passkey flow and you land in wp-admin as your own user.
  6. The site goes live on its own within minutes of that first sign-in (no more 25-user cap or sheet banner): the plugin serves /.well-known/okia-verify.txt with your client ID and the dashboard keeps checking for it. WordPress in a subfolder, or a host that blocks dot-paths? Use the DNS record instead: Going live.

Linking to an existing site rotates its client secret so the plugin can receive a fresh one; anything else using the old secret keeps working for 24 hours.

How it holds together: the plugin mints a random verifier, parks it in a transient bound to your user, and sends sha256(verifier) as the state — the same PKCE shape as the login itself; the dashboard binds a single-use, 10-minute code to that state, the site and the exact callback URL; the plugin exchanges the code plus the verifier server-to-server against the Okia domain it already trusts for tokens. The return URL the browser carries contains nothing that can redeem the code, and the secret never passes through the browser.

Linking an existing account

Okia matches a WordPress user on the okia_sub user meta and nothing else — never on email or phone, which would be a takeover route through any other plugin's meta. So on a site that already has users:

  1. Sign in to WordPress with your password as usual.
  2. Users → Profile → Sign in with Face ID → complete the ceremony. Nothing else changes: no new user, no password reset, and you can unlink from the same place.
  3. From then on the Okia button logs you into that account.

Skip it and the first Okia sign-in creates a fresh user instead — login pw_ + 8 hex characters, a placeholder email, and the Default role from the settings page (not your administrator account). Turn Allow account creation off if you would rather unknown users be refused.

Migrating a whole user base, or scripting it: the meta is a plain string, so WP-CLI can set it from an export of your Okia subs.

wp user meta update <user-id-or-login> okia_sub <sub>

Each sub is that user's pairwise id for this site (pw_…, from the ID token or the dashboard's Users page); a sub from another site never matches.

The login screen

With plugin 1.4.0 wp-login.php leads with Okia and moves the password form behind Use a password instead.

Want Do
The password form back, once /wp-login.php?classic=1 — always works, and is what the "Use a password instead" link points at
Okia beside the password form instead of ahead of it Settings → Okia Login → Sign-in mode → Button on the form
Nothing but Okia (no password form at all) Sign-in mode → Okia only. ?classic=1 still lets an administrator back in, so a broken passkey is never a lockout

Interim logins, reauth=1, password resets and any POST always get the classic form, regardless of mode.

By hand

If you would rather not use Connect:

  1. Settings → Okia Login → copy the callback URL shown there (https://yoursite.com/wp-json/okia/v1/callback).
  2. Dashboard → your site → Settings → add it as a redirect URI. Do this before the first login — a login attempted first fails with redirect_uri_mismatch.
  3. Dashboard → your site → copy the client ID and secret; paste them into Settings → Okia Login and save. The plugin refuses a swapped pair or a value with the wrong prefix (pw_c_ / pw_cs_) on save.
  4. Test connection on the same screen confirms the ID is known and the secret is the right one for it, and shows the site's mode.

Settings

Settings → Okia Login:

Setting Notes
Connect to Okia / Test connection The one-click path above, and a check that the saved credentials work
Client ID / client secret Filled in by Connect; or from your site's page in the dashboard
Callback URL Shown copy-paste: https://yoursite.com/wp-json/okia/v1/callback — Connect registers it; by hand, register it as a redirect URI in the dashboard
Okia domain / Okia dashboard https://auth.okia.io; the dashboard origin is derived (auth. → app.) and only needs setting for a self-hosted deployment
Sign-in mode Okia first (default), a button on the form, or Okia only — see The login screen
Login buttons wp-login form and, when WooCommerce is active, the Woo login and My Account forms
Allow account creation Toggle: create a WP user on first Okia login, or refuse unknown users
Default role Role for created users; defaults to customer when WooCommerce is active
Shortcode [okia_login] renders the button anywhere
Domain verification Nothing to configure: the plugin answers https://yoursite.com/.well-known/okia-verify.txt with your client ID, which the dashboard accepts as proof

The settings page links to your dashboard, and the plugin watches its own callback URL: if permalinks or the site address change, every wp-admin page shows the old and new URL with a Re-sync with Okia button (the Connect flow again, with your site preselected).

How a login works

The button redirects to the hosted Okia page (state + PKCE verifier held in transients, 10 min). Okia redirects back to the REST callback, which exchanges the code via wp_remote_post and verifies the ID token against the JWKS (cached 12 h). Then:

Case Result
A user has okia_sub user meta matching the token's sub Logged in as that user: wp_set_auth_cookie + do_action('wp_login'). This is what Users → Profile → Sign in with Face ID sets
No match, account creation allowed New user created: login pw_ + 8 hex chars, placeholder email, default role, okia_sub meta stored
No match, account creation off Login refused
Match by phone or email Never. Okia users have no email in MVP, and phone-matching against other plugins' meta is a takeover risk — matching is on okia_sub only

Webhooks

The plugin ships Okia_Webhook::verify_request( $secret ) — see Webhooks.

WordPress · Okia docs