AuthLocker
OAuth 2.1 · OpenID Connect · OTP

Zero-config user verification.

Prove who someone is — by social login, by email, or by phone — without registering an OAuth application, without a mail provider and without a messaging account. Register a client in one request and every method is available immediately.

Three ways to verify

One integration, whichever proof you need.

Most products end up needing more than one. AuthLocker gives you all three behind a single set of credentials, so adding the second one later costs nothing.

1

Social login

A standards-compliant OAuth 2.1 and OpenID Connect authorization server that federates to multiple upstream providers. Send people to /oauth/{provider}/authorize and exchange the code for a signed identity token.

2

Email verification

One-time codes or magic links, sent from our infrastructure. Choose from five message templates. Magic links land on your URL, so you keep control of every screen.

3

Phone verification

SMS one-time codes and links, with fraud protection, country allowlists and daily spend caps enforced before anything is sent. No messaging account of your own required.

Quickstart

From nothing to a verified user.

Registration is unauthenticated and returns credentials immediately. Ask for ?format=env and it returns them as dotenv lines, so the first command is the only place a secret ever appears.

1 — register, straight into .env
curl -X POST 'https://authlocker.dev/oauth/register?format=env' \
  -H 'Content-Type: application/json' \
  -d '{ "client_name": "Acme" }' >> .env

# appends:
#   AUTHLOCKER_ISSUER=https://authlocker.dev
#   AUTHLOCKER_CLIENT_ID=al_…
#   AUTHLOCKER_CLIENT_SECRET=als_…
2 — verify an email address
source .env

curl -X POST "$AUTHLOCKER_ISSUER/api/v1/verify/start" \
  -u "$AUTHLOCKER_CLIENT_ID:$AUTHLOCKER_CLIENT_SECRET" \
  -H 'Content-Type: application/json' \
  -d '{ "channel": "email", "method": "otp",
        "to": "ada@example.com", "template": "signin" }'
3 — check the code they typed in
curl -X POST "$AUTHLOCKER_ISSUER/api/v1/verify/check" \
  -u "$AUTHLOCKER_CLIENT_ID:$AUTHLOCKER_CLIENT_SECRET" \
  -H 'Content-Type: application/json' \
  -d '{ "verificationId": "alv_…", "code": "482913" }'

# → { "status": "verified", "to": "ada@example.com" }
# swap "channel": "sms" for phone — same two calls
4 — or send them through social login
"$AUTHLOCKER_ISSUER/oauth/{provider}/authorize
  ?client_id=$AUTHLOCKER_CLIENT_ID
  &redirect_uri=https://acme.com/callback
  &response_type=code&scope=openid%20profile%20email
  &code_challenge=<S256>&code_challenge_method=S256"

# exchange the code at POST /oauth/token for an
# id_token: sub, email, email_verified, name, picture, idp

What you get

Standards on the outside, no accounts on the inside.

Nothing to register anywhere

We hold the upstream OAuth applications, the mail sender and the messaging account. You create no developer app, configure no consent screen, verify no sending domain and wait on no app review.

One credential for all three

The same client_id and client_secret drives social login, email verification and phone verification. There is no second API key and no separate onboarding.

Ordinary OIDC, not a bespoke API

Discovery, JWKS, PKCE, authorization codes and id_tokens. Point any conformant OpenID Connect library at the issuer and it works with no adapter.

Pairwise subject identifiers

The same person gets a different, stable sub for every client, so two applications cannot correlate their users against each other.

Verified means verified

Upstream identity tokens are checked against the provider's own keys with nonce and audience binding. An address the provider has not confirmed never reaches a token.

Spend controls that actually run

Country allowlists, per-client daily caps and a global circuit breaker are checked before a single message is sent, because SMS pumping is a financial attack, not a hypothetical.

Pricing

Free for fair use.

No plans, no card, no seat count. Rate limits and daily caps apply so that one heavy user cannot degrade the service for everyone else — that is what fair use means here, and the limits are published rather than discovered.

Free for fair use

Social login and email verification are unmetered within the published rate limits. SMS is capped per client per day, because every message costs real money.

Open source

The whole authorization server is open source. Read exactly what happens to a profile, or run your own instance if you would rather not depend on ours.

Built by ExtraOrbital

Provided by the team at ExtraOrbital.dev, who build infrastructure that provisions itself.

Security

We never hold a token that belongs to your user.

Upstream access tokens are read once and discarded

On a social login, AuthLocker exchanges the provider's authorization code, reads the profile, and throws the provider's access token away. It is never written to a database, never returned to you, and never logged. AuthLocker is an identity broker, not a delegation proxy, so no stored credential exists that could reach a user's mail, files or repositories.

That property is why client registration can be open to everyone without an approval step: the worst a hostile client can obtain is the profile of someone who actively consented to sign in to it. Verification codes are held only as hashes, and profile data lives in our database for minutes rather than months.

API

Every endpoint.

The discovery document at /.well-known/openid-configuration is the authoritative list for the OAuth surface. Most libraries need nothing but the issuer URL.

GET /.well-known/openid-configurationOIDC discovery — point any client library here
GET /.well-known/oauth-authorization-serverRFC 8414 authorization server metadata
POST /oauth/registerRFC 7591 dynamic client registration, open to anyone
GET /oauth/{provider}/authorizeStart a social login. PKCE is required of every client
POST /oauth/tokengrant_type=authorization_code, returns an ES256 id_token
GET /oauth/userinfoStandard OIDC claims for a bearer access token
GET /oauth/jwksPublic keys for verifying id_tokens
POST /api/v1/verify/startSend a one-time code or magic link, by email or SMS
POST /api/v1/verify/checkConfirm a code or a magic-link token
POST /api/v1/verify/{id}/resendResend, subject to throttling