The SSO class provides methods for managing SSO connections and authenticating users through enterprise identity providers.
Connection Management
listConnections
Retrieves a paginated list of SSO connections.
Filter connections by organization ID
Filter by connection type (e.g., ‘SAML’, ‘GoogleOAuth’, ‘MicrosoftOAuth’)
Number of results to return (default: 10)
Cursor for pagination (previous page)
Cursor for pagination (next page)
connections
AutoPaginatable<Connection>
Paginated list of SSO connections
const connections = await workos.sso.listConnections({
organizationId: 'org_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5',
limit: 20
});
for await (const connection of connections) {
console.log(connection.name, connection.type);
}
getConnection
Retrieves a specific SSO connection by ID.
The unique identifier of the connection
Unique identifier for the connection
Associated organization ID
Connection type (e.g., ‘SAML’, ‘GoogleOAuth’)
state
'draft' | 'active' | 'inactive' | 'validating'
Current state of the connection
Array of domain objects associated with the connection
ISO 8601 timestamp of creation
ISO 8601 timestamp of last update
const connection = await workos.sso.getConnection('conn_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5');
console.log(connection.name);
console.log(connection.state);
deleteConnection
Deletes an SSO connection.
The ID of the connection to delete
await workos.sso.deleteConnection('conn_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5');
Authentication Methods
getAuthorizationUrl
Generates an SSO authorization URL for initiating the OAuth flow.
Organization ID (alternative to connection)
OAuth provider (e.g., ‘GoogleOAuth’, ‘MicrosoftOAuth’)
URL to redirect after authorization
State parameter for CSRF protection
Domain hint to pre-fill login form
Login hint (email) to pre-fill login form
PKCE code challenge for public clients
PKCE code challenge method (e.g., ‘S256’)
The authorization URL to redirect the user to
const url = workos.sso.getAuthorizationUrl({
connection: 'conn_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5',
clientId: 'client_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5',
redirectUri: 'https://myapp.com/callback',
state: 'random_state_string'
});
// Redirect user to this URL
window.location.href = url;
getAuthorizationUrlWithPKCE
Generates an SSO authorization URL with automatic PKCE generation. This method is recommended for public clients (CLI apps, Electron, mobile) that cannot securely store a client secret.
Organization ID (alternative to connection)
URL to redirect after authorization
Domain hint to pre-fill login form
Login hint (email) to pre-fill login form
result
SSOPKCEAuthorizationURLResult
Generated state parameter (store for validation)
PKCE code verifier (store securely for token exchange)
const { url, state, codeVerifier } = await workos.sso.getAuthorizationUrlWithPKCE({
connection: 'conn_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5',
clientId: 'client_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5',
redirectUri: 'myapp://callback'
});
// Store state and codeVerifier securely
localStorage.setItem('oauth_state', state);
localStorage.setItem('pkce_verifier', codeVerifier);
// Redirect user
window.location.href = url;
getProfileAndToken
Exchanges an authorization code for a user profile and access token.
Auto-detects public vs confidential client mode:
- If
codeVerifier is provided: Uses PKCE flow (public client)
- If no
codeVerifier: Uses client_secret from API key (confidential client)
- If both: Uses both for defense in depth (recommended by OAuth 2.1)
Authorization code from the OAuth callback
PKCE code verifier (for public clients or PKCE-enhanced confidential clients)
User’s unique identifier
User’s ID in the identity provider
SSO connection ID used for authentication
User’s group memberships
Raw attributes from the identity provider
Access token for API calls
OAuth tokens from the provider (if available)
// Public client with PKCE
const { profile, accessToken } = await workos.sso.getProfileAndToken({
code: 'auth_code_from_callback',
clientId: 'client_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5',
codeVerifier: codeVerifier // from getAuthorizationUrlWithPKCE
});
// Confidential client (uses API key)
const { profile, accessToken } = await workos.sso.getProfileAndToken({
code: 'auth_code_from_callback',
clientId: 'client_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5'
});
console.log(profile.email);
getProfile
Retrieves a user profile using an access token.
Access token from getProfileAndToken
User profile object with identity provider details
const profile = await workos.sso.getProfile({
accessToken: 'access_token_123'
});
console.log(profile.email);
console.log(profile.firstName, profile.lastName);
Complete SSO Flow Example
For Confidential Clients (Server-Side)
// Step 1: Generate authorization URL
const authUrl = workos.sso.getAuthorizationUrl({
organization: 'org_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5',
clientId: 'client_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5',
redirectUri: 'https://myapp.com/callback',
state: generateRandomState()
});
// Redirect user to authUrl
res.redirect(authUrl);
// Step 2: Handle callback
app.get('/callback', async (req, res) => {
const { code } = req.query;
const { profile, accessToken } = await workos.sso.getProfileAndToken({
code,
clientId: 'client_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5'
});
// Create session and authenticate user
req.session.userId = profile.id;
req.session.email = profile.email;
res.redirect('/dashboard');
});
For Public Clients (Mobile, Desktop, CLI)
// Step 1: Generate authorization URL with PKCE
const { url, state, codeVerifier } = await workos.sso.getAuthorizationUrlWithPKCE({
organization: 'org_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5',
clientId: 'client_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5',
redirectUri: 'myapp://callback'
});
// Store state and codeVerifier securely
await secureStorage.set('oauth_state', state);
await secureStorage.set('pkce_verifier', codeVerifier);
// Open browser for authentication
await openBrowser(url);
// Step 2: Handle callback (when user returns to your app)
async function handleCallback(callbackUrl) {
const params = new URL(callbackUrl).searchParams;
const code = params.get('code');
const returnedState = params.get('state');
// Verify state
const storedState = await secureStorage.get('oauth_state');
if (returnedState !== storedState) {
throw new Error('State mismatch - possible CSRF attack');
}
// Exchange code for profile
const codeVerifier = await secureStorage.get('pkce_verifier');
const { profile, accessToken } = await workos.sso.getProfileAndToken({
code,
clientId: 'client_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5',
codeVerifier
});
// Store tokens securely
await secureStorage.set('access_token', accessToken);
return profile;
}
Custom Attributes
The SSO profile methods support custom attributes from your identity provider:
interface CustomAttributes {
department: string;
employeeId: string;
manager: string;
}
const { profile } = await workos.sso.getProfileAndToken<CustomAttributes>({
code: 'auth_code_123',
clientId: 'client_01HZXK8F9P3QZJQ2Z1Z2Z3Z4Z5'
});
if (profile.customAttributes) {
console.log('Department:', profile.customAttributes.department);
console.log('Employee ID:', profile.customAttributes.employeeId);
}