Onboarding a New Application to ZewstID
This guide covers the complete process of adding a new application to the ZewstID authentication system.
Google Model (February 2026): All applications now integrate via OAuth redirect to
. Users authenticate on ZewstID's login page and are redirected back to your application. This is the same pattern used by Google, Microsoft, and Okta.auth.zewstid.com
Overview
Integration Approach: Standard OAuth 2.0 / OpenID Connect redirect flow.
Authentication Methods: Users can choose from 12 methods on the ZewstID login page:
- Email/Password
- Magic Links
- OTP (email/SMS)
- WebAuthn/Passkeys
- Social Login (Google, GitHub, Microsoft, Apple, Facebook)
- MFA (TOTP, Push)
Who does what:
- ZewstID Admin (us): Configure OAuth client, assign roles
- App Team (them): Install SDK or OAuth library, integrate authentication
Timeline: ~30 minutes for setup + integration time for app team
Quick Start
For Next.js Apps (Recommended)
npm install @zewstid/nextjs next-auth
// app/api/auth/[...nextauth]/route.ts import { createZewstIDAuth } from '@zewstid/nextjs'; import NextAuth from 'next-auth'; export const authOptions = createZewstIDAuth({ clientId: process.env.ZEWSTID_CLIENT_ID!, clientSecret: process.env.ZEWSTID_CLIENT_SECRET!, }); const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
For Other Frameworks
Use any OAuth/OIDC library with these settings:
Discovery URL: https://auth.zewstid.com/.well-known/openid-configuration Issuer URL: Available in Developer Portal → App Settings
See OAuth Integration Guide for complete examples with React, Express, Flask, and more.
Part 1: Admin Setup (ZewstID Team)
Step 1: Create OAuth Client
Go to Admin Dashboard → OAuth Clients → Create Client
Fill in:
| Field | Description | Example |
|---|---|---|
| Client ID | Unique identifier | my-app |
| Client Name | Display name | My Application |
| Client Type | Web, SPA, Mobile, or M2M | Web |
| Redirect URIs | Where to redirect after auth | https://myapp.com/api/auth/callback/zewstid |
| Post-Logout URIs | Where to redirect after logout | https://myapp.com |
Step 2: Configure Client Settings
Set these options:
- Standard Flow Enabled: Yes (authorization code flow)
- Direct Access Grants Enabled: No (ROPC not needed)
- Service Accounts Enabled: Only if using M2M
- PKCE: Required for SPAs/Mobile
Step 3: Assign Roles (Optional)
If your app uses role-based access:
- Go to Roles → Create Role
- Name your roles (e.g., ,
admin,editor)viewer - Assign roles to users via Users → Role Mappings
Part 2: App Integration
Step 1: Environment Variables
# Required ZEWSTID_CLIENT_ID=your_client_id ZEWSTID_CLIENT_SECRET=your_client_secret # NextAuth NEXTAUTH_SECRET=random_secret_min_32_chars NEXTAUTH_URL=https://your-app.com
Step 2: Create Auth Configuration
Next.js with @zewstid/nextjs:
// app/api/auth/[...nextauth]/route.ts import { createZewstIDAuth } from '@zewstid/nextjs'; import NextAuth from 'next-auth'; export const authOptions = createZewstIDAuth({ clientId: process.env.ZEWSTID_CLIENT_ID!, clientSecret: process.env.ZEWSTID_CLIENT_SECRET!, }); const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
Next.js with plain NextAuth:
// app/api/auth/[...nextauth]/route.ts import NextAuth from 'next-auth'; export const authOptions = { providers: [ { id: 'zewstid', name: 'ZewstID', type: 'oidc', clientId: process.env.ZEWSTID_CLIENT_ID!, clientSecret: process.env.ZEWSTID_CLIENT_SECRET!, issuer: process.env.ZEWSTID_ISSUER_URL!, }, ], }; const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
Step 3: Add Provider Wrapper
// app/layout.tsx import { ZewstIDProvider } from '@zewstid/nextjs'; // Or: import { SessionProvider } from 'next-auth/react'; export default function RootLayout({ children }) { return ( <html> <body> <ZewstIDProvider> {children} </ZewstIDProvider> </body> </html> ); }
Step 4: Add Sign In Button
'use client'; import { signIn, signOut, useSession } from 'next-auth/react'; export function AuthButtons() { const { data: session } = useSession(); if (!session) { return ( <button onClick={() => signIn('zewstid')}> Sign in with ZewstID </button> ); } return ( <div> <p>Welcome {session.user?.name}!</p> <button onClick={() => signOut()}>Sign Out</button> </div> ); }
Part 3: Testing
Test the Flow
- Click "Sign in with ZewstID"
- You should be redirected to
auth.zewstid.com - Sign in with any supported method
- You should be redirected back to your app with a session
Verify Token Contents
Check that your token contains the expected claims:
import { getServerSession } from 'next-auth'; const session = await getServerSession(authOptions); console.log('User:', session?.user); console.log('Roles:', session?.roles);
Part 4: Role-Based Access (Optional)
If you assigned roles in Part 1:
import { useRBAC, RBACProvider } from '@zewstid/nextjs'; const rolePermissions = { admin: [{ resource: '*', action: '*' }], editor: [{ resource: 'posts', action: '*' }], viewer: [{ resource: 'posts', action: 'read' }], }; // Wrap your app <RBACProvider clientId="my-app" rolePermissions={rolePermissions}> {children} </RBACProvider> // Check permissions function AdminPanel() { const { hasRole } = useRBAC(); if (!hasRole('admin')) { return <p>Access denied</p>; } return <div>Admin Panel</div>; }
Troubleshooting
"Invalid redirect_uri" Error
Your redirect URI must exactly match what's configured in the OAuth client:
- Check for trailing slashes
- Check http vs https
- Check port numbers
Session Not Persisting
Make sure
NEXTAUTH_SECRETRoles Not in Token
- Check role assignments in Admin Dashboard
- Verify the StandardRolesMapper is enabled on the client
Next Steps
- OAuth Integration Guide - More framework examples
- RBAC Guide - Role-based access control
- Account Linking - Multiple auth methods per user
Was this page helpful?
Let us know how we can improve our documentation