Accountless identity · Open core · Standard OIDC
Identity without the account.
Your phone holds your identity. Your biometric unlocks it. Your app receives a standard OpenID Connect token. No password, no email, and no identity-provider account to create, reset, or breach.
iPhone app on the App Store · Android coming soon See a full integration at jtmerlin.com , our demo bank.
npm install @identizen/react
A browser on acme.com/login shows a Continue with Identizen button, a QR code and the match code 47. The challenge travels to the index, the index pushes it to the phone, and the phone shows Acme, the same match code, and Approve with Face ID. The signed assertion returns to the browser.
Sign-in request
acme.com
Match code
47
Same as on your screen?
- challenge lifetime
- 60 s
- match code
- 2-digit
- secrets stored
- 0
- to integrate
- 5 lines
Accountless identity
Passwordless still has an account.
Replacing the password does not remove the identity-provider account behind it. Identizen does. There is no master account holding your identity. Your phone holds a cryptographic identity and derives a different one for every application you use. Your biometric lets the phone prove it, once, for one request.
Accountless does not mean an application cannot keep user data. It means the identity does not depend on a credential account at a provider. Your app still stores whatever it needs under the per-site identifier it receives; nothing at Identizen can sign in as the user.
What accountless means, in fullTraditional identity
-
You
-
Identity-provider account
a record someone else owns
-
Password, passkey, or MFA
credentials that protect that record
-
Identity provider
holds the credential database
-
Application
Identizen
-
You
-
Your phone
holds the cryptographic identity
-
Your biometric
unlocks it for one request
-
Index
routes and verifies; stores no secrets
-
Application
receives standard OIDC
The phone is not another factor in front of an account. It holds the identity. The index is in the picture because it exists: it routes requests and verifies signatures, and it never holds anything that could sign in as you.
One identity, three questions
Authenticate. Verify. Authorize.
The same phone-held key answers all three. Start with login, add the other two when an action deserves them.
-
Authenticate
“I am this identity.”
Sign people into your app without a password or a provider account. Your app receives a standard OIDC id_token with a per-site identifier.
Learn more -
Verify
“It is really me, right now.”
Ask the phone for a fresh biometric approval when a session needs more assurance: a new country, a sensitive page, an admin console.
Learn more -
Authorize
“I approve this specific action.”
Send the exact action to the phone. The person reads it, approves it, and the signature is bound to that text, so it cannot be reused for anything else.
Learn more
How it works
Three hops, one tap.
Challenge in, signed assertion out. Every step is specified, signed, and verifiable by anyone running the open-source index.
-
01
Your site asks for a login
The SDK requests a challenge from the index: a signed, single-use request that expires in 60 seconds and carries a two-digit match code.
-
02
The phone gets it
A paired browser pushes straight to the phone. Otherwise the user scans a QR, or on Chromium clicks to find the phone over Bluetooth. The match code stops relay tricks.
-
03
Face ID signs, you get OIDC
The phone derives a key for your site and signs the assertion. The index verifies it and hands your app a standard id_token. No email, no password.
Developer experience
Built for the afternoon you have.
A typed SDK, a React component with accessible states, and a CLI that registers your site and scaffolds the callback route. If a quickstart step needs explaining, we treat it as a bug.
- Works with any OIDC library; the SDK is optional.
- Fake phone for local development and CI, no device needed.
- Framework guides for Next.js, Express, ASP.NET Core, Django, React, and plain HTML.
import { IdentizenProvider, IdentizenButton } from '@identizen/react';
export function Login() {
// login = { redirectUri, state, nonce, codeChallenge } from prepareLogin()
return (
<IdentizenProvider indexUrl="https://index.identizen.com" clientId={clientId}>
<IdentizenButton login={login} />
</IdentizenProvider>
);
} npx identizen init # registers the site, writes .env.local, scaffolds /api/auth/*
npx identizen dev # runs a fake phone that approves logins while you build Why it holds up
The index is a phonebook, not a vault.
Everything we host must be safe to leak. That single constraint shapes the protocol.
-
The phone is the identity
A seed on the device derives one key per site. Two sites cannot match a user by identifier, and there is no account with us to take over. Lose the phone: restore from 24 words and revoke the old one.
-
Nothing to leak
The index stores public keys, push tokens, audit events and, for paired browsers, a public key plus the browser’s user-agent and last IP. Never a private key, seed, password, or plaintext token.
-
Standard on the outside
Your app sees OpenID Connect with PKCE, back-channel logout, and a JWKS. Any OIDC library works; ours is just shorter.
-
Pair once, then no QR
After the first approval the browser holds a pairing key. Later logins push to the phone directly. Revoke from the app at any time.
-
Proximity when you want it
The phone advertises a rotating Bluetooth id. Chromium browsers can find it without a camera; the id changes every 15 minutes.
-
Self-host in one command
The same Worker runs index.identizen.com. Deploy it to Cloudflare or run the container; indexes federate over WebFinger.
import { createIdentizenServer } from '@identizen/sdk/server';
const idz = createIdentizenServer({ indexUrl, clientId, clientSecret });
// Any backend, any time after enrollment: the phone shows the reason and signs it.
const v = await idz.verify({ sub, reason: 'Approve wire of $12,000 to Acme?' });
const done = await idz.waitForVerification(v.verification_id);
if (done.status === 'approved') release(wire); // assertion binds the reason hash Authorize
Don't just authenticate the user. Prove they approved the action.
Keep your existing login if you like. Bind a person's phone once, then send it the exact action: a wire transfer, a production deploy, an admin grant. The text is shown on the phone and bound into the signature, so an approval cannot be replayed for something else.
Where it runs
One protocol, every surface.
| Surface | Integration | Ships with |
|---|---|---|
| Web (any framework) | OIDC + @identizen/sdk | @identizen/react |
| Next.js, Express | Guides + CLI scaffolds | npx identizen init |
| iPhone | Identizen app · on the App Store | Face ID |
| Android | Identizen app · Google Play soon | Fingerprint |
| Your own index | Cloudflare Worker or Docker | WebFinger federation |
Add accountless identity this afternoon.
Register a site, drop in the button, and approve your first login with the phone in your pocket. Free for personal identities, forever.