Skip to main content

Adding Auth to Your App

Zyphr Auth-as-a-Service lets you add complete user authentication to any application without building it yourself. Your app talks to the Zyphr API, which handles registration, login, sessions, MFA, OAuth, and more for your end users.

┌─────────────┐       ┌─────────────┐       ┌─────────────┐
│ Your App │──────▶│ Zyphr API │──────▶│ End Users │
│ (Frontend/ │◀──────│ │◀──────│ │
│ Backend) │ └─────────────┘ └─────────────┘
└─────────────┘

Two Authentication Models

Zyphr supports two credential models depending on where your auth calls originate:

ModelHeadersUse Case
Server-sideX-Application-Key + X-Application-SecretBackend API calls (registration, login, token management)
Client-sideX-Application-Key only + Authorization: Bearer <token>Frontend calls with a user's access token (profile, sessions)
caution

Never expose your secret key in client-side code. Use the public key + user token model for frontend calls.

Step 1: Create an Application

Applications are containers for your end users. Each application gets its own keys, user pool, and configuration. You can create applications through the Dashboard or the API.

Via Dashboard

  1. Navigate to Applications in the sidebar
  2. Click Create Application
  3. Enter your application name and configure settings
  4. Copy the secret key — it is only shown once
  5. Store credentials in your environment variables

Via API

curl -X POST https://api.zyphr.dev/v1/applications \
-H "Authorization: Bearer YOUR_DASHBOARD_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "My SaaS App",
"session_duration_minutes": 60,
"refresh_token_duration_days": 30,
"allowed_origins": ["https://myapp.com"],
"redirect_uris": ["https://myapp.com/auth/callback"]
}'

The response includes your keys — save them immediately, the secret key is only shown once:

{
"data": {
"id": "app_abc123",
"name": "My SaaS App",
"public_key": "za_pub_xxxx",
"secret_key": "za_sec_xxxx",
"environments": [
{ "mode": "live", "public_key": "za_pub_live_xxxx", "secret_key": "za_sec_live_xxxx" },
{ "mode": "test", "public_key": "za_pub_test_xxxx", "secret_key": "za_sec_test_xxxx" }
]
},
"meta": {
"warning": "Save all secret keys securely. They will not be shown again."
}
}

See Applications for full CRUD documentation.

Step 2: Configure Your Backend

Store your application credentials as environment variables:

ZYPHR_APP_PUBLIC_KEY=za_pub_xxxx
ZYPHR_APP_SECRET_KEY=za_sec_xxxx

All server-side auth requests use these headers:

Node.js — auth helper
const ZYPHR_BASE = 'https://api.zyphr.dev/v1';

async function zyphrAuth(path, body) {
const response = await fetch(`${ZYPHR_BASE}${path}`, {
method: 'POST',
headers: {
'X-Application-Key': process.env.ZYPHR_APP_PUBLIC_KEY,
'X-Application-Secret': process.env.ZYPHR_APP_SECRET_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
return response.json();
}

Step 3: Register Users

curl -X POST https://api.zyphr.dev/v1/auth/users/register \
-H "X-Application-Key: za_pub_xxxx" \
-H "X-Application-Secret: za_sec_xxxx" \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"password": "SecureP@ss123",
"name": "Jane Doe",
"metadata": { "plan": "pro" }
}'
Node.js
const result = await zyphrAuth('/auth/users/register', {
email: 'jane@example.com',
password: 'SecureP@ss123',
name: 'Jane Doe',
metadata: { plan: 'pro' },
});

// result.data.user — the new user object
// result.data.tokens — { access_token, refresh_token, expires_in, token_type }

Registration returns tokens immediately so the user is logged in after signup.

See End User Authentication for password requirements, validation, and error handling.

Step 4: Login Users

curl -X POST https://api.zyphr.dev/v1/auth/users/login \
-H "X-Application-Key: za_pub_xxxx" \
-H "X-Application-Secret: za_sec_xxxx" \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"password": "SecureP@ss123"
}'
Node.js
const result = await zyphrAuth('/auth/users/login', {
email: 'jane@example.com',
password: 'SecureP@ss123',
});

if (result.data.mfa_required) {
// User has MFA enabled — prompt for TOTP code
// See Step 6 and the MFA docs
const { token, expires_at } = result.data.mfa_challenge;
} else {
// Standard login — store tokens
const { access_token, refresh_token } = result.data.tokens;
}

Login supports optional custom_claims to embed application-specific data in the JWT (max 4KB):

{
"email": "jane@example.com",
"password": "SecureP@ss123",
"custom_claims": { "role": "admin", "org_id": "org_123" }
}

See End User Authentication for the complete login flow including error handling.

Step 5: Token Management

Access tokens are short-lived JWTs. Use the refresh token to get new ones:

curl -X POST https://api.zyphr.dev/v1/auth/sessions/refresh \
-H "X-Application-Key: za_pub_xxxx" \
-H "X-Application-Secret: za_sec_xxxx" \
-H "Content-Type: application/json" \
-d '{ "refresh_token": "zrt_xxxx" }'
Node.js
const result = await zyphrAuth('/auth/sessions/refresh', {
refresh_token: storedRefreshToken,
});

const { access_token, refresh_token } = result.data.tokens;
// Store new tokens — old refresh token is now invalid

To log out, revoke the session:

curl -X POST https://api.zyphr.dev/v1/auth/sessions/revoke \
-H "X-Application-Key: za_pub_xxxx" \
-H "X-Application-Secret: za_sec_xxxx" \
-H "Content-Type: application/json" \
-d '{ "refresh_token": "zrt_xxxx" }'

See End User Authentication for session management, revoke-all, and active session listing.

Step 6: Add Enhancements

Once basic auth is working, you can layer on additional features:

FeatureDescriptionGuide
Magic LinksPasswordless email loginMagic Links
OAuth / Social LoginGoogle, Apple, GitHub, etc.OAuth
Multi-Factor AuthTOTP-based 2FA with backup codesMFA
Password PoliciesConfigurable requirements per appSecurity
Email VerificationVerify user email addressesSecurity
Phone AuthSMS OTP registration and loginSecurity
WebAuthn / PasskeysBiometric / hardware key authSecurity
Account LockoutsBrute-force protectionSecurity
User ImpersonationAdmin debug access (audited)Security

Next Steps