Agent skill
workos-integration
Patterns for WorkOS SSO integration in Battery. Use this skill when implementing authentication, organization management, directory sync, or session handling.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/workos-integration
SKILL.md
WorkOS Integration Patterns
Overview
Battery uses WorkOS for:
- SSO federation (customers connect their Okta/Azure AD)
- Organization management (multi-tenancy)
- Directory sync (user provisioning)
SDK Setup
import { WorkOS } from '@workos-inc/node'
const workos = new WorkOS(process.env.WORKOS_API_KEY!)
SSO Authentication
Authorization URL
// Generate SSO login URL
async function getAuthorizationUrl(
organizationId: string,
redirectUri: string
) {
const authorizationUrl = workos.sso.getAuthorizationUrl({
organization: organizationId,
redirectUri,
clientId: process.env.WORKOS_CLIENT_ID!,
})
return authorizationUrl
}
Handle Callback
// app/api/auth/callback/route.ts
import { NextRequest, NextResponse } from 'next/server'
export async function GET(request: NextRequest) {
const code = request.nextUrl.searchParams.get('code')
if (!code) {
return NextResponse.redirect('/login?error=missing_code')
}
try {
const { profile } = await workos.sso.getProfileAndToken({
code,
clientId: process.env.WORKOS_CLIENT_ID!,
})
// Create session, set cookies, etc.
// profile contains: id, email, firstName, lastName, organizationId
return NextResponse.redirect('/dashboard')
} catch (error) {
return NextResponse.redirect('/login?error=auth_failed')
}
}
Organization Management
Create Organization
async function createOrganization(name: string, domains: string[]) {
const org = await workos.organizations.createOrganization({
name,
allowProfilesOutsideOrganization: false,
domains,
})
return org
}
List Organizations
async function listOrganizations() {
const { data: organizations } = await workos.organizations.listOrganizations({
limit: 100,
})
return organizations
}
Get Organization
async function getOrganization(orgId: string) {
return workos.organizations.getOrganization(orgId)
}
SSO Connection Setup
List Connections
async function getOrgConnections(organizationId: string) {
const { data: connections } = await workos.sso.listConnections({
organizationId,
})
return connections
}
Admin Portal Link
Generate a link for IT admins to configure SSO:
async function getAdminPortalLink(organizationId: string) {
const { link } = await workos.portal.generateLink({
organization: organizationId,
intent: 'sso', // or 'dsync' for directory sync
returnUrl: `${process.env.APP_URL}/settings/sso`,
})
return link
}
Directory Sync
List Directory Users
async function listDirectoryUsers(directoryId: string) {
const { data: users } = await workos.directorySync.listUsers({
directory: directoryId,
})
return users
}
Webhook Events
Handle directory sync webhooks:
// app/api/webhooks/workos/route.ts
import { NextRequest, NextResponse } from 'next/server'
export async function POST(request: NextRequest) {
const payload = await request.text()
const sigHeader = request.headers.get('workos-signature')!
const webhook = workos.webhooks.constructEvent({
payload,
sigHeader,
secret: process.env.WORKOS_WEBHOOK_SECRET!,
})
switch (webhook.event) {
case 'dsync.user.created':
await handleUserCreated(webhook.data)
break
case 'dsync.user.deleted':
await handleUserDeleted(webhook.data)
break
case 'dsync.group.user_added':
await handleUserAddedToGroup(webhook.data)
break
}
return NextResponse.json({ received: true })
}
Session Management
Session Token
interface BatterySession {
userId: string
email: string
organizationId: string
role: 'admin' | 'member'
expiresAt: number
}
// Create session after SSO callback
async function createSession(profile: Profile): Promise<string> {
const session: BatterySession = {
userId: profile.id,
email: profile.email,
organizationId: profile.organizationId,
role: await getUserRole(profile.id, profile.organizationId),
expiresAt: Date.now() + 24 * 60 * 60 * 1000, // 24 hours
}
return signJWT(session)
}
Middleware
// middleware.ts
import { NextRequest, NextResponse } from 'next/server'
import { verifySession } from '@/lib/auth'
export async function middleware(request: NextRequest) {
const session = await verifySession(request)
if (!session) {
return NextResponse.redirect(new URL('/login', request.url))
}
// Add session to request headers for server components
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-battery-user-id', session.userId)
requestHeaders.set('x-battery-org-id', session.organizationId)
return NextResponse.next({
request: { headers: requestHeaders },
})
}
export const config = {
matcher: ['/dashboard/:path*', '/api/:path*'],
}
Auth Gateway Pattern
Battery wraps deployed apps with an auth proxy:
// Deployed app requests flow through Battery auth gateway
// 1. User hits {app}.{org}.battery.app
// 2. Battery checks for valid session cookie
// 3. If no session, redirect to WorkOS SSO
// 4. After SSO, set session cookie and proxy to Vercel app
interface AuthGatewayConfig {
appId: string
organizationId: string
allowedRoles?: string[]
}
Key Patterns
- Organization-first: Always scope operations to an organization
- Admin Portal: Let IT admins self-service SSO setup
- Webhook reliability: Use idempotency keys, handle retries
- Session security: Short-lived tokens, secure cookies
- Role mapping: Map IdP groups to Battery roles via directory sync
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?