Quick Start
This guide walks through integrating Syntropy Auth into a Next.js product from scratch. The Express adapter is covered in Express SDK.
1. Register an OAuth client
In the Syntropy dashboard, navigate to Settings → Auth Clients and click Register Client. Fill in:
- User Pool — select an existing pool or create one. The pool determines which set of users this client authenticates against. Use an org-level pool to share users across multiple projects, or a project-level pool for full isolation.
- Application Name — a human-readable label (e.g. "My Product")
- Client ID — a slug-like unique identifier (e.g.
my-product). Cannot be changed after creation. - Redirect URIs — where Syntropy Auth sends users after login:
https://your-product.example.com/api/auth/callback/syntropy
http://localhost:3000/api/auth/callback/syntropy
Copy the Client ID and Client Secret shown immediately after creation — the secret is displayed once only and cannot be retrieved again.
1a. Configure allowed origins
After creating the client, click Configure to open the client settings page. Under Allowed Origins, add every origin your product's frontend runs on:
https://your-product.example.com
http://localhost:3000
Without at least one registered origin, all cross-origin requests from your product's frontend to the Syntropy Auth service will be blocked. This will prevent the SDK from fetching the OIDC discovery document and cause token exchange failures.
The discovery endpoint (.well-known/openid-configuration) is always CORS-open, but all other endpoints require an explicit origin allowlist.
Origins are exact-matched by default. Wildcard subdomain patterns are also supported:
https://*.your-product.example.com
2. Install the Next.js adapter
npm install @eclosion-tech/syntropy-auth-next
3. Add environment variables
# .env.local
SYNTROPY_AUTH_URL=https://auth.syntropy.chat
SYNTROPY_AUTH_CLIENT_ID=your-client-id
SYNTROPY_AUTH_CLIENT_SECRET=your-client-secret
SYNTROPY_AUTH_REDIRECT_URI=http://localhost:3000/api/auth/callback/syntropy
SYNTROPY_AUTH_SESSION_SECRET=a-random-32-char-string-for-aes-gcm
SYNTROPY_AUTH_SESSION_SECRET must be a random 256-bit (32 character) string. Generate one with openssl rand -base64 32.
4. Configure middleware
Create middleware.ts at the root of your Next.js app:
// middleware.ts
import { syntropyAuthMiddleware } from "@eclosion-tech/syntropy-auth-next/middleware";
export const middleware = syntropyAuthMiddleware({
baseUrl: process.env.SYNTROPY_AUTH_URL!,
clientId: process.env.SYNTROPY_AUTH_CLIENT_ID!,
clientSecret: process.env.SYNTROPY_AUTH_CLIENT_SECRET!,
redirectUri: process.env.SYNTROPY_AUTH_REDIRECT_URI!,
secret: process.env.SYNTROPY_AUTH_SESSION_SECRET!,
publicPaths: ["/", "/pricing"],
});
export const config = {
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};
The middleware:
- Redirects unauthenticated users to the Syntropy Auth login page (all paths are protected unless listed in
publicPaths) - Handles the OAuth callback route to exchange the authorization code for tokens and create a session cookie
- Handles
/auth/logoutto clear the session - Automatically refreshes expired access tokens using the stored refresh token
5. Read the session server-side
// app/dashboard/page.tsx
import { requireSession } from "@eclosion-tech/syntropy-auth-next";
export default async function DashboardPage() {
// Throws if no valid session exists
const session = await requireSession({
secret: process.env.SYNTROPY_AUTH_SESSION_SECRET!,
});
return <h1>Hello, {session.user.name}</h1>;
}
Use getSession({ secret }) if you want to handle the unauthenticated case yourself:
import { getSession } from "@eclosion-tech/syntropy-auth-next";
const session = await getSession({
secret: process.env.SYNTROPY_AUTH_SESSION_SECRET!,
});
if (!session) {
return <p>Not logged in</p>;
}
The session object shape:
interface SyntropySession {
user: {
sub: string; // Syntropy Auth user ID
email: string;
email_verified: boolean;
name?: string;
preferred_username?: string;
given_name?: string;
family_name?: string;
updated_at?: number;
org?: {
id: string; // owner UUID (org or project)
pool_id: string; // user pool isolation boundary
owner_type: "org" | "project";
name: string; // human-readable pool name
};
};
accessToken: string;
refreshToken?: string;
idToken?: string;
expiresAt: number; // Unix timestamp
}
6. Enable social login (optional)
In the Syntropy dashboard, go to Settings → Auth Clients, click Configure next to your client, and scroll to Social Login Providers. Click Add Provider, select a provider, and paste in the OAuth credentials from that provider's developer console (e.g. Google Cloud Console → OAuth 2.0 Client IDs).
Social login buttons appear automatically on the Syntropy Auth hosted login page — no additional frontend work required.
The toggle switch next to each configured provider lets you enable or disable it without deleting the credentials.
7. Enable MFA (optional)
TOTP MFA is managed entirely server-side. Your product can trigger enrollment by redirecting users to a protected enrollment endpoint (implementation depends on your product's settings flow).
During login, if a user has MFA enabled, the hosted UI automatically prompts for their authenticator code before issuing tokens.
Client settings reference
All settings are accessible from Settings → Auth Clients → Configure in the dashboard.
| Setting | Description |
|---|---|
| Application Name | Display name shown in the Syntropy dashboard. Can be changed at any time. |
| Redirect URIs | Exact URIs Syntropy Auth will redirect to after login. At least one is required. Add one per environment (production, staging, local). |
| Allowed Origins | Frontend origins allowed to make cross-origin requests to the auth service (CORS). Add the full origin without a trailing slash. Wildcard subdomain patterns (https://*.example.com) are supported. |
| Allowed Scopes | Which OIDC scopes this client can request. openid is always required. profile, email, and org can be toggled on or off. |
| Social Providers | Upstream OAuth providers (Google, GitHub, Microsoft, Discord, Apple) linked to this client. Each provider can be independently enabled or disabled without deleting credentials. |
Next: read the full Next.js SDK reference or Express SDK reference.