Workos
Build with WorkOS for enterprise SSO and authentication. Use this skill when the
You are an auth specialist who integrates WorkOS into projects. WorkOS provides
enterprise-grade authentication features — SSO (SAML/OIDC), directory sync (SCIM),
audit logs, and AuthKit (a complete auth solution) — so you can sell to enterprise
customers without building SSO from scratch.
## Key Points
- Use AuthKit for complete auth — adds SSO when enterprise customers need it
- Use the admin portal for self-service SSO setup — no manual SAML configuration
- Implement token refresh — access tokens expire, refresh tokens extend sessions
- Use directory sync webhooks to auto-provision/deprovision users
- Store organization ID alongside user data for multi-tenant queries
- Use `organizationId` in auth URLs to route to the correct SSO provider
- Building SAML integration from scratch — WorkOS handles the complexity
- Not implementing token refresh — users get logged out unexpectedly
- Storing access tokens in localStorage — use httpOnly cookies
- Ignoring directory sync events — users won't be deprovisioned when they leave
- Hardcoding connection IDs — use organization-level SSO routing
- Not using the admin portal — manual SSO configuration doesn't scale
## Quick Example
```bash
npm install @workos-inc/node
```
```typescript
import { WorkOS } from '@workos-inc/node';
const workos = new WorkOS(process.env.WORKOS_API_KEY!);
```skilldb get auth-services-skills/WorkosFull skill: 230 linesWorkOS Authentication Integration
You are an auth specialist who integrates WorkOS into projects. WorkOS provides enterprise-grade authentication features — SSO (SAML/OIDC), directory sync (SCIM), audit logs, and AuthKit (a complete auth solution) — so you can sell to enterprise customers without building SSO from scratch.
Core Philosophy
Enterprise SSO without the pain
Adding SAML SSO to your app normally takes weeks of work per customer. WorkOS abstracts the SAML/OIDC complexity — you integrate once, and every enterprise customer can connect their identity provider (Okta, Azure AD, Google Workspace) through a self-service admin portal.
AuthKit = complete auth
AuthKit is WorkOS's full authentication solution — email/password, magic links, OAuth, MFA, and SSO in one. It's free up to 1M MAU for the base auth, with SSO as an add-on for enterprise deals.
Directory sync = automatic provisioning
WorkOS syncs your user directory with your customer's identity provider via SCIM. When they add or remove an employee in Okta, your app automatically provisions or deprovisions the user.
Setup
Install
npm install @workos-inc/node
Initialize
import { WorkOS } from '@workos-inc/node';
const workos = new WorkOS(process.env.WORKOS_API_KEY!);
Environment variables
WORKOS_API_KEY=sk_test_...
WORKOS_CLIENT_ID=client_...
WORKOS_REDIRECT_URI=http://localhost:3000/api/auth/callback
Key Techniques
AuthKit (complete auth flow)
// app/api/auth/login/route.ts
import { WorkOS } from '@workos-inc/node';
const workos = new WorkOS(process.env.WORKOS_API_KEY!);
export async function GET() {
const authorizationUrl = workos.userManagement.getAuthorizationUrl({
provider: 'authkit',
redirectUri: process.env.WORKOS_REDIRECT_URI!,
clientId: process.env.WORKOS_CLIENT_ID!,
});
return Response.redirect(authorizationUrl);
}
// app/api/auth/callback/route.ts
export async function GET(req: Request) {
const url = new URL(req.url);
const code = url.searchParams.get('code')!;
const { user, accessToken, refreshToken } = await workos.userManagement.authenticateWithCode({
code,
clientId: process.env.WORKOS_CLIENT_ID!,
});
// Set session cookies
const headers = new Headers();
headers.append('Set-Cookie', `access_token=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`);
headers.append('Set-Cookie', `refresh_token=${refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`);
headers.set('Location', '/dashboard');
return new Response(null, { status: 302, headers });
}
SSO (enterprise single sign-on)
// Redirect to SSO provider
export async function GET(req: Request) {
const url = new URL(req.url);
const orgId = url.searchParams.get('org');
const authorizationUrl = workos.userManagement.getAuthorizationUrl({
organizationId: orgId!, // Routes to org's configured SSO provider
redirectUri: process.env.WORKOS_REDIRECT_URI!,
clientId: process.env.WORKOS_CLIENT_ID!,
});
return Response.redirect(authorizationUrl);
}
// Or use connection ID directly
const authorizationUrl = workos.userManagement.getAuthorizationUrl({
connectionId: 'conn_...',
redirectUri: process.env.WORKOS_REDIRECT_URI!,
clientId: process.env.WORKOS_CLIENT_ID!,
});
Session management
import { cookies } from 'next/headers';
export async function validateSession() {
const accessToken = (await cookies()).get('access_token')?.value;
if (!accessToken) return null;
try {
const { user } = await workos.userManagement.getUser(accessToken);
return user;
} catch {
// Try refresh
const refreshToken = (await cookies()).get('refresh_token')?.value;
if (!refreshToken) return null;
try {
const { accessToken: newToken, refreshToken: newRefresh } =
await workos.userManagement.authenticateWithRefreshToken({
refreshToken,
clientId: process.env.WORKOS_CLIENT_ID!,
});
// Update cookies with new tokens
(await cookies()).set('access_token', newToken, { httpOnly: true, secure: true });
(await cookies()).set('refresh_token', newRefresh, { httpOnly: true, secure: true });
const { user } = await workos.userManagement.getUser(newToken);
return user;
} catch {
return null;
}
}
}
Organizations
// Create organization
const org = await workos.organizations.createOrganization({
name: 'Acme Corp',
domains: ['acme.com'],
});
// List user's organizations
const { data: memberships } = await workos.userManagement.listOrganizationMemberships({
userId: user.id,
});
Directory sync (SCIM)
// List directory users
const { data: directoryUsers } = await workos.directorySync.listUsers({
directory: directoryId,
});
// Webhook for directory events
export async function POST(req: Request) {
const payload = await req.json();
switch (payload.event) {
case 'dsync.user.created':
await db.insert(users).values({
email: payload.data.emails[0].value,
name: `${payload.data.first_name} ${payload.data.last_name}`,
orgId: payload.data.directory_id,
});
break;
case 'dsync.user.deleted':
await db.delete(users).where(eq(users.email, payload.data.emails[0].value));
break;
case 'dsync.group.created':
// Handle team/group provisioning
break;
}
return new Response('OK');
}
Admin portal (self-service SSO setup)
// Generate admin portal link for customer to configure SSO
const { link } = await workos.portal.generateLink({
organization: orgId,
intent: 'sso', // or 'dsync', 'audit_logs', 'log_streams'
returnUrl: 'https://yourapp.com/settings',
});
// Redirect customer to the portal
return Response.redirect(link);
Best Practices
- Use AuthKit for complete auth — adds SSO when enterprise customers need it
- Use the admin portal for self-service SSO setup — no manual SAML configuration
- Implement token refresh — access tokens expire, refresh tokens extend sessions
- Use directory sync webhooks to auto-provision/deprovision users
- Store organization ID alongside user data for multi-tenant queries
- Use
organizationIdin auth URLs to route to the correct SSO provider
Anti-Patterns
- Building SAML integration from scratch — WorkOS handles the complexity
- Not implementing token refresh — users get logged out unexpectedly
- Storing access tokens in localStorage — use httpOnly cookies
- Ignoring directory sync events — users won't be deprovisioned when they leave
- Hardcoding connection IDs — use organization-level SSO routing
- Not using the admin portal — manual SSO configuration doesn't scale
Install this skill directly: skilldb add auth-services-skills
Related Skills
Auth0
Build with Auth0 for enterprise authentication and identity. Use this skill when
Clerk
Build with Clerk for authentication and user management. Use this skill when the
Cognito
Build with Amazon Cognito for authentication and user management. Use this skill
Descope
Integrate Descope to add secure, no-code/low-code authentication and user management to your applications.
Firebase Auth
Build with Firebase Authentication for user sign-in. Use this skill when the
Hanko
Integrate Hanko for modern, passwordless authentication in your web applications.