WorkOS
Blyp's WorkOS integration reads the sealed session cookie on each request, verifies it using the WorkOS SDK, and attaches the resolved identity — including roles, permissions, and entitlements — to every log record for that request.
Install required peer package
bun add @workos-inc/nodeSetup
Create a WorkOS client and pass it to the framework logger's auth.workos config:
import { WorkOS } from "@workos-inc/node";
import { createLogger } from "@blyp/core/nextjs"; // or your framework
const workos = new WorkOS(process.env.WORKOS_API_KEY);
export const { logger, GET, POST } = createLogger({
auth: {
workos: {
workos,
cookiePassword: process.env.WORKOS_COOKIE_PASSWORD,
},
},
});Config fields
auth: {
workos: {
// Required: WorkOS client instance from @workos-inc/node
workos: workosClient,
// Required: password used to unseal the session cookie
cookiePassword: process.env.WORKOS_COOKIE_PASSWORD,
// Optional: override the cookie name (defaults to WorkOS SDK default)
cookieName: "wos-session",
// Attach non-standard user fields to auth.claims (default: false)
includeClaims: false,
// Attach the raw authenticate response to auth.raw (default: false)
includeRawSession: false,
// Add custom fields to the auth context
enrich: async ({ authResponse }) => ({
plan: authResponse?.user?.metadata?.plan ?? null,
}),
},
}workos—WorkOSinstance from@workos-inc/node; requiredcookiePassword— password for unsealing the WorkOS session cookie; requiredcookieName— override the cookie name the SDK looks forincludeClaims— attach non-standard user fields (everything outside the standardid,email,firstName,lastName, etc.) toauth.claimsincludeRawSession— attach the full rawWorkOsAuthenticateResponsetoauth.rawenrich— async function that receives the resolved args and returns extra fields to merge into the auth context
Auth context shape
WorkOS surfaces more RBAC fields than other providers — roles, permissions, entitlements, and feature flags are all normalized into the auth context when present:
// Authenticated
{
provider: "workos",
authenticated: true,
actor: { kind: "user", id: "user_abc", email: "[email protected]", name?: "Alice Smith" },
session: { id: "sess_xyz" },
organization: { id: "org_123" },
lookup: {
provider: "workos",
userId: "user_abc",
sessionId: "sess_xyz",
organizationId?: "org_123",
email?: "[email protected]",
},
role?: "admin",
roles?: ["admin"],
permissions?: ["reports:read", "billing:write"],
entitlements?: ["enterprise-plan"],
featureFlags?: ["new-dashboard"],
impersonator?: { email: "[email protected]" },
}
// Unauthenticated (missing or invalid cookie)
null // auth field is omitted from the log recordextractWorkOsSessionCookie
extractWorkOsSessionCookie reads the WorkOS session cookie from a Request object. Useful when building custom middleware or resolving auth manually outside a framework adapter:
import { extractWorkOsSessionCookie } from "@blyp/core/workos";
const cookie = extractWorkOsSessionCookie(request);
// → "sealed-session-string..." | nullReturns null if the cookie is not present.
identifyUser
identifyUser extracts a WorkOsLookupDescriptor from any object — useful for querying stored log rows by WorkOS identity:
import { identifyUser } from "@blyp/core/workos";
// Works on Blyp log records (normalized shape)
const descriptor = identifyUser(logRow);
// → { provider: "workos", userId: "user_abc", sessionId: "sess_xyz", ... } | null
// Also works on flat database column shapes
const descriptor2 = identifyUser({
authProvider: "workos",
authActorId: "user_abc",
authSessionId: "sess_xyz",
authOrganizationId: "org_123",
});Return shape
{
provider: "workos",
userId?: string,
sessionId?: string,
organizationId?: string,
email?: string,
}Returns null if the record has no WorkOS auth context.
Notes
- WorkOS is mutually exclusive with Clerk and Better Auth
- Both
workosandcookiePasswordare required — Blyp does not readWORKOS_API_KEYorWORKOS_COOKIE_PASSWORDdirectly; wire them through config - If the cookie is missing or verification fails, Blyp skips auth enrichment for that request without erroring
includeClaimsonly attaches fields not in WorkOS's standard user schema; standard fields (id,email,firstName,lastName,emailVerified,profilePictureUrl,createdAt,updatedAt) are always normalized intoauth.actordirectly