Skip to main content
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.
organizationId
string
Filter connections by organization ID
connectionType
ConnectionType
Filter by connection type (e.g., ‘SAML’, ‘GoogleOAuth’, ‘MicrosoftOAuth’)
limit
number
Number of results to return (default: 10)
before
string
Cursor for pagination (previous page)
after
string
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.
id
string
required
The unique identifier of the connection
connection
Connection
id
string
Unique identifier for the connection
name
string
Connection name
organizationId
string
Associated organization ID
type
ConnectionType
Connection type (e.g., ‘SAML’, ‘GoogleOAuth’)
state
'draft' | 'active' | 'inactive' | 'validating'
Current state of the connection
domains
ConnectionDomain[]
Array of domain objects associated with the connection
createdAt
string
ISO 8601 timestamp of creation
updatedAt
string
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.
id
string
required
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.
connection
string
SSO connection ID
organization
string
Organization ID (alternative to connection)
provider
string
OAuth provider (e.g., ‘GoogleOAuth’, ‘MicrosoftOAuth’)
clientId
string
required
Your WorkOS client ID
redirectUri
string
required
URL to redirect after authorization
state
string
State parameter for CSRF protection
domainHint
string
Domain hint to pre-fill login form
loginHint
string
Login hint (email) to pre-fill login form
codeChallenge
string
PKCE code challenge for public clients
codeChallengeMethod
string
PKCE code challenge method (e.g., ‘S256’)
url
string
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.
connection
string
SSO connection ID
organization
string
Organization ID (alternative to connection)
provider
string
OAuth provider
clientId
string
required
Your WorkOS client ID
redirectUri
string
required
URL to redirect after authorization
domainHint
string
Domain hint to pre-fill login form
loginHint
string
Login hint (email) to pre-fill login form
result
SSOPKCEAuthorizationURLResult
url
string
The authorization URL
state
string
Generated state parameter (store for validation)
codeVerifier
string
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)
code
string
required
Authorization code from the OAuth callback
clientId
string
required
Your WorkOS client ID
codeVerifier
string
PKCE code verifier (for public clients or PKCE-enhanced confidential clients)
result
ProfileAndToken
profile
Profile
id
string
User’s unique identifier
idpId
string
User’s ID in the identity provider
connectionId
string
SSO connection ID used for authentication
connectionType
ConnectionType
Type of SSO connection
organizationId
string
Organization ID
email
string
User’s email address
firstName
string
User’s first name
lastName
string
User’s last name
groups
string[]
User’s group memberships
rawAttributes
object
Raw attributes from the identity provider
accessToken
string
Access token for API calls
oauthTokens
OauthTokens
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.
accessToken
string
required
Access token from getProfileAndToken
profile
Profile
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);
}

Build docs developers (and LLMs) love