Single Sign-On

Add Single Sign-On (SSO) for all Identity Providers to your app with a single integration.

Introduction

Single Sign-On (SSO) is the most frequently asked for requirement by enterprise organizations looking to adopt new SaaS applications. SSO enables authentication via an organization’s Identity Provider (IdP), such as Google Workspace or Okta, as opposed to users or IT admins managing hundreds, if not thousands, of usernames and passwords. Facilitate greater security, easier account management, and accelerated application onboarding and adoption by adding SSO to your app.

The WorkOS SSO API is modeled to meet the OAuth 2.0 framework specification, abstracting away the underlying authentication handshakes between different IdPs. Check out the sequence of events below.

The WorkOS SSO API acts as authentication middleware and intentionally does not handle user database management for your application. This is by design, to minimize vendor lock-in for Developers.

Our SSO API is compatible with any Identity Provider and supports both the SAML and OpenID Connect protocols.

Request an Identity Provider

Don't see an Identity Provider you need? Contact us to request an Identity Provider!

Creating an IP Allowlist

WorkOS makes use of Cloudflare to ensure security and reliability of all operations. If you are looking to create a list of allowed IP addresses for incoming requests, you can use the IP Ranges listed in the Cloudflare documentation.

What you’ll build

In this guide, we’ll take you from learning about Single Sign-On and POC-ing all the way through to authenticating your first user via the WorkOS SSO API.

Sign in to your WorkOS account to see code examples pre-filled with your API keys and resource IDs.

This guide will show you how to:

1

Add SSO to your app.

2

Configure a redirect URI.

3

Configure an SSO Connection.

Before getting started

To get the most out of this guide, you’ll need:

  • A WorkOS account.
  • An IdP account from an Identity Provider that WorkOS supports. Reach out if you need help setting up an IdP instance for development.

API Object Definitions

Object

Definition

Connection

A Connection represents the method by which a group of users (typically in a single organization) sign in to your application.

Profile

A Profile is an object that represents an authenticated user. The Profile object contains information relevant to a user in the form of normalized and raw attributes.

1

Add SSO to your app

Let’s start by building the SSO authentication workflow into your app.

Install the WorkOS SDK of your choice

WorkOS offers native SDKs in several popular programming languages. Choose a language below to see instructions in your application’s language.

  • Node.js

    Node.js

  • Ruby

    Ruby

  • Go

    Go

  • Python

    Python

  • PHP

    PHP

  • Laravel

    Laravel

  • .NET

    .NET

  • Java

    Java

Request an SDK

Don't see an SDK you need? Contact us to request an SDK!


Single Sign-On Example Application

Node.js Example Application

Install the SDK using the command below.

Install the WorkOS SDK

npm install @workos-inc/node
You can also download the workos-node source code from GitHub.

Set environment variables

As a best practice, your WorkOS API key should be kept secret and set as an environment variable on process start. The SDK is able to read the key automatically if you store it in an environment variable named WORKOS_API_KEY; otherwise, you will need to set it manually. The Client ID should also be set dynamically based on the release environment.

Environment Variables

WORKOS_API_KEY='
sk_example_123456789
'
WORKOS_CLIENT_ID='
client_123456789
'

Add an endpoint to initiate SSO

The endpoint to initiate SSO via the WorkOS API is responsible for simply handing off the rest of the authentication workflow to WorkOS. There are a couple configuration options shown below.

You can use the optional state parameter to encode arbitrary information to help restore application state between redirects.


Use the connection parameter when authenticating a user by their Connection's ID.

Authentication Endpoint

1const express = require('express');
2const { WorkOS } = require('@workos-inc/node');
3
4const app = express();
5
6const workos = new WorkOS(process.env.WORKOS_API_KEY);
7const clientID = process.env.WORKOS_CLIENT_ID;
8
9app.get('/auth', (_req, res) => {
10 const connection = // ... The Connection's ID
11 const redirectURI = // ... The callback URI WorkOS should redirect to post-authentication
12
13 const authorizationURL = workos.sso.getAuthorizationURL({
14 clientID: clientID,
15 redirectURI: redirectURI,
16 connection: connection,
17 });
18
19 res.redirect(authorizationURL);
20});

WorkOS will redirect to your Redirect URI if there is an issue generating an authorization URL. Read our API Reference for more details.

Add a callback endpoint

Next, let’s add the redirect endpoint which will handle the callback from WorkOS after a user has authenticated with their Identity Provider. This endpoint should exchange the authorization code (valid for 10 minutes) returned by WorkOS with the authenticated user's Profile.

The redirect URI must use HTTPS.

Callback Endpoint

1const express = require('express');
2const { WorkOS } = require('@workos-inc/node');
3
4const app = express();
5
6const workos = new WorkOS(process.env.WORKOS_API_KEY);
7const clientID = process.env.WORKOS_CLIENT_ID;
8
9app.get('/callback', async (req, res) => {
10 const { code } = req.query;
11
12 const { profile } = await workos.sso.getProfileAndToken({
13 code,
14 clientID,
15 });
16
17 // Use the information in `profile` for further business logic.
18
19 res.redirect('/');
20});
2

Configure a redirect URI

You'll need to set a redirect URI (i.e. the callback endpoint from Add a callback endpoint) via the WorkOS Dashboard - be sure not to include wildcard subdomains or query parameters.

Wildcard characters in Redirect URIs are supported in Staging environments. More information can be found in the Wildcard Redirect URIs documentation..

Multi-tenant apps will typically have a single redirect URI specified. You can set multiple redirect URIs for single tenant apps - just be sure to specify which redirect_uri to use in the WorkOS client call to fetch the authorization URL.

In the IdP-initiated authentication flow, the default redirect URI is used.

3

Configure an SSO Connection

You'll need to configure an SSO Connection for every domain, i.e. organization, that wants to authenticate via SSO. Connections can be configured in the WorkOS Dashboard. Let’s start by creating one for development in your Sandbox Project - get provider specific instructions by selecting the Identity Provider you're planning to use from the list below.

Add the WorkOS Admin Portal to your app to enable your users to create and configure SSO Connections themselves.

Identity Provider

Instructions


Connect to a Microsoft Active Directory Federation Services (AD FS) SAML server by reading through our integration guide below. It provides end-to-end instructions for creating your Connection in the WorkOS Dashboard.

Connect to AD FS SAML

Our guide to creating a new Connection with AD FS SAML.

Once your Connection is successfully created and linked, it’s ready to start being used to authenticate users!

Identity Provider-initiated SSO

The instructions in this guide focus on setting up Service Provider (SP)-initiated SSO. In these scenarios, when a user attempts to login, they navigate to an application (a service provider) and are then redirected to the Identity Provider (IdP) for authentication, via the WorkOS API. Alternatively, users are often able to start the process from the Identity Provider itself. Enterprise companies will often provide an IdP dashboard where employees can select any of the eligible applications that they can access via the IdP. In these cases, the IdP is initiating the SSO request, not the service provider.

Security considerations

IdP-initiated authentication is inherently more exposed to security vulnerabilities since the IdP delivers an SSO response to the Service Provider that the Service Provider had not initiated. There is no way for the application to definitively determine that these unsolicited responses have not been issued or compromised by an attacker, which exposes IdP-initiated SSO to potential CSRF Login and other "man-in-the-middle" attacks. As a result, WorkOS recommends using SP-initiated authentication whenever possible.

Configuring IdP-initiated SSO

The instructions in this guide will allow the Identity Provider to issue IdP-initiated SSO calls to your application's callback endpoint. IdP administrators can configure the RelayState that the IdP will send with these requests. Currently, however, WorkOS does not support processing a RelayState for IdP-initiated authentication flows, so it should be left blank. If a RelayState is received, the request will result in an error. Upon a successful request, the user will be redirected to the default redirect URI in the WorkOS configuration.

We have recently added Beta support for reading the redirect_uri from the RelayState during an IdP-initiated SSO request. This allows an IdP administrator to configure the location where user will be redirected after a successful IdP-initiated authentication request. WorkOS will retrieve the redirect URI from the IdP's RelayState, where it must be configured in the format of a URL parameter: redirect_uri=[uri]. The URI must be one of the Redirect URIs specified in your WorkOS Dashboard, otherwise, the request will result in an error. Any other values in the IdP's RelayState will be ignored and discarded.

RelayState support for IdP-initiated authentication is currently behind a feature flag, please reach out to WorkOS support if you'd like to use it or learn more about it.

Go live checklist

Make sure you're ready to go live to production by going through this checklist.

  • Implement an SSO UI/UX. See our guide for ideas - UI/UX Best Practices for IdP & SP-Initiated SSO.
  • Unlock your Production environment by adding your billing information.

    Only enterprise connections in your Production environment will be charged. Any Google OAuth, Microsoft OAuth or Magic Link connections in Production will be free.

  • Set your Production Client's ID and API Key as environment variables.
  • Secure your Production Project's API key.
  • Configure production redirect URI(s) in your Product Project. Verify the default redirect URI is correct.
  • Ensure that your application can receive redirects from WorkOS.

    Depending on your network architecture, you may need to allowlist incoming redirect traffic from api.workos.com

    WorkOS currently cannot promise that redirect traffic will originate from a static set of IP addresses.

  • Add Connections for your customers in the Production Environment.
  • Evaluate whether your application needs to restrict or configure IdP-initiated logins.

Next steps

Here are some suggestions for taking your app to the next level in Enterprise Readiness.

  • Integrate the WorkOS Admin Portal to enable your users to onboard and set up SSO themselves.
  • Integrate the WorkOS Directory Sync API for automatic user updating, provisioning, and deprovisioning.

Frequently asked questions

How should an application handle the first time a user authenticates using WorkOS?

If a user is authenticating to your application for the first time via SSO and doesn't have an account, you can implement just-in-time provisioning to create a user when authentication is complete.

You can also leverage Directory Sync to pre-provision users with API endpoints or webhooks. In this case, the user will already be created in your application when they authenticate for the first time.

Can we add SSO authentication for a current user in an application?

If a user is authenticating to your application via SSO, but already has an account (with username/password for example), you can "upgrade" them to SSO. Usually the emails are the same for both methods of authentication, so you can match on email address. Once SSO via WorkOS is enabled, you can restrict users to sign-in with only SSO.

How does WorkOS manage user attributes from an identity provider?

WorkOS normalizes user attributes so you can expect known values such as id, email,firstName, andlastName. You will still receive all of the attributes sent by your identity provider in the raw_attributes object.

Is the user attribute mapping configurable in WorkOS?

Yes. For example, let's say the http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname attribute contains the user email rather than the surname as the attribute name suggests. In these edge cases, WorkOS will identify any attributes that are misconfigured and recommend correct mapping in the Attribute Mapper section of the Connection info page.

What does the "Allow Profiles Outside Organization" option do?

By default, WorkOS restricts user profiles for SAML Connections to profiles that have email domains that are in the set of User Email Domains on the Organization.

Enabling this option removes this restriction and allows user profiles with any email address to sign in through Connections under this Organization.

If this option is enabled, your code can not exclusively trust the returned email attribute on user profiles to be a verified email address. Instead, you must use the organization_id or connection_id in order to verify that the profile belongs to whom it claims.

What does "There are 0 profiles awaiting reconciliation" refer to?

This refers to the number of user profiles that have inconsistent attribute mappings, and that need to be updated in order to successfully authenticate.

For IdP-initiated SSO, what should the RelayState be?

We currently don't support the RelayState parameter for IdP-initiated SSO, so this should be left blank.

We have recently added Beta support for reading the redirect_uri from the RelayState during an IdP-initiated SSO request. If a redirect_uri is found and matches one of the allowed Redirect URI's in the WorkOS Dashboard, the user will be redirected to that location upon a successful login. All other values in the IdP-initiated RelayState will be discarded and ignored. The functionality is currently behind a feature flag; if you'd like to learn more about it or enable it for your account, please reach out to WorkOS support.

What if I encounter a CORS error when testing the authentication flow?

If you see a CORS error thrown when testing out the authentication flow, you should ensure that you are implementing frontend requests as form POST or GET requests to the backend. If you are using a Fetch request, the backend won't be able to properly redirect the browser, and a CORS error may occur.