# Workos > Documentation for Workos --- # Workos Documentation Source: https://workos.com/docs/llms-full.txt --- --- # WorkOS Documentation > WorkOS provides developer-friendly APIs for enterprise features like Single Sign-On, Directory Sync, User Management, Admin Portal, Audit Logs, and more. This documentation site helps developers implement these features. This documentation site provides guides, references, and examples for implementing WorkOS features in your applications. - [Postman](#postman) - [On prem deployment](#on-prem-deployment) - [Glossary](#glossary) - [Email](#email) - [Widgets](#widgets) - [Vault](#vault) - [Single Sign-On](#sso) - [Sdks](#sdks) - [API Reference](#reference) - [RBAC](#rbac) - [Pipes](#pipes) - [Migrations](#migrate) - [Multi-Factor Auth](#mfa) - [Magic Link](#magic-link) - [Integrations](#integrations) - [FGA](#fga) - [Feature Flags](#feature-flags) - [Events](#events) - [Domain Verification](#domain-verification) - [Directory Sync](#directory-sync) - [Docs](#demo) - [Custom Domains](#custom-domains) - [AuthKit](#authkit) - [Audit Logs](#audit-logs) - [Admin Portal](#admin-portal) ## Postman {#postman} ### WorkOS Postman collection Test the WorkOS API with Postman. ## Introduction Postman is a popular API development tool that allows users to easily test API endpoints. The [WorkOS API collection](https://www.postman.com/workos/workspace/workos-public/collection/25188762-79ce1172-4741-4f1d-a486-64380f9a599f?ctx=documentation) is a set of pre-configured requests specific to the WorkOS API, meant to help developers to quickly get started testing the WorkOS API endpoints. The [environment template](https://www.postman.com/workos/workspace/workos-public/environment/25188762-b99e7518-d907-4aa0-82d2-a199157a53c7) supports this collection, and allows variables to be abstracted away from the individual requests. The environment template makes it easier to manage and re-use common variables across the collection’s requests. ## Configuring Postman There are several ways to use this collection. You can create a fork, or you can export/import the collection and environment. ### Creating a fork The preferred and simplest way to get started using the WorkOS API collection is to create a fork of the collection and environment. To create a fork of the collection, first sign in to your Postman account. Then navigate to the WorkOS API collection. Hover over the name of the collection and click the three dots, then click "Create a fork". ![A screenshot showing how to fork a collection in Postman](https://images.workoscdn.com/images/a3d67b02-a824-4f27-b055-c06eaf5a7e94.png?auto=format&fit=clip&q=50) Select your fork label and workspace, then click the "Fork collection" button. ![A screenshot showing the fork collection details page in Postman.](https://images.workoscdn.com/images/c9074bd3-8ab8-4864-9b68-56c6a858a17e.png?auto=format&fit=clip&q=50) You will now see the WorkOS API collection appear in your workspace’s collection tab. To fork the WorkOS environment template, the same process is used. Navigate to the environments tab of the WorkOS Public workspace. Hover over the WorkOS environment template, click the three dots, and then click "Create a fork". Select your fork label and workspace, then click the "Fork environment" button. ### Exporting the collection and environment Another way to use the WorkOS API collection is to import the collection and environment into your workspace. Using this approach allows you to share the collection as a JSON file to easily share it with others. To export the collection, navigate to the collection tab in the WorkOS workspace, then hover over the WorkOS API collection name and click on the three dots. Click export to download the collection as a JSON file. ![A screenshot showing the export option in Postman.](https://images.workoscdn.com/images/54aed639-6c8f-467e-baa6-53099c36fe35.png?auto=format&fit=clip&q=50) Navigate to your workspace’s collections tab and click on the import button. ![A screenshot showing where to find the import button in Postman.](https://images.workoscdn.com/images/802d9d45-c258-4548-9f88-7d04f2d260c2.png?auto=format&fit=clip&q=50) Select the JSON file that was downloaded in the previous step and then click import. You will now see the collection available to use and edit in the collection tab. The environment can be exported from the WorkOS workspace and imported to your personal workspace using these same steps. Navigate to the collection tab in your workspace and select the environment. This allows the collection to reference the environment variables. ## Environment variables The WorkOS API collection makes use of environment variables. All environment variables that are used in the WorkOS API collection are defined in the environment tab in Postman. ![A screenshot showing the environments tab in Postman.](https://images.workoscdn.com/images/bd26c85b-8d66-478c-909b-f5ee01ffaffd.png?auto=format&fit=clip&q=50) To get started, you will need to obtain the `api_key` and `client_id` values from your WorkOS dashboard and enter them in the environment template. You can find your API key and the client ID on the [API Keys](https://dashboard.workos.com/api-keys) page in the WorkOS dashboard. There are also several other environment variables in the template which will need to be replaced with various IDs and values in the course of making API calls. These values are defined in the variable descriptions. ## Sending requests to the WorkOS API The WorkOS collection sends data in several ways. Some requests use values directly in the URL, some requests use query parameters, and some requests send data in the body of the request. Each call will indicate where there are values present with a green dot. The "Get A Directory User" request for instance uses the `api_key` environment variable in the authorization tab of the request, and the `base_url` and `directory_user_id` values in the URL of the request. ![A screenshot showing the Get a Directory User request in Postman.](https://images.workoscdn.com/images/76d3df52-cf4e-467a-a898-df62a920a800.png?auto=format&fit=clip&q=50) The "Generate a Portal Link" request uses the `base_url` and `api_key` variables in the same way that the Get A Directory User call does, but also sends the name of the Organization and intent in the body of the request as x-www-form-urlencoded data. ![A screenshot showing the Generate a Portal Link request in Postman.](https://images.workoscdn.com/images/c2ae7131-dc79-49ee-aac1-724d3de42c48.png?auto=format&fit=clip&q=50) To send a request, first select the WorkOS environment template so the collection has access to its variables. ![A screenshot showing where to select the Environment in Postman.](https://images.workoscdn.com/images/fea5d174-0fea-400b-b498-3753c85c5eeb.png?auto=format&fit=clip&q=50) Finally, ensure all the values are defined where they are needed for the particular request and then click send. ## Debugging requests Postman provides a developer console if you need to debug any requests. Navigate to a request and click on the console button to view the details of the requests you send. ![A screenshot showing the developer console in Postman.](https://images.workoscdn.com/images/9dafe4a0-5a9a-46d3-bee9-ba01d5b25724.png?auto=format&fit=clip&q=50) If you have any questions while using the WorkOS API collection, please reach out to our team at [support@workos.com](mailto:support@workos.com). ## On prem deployment {#on-prem-deployment} ### Using WorkOS with On-prem Customers Best practices for using WorkOS with on-prem customers. ## Introduction WorkOS can be used with both cloud and on-prem deployments. This guide explains the considerations needed to use WorkOS features with on-prem deployment strategies. For example, many SaaS companies offer enterprise solutions where their infrastructure can be deployed to a customer's cloud or data center. When using an on-prem deployment strategy, two key considerations are: - Deploying a static API key to each customer's installation to isolate access to their team only - Ensuring your customer's network can send and receive requests from the WorkOS API Outside of these considerations, WorkOS integration for on-prem customers functions in the same way as in cloud deployments. ![diagram showing on-prem configuration using WorkOS](https://images.workoscdn.com/images/17460e43-790f-4791-93ee-f0b001ef5eae.png?auto=format&fit=clip&q=50) ## Using a static API key for each customer's deployment Since a full deployment of your software is being deployed to your customer's environment, each deployment requires its own unique WorkOS API key. This can be accomplished by creating a separate environment in your WorkOS dashboard for each on-prem customer. Each WorkOS workspace comes with Staging and Production environments by default. To create a new environment for an on-prem customer: - Reach out to the WorkOS support team at [support@workos.com](mailto:support@workos.com) - Provide the name you'd like to use for the new environment and specify that it should be a production environment ![diagram showing different environments in the WorkOS dashboard](https://images.workoscdn.com/images/2e280efe-011f-4583-9c67-1fedd60f0071.png?auto=format&fit=clip&q=50) The support team will create the environment, which will then be available in the environments dropdown menu in your WorkOS workspace. To retrieve the client ID and API key for this environment, navigate to the [API Keys section](https://dashboard.workos.com/api-keys) of the WorkOS dashboard where the values are available to download. ## Allowing WorkOS Traffic Through Firewalls A common challenge with on-premise deployments is coordinating which traffic will be allowed by the firewall. Several strategies exist for allowing traffic to and from WorkOS to communicate with an on-prem deployment. ### Strategy 1: Configure Firewall Rules or ACLs The most common approach is to deploy your application with the WorkOS integration to your customer's on-prem environment configured the same as you would for cloud application users, then have the firewall rules or access control lists (ACLs) set to allow WorkOS API traffic. WorkOS uses Cloudflare to ensure security and reliability. If you need to allowlist IP addresses for redirect requests, you can use the IP ranges listed in the [Cloudflare documentation](https://www.cloudflare.com/ips/). ![diagram showing different environments in the WorkOS dashboard](https://images.workoscdn.com/images/23e605b6-2b82-41be-a93b-664d07b07d0a.png?auto=format&fit=clip&q=50) #### Firewall Ingress Rules (Incoming Traffic) Ingress rules control external traffic entering your network. Some features of WorkOS require requests originating from our APIs directly to the on-prem installation, such as authentication callbacks, action callbacks, and webhooks. Events can also be ingested with the Events API, which is the preferred method for event delivery in an on-prem deployment scenario since those requests will originate from your on-prem application infrastructure. - All requests use HTTPS on port 443 - All authentication requests originate from [Cloudflare's published IP ranges](https://www.cloudflare.com/ips/) - All outbound requests for [Actions Webhooks](/authkit/actions) and [event and log streaming](/events/observability/datadog) will originate from the following IP ranges: - 3.217.146.166 - 23.21.184.92 - 34.204.154.149 - 44.213.245.178 - 44.215.236.82 - 50.16.203.9 - 52.1.251.34 - 52.21.49.187 - 174.129.36.47 - Requests will require an external domain name that resolves to the installation's host #### Firewall Egress Rules (Outgoing Traffic) Egress rules manage traffic leaving your network to external services. Key aspects include: - All requests leave the on-prem network over HTTPS on port 443 - All traffic is handled on Cloudflare's published IP ranges ##### Best Practices - Apply the principle of least privilege - Log and monitor cross-boundary traffic - Regularly audit firewall rules Implement a workflow of starting with restrictive default deny rules, then carefully opening only necessary ports and protocols to ensure that your integration with WorkOS is secure. ### Strategy 2: Use ngrok for Network Traffic Management Another approach is to use a service like [ngrok](https://ngrok.com/) to manage traffic to and from the WorkOS API instead of modifying firewall rules. This approach allows you to implement WorkOS authentication without adjusting firewall configurations. With ngrok, you can: - Create secure tunnels from the public internet to your on-premise deployment - Receive webhook events from WorkOS directly to your local development environment - Implement WorkOS AuthKit, SSO and Directory Sync features in environments with restrictive network policies Implementation involves installing the ngrok client on your application server, establishing a tunnel to your application's local port, and configuring your WorkOS integration to use the ngrok-provided public URL. ![diagram showing a WorkOS on-prem configuration using ngrok ](https://images.workoscdn.com/images/42766c0c-741c-460f-818f-6bb4875634ca.png?auto=format&fit=clip&q=50) This approach requires configuration of third-party software and additional cost. ngrok offers different pricing tiers based on your needs, with paid plans providing features like persistent URLs, IP restrictions, and additional security controls essential for production environments. ## Air-Gapped Environments For customers operating in air-gapped environments with no external network connectivity, cloud-based authentication services like WorkOS cannot be utilized as they require API connectivity. However, many organizations with air-gapped environments have established security protocols that permit the deployment of approved third-party software within their isolated networks, as their security architecture already provides robust authentication mechanisms internally. In these scenarios, we recommend a dual-implementation approach: - Continue leveraging WorkOS for authentication in cloud-based and network-connected on-premises deployments - Develop a specialized deployment package for air-gapped environments that: - Integrates with the customer's existing internal authentication infrastructure - Maintains feature parity while operating independently of external services - Adheres to the security policies specific to air-gapped environments This approach allows you to maintain a consistent product experience across different deployment scenarios while accommodating the strict security requirements of air-gapped customers. ## Glossary {#glossary} ### Glossary Terminology and concepts used in the WorkOS documentation. ## Access Token An access token represents the successful authorization of your application to access a user’s profile. During the Single Sign-On authorization flow, you’ll receive an access token and profile in exchange for your authorization code. ## ACS URL An Assertion Consumer Service URL (ACS URL) is an endpoint where an identity provider posts SAML responses. ## API Key A unique identifier used to authenticate your API requests. ## Attribute Mapping Attribute mapping allows IT administrators to customize the user claims that are sent to your application. WorkOS normalizes these claims, so you can depend on a reliable, expected set of user profile information. ## Authorization Code An authorization code is a temporary code that you will exchange for an access token. During the Single Sign-On authorization flow, you’ll exchange your authorization Code for an access token and profile. ## Authentication Challenge An authentication challenge, also known as challenge-response authentication, is a set of protocols that helps validate actions and protect resources from unauthorized access. ## Authentication Factor An authentication factor is a category of credential that is intended to verify, sometimes in combination with other factors, that an entity requesting access to some system is who, or what, they are declared to be. ## Authorization URL An authorization URL is the location your user will be directed to for authentication. ## Bearer Token A Bearer Token is an HTTP authentication scheme that uses a single security token to act as the authentication of an API request. The client must send this token in the Authorization header when making requests to protected resources. In the context of a Directory Sync integration, a Bearer Token is generated by WorkOS for SCIM providers such as Okta to authenticate endpoint requests. ## CIMD Client ID Metadata Document (CIMD) is the mechanism through which an MCP client identifies itself to an authorization server. You can use WorkOS and AuthKit to implement authentication for an MCP server you develop. As part of that, you’ll enable CIMD in the WorkOS Dashboard under _Connect_ → _Configuration_. ## Client ID The client ID is a public identifier for your application that maps to a specific WorkOS environment. ## Client Secret The client secret is a value only known to your application and an OAuth identity provider. Currently, client secrets are used in OpenID Connect and Google/Microsoft/GitHub OAuth connections. ## Connection A connection is a way for a group of users (typically in a single organization) to sign in to your application. A directory connection is a way to retrieve a complete list of users and groups from an organization. ## Discovery Endpoint An OIDC discovery endpoint is a URL that provides metadata about an OIDC provider, including the issuer URL, supported authentication and token endpoints, supported scopes, public keys for signature verification, and other configuration information. The discovery endpoint path is `/.well-known/openid-configuration` on a URL. Clients can use this endpoint to dynamically discover and interact with an OIDC provider without requiring manual configuration. ## Directory Group A directory group is a collection of users within an organization who have been provisioned with access to your application. ## Directory Provider A directory provider is the source of truth for your enterprise client’s user and group lists. ## Directory User A directory user is a person or entity within an organization who has been provisioned access to your application. ## Endpoint An endpoint is a location where an API receives requests about a specific resource. In the context of a Directory Sync integration, an endpoint is the standardized SCIM definition of two things: a `/Users` endpoint and a `/Groups` endpoint. ## HRIS A Human Resources Information System (HRIS) is software designed to maintain, manage, and process detailed employee information and human resources-related policies. ## IdP An Identity Provider (IdP) is the source of truth for your enterprise client’s user database and authentication. Sometimes referred when describing the IdP-initiated flow, which is an authentication flow that starts from an identity provider like Okta instead of your application. ## IdP URI (Entity ID) An Identity Provider URI (Entity ID) is a globally unique name for an identity provider that performs SAML authentication assertions. Sometimes referred to as Identity Provider Issuer (Okta, Entra ID). ## IdP SSO URL An Identity Provider SSO URL (IdP SSO) is the URL your application’s users will be redirected to for authentication with an identity provider. Sometimes referred to as Identity Provider SAML 2.0 Endpoint (OneLogin). ## IdP Metadata An Identity Provider Metadata (IdP Metadata) is the URL or XML file containing all of the metadata relevant to a specific identity provider. It includes attributes used by a service provider to route SAML messages, which minimizes the possibility of a rogue identity provider orchestrating a man-in-the-middle attack. ## JIT User Provisioning Just-in-time (JIT) user provisioning creates a user in an app when the user attempts to sign in for the first time. The account and respective role doesn’t exist until the user creates it – just-in-time. ## JWT JSON Web Tokens are an open, industry standard method for representing claims securely between two parties. ## Logout redirect An allowlisted location a user will be redirected to after their session has been ended by the Logout API. ## OAuth 2.0 OAuth 2.0 is an open standard for authorization. WorkOS supports OAuth 2.0, and our Single Sign-On API is modeled after concepts found in OAuth. ## OIDC OpenID Connect (OIDC) is an open standard and identity layer built on top of the OAuth 2.0 framework. ## Redirect URI A redirect URI is a required, allowlisted callback URL. The redirect URI indicates the location to return an authorized user to after an authorization code is granted, and the authentication process is complete. ## SAML Security Assertion Markup Language (SAML) is an open standard for authentication. Most of your enterprise clients will require SAML 2.0 authentication for their Single Sign-On. ## SCIM System for Cross-domain Identity Management (SCIM) is an open standard for managing automated user and group provisioning. It’s a standard that many directory providers interface with. ## SP Service Provider (SP) is SAML parlance for “your application”. Sometimes referred when describing the SP-initiated flow, which is an authentication flow that starts from your application instead of an identity provider like Okta. ## SP Entity ID A Service Provider (SP) Entity ID is a globally unique name for a service provider that performs SAML authentication requests, and is the intended audience for SAML responses. It is sometimes referred to as the Audience value. ## SP Metadata Service Provider Metadata (SP Metadata) is an XML file containing all of the metadata relevant to a specific service provider. Identity providers will use SP metadata files to make onboarding your application easier. ## TOTP Time-based One-time Password (TOTP) is a temporary code, generated by an algorithm that uses the current time as a source of uniqueness. ## X.509 Certificate An X.509 Certificate is a public key certificate used to authenticate SAML assertions. Sometimes referred to as Token Signature (AD FS). ## Email {#email} ### Email delivery Best practices for sending email with WorkOS. ## Introduction Many WorkOS features rely on your users receiving and acting upon email. For example, this includes invitations to join your app, password reset links, or Magic Auth sign-in. Prompt delivery of these emails is crucial. WorkOS offers three options for sending email: - **WorkOS email domain:** WorkOS sends email from the `workos-mail.com` domain. - **Your email domain:** WorkOS sends email from your own email domain. - **Send your own email:** WorkOS emits events, allowing your app to listen to these events and send email using your own email provider. These options provide different trade-offs between convenience, customization, and control over email deliverability. WorkOS follows industry best practices when sending email. SPF and DKIM email authentication records are configured automatically, the email content is continually refined to ensure it passes spam filters, and delivery of every email is actively monitored. However, regardless of the option you chose for sending email to your users, there are additional steps you can take to ensure that it reaches user inboxes. --- ## (A) WorkOS email domain By default WorkOS will send the following emails from the `workos-mail.com` domain in production environments. | Email | Sent From | Purpose | | ------------------ | :---------------------- | :------------------------------------- | | Invitation | welcome@workos-mail.com | Invite a user to create an account | | Magic Auth | access@workos-mail.com | Allow sign in with a one-time-use code | | Email verification | welcome@workos-mail.com | Verify ownership of a given email | | Password reset | access@workos-mail.com | Support the password reset flow | WorkOS has configured SPF, DKIM and DMARC email authentication records for the `workos-mail.com` domain. These records prove to the receiving mail server that a given email comes from WorkOS. We actively monitor the delivery of email sent from the `workos-mail.com` domain to protect the domain's reputation. If we detect unusually high rates of undelivered mail or mail marked as spam from a WorkOS team account, we may suspend that team's ability to send email. ### Do not send unsolicited email To ensure email is delivered when using the WorkOS email domain, be sure not to allow unsolicited email to be sent on your behalf. For example, an invitation email should be sent only if a user explicitly requests access to your application for themselves or another user. Do not attempt to bulk invite users from an email marketing list. ### Use appropriate team and organization names It is also important to ensure that your WorkOS team account and all organizations under your team have appropriate names that avoid [common spam words](https://mailtrap.io/blog/email-spam-words/) that may trigger spam filters. While our static email content is thoroughly tested, WorkOS emails can include your team name as well as the names of organizations under your team. There may be an impact to email deliverability if these names use terms often flagged by spam filters. --- ## (B) Your email domain While using the WorkOS email domain option is convenient, you can provide your users a better experience. Using your own email domain means that your users will receive emails from a domain they recognize, one associated with your app. In addition, because you control the email domain, you have more control over the domain reputation and therefore more control over email deliverability. You can configure your own email domain in the [WorkOS dashboard](https://dashboard.workos.com). You will need to verify ownership of the domain by setting up a CNAME record with your domain provider. Two additional CNAME records are required to automatically configure SPF and DKIM email authentication using [SendGrid's automated security feature](https://support.sendgrid.com/hc/en-us/articles/21415314709147-Email-Authentication-SendGrid-s-Automated-Security-Explained). ![Configuring your email domain](https://images.workoscdn.com/images/84e47c58-e5e5-47c3-8245-f414a203f284.png?auto=format&fit=clip&q=50) In addition to not sending unsolicited emails and using appropriate team and organization names, when using your own email domain there are a few additional steps you can take to ensure email is delivered promptly. ### Set up inboxes When using your own domain, email will be sent from `welcome@` and `access@`. Email providers check if there are inboxes associated with sender addresses, so setting up inboxes for both the `welcome` and `access` email addresses on your domain can help ensure your emails reach users. ### Set up DMARC WorkOS recommends that you set up DMARC (Domain-based Message Authentication, Reporting & Conformance) with your domain provider. Google has released [guidelines](https://support.google.com/a/answer/81126?visit_id=638529785140327067-2643207201&rd=1#zippy=%2Crequirements-for-all-senders%2Crequirements-for-sending-or-more-messages-per-day) for email senders and the guidelines include DMARC requirements. Apple and Yahoo have released similar best practice guides. A DMARC policy tells a receiving mail server what to do when a message from your domain doesn’t pass DMARC authentication. Configuring DMARC requires setting up a DNS TXT record with your domain provider. Here is an example DMARC record that will reject all emails not legitimately sent by an email provider on your behalf: ```plaintext TXT Record name: _dmarc<.example.com> content: v=DMARC1; p=reject; rua=mailto:postmaster@example.com, mailto:dmarc@example.com; pct=100; adkim=s; aspf=s ``` More details about DMARC can be found at [dmarc.org](https://dmarc.org/overview/). --- ## (C) Connect your own email provider to WorkOS By connecting your own email provider to WorkOS, you get control over deliverability, reputation, and compliance, while still offloading the heavy lifting of email handling. This option also allows you to easily utilize an existing email service provider configuration. For complete instructions on configuring a custom email provider, see the [custom email providers section](/authkit/custom-email-providers). --- ## (D) Send your own email There are a number of reasons why you may want to send email using your own email provider. Perhaps you already send a welcome email to new users and want to include an invitation link instead of sending a second email. Perhaps you already track sent email status with your own email provider and want a unified view into the status of all emails associated with your app. Regardless, when you send your own email, you have complete control over email deliverability. For complete instructions on sending your own email, see the section on [custom emails](/authkit/custom-emails) in the AuthKit documentation. When sending your own email, you will want to follow the all of the recommendations in Google's [email sender guidelines](https://support.google.com/a/answer/81126?hl=en). This includes setting up SPF, DKIM and DMARC email authentication. You will also need to be conscious of your sender reputation. It's based on the quality of emails, their frequency, and user interaction. A good sender reputation can increase the chances of your emails reaching inboxes. SendGrid provides some [useful tips for improving sender reputation](https://sendgrid.com/en-us/blog/email-reputation-101-ip-reputation-vs-domain-reputation). If you author your own email content, you may want to test your emails against various email providers' spam filters. There are a number of spam testing services available such as [Litmus](https://www.litmus.com/email-testing) and [Warmly](https://www.warmy.io/free-tools/email-deliverability-test/). --- ## Troubleshooting Even when following industry best practices, an email may get filtered as spam and not reach a user's inbox. Other times an email might be delayed, for example, when [Enhanced Pre-delivery Message Scanning](https://apps.google.com/supportwidget/articlehome?hl=en&article_url=https%3A%2F%2Fsupport.google.com%2Fa%2Fanswer%2F7380368%3Fhl%3Den&product_context=7380368&product_name=UnuFlow&trigger_context=a) is enabled on a Google workspace or when a similar feature is enabled with other email providers. Email providers do not explain the heuristics used by their spam filters and security mechanisms, and they are often changing, making it especially frustrating to troubleshoot problems. The first step in troubleshooting is to determine if the problem exists for all users or only a subset of users. Generally, this will provide insight into the nature of the issue and how best to resolve it. If the issue exists for all users, it is most likely a matter of poor domain reputation. If the issue only exists for a subset of users, it may be because of specific settings used by an email provider or the IT department at a given organization. Both Google and Microsoft have been noted as being especially aggressive when identifying spam. However, both companies provide some tooling to help you debug email deliverability problems. Google offers [Postmaster Tools](https://www.gmail.com/postmaster/) to help with email deliverability related to Gmail and Google Workspaces. Microsoft offers similar tools with [Sender Support](https://sendersupport.olc.protection.outlook.com/pm/). Lastly, more general spam testing services such as [Litmus](https://www.litmus.com/email-testing) and [Warmly](https://www.warmy.io/free-tools/email-deliverability-test/) are available. If you continue to have issues regarding email deliverability despite following all of the above suggestions, please [contact support](mailto:support@workos.com). ## Widgets {#widgets} ### User Sessions Widget A widget for displaying and managing user sessions in your application. The `` widget provides users with visibility into their active sessions across different devices and browsers. Users can view session details and sign out of individual sessions as needed. No special permissions are required to use this widget. ## API Reference ### User Security Widget A widget for controlling user security settings in your application. The `` widget enables users to control their security settings. With this widget, users can: - Set or change their password - Configure and reset Multi-Factor Authentication No special permissions are required to use this widget. ## API Reference ### User Profile Widget A widget for displaying and managing a user’s profile in your application. The `` widget allows users to view and manage their personal information. Users can see their profile details and edit their display name. This widget provides a simple, user-friendly interface for basic profile management. No special permissions are required to use this widget. ## API Reference ### User Management Widget A widget for displaying and managing users in your application. ![Users Management screenshot](https://images.workoscdn.com/images/20f235c5-c888-48f5-90aa-87ec9189483a.png?auto=format&fit=clip&q=50) The `` widget allows an organization admin to manage the members in an organization. Admins can invite new users, remove users, and change roles all within the widget. In order to use the User Management widget, a user must have a role that has the `widgets:users-table:manage` permission. ## API Reference ### Authorization Tokens Ensure Widgets have the appropriate permissions in your application. Widgets must be supplied with an authorization token. The token can be acquired in one of two ways: - If you are using the `authkit-js` or `authkit-react` libraries, you can use the provided access token. - If you use one of our backend SDKs, use the "get token" method in the SDK to request a token with the appropriate scope for the widget you want to use. Widget tokens expire after one hour. > New WorkOS accounts are created with an "Admin" role that has all Widget permissions assigned. Existing accounts will need to assign the proper permissions to a role. This can be done on the "Roles" page of the WorkOS Dashboard. See the [Roles and Permissions guide](/authkit/roles-and-permissions) for more information. To successfully generate a token, the user must be assigned a role with the correct permissions for the widget. ### Quick Start A step-by-step guide for setting up WorkOS Widgets in your application. ## Installation First, install the `@workos-inc/widgets` package from the npm registry, along with its peer dependencies: ```bash title="Install packages" npm install @workos-inc/widgets @radix-ui/themes @tanstack/react-query ``` WorkOS Widgets uses [Radix Themes](https://www.radix-ui.com/themes) for its UI components and style customization APIs, while [TanStack Query](https://tanstack.com/query/latest) is used for data fetching and caching. Since both libraries are often used in applications, we require them as peer dependencies to avoid duplication, version conflicts, and bloated bundles. > Widgets can be used in any client- or server-rendered React application. See our [Widgets examples on GitHub](https://github.com/workos/widgets-examples) to see how they can be integrated in various frameworks. ## Styles WorkOS Widgets are powered by Radix Themes, which provides beautiful default styles with zero configuration. Start by importing styles exported from both Radix Themes and WorkOS Widgets. > Widgets can be customized using the `theme` prop or with plain CSS. See the [styling guide](/widgets/styling) for more details. ## Root component The `WorkOsWidgets` component should be rendered at the top of your application. This component is responsible for managing context for data fetching and providing theme styles to all Widgets. ## CORS configuration Because WorkOS widgets issue client-side requests to WorkOS, it is necessary to configure your site as an allowed web origin. Adding this in the [Authentication section of the dashboard](https://dashboard.workos.com/) will prevent CORS issues when using the widget. ![CORS configuration](https://images.workoscdn.com/images/deb27664-e2e1-4c3b-afa1-e8ba2578c77c.png?auto=format&fit=clip&q=50) ### Pipes Widget A widget for displaying and managing connected accounts with Pipes. ![Pipes widget screenshot](https://images.workoscdn.com/images/e84a33bb-0510-4d85-9041-33b1a0ce938c.png?auto=format&fit=clip&q=50) The `` widget allows users to manage their connections to third-party providers. Users can view the available providers, connect their accounts, reauthorize when needed, and disconnect their accounts. Read more in the [Pipes guide](/pipes). ## API Reference ### Organization Switcher Widget A widget for switching between organizations in your application. The `` widget allows users to switch between organizations. There are no special permissions required to use this widget as users can switch between organizations they have access to. If an organization requires SSO or MFA, the user will be redirected to reauthorize with the new organization. ![Organization Switcher screenshot](https://images.workoscdn.com/images/e22cad7a-f11a-4f47-8cc7-fb015a22114f.png?auto=format&fit=clip&q=80) ### Switching Organizations There are multiple ways to integrate with the Organization Switcher widget depending on your library choice. If you are using either the `authkit-js` or `authkit-react` libraries, you can use the `useAuth` hook to get the current organization and pass it to the widget. If you are using one of the backend SDKs, you can build the organization switcher action in the backend and pass it in as a prop to the widget to be called when the user attempts to switch organizations. See the [Switching Organizations](/authkit/sessions/integrating-sessions/switching-organizations) guide for more information to set up the backend actions. This can then be passed in as a prop to the widget. ### Creating Organizations The widget accepts children components that can be used to either redirect the user to create an organization or to show a modal with a form to create an organization. You can use this to integrate with your existing organization creation flow that uses the WorkOS APIs to create organizations. ## API Reference ### WorkOS Widgets Learn how to integrate WorkOS Widgets in your app. ## Introduction WorkOS Widgets are React components that provide complete functionality for common enterprise app workflows, for example a Users Management Widget that provides a UI for inviting, removing and editing users. This guide will cover how to add a widget to your app, configure CORS, and supply an authorization token for the widget. ### API Keys Widget A widget for displaying and managing API Keys. ![API Keys widget screenshot](https://images.workoscdn.com/images/13e0893f-eb84-43f1-9467-2598567538f3.png?auto=format&fit=clip&q=50) The `` widget allows an admin to manage API keys in an organization. Admins can create API keys with specific permissions, view details of existing API keys, and revoke API keys, all within the widget. In order to use the API Keys widget, a user must have a role that has the `widgets:api-keys:manage` permission. ## API Reference ### SSO Connection Widget A widget for setting up SSO connections in the Admin Portal. The `` widget enables users to set up SSO connections in the Admin Portal. In order to use the SSO Connection widget, a user must have a role that has the `widgets:sso:manage` permission. ## API Reference ### Domain Verification Widget A widget for verifying domains in the Admin Portal. The `` widget enables users to verify domains in the Admin Portal. In order to use the Domain Verification widget, a user must have a role that has the `widgets:domain-verification:manage` permission. ## API Reference ### Theme Customization Customize the look and feel of WorkOS Widgets using Radix Themes. ## Using the `theme` prop The `theme` prop can be used to customize the overall appearance of WorkOS Widgets. `theme` support relies on external stylesheets from Radix Themes and WorkOS Widgets. Start by importing both stylesheets into your application. ### `theme` properties See the [Radix Themes API reference](https://www.radix-ui.com/themes/docs/components/theme#api-reference) for more information on theming options. ## Using the `elements` prop Underlying components can be styled using the `elements` prop. This object is a mapping of component names to their respective Radix Theme component props. ### `elements` properties Each element is mapped to a Radix Theme component and accepts the same props as its respective component. See the Radix Themes documentation for each component for all available props. | Component | Radix component | | :-------------------- | :-------------------------------------------------------------------------- | | `avatar` | [`Avatar`](https://www.radix-ui.com/themes/docs/components/avatar) | | `badge` | [`Badge`](https://www.radix-ui.com/themes/docs/components/badge) | | `primaryButton` | [`Button`](https://www.radix-ui.com/themes/docs/components/button) | | `secondaryButton` | [`Button`](https://www.radix-ui.com/themes/docs/components/button) | | `destructiveButton` | [`Button`](https://www.radix-ui.com/themes/docs/components/button) | | `dialog` | [`Dialog`](https://www.radix-ui.com/themes/docs/components/dialog) | | `dropdown` | [`Dropdown`](https://www.radix-ui.com/themes/docs/components/dropdown) | | `iconButton` | [`IconButton`](https://www.radix-ui.com/themes/docs/components/icon-button) | | `label` | [`Label`](https://www.radix-ui.com/themes/docs/components/label) | | `primaryMenuItem` | [`MenuItem`](https://www.radix-ui.com/themes/docs/components/menu-item) | | `destructiveMenuItem` | [`MenuItem`](https://www.radix-ui.com/themes/docs/components/menu-item) | | `select` | [`Select`](https://www.radix-ui.com/themes/docs/components/select) | | `skeleton` | [`Skeleton`](https://www.radix-ui.com/themes/docs/components/skeleton) | | `textfield` | [`TextField`](https://www.radix-ui.com/themes/docs/components/text-field) | ### Styling Customize the look and feel of WorkOS Widgets. WorkOS Widgets are powered by Radix Themes, which provides beautiful default styles with zero configuration. The fastest way to style your Widgets is with the [`theme` prop](/widgets/styling/theme-customization). This prop is provided to the `WorkOsWidgets` component rendered at the top of your application. All Widgets will inherit styles configured in the `theme` prop. See the [theme customization guide](/widgets/styling/theme-customization) for more details on `theme` prop. ## Using CSS If you choose not to use the theming capabilities in Radix Themes, you can style Widgets using CSS. Individual elements in Widgets are accessible via CSS class selectors prefixed with `woswidgets-`. For example, you can add your own button styles by selecting the `woswidgets-button` class. See the [CSS customization guide](/widgets/styling/css-customization) for more details on styling Widgets with CSS. ### CSS Customization Customize the look and feel of WorkOS Widgets using CSS. Widgets can be styled using plain CSS using namespaced class and data-attribute selectors. While optional, we recommend starting with the `layout.css` stylesheet from Radix Themes, as well as the `base.css` stylesheet from WorkOS Widgets. These styles provide a base level of functional styling without opinionated design choices. ## Universal selectors Elements in Widgets are accessible via CSS class selectors prefixed with `woswidgets-`. | Selector | Description | | :------------------- | :-------------------------------------------------- | | `.woswidgets-root` | The root element for the Widgets provider | | `.woswidgets-widget` | A selector used on the root element for all Widgets | ## Element selectors ### Avatar | Selector | Description | | :------------------- | :-------------------------- | | `.woswidgets-avatar` | Targets all avatar elements | ### Badge | Selector | Description | | :------------------ | :------------------------- | | `.woswidgets-badge` | Targets all badge elements | ### Button | Selector | Description | | :-------------------------------- | :-------------------------- | | `.woswidgets-button` | Targets all button elements | | `.woswidgets-button--primary` | Targets primary buttons | | `.woswidgets-button--secondary` | Targets secondary buttons | | `.woswidgets-button--destructive` | Targets destructive buttons | ### Dialog | Selector | Description | | :--------------------------- | :--------------------------------------- | | `.woswidgets-dialog` | Targets all dialog elements | | `.woswidgets-dialog-overlay` | Targets the overlay for a dialog element | ### Dropdown | Selector | Description | | :--------------------- | :---------------------------- | | `.woswidgets-dropdown` | Targets all dropdown elements | ### Icon Button | Selector | Description | | :------------------------ | :------------------------------- | | `.woswidgets-button` | Targets all button elements | | `.woswidgets-icon-button` | Targets all icon button elements | ### Label | Selector | Description | | :------------------ | :------------------------- | | `.woswidgets-label` | Targets all label elements | ### Menu Item | Selector | Description | | :----------------------------------- | :----------------------------- | | `.woswidgets-menu-item` | Targets all menu item elements | | `.woswidgets-menu-item--destructive` | Targets destructive menu items | ### Select | Selector | Description | | :---------------------------- | :----------------------------------------------- | | `.woswidgets-select` | Targets all select elements | | `.woswidgets-select-dropdown` | Targets dropdown elements belonging to a select | | `.woswidgets-select-item` | Targets menu item elements belonging to a select | ### Skeleton | Selector | Description | | :--------------------- | :---------------------------- | | `.woswidgets-skeleton` | Targets all skeleton elements | ### Text Field | Selector | Description | | :----------------------- | :------------------------------ | | `.woswidgets-text-field` | Targets all text field elements | ## Vault {#vault} ### Quick Start A step-by-step guide on how to start using Vault to manage encrypted objects. ## Before getting started To get the most out of these guides, you’ll need: - A [WorkOS account](https://dashboard.workos.com/) Sign in to your WorkOS Dashboard account and create a new Organization. ![WorkOS Dashboard UI showing organization creation](https://images.workoscdn.com/images/1c69fd98-01be-491d-9255-58363bc6a983.png?auto=format&fit=clip&q=50) ## What you'll build In this guide, we will walk you through what you will need to set up Vault for securing and isolating organization-specific data: - Encrypt and store data linked to an organization - Retrieve the encrypted data - Delete an object that's no longer in use ## API object definitions [Object](/reference/vault/object) : Represents an encrypted key-value item stored by Vault. [Organization](/reference/organization) : Describes an organization whose users sign in with a SSO Connection, or whose users are synced with a Directory Sync Connection. ## Add Vault to your app ### Install the WorkOS SDK WorkOS offers native SDKs in several popular programming languages. Choose a language below to see instructions in your application’s language. ### Set objects To make calls to WorkOS, provide the API key and, in some cases, the client ID. Store these values as managed secrets, such as `WORKOS_API_KEY` and `WORKOS_CLIENT_ID`, and pass them to the SDKs either as environment variables or directly in your app's configuration based on your preferences. ```plain title="Environment variables" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' ``` > The code examples use your staging API keys when [signed in](https://dashboard.workos.com) ### Create an object The Vault API and SDKs provide a method to encrypt and store a blob of data linked to a WorkOS organization. The encryption key used will be both unique to the KV item and cryptographically isolated from all other organizations. ### Update the value of the object Once created, the key context for an object cannot be changed. Only the value can be updated. The expected version of the object can be provided as a consistency lock when writing to the object. ### Retrieve the object value Objects can be listed, returning just the names of the objects. The metadata for each object can be queried - this provides more information about it without needing to decrypt the actual value. Fetching the object value will return the same metadata in addition to the unencrypted value. ### Delete the object When an object is no longer needed it can be marked for deletion. This will make the object unavailable to API operations, but the data will not be immediately deleted. ### Key Context User-managed cardinality for keys within Vault. When encrypting data with Vault, a set of key-value metadata pairs called the key context is required. This determines which key or keys will be used to encrypt the data without needing to explicitly list IDs for the keys. The key context is used both when [creating an encrypted object](/reference/vault/object/create) and when [encrypting locally](/reference/vault/key/encrypt-data) with Vault-managed keys. ## Key matching Each item in the context is used to identify a long-lived key within the WorkOS environment called a key-encrypting key (KEK). The key material lives in a Hardware Security Module (HSM) and cannot be exported to plaintext - it can only be used to generate or decrypt data keys. KEKs are created just-in-time and don't require any configuration in advance. ### Bring Your Own Key (BYOK) When Vault is used with a BYOK setup, the customer-managed key (CMK) is used in place of the WorkOS managed KEK. Matching the encryption operation to the CMK is still done based on the key context. For example, if Vault is configured to use a CMK called `key_abc` for all data of `organization_abc123`, then that key would automatically be used when the key context is set to `{"organization_id": "organization_abc123"}`. The same operation with a context of `{"organization_id": "organization_xzy987"}` would instead use a WorkOS managed KEK. ## Data keys Although the KEKs identified by key context are long-lived, they aren't directly used for encrypting data. A random data-encrypting key (DEK) is generated for an encryption operation. The DEK is then encrypted using each KEK from the key context, resulting in a single plaintext key and one or more encrypted keys. The encrypted keys are then stored with the encrypted data for future decryption. This ensures that the data and keys have the same durability while keeping the keys safe. It also means that even if one key is exposed, not all of the data will be at risk since many different data keys are used for the same key context. ## Limitations The following limitations are enforced by the Vault API for the key context object: - All values in the context must be strings. - A maximum of 10 items can be present in a single context. - Each context name has a maximum length of 120 characters. - Each context value has a maximum length of 500 characters. ### Vault Encrypt, store, and control access to sensitive data. --- # Introduction WorkOS Vault is a developer-friendly EKM to encrypt and optionally store data including tokens, passwords, certificates, files, and any other customer content. Ideal for scaling encryption in cloud applications, it minimizes key exposure and simplifies compliance. ## Key features ### Encrypted Key-Value Storage Each secret stored with Vault uses a unique encryption key and is cryptographically isolated based on user-provided context. Envelope encryption enhances security by encrypting data with a data encryption key (DEK), which is then encrypted with a key encryption key (KEK). This approach ensures sensitive data remains protected while allowing secure key management and access control. ### Enterprise Key Management (EKM) The Enterprise Key Management features of Vault centralize control over encryption keys used for customer data in multi-tenant architectures. It streamlines key lifecycle management, access policies, and auditability while integrating seamlessly with your existing applications. Key segmentation by organization, user, or any provided context ensures cryptographic keys are isolated, reducing risk and enforcing access control at boundaries that make sense for your business. ### Bring-Your-Own-Key (BYOK) With Vault you can provide keys either from your own environment or directly linked to your customers' cloud environments. BYOK gives you full control over encryption keys while integrating seamlessly with your own security tooling such as cloud SIEMs. It ensures your keys stay protected in your custody while enabling secure access for encryption operations, perfect for compliance-driven workloads. BYOK integration is available for many popular key management services, including Amazon Web Service KMS, Google Cloud Compute KMS, Azure Key Vault, and HashiCorp Vault. ## Common Use Cases ### Organizational secrets Sensitive data in a B2B application is often linked to specific organization. This can be shared secrets, API keys, OAuth credentials, or even data generated by your application. Vault protects this information and easily links each secret with the organization it belongs to in order to provide full cryptographic separation from other organizations within your application. ### User secrets User data such as Personally Identifiable Information (PII) or Protected Health Information (PHI) is highly sensitive and can have strict regulatory requirements including strong encryption, access controls, and data minimization. The risk for mishandling this data is very high - both financially and reputationally. Vault lets you store this data using unique encryption keys without needing to manage the complex lifecycle of key hierarchies. ### Application secrets With short-lived dynamic workloads in the cloud, static credentials represent a huge security risk. Secrets can get spread out across many services, making rotation difficult and increasing the risk of a leak. Vault can encrypt and store application data such as API keys, database credentials, and PKI certificates in a centralized service and provide them to your application at runtime. ### Bring Your Own Key (BYOK) Allow your customers to use their own encryption keys with WorkOS Vault for enhanced security and compliance. Bring Your Own Key (BYOK) allows your customers to use their own customer-managed keys (CMKs) with WorkOS Vault instead of relying solely on WorkOS-managed keys. This feature enables you to offer your customers additional control over their encryption keys and help them meet specific compliance requirements. ## Overview With BYOK, your customers maintain control over their key material while still leveraging Vault's encryption and data management capabilities. Customer-managed keys are used as key-encrypting keys (KEKs) in place of WorkOS-managed KEKs, providing an additional layer of security and compliance for your application's users. ## How BYOK works When Vault is configured with BYOK: 1. **Key Matching**: Encryption operations are matched to customer CMKs based on the [key context](/vault/key-context) provided 2. **Envelope Encryption**: Customer CMKs encrypt data-encrypting keys (DEKs), not the data directly 3. **Automatic Fallback**: Operations that don't match a customer's CMK configuration will use WorkOS-managed KEKs ### Key Context Matching BYOK uses the same key context mechanism as standard Vault operations. When a customer's CMK is configured for specific context values, Vault automatically uses that key for matching operations. **Example Configuration:** - Customer CMK `key_abc` configured for `organization_id: "org_123"` - Key context `{"organization_id": "org_123"}` → Uses customer CMK `key_abc` - Key context `{"organization_id": "org_456"}` → Uses WorkOS-managed KEK ## Benefits ### Enhanced Security - **Key Control**: Your customers maintain complete control over their encryption keys - **Isolation**: Customer keys remain separate from other tenants' data - **Audit Trail**: Customers have full visibility into their key usage and access patterns ### Compliance - **Regulatory Requirements**: Help customers meet compliance standards that require customer-controlled keys - **Data Sovereignty**: Enable customers to ensure encryption keys remain within their control - **Risk Management**: Reduce customer dependency on third-party key management ## Use Cases ### Multitenant Applications Allow different customers to use their own CMKs while maintaining a single Vault integration: ```javascript // Customer A data - uses Customer A's CMK await vault.createObject({ name: 'customer-a-pii', value: '{"fullname": "customer_a_name"}', context: { organization_id: 'customer_a' }, }); // Customer B data - uses Customer B's CMK await vault.createObject({ name: 'customer-b-pii', value: '{"fullname": "customer_b_name"}', context: { organization_id: 'customer_b' }, }); ``` ### Compliance Sensitive Data Allow customers to apply stricter key controls to specific data types: ```javascript // PCI data - uses customer's CMK await vault.createObject({ name: 'customer-123-payments', value: '{"creditCard": "4111-1111-1111-1111"}', context: { organization_id: 'customer_123', }, }); // General data - uses WorkOS-managed keys await vault.createObject({ name: 'customer-123-preferences', value: '{"preference": "dark_mode"}', context: { data_type: 'preferences', }, }); ``` ### Geographic Data Residency Allow customers to ensure their encryption keys remain in specific regions: ```javascript // EU data - uses customer's EU-based CMK await vault.createObject({ name: 'customer-789-pii', value: '{"userEmail": "user@example.eu"}', context: { organization_id: 'customer_789', }, }); ``` ## Configuration BYOK configuration is managed through your WorkOS dashboard and admin portal. Contact your WorkOS representative to enable BYOK for your application. ### Prerequisites - Your customers must have compatible key management systems (AWS KMS, Azure Key Vault, Google Cloud KMS) - Proper IAM permissions for WorkOS Vault to access customer keys ### Generate Admin Portal link Navigate to the organization of your customer who will configure their CMK. Generate a unique portal link by clicking "Invite admin" and selecting "Bring Your Own Key" from the feature selection. ![Generate admin portal link](https://images.workoscdn.com/images/d374bc73-7cdc-441c-b177-82c4ae604db7.png?auto=format&fit=clip&q=80) ### Share link with your customer's IT team The admin portal will walk an IT admin through the setup and configuration of the CMK. It includes screenshots for using the cloud provider of choice to create a key and set the appropriate permission in IAM policies to allow Vault to use the key. ![Share link with IT](https://images.workoscdn.com/images/7f237529-584b-4a98-b17e-2ce4bf6c1e08.png?auto=format&fit=clip&q=80) ### Confirm successful admin portal setup The final step of the admin portal setup flow will validate that Vault can use the CMK the IT admin configured. If they see "Setup is complete", Vault will use the customer's CMK whenever an operation includes their organization id as context. ![Confirm CMK setup success](https://images.workoscdn.com/images/f46f7009-3cf5-4706-a37e-691768d63440.png?auto=format&fit=clip&q=80) ### View CMK under Organization details A Key details card will appear under Organization details, which shows configuration information, CMK active state, and the key context associated with the CMK. ![View key details](https://images.workoscdn.com/images/54c026c7-f3b0-497a-bb48-83661ba1ae3e.png?auto=format&fit=clip&q=80) ## Single Sign-On {#sso} ### Test SSO Learn how to test your Single Sign-On integration end-to-end. ## Testing with the Test Identity Provider To confirm your Single Sign-On integration works correctly you can use the Test Identity Provider to simulate login flows end-to-end. Your staging environment includes a default Test Organization and active SSO connection configured with the Test Identity Provider. ![WorkOS Test Identity Provider](https://images.workoscdn.com/images/f3b0d507-2d6f-4ed8-a12f-e026c8a2987c.png?auto=format&fit=clip&q=80) ### Getting started Log into the [WorkOS Dashboard](https://dashboard.workos.com/) and navigate to the _Test SSO_ page to get started with the Test IdP. This page outlines a number of different SSO scenarios you can follow and provides all the necessary information to complete the tests. ![Test SSO WorkOs Dashboard](https://images.workoscdn.com/images/7b7407d7-dcc7-4fd4-859f-4ee4214d69c2.png?auto=format&fit=clip&q=80) ### Service provider-initiated SSO This case is likely the first [login flow](/sso/login-flows/sp-initiated-sso) you would test when implementing SSO in your app. The test simulates users initiating authentication from your sign-in page. In this scenario, the user enters their email in your app, gets redirected to the identity provider, and then is redirected back to your application. ### Identity provider-initiated SSO This test simulates users initiating authentication from their identity provider. It is a common [login flow](/sso/login-flows/idp-initiated-sso) that developers forget to consider. In the scenario, users log in to the identity provider directly, select your application from their list of SSO-enabled apps, and are redirected to your application upon successful authentication. > Ensure [AuthKit is disabled](https://dashboard.workos.com/authentication) before testing. ### Guest email domain This test simulates users authenticating with an email domain different from the verified domain of the test organization, `example.com`. A relevant scenario is authenticating freelance users, whose email domain is not owned by the company. ### Error response This test simulates a generic [error response](/reference/sso/get-authorization-url/error-codes) from the user’s identity provider. In this scenario, SSO authentication has failed for the user. Below is an example of the error-related parameters passed to the [redirect URI](/sso/redirect-uris) in your application. --- ## Testing with other identity providers Test Identity Provider saves time by providing an out of the box experience compared to the configuration process that someone using a real identity provider would have to go through to enable Single Sign-On for your app. If your integration works with the Test Identity Provider, you can be sure it will work with other identity providers. However, it may be helpful to also learn about the setup process that your customers will go through on their side, which varies depending on a specific identity provider. ### (1) Create an organization To get started, you will need to [create an organization](https://dashboard.workos.com/organizations) in the WorkOS Dashboard. Organizations in WorkOS represent your customer, so by creating an organization, you can test your SSO connection the way your customers will experience it. ![Create an organization dialog](https://images.workoscdn.com/images/2ef3565c-526a-42e6-9830-622e83b67ee5.png?auto=format&fit=clip&q=80) ### (2) Create a connection Go to the organization you created and click _Invite admin_. Select _Single Sign-On_ from the list of features. In the next step, enter an email address to send the setup link to, or click _Copy setup link_. The setup link goes to Admin Portal, where your customers get the exact instructions for every step they need to take to enable Single Sign-On with your app. > You can also integrate [Admin Portal](/admin-portal) directly into your app to enable self-serve setup of Single Sign-On and other enterprise features for your users. ![Invite an admin dialog](https://images.workoscdn.com/images/b9ab80fc-606a-417c-bade-3483ef48c2ae.png?auto=format&fit=clip&q=80) ### Follow the Admin Portal instructions To complete the integration, you’ll have to also create an account with the identity provider you want to test with. After you have signed up with an identity provider of your choice, follow the corresponding Admin Portal instructions from the setup link. Once done, you can start testing your SSO integration with that identity provider. ![Admin Portal setup instructions](https://images.workoscdn.com/images/0ee15c3d-5356-4f41-a26a-440f95355b28.png?auto=format&fit=clip&q=80) The setup instructions you’ve seen in the Admin Portal are also available directly in the docs if you want to create a connection manually: --- ### Single Logout Learn how to implement Single Logout with WorkOS > Currently, Single Logout is only supported for [OpenID Connect connections](/integrations/oidc) and limited scenarios. > If you are looking to implement this feature, please reach out to [WorkOS support](mailto:support@workos.com). ## RP-initiated Logout With an Relying-Party-initiated (RP-initiated) logout, a user is logged out of your application and all other applications they are logged into via the identity provider. This is achieved by redirecting the user to the [Logout Redirect](/reference/sso/logout/redirect) endpoint. Before redirecting the user, you need to generate a logout token by calling the [Logout Authorize](/reference/sso/logout/authorize) endpoint with the user’s profile ID which can be obtained from the [User Profile](/reference/sso/profile/get-profile-and-token) endpoint. Next, pass the logout token as a query parameter to the [Logout Redirect](/reference/sso/logout/redirect) endpoint. ![RP-initiated logout](https://images.workoscdn.com/images/63a9710b-ff61-456b-aea7-d572b3621271.png?auto=format&fit=clip&q=50) By following these steps, the user will be securely logged out of your application and all other associated applications through the identity provider. Note that, this feature is only supported for OpenID Connect providers that brings the `revocation_endpoint` and `end_session_endpoint` in the OIDC discovery document. --- ## IdP-initiated Logout For the Identity-Provider-initiated (IdP-initiated) logout, WorkOS provides the `https://auth.workos.com/sso/oidc/idp-logout/:external_key` endpoint which needs to be registered in the customer's Identity Provider as the logout endpoint for your application. When a user logs out of your application via the IdP, the IdP should call this endpoint which will redirect to a logout endpoint in your application. This logout endpoint should clear all the cookies in your application. You should contact [WorkOS support](mailto:support@workos.com) for both: - obtaining the `https://auth.workos.com/sso/oidc/idp-logout/:external_key` for registering in your customer's IdP - informing the logout endpoint in your application. ![IdP-initiated logout](https://images.workoscdn.com/images/aeda8074-7e61-4a3c-850e-278acd510bd8.png?auto=format&fit=clip&q=50) ### SAML Signing Certificates Verify the authenticity of SAML responses and requests. SAML signing certificates are X.509 certificates used in SAML responses to allow the [Service Provider (SP)](/glossary/sp) to verify the authenticity of a SAML response. Some [Identity Providers (IdP’s)](/glossary/idp) may require or provide the option to use a SAML signing certificate for the SAML request as well. In these cases the IdP verifies the authenticity of the SAML request. ![SAML Flow Diagram](https://images.workoscdn.com/images/d9771da5-ee40-4e41-bc96-f393ee0af577.png?auto=format&fit=clip&q=80)[border=false] SAML response signing certificates are generated by your customer’s IdP and must then be uploaded to WorkOS manually or using a monitored metadata URL. Your customer can either upload the certificate themselves via the Admin Portal, or you can upload it for them via the WorkOS Dashboard if your customer provides it to you. Unlike SAML response signing, for request signing you will need to provide your customer with a metadata URL called the SP metadata URL. Your customer will then upload the SP metadata URL to their IdP, where it will either be monitored for updates automatically made by WorkOS, or it will be manually updated by your customer in their IdP. --- ## SAML Response Signing Certificate When the IdP sends a SAML response, the SP must verify the authenticity of the response, and that it has not been tampered with by an unauthorized third party. The SAML response signing certificate allows the SP to perform this verification. ### Sample scenario Consider the fictional SaaS company _HireOS_, which offers recruiting software to other businesses. _HireOS_ is an online application that allows its customers to track leads, candidates, and interviews. _HireOS_ is referred to as the SP by SAML. Now let’s consider _HireOS_’ newest enterprise customer: _Enterprise Corp_. _Enterprise Corp_ is a large enterprise company that wants to use _HireOS_ to manage their recruiting. _Enterprise Corp_ IT admins need recruiters and other employees who will use _HireOS_ to log in using _Enterprise Corp_'s identity provider, Okta. Okta is one of many companies known as an IdP to SAML. ### Verifying the SAML response After identifying the user—whether from the SAML request or from IdP initiated SSO—Okta SAML will generate the SAML response, which includes SAML assertions, the X.509 certificate, and the signature value. Upon receiving the response from Okta SAML, _HireOS_ will verify that the response came from Okta SAML by decrypting the signature, using the public key on the X.509 certificate, and checking if the hash values match. ![SAML Response Diagram](https://images.workoscdn.com/images/96ec0449-2080-4b84-8574-43d1bc24c24a.png?auto=format&fit=clip&q=80)[border=false] ### Planning considerations When planning your SAML integration, there are a few things to consider related to SAML response signing certificates. ### Certificate expiration Your SAML response signing certificate will eventually expire and must be kept up to date in order to maintain service. Your certificate’s expiration time will vary, but typically, response certificates are valid anywhere from 1-5 years. If your certificate is uploaded in the WorkOS Dashboard, you can see when it expires by going to Organizations, selecting the Organization, and then clicking on the Connection containing the response certificate. If your company has a shared Slack channel with WorkOS, we will help ensure that your SAML response signing certificates stay up to date by automatically sending a notification before a certificate expires. ![WorkOS Dashboard UI showing a SAML certificate expiration date](https://images.workoscdn.com/images/eee34072-6363-498e-bb10-cc4f2171c98b.png?auto=format&fit=clip&q=90) ### Monitored metadata versus manual upload There are two options to upload your response certificate to a Connection, both of which can be done either in the WorkOS Dashboard, or by your customer using the Admin Portal. ### Renewing certificates To facilitate certificate renewal, WorKOS offers the ability to renew SAML certificates through the Admin Portal. When a certificate is nearing expiration (within 90 days), or has already expired, a notification will appear on the Dashboard Overview page with details about the certificate. ![Notification for expired certificate](https://images.workoscdn.com/images/5eba5473-fa61-4d57-bf60-bb9359d61797.png?auto=format&fit=clip&q=50) Alternatively, you are also able to filter connections that have either expired or expiring connections directly from the Organization page's filters. ![Organization page expired filter](https://images.workoscdn.com/images/f306979d-ab49-4c2a-832c-895d16a86041.png?auto=format&fit=clip&q=50) From the Connection page you can generate an Admin Portal link that WorkOS can email directly to the IT admin. By entering the IT admins' email address, WorkOS will email them with a certificate renewal Admin Portal link, and they will be notified about future expiring certificates. Alternatively, you can copy the link and share it with them directly. ![Connection page for an expiring certificate](https://images.workoscdn.com/images/c7896f7f-fcde-4440-9f66-8f3dc8445568.png?auto=format&fit=clip&q=50) The IT admin will be guided to a step by step flow to renew their certificate; the exact steps will vary based on the IdP. ![IT admin flow for Entra ID](https://images.workoscdn.com/images/2c8334f2-3784-4e7d-8ba9-f4896da336cb.png?auto=format&fit=clip&q=50) ### Monitored metadata To streamline this process, you can instead choose to upload a metadata URL to WorkOS that we will automatically keep updated as metadata changes. If your customer's IdP refreshes a certificate, WorkOS will automatically pull in the updated metadata. Your customer can upload a metadata URL to the Admin Portal during setup. Alternatively, they can provide it to your to manually upload via the Dashboard. ![WorkOS Dashboard UI configuring a connection's metadata URL](https://images.workoscdn.com/images/6407b054-9f84-45cf-81bd-35c25b7af0b5.png?auto=format&fit=clip&q=90) ### Manual upload SP metadata such as the Entity ID, IdP SSO URL, and SAML response signing certificate can be uploaded manually through the Dashboard or the Admin Portal. This may be done either by uploading an XML metadata file, or by individually inputting metadata values. When metadata becomes out of date, such as an X.509 certificate expiring, new information must manually be uploaded. If you would like to upload the data for your customer, they must first send the relevant metadata to you. You can then upload it via the WorkOS Dashboard by navigating to the Organization and selecting the specific Connection. ![WorkOS Dashboard UI manually configuring a connection's Entity ID, IdP URL, and X509 certificate](https://images.workoscdn.com/images/5002b5ca-d94e-40a9-9dec-71575ba24a91.png?auto=format&fit=clip&q=90) --- ## SAML Request Signing Certificate When the SP sends a SAML request, the IdP must verify that the request is actually coming from the SP and has not been tampered with by an unauthorized third party. IdP’s choose to handle this verification in different ways, and some use a SAML request signing certificate. Microsoft AD FS SAML uses a relying party trust, which is similar to a SAML request signing certificate, and the concepts covered in this article are applicable. In WorkOS, Connections that take advantage of a request certificate will expose an SP metadata URL that can be sent to the IdP in order to give it access to the signing certificate. ### Sample scenario Once again, let’s consider the fictional SaaS company _HireOS_, which offers recruiting software to other businesses. _HireOS_ is referred to as the SP by SAML. _HireOS_’ newest enterprise customer is called _Enterprise Corp_. _Enterprise Corp_ IT admins need recruiters and other employees who will use _HireOS_ to log in using _Enterprise Corp_'s identity provider, Okta. Okta is one of many companies known as an IdP to SAML. ### Verifying the SAML request In SP initiated SSO, _HireOS_ will first send a SAML request to Okta SAML. If a request certificate is being used, then the X.509 certificate along with a signing signature will be attached to the request. Upon receiving the request, Okta SAML will verify that the request came from _HireOS_ by decrypting the signature using the public key on the X.509 certificate and confirming the hash values match. ![SAML Request Diagram](https://images.workoscdn.com/images/6f244bd0-3f76-434f-99c3-be8bcf65d3da.png?auto=format&fit=clip&q=80)[border=false] ### Planning considerations When planning your SAML integration, there are a few things to consider related to SAML request signing certificates. ### Certificate expiration Your SAML request signing certificate will eventually expire and must be kept up to date in order to maintain service. WorkOS will automatically update the request signing certificate on the SP metadata URL before it expires. It is up to your customer and their IdP to either monitor the SP metadata URL, or manually keep it up to date. If your company has a shared Slack channel with WorkOS, you will automatically be notified when the X.509 certificate on the SP metadata URL is updated, so that you can check with your customer that they have the latest metadata. ### Monitored metadata versus manual upload There are potentially two options for your customer to upload SP metadata, and will vary based on their IdP. In both cases, you will need to provide your customer with the SP metadata URL, which can be found in the WorkOS Dashboard by going to Organizations, selecting the Organization, and then selecting the Connection. ![WorkOS Dashboard UI with SP metadata URL](https://images.workoscdn.com/images/5bab9063-e0cd-4bca-abe6-68db5162be5e.png?auto=format&fit=clip&q=90) ### Monitored metadata To streamline this process, your customer instead may choose to monitor our SP metadata URL. Their IdP will regularly check our URL for updates to the metadata. When WorkOS makes an update, such as refreshing an X.509 certificate that is expiring soon, their IdP will automatically make the change. ### Manual upload Your customer can manually download the SP metadata document from the URL, extract the certificate, and upload it to their IdP. When the certificate is getting ready to expire, they can repeat this process to give their IdP the most up to date certificate. ## Implementing SSO with WorkOS This document offers guidance to integrate Single Sign-On with our standalone API into your existing auth stack. You might also want to look at [AuthKit](/authkit), a complete authentication platform that leverages Single Sign-On functionality out of the box, following best practices. ### Sign-in Consent Learn about the sign-in consent screen, an extra layer of protection against login CSRF attacks and phishing attempts. The sign-in consent screen is an extra layer of protection against login CSRF attacks or phishing attempts. A user may click a link that appears legitimate, but which unknowingly leads them to signing in through a malicious identity provider controlled by an attacker. The sign-in consent screen mitigates this risk by displaying the user's email and the identity provider's domain, ensuring the user is aware of how they are signing in to the application. ## How it works The sign-in consent screen is an interstitial page that appears during the Single Sign-on flow, after the user has gone through the identity provider (IdP), before redirecting to the application. ![Sign-in consent screen](https://images.workoscdn.com/images/32760d6d-eb42-480f-92bc-fe6d2e8709ea.png?auto=format&fit=clip&q=80) This page displays to the user the `email` returned from the IdP, as well as the IdP origin. With this information, the user must either consent to or deny the sign-in flow. - **Consenting sign-in** leads to completing the SSO flow, where the authorization code is forwarded to the application callback. - **Denying the sign-in** will result in an SSO session failure and the user will be redirected to the application callback with a `signin_consent_denied` error. ## Enabling sign-in consent In order to activate the sign-in consent protection, you should go to the **Authentication** section and enable the sign-in consent checkbox in the Single Sign-On settings. ![Enable sign-in consent checkbox](https://images.workoscdn.com/images/0ab5bb9f-6acb-45d0-a351-468a7e57a428.png?auto=format&fit=clip&q=80) ## Handling the `signin_consent_denied` error We recommend using the `signin_consent_denied` error code to display useful information to the user, so that they can contact their admin and your support team for information about a possible phishing attempt. When a user denies the sign-in consent, your application's callback will receive an error response: ```url title="Redirect URI with signin_consent_denied error" https://your-app.com/callback?error=signin_consent_denied&error_description=User%20cancelled%20the%20authentication%20request&state=123456789 ``` For more information about error handling, see the [Get Authorization URL error codes](/reference/sso/get-authorization-url/error-codes) documentation. ## When sign-in consent is displayed WorkOS determines whether the sign-in consent screen should be displayed, based on the identity provider, user fingerprint, and SSO flow parameters. Once a user accepts the sign-in consent screen, the system remembers this approval and avoids displaying the page again for a better user experience. The sign-in consent screen is always displayed in the following scenarios: - **IdP-initiated flows**: The sign-in consent screen is always displayed for IdP-initiated flows (i.e. users clicking on a tile in their IdP), regardless of the identity provider, if the user has not previously approved it. - **Custom SAML or OIDC connections**: The sign-in consent screen is displayed for custom connections if the user has not previously approved sign-in consent. ## Branding The sign-in consent screen automatically inherits the Admin Portal branding and is served through your custom authentication API domain, if available. Ensure you review the primary button color and logos before enabling this feature. This ensures a trusted experience for your customers. ## Availability The sign-in consent is currently only available for Enterprise SSO users, not AuthKit. > If you're using AuthKit and would like to enable the sign-in consent screen, please reach out to [WorkOS support](mailto:support@workos.com). ### SAML Security Considerations Learn about additional SAML features that WorkOS supports. SAML requests and responses each have their own unique confidentiality and integrity features. To use [SAML](/glossary/saml) with WorkOS, the only requirement is that the Identity Provider ([IdP](/glossary/idp)) signs the assertions within the SAML authentication response. However, you may have customers that have stricter configuration requirements or you may simply want to raise the security bar by following recommendations. This document details what security features are available, how they can benefit you, your customer and their identity provider. The parties involved in a SAML authentication request and response flow are: - Identity Provider - Service Provider ([SP](/glossary/sp)) - User Agent, i.e. a browser --- ## SAML Binding Methods WorkOS uses the HTTP Redirect binding to transmit SAML authentication requests from the SP to the IdP, and the HTTP POST binding to receive SAML responses from the IdP back to the SP: - Redirect binding sends the request via HTTP GET, with the SAML message included in the URL. - POST binding delivers the response via HTTP POST, with the SAML message in the form body. --- ## SP to IdP security features The SAML authentication request is a way for the SP to request confirmation that the user they're presented with is who they're claiming to be. It is relayed to the IdP via the user agent. ![SAML authentication request options](https://images.workoscdn.com/images/dc5df10c-50dc-4bb0-bede-26d16b197f20.png?auto=format&fit=clip&q=80) ### SAML request signing To address the opportunity to spoof or tamper with a SAML request to the IdP, the IdP may require that all SP's sign the request. To accommodate this there needs to be a pre-existing relationship between the SP and IdP where a key-pair is shared. The IdP holds the public key (for verifying the request) and the SP holds the private key (for signing the request). WorkOS recommends SAML request signing, this is especially important in cases where HTTPS is terminated or interrupted prior to reaching the IdP. All of our requests embed the `` timestamp to allow the IdP to reject stale requests, however to mitigate tamper of this value request signing must be used.\ (See [SAML 2.0 Security Considerations](https://docs.oasis-open.org/security/saml/v2.0/saml-sec-consider-2.0-os.pdf) sections 5.2.1.2, 6.5.1 for more detail). | Supported by WorkOS | Enabled by default | Usage recommendation | | ------------------- | ------------------ | --------------------------------- | | Yes | No | Use with any IdP that supports it | WorkOS supports SAML request signing for all compatible connection types. Please [contact WorkOS support](mailto:support@workos.com) to enable it. --- ## IdP to SP security features The SAML response is an XML document provided by an IdP containing details about a user so that an SP can authenticate them. It is relayed to the SP via the user agent. ![SAML authentication response options](https://images.workoscdn.com/images/f888365e-fa7d-4c1e-a76d-a19777e6cbb2.png?auto=format&fit=clip&q=80) For reference in understanding the following features, below is a simplified hierarchy of the XML elements in a SAML Response: ```xml title="SAML response" ``` ### Signed response assertions This is **required** by WorkOS for all SAML connections. It is a core requirement for SAML IdPs to implement as of SAML 2.0 (see [SAML 2.0 Profiles](https://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf) section 4.1.3.5). | Supported by WorkOS | Enabled by default | Usage recommendation | | ------------------- | ------------------ | --------------------------------------- | | Yes | Yes | All WorkOS SAML connections must use it | Signed response assertions are enabled in the setup steps when you [create a SAML connection](/integrations/saml). ### Signed response message envelope This is the complete signature over the SAML response payload. In combination with an assertion signature it will provide additional integrity protection and is recommended by WorkOS (For details on threats addressed see [SAML Security Considerations](https://docs.oasis-open.org/security/saml/v2.0/saml-sec-consider-2.0-os.pdf) sections 7.1.1.6, 7.1.1.7). | Supported by WorkOS | Enabled by default | Usage recommendation | | ------------------- | ------------------ | --------------------------------- | | Yes | No | Use with any IdP that supports it | Please [contact WorkOS support](mailto:support@workos.com) to enable signed response message envelope. ### Encrypted response assertion The SAML assertions in the SAML response may contain sensitive data, and therefore there is an option to encrypt them to preserve confidentiality. This feature is recommended in scenarios where the SAML response travels through HTTPS termination, so that accidental logging of sensitive data can be mitigated. | Supported by WorkOS | Enabled by default | Usage recommendation | | ------------------- | ------------------ | --------------------------------- | | Yes | No | Use with any IdP that supports it | Please [contact WorkOS support](mailto:support@workos.com) to enable encrypted response assertion. ### Encrypted response attributes The attribute statement is a sub-element of the assertion, some or all of the attributes in the statement can be encrypted as part of the SAML authentication protocol. | Supported by WorkOS | Enabled by default | Usage recommendation | | ------------------- | ------------------ | ------------------------------------ | | No | No | Use **encrypted assertions** instead | WorkOS does not currently support encrypted response attributes. It is recommended to use assertion encryption to envelope all the attributes if confidentiality is required. ## Implementing SSO with WorkOS This document offers guidance to integrate Single Sign-On with our standalone API into your existing auth stack. You might also want to look at [AuthKit](/authkit), a complete authentication platform that leverages Single Sign-On functionality out of the box, following best practices. ### Redirect URIs Learn what a redirect URI is and how it relates to Service Provider and Identity Provider initiated login flows. ## Introduction With a [WorkOS Service Provider (SP) initiated login flow](/sso), there are a series of exchanges that take place between a Service Provider (your application), WorkOS, and the IdP that’s being used to authenticate the user as shown in the diagram below. The [Redirect URI](/glossary/redirect-uri) is the location to which the user gets returned to after successfully completing the authentication with their [Identity Provider (IdP)](/glossary/idp). With an Identity Provider (IdP) initiated login flow, the approach is similar but the user will begin the login flow by clicking on the tile within their IdP platform instead of from your application. ![Authentication Flow Diagram](https://images.workoscdn.com/images/90b84f08-3363-446a-8610-f7b2bd2ee2ca.png?auto=format&fit=clip&q=80) In WorkOS Production Environments, the Redirect URI to your application cannot use HTTP or localhost, however, Redirect URIs that use HTTP and localhost are allowed in Sandbox Environments. There should be at least one redirect URI configured and selected as a default for a WorkOS Environment. This can be done from the [Redirects](https://dashboard.workos.com/redirects) page in the WorkOS dashboard. If you try to route the authorization flow to a Redirect URI that is not yet defined in the Dashboard it will result in an error and users will be unable to sign in, so it’s important to define them in the dashboard first. ![Dashboard Redirect URIs](https://images.workoscdn.com/images/6da31d23-c823-4557-8403-b38b2700e4d2.png?auto=format&fit=clip&q=50) The Redirect URI can also be included directly in the Get Authorization URL call as a redirect_uri parameter. When the Redirect URI is set in this fashion, it will override the default Redirect URI that is set in the WorkOS Dashboard. --- ## Wildcard characters WorkOS supports using wildcard characters in Redirect URIs. ![Dashboard updating the redirect URIs to use a wildcard in staging](https://images.workoscdn.com/images/12f99da0-ef62-4b09-acf8-b3d05b48f9e3.png?auto=format&fit=clip&q=50) The `*` symbol can be used as a wildcard for subdomains; however, it must be used in accordance with the following rules in order to properly function. - The protocol of the URL **must not** be `http:` in production environments. - The sole exception is the use of `http://127.0.0.1` in production environments to support native clients. - The wildcard **must** be located in a subdomain within the hostname component. For example, `http://*.com` will not work. - The wildcard **must** be located in the subdomain which is furthest from the root domain. For example, `https://sub.*.example.com` will not work. - The URL **must not** contain more than one wildcard. For example, `https://*.*.example.com` will not work. - A wildcard character **may** be prefixed and/or suffixed with additional valid hostname characters. For example, `https://prefix-*-suffix.example.com` will work. - A URL with a valid wildcard **will not** match a URL more than one subdomain level in place of the wildcard. For example, `https://*.example.com` will not work with `https://sub1.sub2.example.com`. - In production environments, wildcards cannot be used with [public suffix domains](https://publicsuffix.org). For example, `https://*.ngrok-free.app` will not work. - The wildcard will match a sequence of letters (`A` – `Z`, `a` – `z` ); digits (`0` – `9`), hyphens (`-`), and underscores (`_`). - A URL with a wildcard cannot be set as the default redirect URI. ## Implementing SSO with WorkOS This document offers guidance to integrate Single Sign-On with our standalone API into your existing auth stack. You might also want to look at [AuthKit](/authkit), a complete authentication platform that leverages Single Sign-On functionality out of the box, following best practices. ### Login Flows Learn the differences between SP‑initiated and IdP‑initiated SSO. The instructions in the [Quick Start guide](/sso) 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)](/glossary/idp) for authentication, via the WorkOS API. Alternatively, most users are able to start the process from the Identity Provider itself. Organizations will often provide an IdP dashboard where employees can select any of the eligible applications that they can access via the IdP, similar to the screenshot below. Clicking on a tile results in an IdP-initiated login flow, since the user initiates the login from the Identity Provider, not the application. ![Screenshot of the Okta dashboard](https://images.workoscdn.com/images/1489f46f-bbcd-4e47-a217-3a45f0f795aa.png?auto=format&fit=clip&q=50) --- ## SP-initiated SSO With an SP-initiated login flow, the user begins the authentication process from your application. You can control where the user will be redirected after login by specifying the `redirectURI` parameter when making the [Get Authorization URL](/reference/sso/get-authorization-url) call. Additionally, this call can take an optional `state` parameter - this parameter will be returned in the callback after authentication, where your application can use it to verify the validity of the response or to pass any state from the originating session. One common practice is to route requests from different Organizations to a single Redirect URI, but instead utilize the `state` parameter to deep link users into the application after the authentication is completed. ## Implementing SSO with WorkOS This document offers guidance to integrate Single Sign-On with our standalone API into your existing auth stack. You might also want to look at [AuthKit](/authkit), a complete authentication platform that leverages Single Sign-On functionality out of the box, following best practices. ### Launch Checklist Make sure you’re ready to take your app to production. ## Implement complementary enterprise features - Integrate the WorkOS [Admin Portal](/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. ### Before you start This document offers guidance to integrate Single Sign-On with our standalone API into your existing auth stack. You might also want to look at [AuthKit](/authkit), a complete authentication platform that leverages Single Sign-On functionality out of the box, following best practices. ## Create 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 redirect requests, you can use the IP Ranges listed in the [Cloudflare documentation](https://www.cloudflare.com/ips/). ## Go-live checklist - [ ] Implement an SSO UI/UX. See our guide for ideas – [UI/UX Best Practices for IdP & SP-Initiated SSO](https://workos.com/blog/ui-ux-best-practices-for-idp-and-sp-initiated-sso) - [ ] [Test the end-to-end SSO](/sso/test-sso) experience in your Staging environment. - [ ] Unlock your Production environment by adding your billing information > Only enterprise connections in your Production environment will be charged. OAuth 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`. - [ ] Add Connections for your customers in the Production Environment ## 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](/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`, and `lastName`. ### 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](/reference/organization-domain) 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. ### How do I integrate WorkOS SSO with my native mobile application? When it comes to mobile applications, our typical advice in implementing SSO authentication goes like this: 1. Generate the authentication URL and route the user to a browser or browser fragment in order to authenticate. 2. The end user authenticates via the native UI of their IdP within that browser. 3. Upon successful authentication, deep-link the user back into your native application. ### Just-In-Time User Provisioning Learn how to provision users in your app using Just-In-Time user provisioning. ## Introduction User provisioning is the process of creating a user account and associated identity information. There are various ways for an application to provision users. This guide explores user provisioning strategies and offers a deep dive into SSO-based just-in-time (JIT) user provisioning. ## Definitions **User provisioning** : Provisioning is the process of creating a user and setting attributes for them inside an app. **JIT user provisioning** : Just-in-time user provisioning creates a user in an app when the user attempts to sign in for the first time. The account and respective role don’t exist until the app creates them – just-in-time. **Identity** : An identity is a collection of attributes associated with a user or entity in an identity provider. For example, an identity includes at least one unique identifier, such as id, and user profile attributes, such as name and email. **Role** : A primitive in your app that defines specific permissions for the users. Roles are often defined as an ability or a job title, for example, “Editor” or “Accountant”. ## User provisioning strategies User provisioning is the process of creating a user account with associated identity data in your app. Your app needs to determine a unique identifier for an identity, create a unique account for that user, and link the identity profile attributes to that user’s account. There are many strategies to provision users in an app, but the main three are: 1. Self-registration 2. Provisioning users via [Directory Sync](/directory-sync) 3. JIT provisioning via SSO The type of provisioning needed will depend on your app’s architecture and level of enterprise feature support: | Strategy | Description | Usage | | ---------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | | Self-registration | Users fill out a registration form to create an account in the app | For users that don’t have an SSO service, usually the first authentication mechanism built in an app | | Pre-provisioning users | Use a service like Directory Sync to create users in the app | Required by large enterprises to automatically provision users | | JIT provisioning | Create a user account when a user signs in via SSO for the first time | Leverage user identity from an SSO provider to create an account in your app | ## What is JIT provisioning? JIT provisioning creates a user account with associated identity information when a user authenticates via SSO for the first time. IT admins often use JIT provisioning to quickly set up accounts in an app. Typically, apps that implement only SSO will have JIT provisioning support as the alternative is self-registration by individual users or manual entry of all users by the IT admin. ### Sample scenario Consider the fictional SaaS company _HireOS_, which offers recruiting software to other businesses. _HireOS_ is an online app allowing customers to track leads, candidates, and interviews. _HireOS_ has integrated SSO using WorkOS and supports JIT provisioning. For example, a _HireOS_ customer would like their users to have accounts automatically provisioned in _HireOS_ when they first log in. The customer’s IT admin will only need to assign the users to the _HireOS_ SAML app in their identity provider. When users log into _HireOS_ via SSO, they will have accounts created in _HireOS_, just in time. A usual account setup flow using JIT provisioning follows these steps: 1. An IT admin self-registers via username and password to create a team account in _HireOS_. 2. The IT admin configures the _HireOS_ team account to use SSO as the authentication mechanism. 3. The IT admin enables JIT provisioning for this team account by clicking the "Enable JIT Provisioning" checkbox. 4. The IT admin adds the users that should get access to _HireOS_ to the app in the identity provider. 5. When a user logs into _HireOS_ with the correct email domain and authenticates via SSO, _HireOS_ creates the user account upon successful first-time login. ## JIT provisioning with WorkOS SSO When a user authenticates to your app via SSO for the first time, and JIT provisioning is enabled, your app provisions a new user account. You can create the account by saving the identity information (the WorkOS SSO profile) directly on your app's user account. Or, you can create a separate identity from the WorkOS SSO profile related to this new user account. This logic allows users to have multiple identities if your app supports several login methods per user. You can use the WorkOS SSO profile `id` attribute as the unique identifier for this identity from WorkOS. WorkOS ensures the profile is unique per SSO connection via the `idp_id`. In addition, your app can use either the `connection_id` or `organization_id` to tie the identity to a team account. ```json language="json" title="SSO user profile" { "object": "profile", "id": "prof_01DMC79VCBZ0NY2099737PSVF1", "connection_id": "conn_01E4ZCR3C56J083X43JQXF3JK5", "connection_type": "OktaSAML", "organization_id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY", "email": "todd@example.com", "first_name": "Todd", "last_name": "Rundgren", "idp_id": "00u1a0ufowBJlzPlk357", "role": { "slug": "admin" }, "raw_attributes": {} } ``` You may want to grant new users roles in your application via JIT provisioning. For more information on mapping role data between the IdP and your app, see the [Mapping Roles](/sso/identity-provider-role-assignment) guide. ### New account creation When your app receives a WorkOS SSO profile, it is standard to perform the following series of checks: 1. Find an identity with the profile `id` or `idp_id`. If found, log in the corresponding user. 2. If you cannot find an identity, try to find a user with the same `email` as the profile. If found, create an identity for the user and log them in. 3. Otherwise, create a new identity using the WorkOS SSO profile, create a new user, and associate this identity with the user account. ### Linking an existing user If an admin adds SSO authentication to their team account after they've had users register, your app can link these new SSO identities to the current user accounts, just-in-time. A linking field (e.g. `email`) should be established to find a current user with the incoming WorkOS SSO Profile. Then, the identity information can be linked with the existing user account via a persistent identifier in case of an email change later. ## Implementing SSO with WorkOS This document offers guidance to integrate Single Sign-On with our standalone API into your existing auth stack. You might also want to look at [AuthKit](/authkit), a complete authentication platform that leverages Single Sign-On functionality out of the box, following best practices. ### FAQ for IT teams Answers to common questions from your customer’s IT team. ## What is WorkOS? WorkOS is a software company that provides a suite of products to make an app enterprise-ready. These products include Single Sign-On, Directory Sync, and AuthKit (user management), among others. Developers integrate WorkOS services into their apps in order to provide a secure authentication and user provisioning experience. It’s trusted by companies like Webflow, Plaid, Vercel, and many others. ## What data does WorkOS store? For Single Sign-On, WorkOS stores the user profile from the identity provider. This includes the user's name, email and IP address. For Directory Sync, WorkOS will store the data that the identity provider sends. The shape and content of that data is at the discretion of the identity provider. For more information, view our [Privacy Policy](https://workos.com/legal/privacy) ## How do developer apps communicate with WorkOS? Developers integrate with WorkOS using its Rest API and the related SDKs. You can find a list of all WorkOS API endpoints in the [API reference](/reference). ## What IP addresses does WorkOS use? WorkOS uses Cloudflare to ensure security and reliability of all operations. If you are looking to create a list of allowed IP addresses for the WorkOS API, you can use the IP ranges listed in the [Cloudflare documentation](https://www.cloudflare.com/ips/). ## Is WorkOS certified for SOC 2 Type II, SOC 3 and SIG Lite? Yes, WorkOS is compliant with all the above and regularly undergoes penetration testing. ## Is WorkOS GDPR compliant? Yes, WorkOS is GDPR compliant. Reach out to [support](mailto:support@workos.com) to request deletion of data. ### Single Sign-On Facilitate greater security, easier account management, and accelerated application onboarding and adoption. ## Choose your integration approach There are two ways to integrate Single Sign-On (SSO) with WorkOS: ### (A) With the standalone SSO API The standalone API (covered in this document), is a standalone API for integrating into an existing auth stack. ### (B) Using WorkOS AuthKit [AuthKit](/authkit) is a complete authentication platform which includes SSO out of the box. ## How Single Sign-On works Single Sign-On is the most frequently asked for requirement by organizations looking to adopt new SaaS applications. SSO enables authentication via an organization’s [identity provider (IdP)](/glossary/idp). This service is compatible with any IdP that supports either the [SAML](/glossary/saml) or [OIDC](/glossary/oidc) protocols. It’s modeled to meet the [OAuth 2.0](/glossary/oauth-2-0) framework specification, abstracting away the underlying authentication handshakes between different IdPs. ![Authentication Flow Diagram](https://images.workoscdn.com/images/90b84f08-3363-446a-8610-f7b2bd2ee2ca.png?auto=format&fit=clip&q=80)[border=false] WorkOS SSO API acts as authentication middleware and intentionally does not handle user database management for your application. ## 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. ## Before getting started To get the most out of this guide, you’ll need: - A [WorkOS account](https://dashboard.workos.com/) - A local app to integrate SSO with. Reference these [example apps](/sso/example-apps) as you follow this guide. ## API object definitions [Connection](/reference/sso/connection) : The method by which a group of users (typically in a single organization) sign in to your application. [Profile](/reference/sso/profile) : 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 build the SSO authentication workflow into your app. ### Install the WorkOS SDK WorkOS offers native SDKs in several popular programming languages. Choose a language below to see instructions in your application’s language. ### Set secrets To make calls to WorkOS, provide the API key and, in some cases, the client ID. Store these values as managed secrets, such as `WORKOS_API_KEY` and `WORKOS_CLIENT_ID`, and pass them to the SDKs either as environment variables or directly in your app’s configuration based on your preferences. ```plain title="Environment variables" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' ``` > The code examples use your staging API keys when [signed in](https://dashboard.workos.com) ### Add an endpoint to initiate SSO The endpoint to initiate SSO via the WorkOS API is responsible for 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. - | Using organization ID Use the organization parameter when authenticating a user by their specific organization. This is the preferred parameter for SAML and OIDC connections. The example below uses the Test Organization that is available in your staging environment and uses a mock identity provider. It’s created to help you test your SSO integration without having to go through the process of setting up an account with a real identity provider. - | Using connection ID You can also use the connection parameter for SAML or OIDC connections when authenticating a user by their connection ID. - | Using provider The provider parameter is used for OAuth connections which are configured at the environment level. > The supported `provider` values are `GoogleOAuth`, `MicrosoftOAuth`, `GitHubOAuth`, and `AppleOAuth`. If there is an issue generating an authorization URL, WorkOS will return the redirect URI as is. Read the [API Reference](/reference/sso/get-authorization-url) 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 returned by WorkOS with the authenticated user’s profile. The authorization code is valid for 10 minutes. When adding your callback endpoint, it is important to always validate the returned profile’s organization ID. It’s unsafe to validate using email domains as organizations might allow email addresses from outside their corporate domain (e.g. for guest users). --- ## (2) Configure a redirect URI Go to the [Redirects](https://dashboard.workos.com/redirects) page in the dashboard to configure allowed redirect URIs. This is your callback endpoint you used in the previous section. Multi-tenant apps will typically have a single redirect URI specified. You can set multiple redirect URIs for single-tenant apps. You’ll need to be sure to specify which redirect URI to use in the WorkOS client call to fetch the authorization URL. > More information about wildcard characters support can be found in the [Redirect URIs](/sso/redirect-uris/wildcard-characters) guide. ![Redirects in the Dashboard](https://images.workoscdn.com/images/195dbff3-adbf-4010-b07c-ffc73ceeca68.png?auto=format&fit=clip&q=90) ### Identity provider-initiated SSO Normally, the default redirect URI you configure in the WorkOS dashboard is going to be used for all identity provider-initiated SSO sessions. This is because the WorkOS client is not used to initiate the authentication flow. However, your customer can specify a separate redirect URI to be used for all their IdP-initiated sessions as a `RelayState` parameter in the SAML settings on their side. Learn more about configuring IdP-initiated SSO in the [Login Flows](/sso/login-flows/idp-initiated-sso/configure-idp-initiated-sso) guide. --- ## (3) Test end-to-end If you followed this guide, you used the Test Organization available in your staging environment to initiate SSO. With that, you can already test your integration end-to-end. ![Test SSO WorkOs Dashboard](https://images.workoscdn.com/images/7b7407d7-dcc7-4fd4-859f-4ee4214d69c2.png?auto=format&fit=clip&q=80) Head to the _Test SSO_ page in the [WorkOS Dashboard](https://dashboard.workos.com/) to get started with testing common login flows, or read on about that in detail in the next guide. ### Identity Provider Role Assignment Learn how to map role data from identity providers to roles in your app with SSO. ## Introduction A role represents a logical grouping of permissions, defining access control levels for users within your application. Roles are identified by a unique, immutable slug and are assigned to [SSO user profiles](/reference/sso/profile) through their identity provider group memberships. These group role mappings can be configured on the WorkOS dashboard. To utilize Identity Provider (IdP) role assignment, you must first [configure roles](/rbac/configuration). ## SSO group role assignment Users are assigned to groups via the identity provider. Groups usually correspond to roles in your app. Therefore, IT admins will often map a group one-to-one to a role. During authentication, a user's identity provider group memberships can be read via attributes. This enables you to define SSO groups that correspond to IdP groups and set role assignments for those groups in the WorkOS Dashboard. Based on these settings, SSO user profiles returned from WorkOS will include a role attribute that reflects their highest priority group membership. The SSO user profile role is calculated during each sign-in. ![Session page showing user profile with role defined](https://images.workoscdn.com/images/ceea13ba-bf6b-4ea1-a25c-0a08e8833fb0.png?auto=format&fit=clip&q=50) > Supported in both SAML and OIDC-based connection types, except for Google OIDC due to [a limitation](https://issuetracker.google.com/issues/133774835?pli=1) with the groups claim. ### Sample scenario Consider the fictional SaaS company _HireOS_. _HireOS_ has set up an SSO Connection and configured group-based role assignment. For example, a _HireOS_ customer would like to assign their engineering team to the application. The customer’s IT admin would take the following steps: 1. Create an “Engineering” group using their identity provider. 2. Configure the `groups` attribute in their SAML app to return the group memberships. 3. Provide the developer with the IdP ID for the "Engineering" group. In the WorkOS dashboard, the developer can then assign users of that group to the role "Engineer". 1. Navigate to the _Connection_ section of the WorkOS dashboard. ![SSO group role assignment card](https://images.workoscdn.com/images/28606b9b-fd5b-4219-8b8f-3a640295e784.png?auto=format&fit=clip&q=50) 2. Create an SSO group defining the IdP ID for the "Engineering" group. Then, assign this group to the "Engineer" role. ![Dialog to create connection group with role assignment](https://images.workoscdn.com/images/648410f3-1b82-4ebd-97f3-a8f6edbdd27e.png?auto=format&fit=clip&q=50) From this point on, whenever a user in the "Engineering" group authenticates via SSO, they will be granted the "Engineer" role for that session from the WorkOS API. The role will be returned in the [profile response](/reference/sso/profile). ```json language="json" title="SSO user profile" { "object": "profile", "id": "prof_01DMC79VCBZ0NY2099737PSVF1", "connection_id": "conn_01E4ZCR3C56J083X43JQXF3JK5", "connection_type": "OktaSAML", "organization_id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY", "email": "todd@example.com", "first_name": "Todd", "last_name": "Rundgren", "idp_id": "00u1a0ufowBJlzPlk357", "role": { "slug": "engineer" }, "roles": [ { "slug": "engineer" }, ] "raw_attributes": {} } ``` > When a user is not a member of any groups or their groups do not match any SSO group role assignments, the user will be granted the [default role](/rbac/configuration/configure-roles/default-role) in the SSO profile. ### Multiple roles When [multiple roles is enabled](/rbac/configuration/configure-roles/multiple-roles), a user can be assigned multiple roles from their identity provider group memberships. If a user belongs to multiple mapped groups, they will receive all corresponding roles in their SSO profile. For example, if a user is a member of both "Engineering" and "Design" groups, and both groups are mapped to roles, the user will receive both the "Engineer" and "Designer" roles. If a user is not a member of any groups with explicit mappings, they will receive the [default role](/rbac/configuration). #### Use cases By default, multiple roles is disabled and users can only have a single role per entity. It's recommended to start with a single-role setup for simplicity, where it's easier to maintain consistent and correct access patterns. You might want to enable multiple roles when you need: - **Cross-department collaboration**: e.g., designers who need some engineering permissions. - **Additive, disjoint permissions**: independent permission sets that should stack. - **Temporary access**: grant time-bound extra capabilities without creating hybrid roles. ### Role assignment in Admin Portal Once [roles](/rbac/configuration) are configured for your application, enable SSO group role assignment in [Admin Portal](/admin-portal) to allow IT admins to assign roles to groups during SSO connection setup. If enabled, all Admin Portal sessions for SSO connections will have the ability to configure and assign roles to groups. ![Enable SSO group role assignment dashboard setting](https://images.workoscdn.com/images/04f86ccc-87a1-4db6-bd54-54a685d409ef.png?auto=format&fit=clip&q=50) This is an environment-level setting, but can be configured per organization via the _Roles_ tab under an organization in the WorkOS Dashboard. ## Considerations Your customers will store role information in different forms, depending on their preferred provisioning workflow. WorkOS allows for flexibility in how you source role data. However, there are some considerations to keep in mind when using SSO-based connection groups for role assignment. ### Drawbacks **Strictly** assigning roles during [JIT user provisioning](/sso/jit-provisioning) has a few caveats: - Your customer must explicitly map the SAML `groups` attribute in the SSO setup so that you can retrieve that attribute in the SSO profile. - SSO groups need to be manually defined. - Your app will receive updates to this user’s group data only once they sign-in with SSO again. This delay can allow unauthorized users to access resources using a stale role. ### Directory group role assignment Directory Sync supports [group-based role assignment](/directory-sync/identity-provider-role-assignment/directory-group-role-assignment) and avoids the pitfalls mentioned above. For organizations with a directory, this method of group-based role assignment is preferred. It’s recommended to use only one method of role assignment—either from a Directory or an SSO Connection—to avoid overlap. ### Example Apps View sample Single Sign-On apps for each SDK. You can view minimal example apps that demonstrate how to use the WorkOS SDKs to authenticate users via SSO: ### Domains Understand how Organization domains are used with SSO. ## Organizations When an [Organization](/reference/organization) is created in the WorkOS Dashboard or the [Create Organization API](/reference/organization/create), one or more domains can be associated with the organization. Domains added to an organization need to be verified in order to activate SSO. When creating an organization via the API, domains can be initially added as either `'verified'` if already trusted, or `'pending'` if further verification is required. If added as `'pending'`, the domain can later be verified manually via the [Domain Verification API](/domain-verification/api) or WorkOS Dashboard, or by an IT admin via the self-serve [Admin Portal](/domain-verification/) flow. > Domains manually added in the WorkOS Dashboard are automatically considered verified. ## Email validation During authentication, WorkOS uses these domains to verify the user signing in through the organization's [Connection](/reference/sso/connection) belongs to one of these domains. If the domain of the user's email address does not match one of the organization's domains (or the organization has no verified domains) they will be sent to your [Redirect URI](/sso/redirect-uris) with a [`profile_not_allowed_outside_organization`](/reference/sso/get-authorization-url/error-codes) error. Rejecting users with non-matching email domains prevents the impersonation of users in other organizations. This would otherwise be possible since many Identity Providers allow IT admins to create user accounts with _any_ email address, regardless of whether the IT admin actually controls the email address or its domain. For example, an IT admin of an organization with the domain `foo.com` can create a user account for `user@bar.com` in their Identity Provider and then sign in as that user. If the application were to receive the profile and naively look up the user record using _only_ the email address, then the IT admin will have gained access to the `user@bar.com` account. Since WorkOS cannot guarantee every application handles this scenario correctly, **the default behavior is to reject profiles when its email address does not match the associated organization's domains.** ## Allowing any domain Some applications may have organizations whose users sign in using a list of domains that cannot be statically defined, or a set of domains so large as to be cumbersome to configure. A common use-case is non-domain guests. Imagine an organization hires a design consultancy and requires the designers to sign in using the organization's IdP. While the organization can create accounts in their IdP for these guests, they cannot add the designer's domain to the WorkOS organization since they cannot verify ownership of it. The default organization domain verification policy will prevent these designer's from signing in. If your application has a similar use-case, [contact support](mailto:support@workos.com) and we can work with you to relax the default organization domain verification policy. SSO will no longer require any domains to be added to the organization. This change can be made for any of your environments and will affect all organizations in the environment. ## Implement profile validation Your application will be responsible for validating the email addresses of users using SSO, and checking the appropriate fields from the SSO profile. Important data from the SSO profile includes the `id` and the `organization_id`. Generally applications will store the Profile `id` alongside its users, such as a column on a `users` table. Similarly, the `organization_id` will be stored on the matching entity, such as a `teams` or `workspace` table; whichever represents a collection of users that are related to each other. ```json language="json" title="SSO profile" { "object": "profile", "id": "prof_01DMC79VCBZ0NY2099737PSVF1", "connection_id": "conn_01E4ZCR3C56J083X43JQXF3JK5", // Your application should restrict any email-based JIT user // provisioning to within the organization that matches this ID. "organization_id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY", // Only match based on email or email domain unless you are // filtering potential matches by the organization ID above. "email": "todd@example.com" // ... } ``` Here's an updated version of the WorkOS callback endpoint from the [Quick Start guide](/sso/1-add-sso-to-your-app/add-a-callback-endpoint) with examples of these checks added: ```javascript langauge="JavaScript" title="WorkOS callback" const { WorkOS } = require('@workos-inc/node'); const workos = new WorkOS(process.env.WORKOS_API_KEY); app.get('/callback', async (req, res) => { const { profile } = await workos.sso.getProfileAndToken({ code: req.query.code, clientId: process.env.WORKOS_CLIENT_ID, }); // Your application should have a resource that is analogous to the WorkOS // organization, like a "team" or "workspace". const team = TeamsService.findByWorkOsOrganizationId(profile.organizationId); if (!team) { return res.status(401).send({ message: 'Unauthorized', }); } // Your application should use the Profile ID to determine whether there is an // existing user linked to the SSO profile, within the scope of the "team" or // "workspace" associated with the WorkOS organization. // // If none is found, you can then fall back to the `email` address. If one is // found you should link the profile ID to the user for subsequent sign-ins. // // Finally, if no user exists with the email either, you can implement // JIT-provisioning and create a new user record, persisting both the `email` // and the ID from the profile. const { user } = team.users.findOrCreateByWorkOsProfile(profile); // Make sure to verify the user's email address. You may choose to skip // email verification in order to improve UX, but should only do so if // the new user's email address matches an expected domain for the "team". if (!user.emailVerified) { res.redirect('/verify-email'); } else { // Start a session for the user. // ... res.redirect('/'); } }); ``` > The above example makes use of JIT-provisioning, which you can read more about in more our dedicated [JIT-provisioning guide](/sso/jit-provisioning). With the above checks in place, your application can safely sign in and verify users through SSO from any domain. ## Custom ACS domains While your users will authenticate with SSO using your application, they might briefly see the WorkOS [ACS URL](/glossary/acs-url). This can be configured in the production environment to a custom domain of your choosing. For more information see the [Custom Domains](/custom-domains) documentation. ### Profile Attributes Configure how attributes map from identity providers to SSO Profiles. ## Introduction WorkOS automatically normalizes a standard set of attributes from identity providers (IdPs) into the [Single Sign-On (SSO) Profile](/reference/sso/profile) object. More unique cases can be mapped by your customer admins. In this guide, we’ll explain how to map data from identity providers to the SSO Profiles. ## Definitions **Standard attributes** : The most common user information, normalized across providers. **Predefined attributes** : Detailed user attributes for specific use cases, normalized across providers. You can opt-in to each attribute you'd like organization admins to map during SSO connection configuration. **Custom attributes** : For unique cases, you can create custom attributes your customers can map when setting up an SSO connection. ## Standard attributes Every SSO Profile comes with the following standard attributes. These are the core set of attributes that are common across all identity providers. These are structured fields with a guaranteed schema in the top-level SSO Profile payload. | Attribute | Description | | ------------ | ---------------------------------------------------------------------------------------------------------------------- | | `idp_id` | The user’s unique identifier, assigned by the identity provider. Different identity providers use different ID formats | | `email` | The user’s email | | `first_name` | The user’s first name | | `last_name` | The user’s last name | --- ## Custom attributes For more detailed user information, you can opt-in to additional predefined attributes and define your own custom attributes. These attributes will appear in the custom attributes field on [SSO Profile](/reference/sso/profile) objects and can be configured in the [WorkOS Dashboard](https://dashboard.workos.com/). ### Predefined attributes When enabled, organization admins will be asked to map these attributes during SSO configuration in [Admin Portal](/admin-portal). These fields are always optional if enabled. These fields are named and schematized by WorkOS – they cannot be renamed. | Attribute | Type and description | Status | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -------- | | `addresses` | The user’s list of address objects (`street_address`, `locality`, `region`, `postal_code`, `country`, `primary`, `raw_address`) | Optional | | `cost_center_name` | The user’s cost center name | Optional | | `department_name` | The user’s department name | Optional | | `division_name` | The user’s division name | Optional | | `emails` | The user’s list of email objects (`type`, `value`, `primary`) | Optional | | `employee_type` | The user’s employment type | Optional | | `employment_start_date` | The user’s start date | Optional | | `job_title` | The user’s job title | Optional | | `manager_email` | The email address for the user’s manager | Optional | | `username` | The user’s username | Optional | #### Enable or disable a predefined attribute Predefined attributes can be enabled or disabled in the [WorkOS Dashboard](https://dashboard.workos.com/) on the Identity Provider Attributes page. ![WorkOS Dashboard UI showing editing predefined attributes](https://images.workoscdn.com/images/73b775ed-c3ef-4c81-bb56-7b040d3d073a.png?auto=format&fit=clip&q=50) > For SSO Profiles, making changes to IdP attributes will take effect upon next sign-in. ### Custom attributes Custom attributes can be utilized to enrich SSO Profiles with additional data from the identity provider. You can create attributes that appear as fields in the [Admin Portal](https://workos.com/admin-portal). Your customers can map these fields to the correct values in their system when setting up SSO with their identity provider. #### Create a custom attribute Custom attributes can be created in the [WorkOS Dashboard](https://dashboard.workos.com/) on the Identity Provider Attributes page. ![WorkOS Dashboard UI showing custom attribute creation](https://images.workoscdn.com/images/c1d00c4c-4dea-415e-a8f8-c870317410df.png?auto=format&fit=clip&q=50) > For SSO Profiles, making changes to IdP attributes will take effect upon next sign-in. #### Delete a custom attribute When a custom attribute is deleted, [SSO Profiles](/reference/sso/profile) will retain these existing attribute values until the next sign-in. #### Editing attribute mappings If attribute data for a particular SSO connection has changed and is no longer mapped properly, you or the organization admin can edit the attribute mappings via the [WorkOS Dashboard](https://dashboard.workos.com/) connection page or [Admin Portal](https://workos.com/admin-portal), respectively. ![WorkOS Dashboard UI showing editing attribute mappings for a connection](https://images.workoscdn.com/images/09395b6c-d037-440f-a17e-ef0507868532.png?auto=format&fit=clip&q=50) ### Custom attribute mapping in Admin Portal You can control the visibility of custom attribute mapping for Directory Sync and Single Sign-On flows in the Admin Portal at the environment and organization level. The environment-level setting is controlled on the Identity Provider Attributes page in the [WorkOS Dashboard](https://dashboard.workos.com/). ![WorkOS Dashboard UI showing editing custom attribute mapping in Admin Portal setting](https://images.workoscdn.com/images/23ee5439-6cbb-4c18-ac39-0870d63bfc0b.png?auto=format&fit=clip&q=50) Organization-level settings are controlled on an individual organization's Attributes tab in the [WorkOS Dashboard](https://dashboard.workos.com/). Organizations mirror the environment-level settings by default. ## Frequently asked questions ### Which identity providers support mapping additional predefined and custom attributes? Additional predefined and custom attributes are supported for all SAML SSO connections. ### Can our customers add their own custom attributes outside of what is defined in the WorkOS Dashboard? We do not currently support this functionality. Custom attributes must be defined in the WorkOS Dashboard first. Please reach out to [support](mailto:support@workos.com) if you have a specific use case that you would like to discuss. ### What happens if an attribute cannot be mapped from the IdP? Attributes that cannot be mapped for a particular [SSO Profile](/reference/sso/profile) will result in a `null` value for the attribute. ### Sign-In UX User experience considerations for Single Sign-On. ## Introduction Now that we’ve seen how the Single Sign-On (SSO) APIs work, you may want to consider how to best integrate this new flow in the sign-in experience for your users. This guide will walk you through a few different approaches you could take in your application: - Separate SSO flow - Separate email and password fields - Auto-hide the password field Throughout this guide, let’s consider the following scenario: - You are building an app called _Demo App_ - An organization named _Foo Corp_ is using Single Sign-On with Okta as the [IdP](/glossary/idp) ### Implementing SSO with WorkOS This document offers guidance on UX best practices when integrating SSO with the standalone API. You might instead consider [WorkOS AuthKit](/authkit), a complete authentication platform which handles all of the UX complexity for you. ## Separate SSO flow A basic approach would be to create a link or button on your login page with a **Sign in with SSO** or **Use Single Sign-On** option. This method differentiates the flows for the user explicitly. You may still look up the domain if they try to sign in with their corporate email and redirect them to the appropriate flow too—see the demo below as an example. As this adds yet another button, one thing to be mindful with this approach is the [NASCAR problem](https://indieweb.org/NASCAR_problem) where a cluster of 3rd party branded buttons creates both visual noise and confusion. Consider only offering a couple of options that are relevant to your user base. ## Separate email and password fields Instead of asking users for their email and password in one screen, you could first ask them for their email. This method gives you an opportunity to check if a particular domain is SSO-enabled and redirect the user to the appropriate SSO flow. It is a very popular approach employed by many applications (including WorkOS itself, Apple, and Google). ## Auto-hide the password field Finally, as an extension to the previous approach, you can automatically hide the password field if the user’s domain is SSO-enabled. This feature is a bit more complicated to implement, but provides a more seamless experience for users. ## Sdks {#sdks} ### ruby ## Installation ### python ## Installation ### php ## Installation ### node ## Installation ### laravel ## Installation ### java ## Installation ### go ## Installation ### elixir ## Installation ### dotnet ## Installation ## API Reference {#reference} ### Testing the API --- # Testing the API You can test the API directly with cURL, or use the [Postman collection](https://www.postman.com/workos/workspace/workos-public/collection/25188762-79ce1172-4741-4f1d-a486-64380f9a599f?ctx=documentation) for convenience. > Check out the [guide](/postman) about the WorkOS API Postman collection to learn more about it. ### Rate limits --- # Rate limits WorkOS APIs are rate limited to ensure that they are fast for everyone. If you find yourself getting 429 errors, double check your integration to make sure you aren’t making unnecessary requests. ## General | Name | Path | Limit | | ------------ | ---- | -------------------------------------------- | | All requests | \* | 6,000 requests per 60 seconds per IP address | This rate limits applies to all environments, staging and production. Exceptions to the general rate limit are listed below. ## Single Sign-On | Name | Path | Limit | | ------------------------------------------------------------- | -------------- | -------------------------------------------- | | [Get Authorization URL](/reference/sso/get-authorization-url) | /sso/authorize | 1,000 requests per 60 seconds per connection | ## Directory Sync | Name | Path | Limit | | ----------------------------------------------------------- | ---------------- | ----------------------------------- | | [Directory Users](/reference/directory-sync/directory-user) | /directory_users | 4 requests per second per directory | ## Organizations | Name | Path | Limit | | ----------------------------------------------------- | ----------------- | -------------------------------------- | | [Delete Organization](/reference/organization/delete) | /organizations/\* | 50 requests per 60 seconds per API key | ## AuthKit Rate limiting for AuthKit APIs are enforced on a per environment basis. | Name | Path | Limit | | ----------------------------------------------------------- | -------------------------------------------- | ---------------------------------------------------- | | Reads | /user_management/\* | 1,000 requests per 10 seconds | | Writes | /user_management/\* | 500 requests per 10 seconds | | [Authentication](/reference/authkit/authentication) | /user_management/authenticate | 10 requests per 60 seconds per email or challenge ID | | [Magic Auth](/reference/authkit/magic-auth) | /user_management/magic_auth/send | 3 requests per 60 seconds per email | | [Email verification](/reference/authkit/email-verification) | /user_management/:id/email_verification/send | 3 requests per 60 seconds per user | | [Password reset](/reference/authkit/password-reset) | /user_management/password_reset/send | 3 requests per 60 seconds per email | ## Hosted AuthKit | Name | Limits | | ------------------------ | ---------------------------------------------------------- | | Reads | 1,000 requests per 10 seconds | | Writes | 500 requests per 10 seconds | | SSO sign-ins | 3 requests per 60 seconds per IP address | | Email sign-ins | 10 requests per 60 seconds per email and IP address | | Magic Auth sign-ins | 10 requests per 60 seconds per IP address and challenge ID | | Magic Auth code requests | 3 requests per 60 seconds per IP address and email | ### Pagination --- # Pagination Many top-level resources have support for bulk fetches via list API methods. For instance, you can [list connections](/reference/sso/connection/list), [list directory users](/reference/directory-sync/directory-user/list), and [list directory groups](/reference/directory-sync/directory-group/list). These list API methods share a common structure, taking at least these four parameters: `limit`, `order`, `after`, and `before`. WorkOS utilizes pagination via the `after` and `before` parameters. Both parameters take an existing object ID value and return objects in either descending or ascending order by creation time. ### organization-domain ## Organization Domain An Organization Domain (also known as a User Email Domain) represents an [Organization](/reference/organization)'s domain. These domains restrict which email addresses are able to sign in through SAML Connections when [allow profiles outside organization](/reference/organization) is `false`. This is the default behavior for Organizations. See [SSO frequently asked questions](/sso/launch-checklist/frequently-asked-questions) for more details on this behavior. Organization domains can be verified manually (through the API or the Dashboard), or through [a self-serve flow](/domain-verification) through the Admin Portal. The organization that defines this domain policy exerts authentication policy control over that domain across your application. For this reason, it is important to verify ownership of manually added domains. Additionally, WorkOS does not allow addition of common consumer domains, like `gmail.com`. ### API reference --- # API reference The WorkOS API enables adding Enterprise Ready features to your application. This REST API provides programmatic access to AuthKit (user management), Single Sign-On, Directory Sync, and Audit Log resources. [Sign in](https://dashboard.workos.com/) to see code examples customized with your API keys and data. ```url title="API Base URL" https://api_workos_com ``` ### idempotency ### Errors --- # Errors WorkOS uses standard HTTP response codes to indicate the success or failure of your API requests. 200 : Successful request. 400 : The request was not acceptable. Check that the parameters were correct. 401 : The API key used was invalid. 403 : The API key used did not have the correct permissions. 404 : The resource was not found. 422 : Validation failed for the request. Check that the parameters were correct. 429 : Too many requests. Refer to the [Rate Limits](/reference/rate-limits) section. 5xx : Indicates an error with WorkOS servers. ### Client libraries --- # Client libraries WorkOS offers native SDKs in several popular programming languages. Choose one language below to see our API Reference in your application’s language. ### API Authentication --- # API Authentication WorkOS authenticates your API requests using your account’s API keys. API requests made without authentication or using an incorrect key will return a `401` error. Requests using a valid key but with insufficient permissions will return a `403` error. All API requests must be made over HTTPS. Any requests made over plain HTTP will fail. You can view and manage your API keys in the [WorkOS Dashboard](https://dashboard.workos.com/api-keys). ## Secure your API Keys API keys can perform any API request to WorkOS. They should be kept secure and private! Be sure to prevent API keys from being made publicly accessible, such as in client-side code, GitHub, unsecured S3 buckets, and so forth. API keys are prefixed with `sk_`. ## In Staging Your Staging Environment comes with an API key already generated for you. Staging API keys may be viewed as often as they are needed and will appear inline throughout our documentation in code examples if you are logged in to your WorkOS account. API requests will be scoped to the provided key’s Environment. ## In Production Once you unlock Production access you will need to generate an API Key for it. Production API keys may only be viewed once and will need to be saved in a secure location upon creation of them. ### WorkOS Connect --- # WorkOS Connect WorkOS Connect is a unified interface that simplifies authentication and authorization across customers, partners, and external SaaS tools. Read more about [how Connect integrates with AuthKit here](/authkit/connect). ### userinfo ## User information Provides information about the [User](/reference/authkit/user) referenced by the access token’s `sub` claim. Which claims are returned depends on the scopes originally granted when the access token was issued. This endpoint is authenticated by providing the previously acquired access token in the `Authorization` header. ### refresh-token-grant ### Refresh token grant Used by WorkOS Connect OAuth Applications to exchange a refresh token for new access tokens and/or ID tokens. The refresh token is provided when the initial `oauth2/authorize` request is made with the `offline_access` scope. The [access token](reference/workos-connect/token/authorization-code-grant/access-token) and [ID tokens](reference/workos-connect/token/authorization-code-grant/id-token) issued here are the same as those issued for the initial `authorization_code` grant. ### token ## Token This endpoint is called by WorkOS Connect Applications to get access tokens, ID tokens, and refresh tokens, depending on the `grant_type` provided when requested. This endpoint is authenticated by providing the WorkOS Application's client ID and client secret in the body of the request. There are four grant types available: - [Authorization code](/reference/workos-connect/token/authorization-code-grant) - [Refresh token](/reference/workos-connect/token/refresh-token-grant) - [Client credentials](/reference/workos-connect/token/client-credentials-grant) - [Device code](/reference/workos-connect/cli-auth/device-code-grant) Each is described in greater detail below. ### client-credentials-grant ### Client credentials grant Used by WorkOS Connect M2M Applications to exchange the app’s credentials for access tokens. ### access-token #### Access token The access token for WorkOS Connect M2M Applications contains the following claims. ### authorization-code-grant ### Authorization code grant Used by WorkOS Connect OAuth Applications to exchange an authorization code for access tokens, ID tokens, and refresh tokens. ### id-token #### ID token The ID token, when requested with the `openid` scope, contains information about the user’s identity, like name and email address. ### access-token #### Access token The access token for WorkOS Connect OAuth Applications contains the following claims. ### user-consent-options ## User Consent Options The `user_consent_options` can take an array of consent options that the user will be required to choose from on AuthKit's OAuth consent screen. The chosen option will then become available as a JWT claim on the issued access token. These options can be presented as either a flat or grouped set of options. ### Standalone Connect --- # Standalone Connect Standalone Connect allows applications with existing authentication systems to use AuthKit as their OAuth authorization server. Instead of migrating your entire authentication stack, you can leverage WorkOS's OAuth infrastructure while keeping your existing user authentication as the source of truth. Read more in the [Standalone Connect guide](/authkit/connect/standalone). ### complete ## Complete external authentication Completes an external authentication flow and returns control to AuthKit. This endpoint is used with [Standalone Connect](/authkit/connect/standalone) to bridge your existing authentication system with the Connect OAuth API infrastructure. After successfully authenticating a user in your application, calling this endpoint will: - Create or update the user in AuthKit, using the given `id` as its `external_id`. - Return a `redirect_uri` your application should redirect to in order for AuthKit to complete the flow Users are automatically created or updated based on the `id` and `email` provided. If a user with the same `id` exists, their information is updated. Otherwise, a new user is created. If you provide a new `id` with an `email` that already belongs to an existing user, the request will fail with an error as email addresses are unique to a user. ### metadata ## Metadata Connect exposes several metadata endpoints in order to be compatible with a wide array of clients that support discovery and automatic configuration. ### openid-configuration ### OpenID configuration This discovery endpoint provides the standard configuration for OpenID clients to interact with WorkOS Connect. ### oauth-authorization-server ### OAuth Authorization Server This endpoint provides [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749)-compatible OAuth Authorization Server metadata. Model Context Protocol (MCP) clients that support the latest version of the specification use this endpoint. [Read more here](/authkit/mcp) about how to use AuthKit as an authorization server for an MCP server. ### introspection ## Token introspection Indicates whether the given token (access token or refresh token) is valid and active. Additionally, it provides details about the token. This endpoint is authenticated by provided the WorkOS Application’s client ID and client secret in the body of the request. ### CLI Auth --- # CLI Auth CLI Auth for WorkOS Connect enables third-party applications to build command-line tools that integrate with your app's credentials using the [OAuth 2.0 Device Authorization Flow](https://datatracker.ietf.org/doc/html/rfc8628). The CLI Auth flow for Connect involves two main endpoints: 1. The **device authorization URL** initiates the flow by obtaining device codes, user codes, and verification URIs. 2. The **device access token URL** is where the device exchanges the device code for access and refresh tokens after the user authenticates. Read more about [CLI Auth here](/authkit/cli-auth/connect). ### device-code-grant ## Device code grant Exchanges a device code for access and refresh tokens as part of the device authorization flow for WorkOS Connect applications. This endpoint should be polled repeatedly until the user authorizes the request, declines it, or the device code expires. The returned tokens are similar to those provided by the [authorization code grant](/reference/workos-connect/token/authorization-code-grant). ### authorize-device ## Authorize device Initiates the device authorization flow for WorkOS Connect applications. This endpoint implements the [OAuth 2.0 Device Authorization Flow](https://datatracker.ietf.org/doc/html/rfc8628) and is designed for CLI applications and other devices with limited input capabilities. This endpoint is used by third-party applications to authenticate users through WorkOS Connect. Users will be prompted to authorize the application's access to their data as part of the consent flow. ### authorize ## Authorize When authenticating a user for a WorkOS Connect application, this is the endpoint they should be redirected to. If they’re not already logged in, the user will be redirected to the AuthKit login page. For a third-party application, the user will have to authorize the application’s access on their first access. ### Widgets --- # Widgets Widgets are React components that provide complete functionality for common enterprise app workflows. ### get-token ## Generate a Widget token Generate a widget token scoped to an organization and user with the specified scopes. ### Vault --- # Vault Vault provides centralized encryption and storage of sensitive data such as API keys, database credentials, or personally identifiable information (PII). All data is encrypted using keys automatically provisioned based on the provided context of the object. ### versions ## List object versions Get list of versions for an object stored in Vault. ### Object Version --- --- # Object Version Represents a static version of an object stored by Vault. ### update ## Update an object value Update the value for an object. The key context of the original object will be used to encrypt the new data. ### metadata ## Retrieve metadata Retrieve metadata about an object. The value itself is not returned. ### list ## List objects Get list of object names stored in Vault. ### Encrypted Object --- --- # Encrypted Object Represents an encrypted object stored by Vault. ### get ## Get an object Get an existing object. The stored value will be decrypted and returned. ### get-by-name ## Get an object by name Get an existing object by its name. The stored value will be decrypted and returned. ### delete ## Delete an object Permanently delete an object. ### create ## Create an object Create a new object, encrypted with the key(s) matching the provided key context. ### Encryption Key Management --- # Encryption Key Management The key management APIs can be used to generate isolated encryption keys for local encryption and decryption operations. ### encrypt-data ## Encrypt data Perform a local encryption option. A data key is generated based on the provided key context and used to encrypt the data. The operation happens locally and neither the plaintext nor encrypted data are sent over the network. ### decrypt-data ## Decrypt data Decrypt data that was previously encrypted with Vault. The data key in the ciphertext is decrypted using the Vault API and used to decrypt the remaining data. The decryption operations happen locally and neither the plaintext nor encrypted data are sent over the network. ### decrypt-data-key ## Decrypt a data key Decrypt a data key that was previously encrypted using WorkOS Vault. ### create-data-key ## Create a data key Generate a data key for local encryption based on the provided key context. The encrypted data key **MUST** be stored by the application, as it cannot be retrieved after generation. ### Single Sign-On --- # Single Sign-On The Single Sign-On API has been modeled to meet the [OAuth 2.0](/glossary/oauth-2-0) framework specification. As a result, authentication flows constructed using the Single Sign-On API replicate the OAuth 2.0 protocol flow. To automatically respond to changes in your SSO connections, use the [Connection events](/events/connection). ### profile ## 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 attributes. After receiving the Profile for an authenticated user, use the Profile object attributes to persist relevant data to your application’s user model for the specific, authenticated user. To surface additional attributes on the Profile, refer to the [SSO custom attributes](/sso/attributes/custom-attributes) guide. ### get-user-profile ## Get a User Profile Exchange an access token for a user’s [Profile](/reference/sso/profile). Because this profile is returned in the [Get a Profile and Token endpoint](/reference/sso/profile/get-profile-and-token) your application usually does not need to call this endpoint. It is available for any authentication flows that require an additional endpoint to retrieve a user’s profile. ### get-profile-and-token ## Get a Profile and Token Get an access token along with the user [Profile](/reference/sso/profile) using the code passed to your [Redirect URI](/reference/sso/get-authorization-url/redirect-uri). ### redirect ## Logout Redirect Logout allows to sign out a user from your application by triggering the identity provider sign out flow. This `GET` endpoint should be a redirection, since the identity provider user will be identified in the browser session. Before redirecting to this endpoint, you need to generate a short-lived logout token using the [Logout Authorize](/reference/sso/logout/authorize) endpoint. ### logout ## Logout The Logout endpoints enable the RP-initiated logout functionality for users in your application. Refer to [Single Logout](/sso/single-logout/idp-initiated-logout) section for more details on how to handle RP-initiated or IdP-initiated logout. > Please note that the Logout feature is only available for Custom Open ID connections that provide > specific logout features. These features include the presence of the `revocation_endpoint` and `end_session_endpoint` > in the discovery document. ### authorize ## Logout Authorize You should call this endpoint from your server to generate a logout token which is required for the [Logout Redirect](/reference/sso/logout) endpoint. ### redirect-uri ### Redirect URI In the [OAuth 2.0](/glossary/oauth-2-0) protocol, a redirect URI is the location that the user is redirected to once they have successfully authenticated with their identity provider. When redirecting the user, WorkOS will generate an authorization code and pass it to your redirect URI as a `code` query parameter, your app will use this code to [get the user’s profile](/reference/sso/profile/get-profile-and-token). Additionally, WorkOS can pass a `state` parameter back to your application that you may use to encode arbitrary information to restore your application state between the redirects. ```url title="Redirect URI with query parameters" https://your-app.com/callback?code=01E2RJ4C05B52KKZ8FSRDAP23J&state=dj1kUXc0dzlXZ1hjUQ== ``` You’ll need to configure the allowed redirect URIs for your application via the [Redirects](https://dashboard.workos.com/redirects) page in the dashboard. Without a valid redirect URI, your users will be unable to sign in. Make sure that the redirect URI you use as a parameter to get the authorization URL matches one of the redirect URIs you have configured in the dashboard. Redirect URIs follow stricter requirements in production environments: - `HTTPS` protocol is required in production environments - `HTTP` and `localhost` are allowed in staging environments - Wildcard characters are not allowed in production environments #### Wildcards WorkOS supports using wildcard characters in Redirect URIs. The `*` symbol can be used as a wildcard for subdomains; however, it must be used in accordance with the following rules in order to properly function. - The wildcard **must** be located in a subdomain within the hostname component. For example, `http://*.com` will not work. - The wildcard **must** be located in the subdomain which is furthest from the root domain. For example, `https://sub.*.example.com` will not work. - The URL **must not** contain more than one wildcard. For example, `https://*.*.example.com` will not work. - A wildcard character **may** be prefixed and/or suffixed with additional valid hostname characters. For example, `https://prefix-*-suffix.example.com` will work. - A URL with a valid wildcard **will not** match a URL more than one subdomain level in place of the wildcard. For example, `https://*.example.com` will not work with `https://sub1.sub2.example.com`. - In production environments, wildcards cannot be used with [public suffix domains](https://publicsuffix.org). For example, `https://*.ngrok-free.app` will not work. - The wildcard will match a sequence of letters (`A` through `Z`, and `a` through `z` ); digits (`0` through `9`), hyphens (`-`), and underscores (`_`). For example, `https://user:secret@foo.example.com` will not work with `https://*.example.com`. - A URL with a wildcard cannot be set as the default redirect URI. ### get-authorization-url ## Get an authorization URL Generates an OAuth 2.0 authorization URL to authenticate a user with SSO. You’ll have to specify the user’s connection, organization, or OAuth provider as a parameter. These connection selectors are mutually exclusive, and exactly one must be provided. The generated URL automatically directs the user to their identity provider. Once the user authenticates with their identity provider, WorkOS then issues a redirect to your redirect URI to complete the sign-in flow. ### error-codes ### Error codes If there is an issue generating an authorization URL, the API will return the original redirect URI with `error` and `error_description` query parameters. If provided, the `state` value will also be included. ```url title="Redirect URI with an error code" https://your-app.com/callback?error=organization_invalid&error_description=No%20connection%20associated%20with%20organization&state=123456789 ``` Possible error codes and the corresponding descriptions are listed below. | Error code | Description | | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `access_denied` | The identity provider denied the user's access to the client application, or the user declined the OAuth authorization request at the identity provider. | | `ambiguous_connection_selector` | A connection could not be uniquely identified using the provided connection selector (e.g., organization). This can occur when there are multiple SSO connections under the same organization. If you need multiple SSO connections for an organization, use the connection parameter to identify which connection to use for SSO. | | `connection_domain_invalid` | There is no connection for the provided domain. | | `connection_invalid` | There is no connection for the provided ID. | | `connection_strategy_invalid` | The provider has multiple strategies associated per environment. | | `connection_unlinked` | The connection associated with the request is unlinked. | | `domain_connection_selector_not_allowed` | This is a legacy error code that only applies if using the deprecated “domain” query parameter which is no longer valid for this endpoint. Use the “organization” or “connection” query parameters to target a connection instead. | | `idp_initiated_sso_disabled` | IdP-initiated SSO is disabled for the connection (see [Disable IdP-initiated SSO](/sso/login-flows/idp-initiated-sso/disable-idp-initiated-sso-beta)). | | `invalid_connection_selector` | A valid connection selector query parameter must be provided in order to correctly determine the proper connection to return an authorization URL for. Valid connection selectors are either `connection`, `organization`, or `provider`. | | `organization_invalid` | There is no organization matching the provided ID. | | `oauth_failed` | An OAuth authorization request failed for a user. | | `profile_not_allowed_outside_organization` | A profile was received that has an `email` that is outside the [organization’s domain](/reference/organization-domain) and the organization does not allow this. To resolve this, add the missing domain to the organization's Domains. You can read about other options in the [SSO Domains guide](/sso/domains). | | `server_error` | The SSO authentication failed for the user. More detailed errors and steps to resolve are available in the Sessions tab on the connection page in the WorkOS Dashboard. | | `signin_consent_denied` | The user rejected the sign-in consent screen. This screen prompts the user to verify the email provided by the identity provider to confirm the legitimacy of the sign-in attempt. | ### list ## List Connections Get a list of all of your existing connections matching the criteria specified. ### connection ## Connection A connection represents the relationship between WorkOS and any collection of application users. This collection of application users may include personal or enterprise identity providers. As a layer of abstraction, a WorkOS connection rests between an application and its users, separating an application from the implementation details required by specific standards like [OAuth 2.0](/glossary/oauth-2-0) and [SAML](/glossary/saml). See the [events reference](/events/connection) documentation for the connection events. ### get ## Get a Connection Get the details of an existing connection. ### delete ## Delete a Connection Permanently deletes an existing connection. It cannot be undone. ### list-for-organization ## List roles for an organization Get a list of all roles for the provided organization in priority order. Includes all environment and organization roles. ### Roles --- # Roles A role is an access control resource that can be assigned to [organization memberships](/reference/authkit/organization-membership), [directory users](/directory-sync/identity-provider-role-assignment), and [SSO profiles](/sso/identity-provider-role-assignment). ### Radar --- # Radar Radar allows you to detect, verify, and block harmful behavior in real time. The Radar API supports the management of WorkOS Radar block and allow lists as well as standalone Radar use-cases. While Radar is natively integrated with AuthKit, you can also leverage Radar's risk decisioning engine outside of AuthKit to detect fraudulent sign-in and signup attempts in your own custom authentication flows using the [attempts API](/reference/radar/attempts). The Radar standalone API is currently in preview, [contact us](mailto:support@workos.com) to request access. ### update ## Add Entry Adds an entry to a Radar list ### lists ## Radar lists Radar supports explicitly blocking and allowing attempts based on attempt attributes. You can manage these lists via the Radar list management APIs ### delete ## Remove Entry Removes an entry from a Radar list ### update ## Update an Attempt You may optionally inform Radar that an authentication attempt or challenge was successful using this endpoint. Some Radar controls depend on tracking recent successful attempts, such as impossible travel. ### attempts ## Attempts A Radar attempt represents a sign-in or signup attempt and includes context such as IP address and user agent. The Radar engine assesses attempts for risk and returns a decision that you can use to drive behavior in your application. ### create ## Create an Attempt Evaluates an authentication attempt based on the parameters provided and returns a verdict. ### Pipes --- # Pipes Pipes provides OAuth integrations with third-party providers that allow your users to securely connect their accounts to your application. Pipes handles the complete OAuth lifecycle including token refresh and credential storage. Read more in the [Pipes guide](/pipes). ### get-token ## Get an access token for a connected account Fetches a valid OAuth access token for a user's connected account. WorkOS automatically handles token refresh, ensuring you always receive a valid, non-expired token. ### update ## Update an Organization Updates an organization in the current environment. You can include one or more domains to associate with the organization, but you should [verify the ownership](/authkit/domain-verification) of every domain before setting its state to `verified`. ### list ## List Organizations Get a list of all of your existing organizations matching the criteria specified. ### Organization --- # Organization An Organization is a top-level resource in WorkOS. Each Connection, Directory, and Audit Trail Event belongs to an Organization. An Organization will usually represent one of your customers. There is no limit to the number of organizations you can create in WorkOS. ### get ## Get an Organization Get the details of an existing organization. ### get-by-external-id ## Get an Organization by External ID Get the details of an existing organization by an [external identifier](/authkit/metadata/external-identifiers). ### delete ## Delete an Organization Permanently deletes an organization in the current environment. It cannot be undone. ### create ## Create an Organization Creates a new organization in the current environment. You can include one or more domains to associate with the organization, but you should [verify the ownership](/authkit/domain-verification) of every domain before setting its state to `verified`. ### verify-challenge ## Verify Challenge Verify Authentication Challenge. ### Multi-Factor Authentication --- # Multi-Factor Authentication The multi-factor authentication (MFA) API can be used to add additional factors of authentication to existing authentication strategies. The API currently supports both time-based one-time passwords (TOTP) and SMS factors. ### get-factor ## Get Factor Gets an Authentication Factor. ### enroll-factor ## Enroll Factor Enrolls an Authentication Factor to be used as an additional factor of authentication. The returned ID should be used to create an authentication Challenge. ### delete-factor ## Delete Factor Permanently deletes an Authentication Factor. It cannot be undone. ### challenge-factor ## Challenge Factor Creates a Challenge for an Authentication Factor. ### authentication-factor ## Authentication Factor An object representing an Authentication Factor. ### authentication-challenge ## Authentication Challenge An object representing a Challenge of an Authentication Factor. ### Magic Link --- # Magic Link The Magic Link API can be used to add Passwordless Authentication to your app. ### send-email ## Email a Magic Link [Deprecated] Email a user the Magic Link confirmation URL. ### passwordless-session ## Passwordless Session [Deprecated] An object representing a passwordless authentication session. ### create ## Create Passwordless Session [Deprecated] Create a Passwordless Session for a Magic Link Connection. ### Query --- --- # Query Use the [Query Language](/fga/query-language) to list the set of subjects that have access to a particular resource or to list the set of resources a particular subject has access to. ### Fine-Grained Authorization --- # Fine-Grained Authorization Fine-Grained Authorization (FGA) is a set of APIs designed to help you implement scalable, centralized, fine grained authorization in your application. ### Check --- --- # Check Check if a subject has a particular relation on a resource. ## Single Check ## Multiple Checks ### Batch Check --- --- # Batch Check Executes a batch of checks and returns a list of results in a single operation. ### list ## List warrants Get a list of all your existing warrants matching the criteria specified. ### Warrant --- --- # Warrant Represents a relation between resources in your application. ### delete ## Delete a warrant Deletes a warrant in the current environment. ### create ## Create a warrant Creates a new warrant in the current environment. ### batch-write ## Batch Write Warrants Executes a batch of warrant writes in the current environment. ### Schema --- # Schema Represents the authorization model in your FGA environment. Includes resource type definitions and policies that define how authorization checks are processed. ### get ## Get a schema Get the authorization model for your current environment. ### apply ## Apply schema Sets resource types and policies in the current environment. > This endpoint performs a batch operation which will override your entire schema for the environment. Any existing resource types and policies not included in the request will be deleted. ### update ## Update a resource type Update properties of a resource type. ### list ## List resource types Get a list of all your existing resource types matching the criteria specified. ### Resource Type --- --- # Resource Type Represents a type of resource and its possible relationships in your application. See [Resource Types](/fga/schema/schema-syntax/resource-types) to learn more about relation rules. See [JSON Syntax](/fga/schema/schema-syntax) for more examples. ### get ## Get a resource type Get the definition of an existing resource type. ### delete ## Delete a resource type Deletes a resource type in the current environment. ### create ## Create a resource type Create a new resource type in the current environment. ### apply ## Apply resource types Sets resource types in the current environment to match the provided resource types. > This endpoint performs a batch operation which will override your entire schema for the environment. Any existing resource types not included in the request will be deleted. ### update ## Update a resource Update the meta of an existing resource in the current environment. ### list ## List resources Get a list of all your existing resources matching the criteria specified. ### Resource --- --- # Resource Represents a resource in your application. ### get ## Get a resource Get an existing resource. ### delete ## Delete a resource Deletes a resource in the current environment. > Deleting a resource will also delete all warrants where the resource is the `resource` or `subject` of the warrant. ### create ## Create a resource Create a new resource in the current environment. ### batch-write ## Batch write resources Create or delete up to 100 resources in one request. ### Batch create resources ### Batch delete resources ### update ## Update a policy Update properties of a policy. ### list ## List policies Get a list of all your existing policies matching the criteria specified. ### Policy --- --- # Policy Represents a policy that defines the access control rules for your application. ### get ## Get a policy Get the definition of an existing policy. ### delete ## Delete a policy Deletes a policy in the current environment. ### create ## Create a policy Create a new policy in the current environment. ### remove-flag-target ## Remove flag target Removes a target from the feature flag's target list in the current environment. Currently, supported targets include users and organizations. ### list ## List feature flags Get a list of all of your existing feature flags matching the criteria specified. ### list-for-user ## List feature flags for a user Get a list of all enabled feature flags for the provided user. This includes feature flags enabled specifically for the user as well as any organizations that the user is a member of. ### list-for-organization ## List feature flags for an organization Get a list of all enabled feature flags for the provided organization. ### Feature Flags --- # Feature Flags Feature flags allow you to control feature availability for organizations in your application. Flags can either be enabled for individual organizations or all organizations in an environment. Read more about [how feature flags integrate with AuthKit here.](/feature-flags) ### get ## Get a feature flag Get the details of an existing feature flag. ### enable-flag ## Enable flag Enables a feature flag in the current environment. ### disable-flag ## Disable flag Disables a feature flag in the current environment. ### add-flag-target ## Add flag target Enables a feature flag for a specific target in the current environment. Currently, supported targets include users and organizations. ### list ## List events Get a list of all of events up to 30 days old. ### Events --- # Events Events represent activity that has occurred within WorkOS or within third-party identity and directory providers. They are used to keep your app in sync with WorkOS data. For more details on consuming events in your app, check out the [data syncing](/events/data-syncing) guide. Refer to the [Events](/events) page for a full list of events that WorkOS emits. ### verify ## Verify an Organization Domain Initiates verification process for an Organization Domain. ### Organization domain --- # Organization domain An organization domain represents an [organization](/reference/organization)'s domain. Domains can be verified to assert that an organization owns the configured domain which is accomplished through DNS TXT record verification. To automatically respond to changes in the organization domains, use [organization domain events](/events/organization-domain). ### get ## Get an Organization Domain Get the details of an existing organization. ### create ## Create an Organization Domain Creates a new Organization Domain. ### Directory Sync --- # Directory Sync Directory Sync allows you to connect with directory providers to inform your application of any changes in their users, groups, or access rules. Using Directory Sync, one integration grants your application the ability to support multiple directory providers. Get real-time updates of any changes to the organization's access rules, groups, and users by integrating webhooks into your application. To automatically respond to changes in the connected directories and their users and groups, use the [Directory Sync events](/events/directory-sync). ### list ## List Directory Users Get a list of all of existing Directory Users matching the criteria specified. ### directory-user ## Directory User A Directory User represents an active organization user. Developers can receive [Webhooks](/events/directory-sync) as employees are added, updated or removed, allowing for provisioning and de-provisioning Users within an application. ### get ## Get a Directory User Get the details of an existing Directory User. ### list ## List Directory Groups Get a list of all of existing directory groups matching the criteria specified. ### directory-group ## Directory Group A directory group represents an organizational unit of users in a directory provider. ### get ## Get a Directory Group Get the details of an existing Directory Group. ### list ## List Directories Get a list of all of your existing directories matching the criteria specified. ### directory ## Directory A directory stores information about an organization's employee management system. Synchronizing with a directory enables you to receive changes to an organization’s [user](/reference/directory-sync/directory-user) and [group](/reference/directory-sync/directory-group) structure. Directory providers vary in implementation details and may require different sets of fields for integration, such as API keys, subdomains, endpoints, usernames, etc. Where available, the WorkOS API will provide these fields when fetching directory records. ### get ## Get a Directory Get the details of an existing directory. ### delete ## Delete a Directory Permanently deletes an existing directory. It cannot be undone. ### AuthKit --- # AuthKit AuthKit is a user management platform that provides a set of user authentication and organization security features designed to provide a fast, scalable integration while handling all of the user management complexity that comes with advanced B2B customer needs. To automatically respond to AuthKit activities, like authentication and changes related to the users, use the corresponding [events](/events). ### update ## Update a user Updates properties of a user. The omitted properties will be left unchanged. ### list ## List users Get a list of all of your existing users matching the criteria specified. ### User --- --- # User Represents a user identity in your application. A user can sign up in your application directly with a method like password, or they can be [JIT-provisioned](/authkit/jit-provisioning) through an organization’s SSO connection. Users may belong to [organizations](/reference/organization) as members. See the [events reference](/events/user) documentation for the user events. ### get ## Get a user Get the details of an existing user. ### get-by-external-id ## Get a user by external ID Get the details of an existing user by an [external identifier](/authkit/metadata/external-identifiers). ### delete ## Delete a user Permanently deletes a user in the current environment. It cannot be undone. ### create ## Create a user Create a new user in the current environment. ### refresh-token ## Refresh token The refresh token can be used to obtain a new access token using the [authenticate with refresh token ](reference/authkit/authentication/refresh-token) endpoint. Refresh tokens may only be used once. Refreshes will succeed as long as the user's session is still active. ### jwks ## JWKS URL This hosts the public key that is used for verifying access tokens. ### Session tokens --- # Session tokens ### access-token ## Access token The access token that is returned in successful authentication responses is a JWT that can be used to verify that a user has an active session. The JWT is signed by a JWKS which can be retrieved from the [WorkOS API](/reference/authkit/session-tokens/jwks). ### refresh ## Refresh Refreshes the user's session with the refresh token. Passing in a new organization ID will switch the user to that organization. ### load-sealed-session ## Load sealed session Load the session by providing the sealed session and the cookie password. ### Session helpers [object Object] --- # Session helpers After authenticating and [storing the encrypted session as a cookie](/authkit/vanilla/nodejs/3-handle-the-user-session/save-the-encrypted-session), retrieving and decrypting the session is made easy via the session helper methods. ### get-logout-url ## Get log out URL End a user’s session. The user’s browser should be redirected to this URL. Functionally similar to [Get logout URL](/reference/authkit/logout/get-logout-url) but extracts the session ID automatically from the session data. ### authenticate ## Authenticate Unseals the session data and checks if the session is still valid. ### revoke ## Revoke session Revoke a session. ### list ## List sessions Get a list of all active sessions for a specific user. ### Session --- --- # Session Represents an authenticated user's connection to your application. A session is created when a user signs in through AuthKit and contains information about the authentication method, device details, and session status. ### reset-password ## Reset the password Sets a new password using the `token` query parameter from the link that the user received. Successfully resetting the password will verify a user's email, if it hasn't been verified yet. ### Password reset --- --- # Password reset Create a password reset token for a user and reset the user's password. > When a user’s password is reset, all of their active sessions are revoked. ### get ## Get a password reset token Get the details of an existing password reset token that can be used to reset a user's password. ### create ## Create a password reset token Creates a one-time token that can be used to reset a user's password. ### update ## Update an organization membership Update the details of an existing organization membership. ### reactivate ## Reactivate an organization membership Reactivates an `inactive` organization membership, retaining the pre-existing role(s). Emits an [organization_membership.updated](/events/organization-membership) event upon successful reactivation. - Reactivating an `active` membership is a no-op and does not emit an event. - Reactivating a `pending` membership returns an error. The user needs to [accept the invitation](/authkit/invitations) instead. See the [membership management documentation](/authkit/users-organizations/organizations/membership-management) for additional details. ### list ## List organization memberships Get a list of all organization memberships matching the criteria specified. At least one of `user_id` or `organization_id` must be provided. By default only active memberships are returned. Use the `statuses` parameter to filter by other statuses. ### Organization membership --- --- # Organization membership An organization membership is a top-level resource that represents a [user](/reference/authkit/user)’s relationship with an [organization](/reference/organization). A user may be a member of zero, one, or many organizations. See the [events reference](/events/organization-membership) documentation for the organization membership events. ### get ## Get an organization membership Get the details of an existing organization membership. ### delete ## Delete an organization membership Permanently deletes an existing organization membership. It cannot be undone. ### deactivate ## Deactivate an organization membership Deactivates an `active` organization membership. Emits an [organization_membership.updated](/events/organization-membership) event upon successful deactivation. - Deactivating an `inactive` membership is a no-op and does not emit an event. - Deactivating a `pending` membership returns an error. This membership should be [deleted](/reference/authkit/organization-membership/delete) instead. See the [membership management documentation](/authkit/users-organizations/organizations/membership-management) for additional details. ### create ## Create an organization membership Creates a new `active` organization membership for the given organization and user. Calling this API with an organization and user that match an `inactive` organization membership will activate the membership with the specified role(s). ### list-auth-factors ## List authentication factors Lists the authentication factors for a user. ### mfa ### enroll-auth-factor ## Enroll an authentication factor Enrolls a user in a new authentication factor. ### authentication-factor ## Authentication factor Represents an authentication factor. ### authentication-challenge ## Authentication challenge Represents a challenge of an authentication factor. ### Magic Auth --- --- # Magic Auth Magic Auth is a passwordless authentication method that allows users to sign in or sign up via a unique, six digit one-time-use code sent to their email inbox. To verify the code, [authenticate the user with Magic Auth](/reference/authkit/authentication/magic-auth). ### get ## Get a Magic Auth code Get the details of an existing Magic Auth code that can be used to send an email to a user for authentication. ### create ## Create a Magic Auth code Creates a one-time authentication code that can be sent to the user’s email address. The code expires in 10 minutes. To verify the code, [authenticate the user with Magic Auth](/reference/authkit/authentication/magic-auth). ### Logout --- # Logout End a user's session. The user's browser should be redirected to this URL. ### Get logout URL --- # Get logout URL ### Get logout URL from session cookie --- # Get logout URL from session cookie Generates the logout URL by extracting the session ID from the session cookie. Use this over `getLogoutUrl` if you don't have a saved reference to the session ID and you'd like the SDK to handle extracting the session ID from the cookie for you. ### send ## Send an invitation Sends an invitation email to the recipient. ### revoke ## Revoke an invitation Revokes an existing invitation. ### resend ## Resend an invitation Resends an invitation email to the recipient. The invitation must be in a pending state. ### list ## List invitations Get a list of all of invitations matching the criteria specified. ### Invitation --- --- # Invitation An email invitation allows the recipient to sign up for your app and join a specific [organization](/reference/organization). When an invitation is accepted, a [user](/reference/authkit/user) and a corresponding [organization membership](/reference/authkit/organization-membership) are created. Users may be invited to your app without joining an organization, or they may be invited to join an organization if they already have an account. Invitations may be also issued on behalf of another user. In this case, the invitation email will mention the name of the user who invited the recipient. ### get ## Get an invitation Get the details of an existing invitation. ### find-by-token ## Find an invitation by token Retrieve an existing invitation using the token. ### accept ## Accept an invitation Accepts an invitation and, if linked to an organization, activates the user’s membership in that organization. In most cases, use existing authentication methods like [`authenticateWithCode`](/reference/authkit/authentication/code), which also accept an invitation token. These methods offer the same functionality (invitation acceptance and membership activation) while also signing the user in. This method is useful for apps requiring a highly customized invitation flow, as it focuses solely on handling invitations without authentication. It’s also helpful when users can be invited to multiple organizations and need a way to accept invitations after signing in. Your application should verify that the invitation is intended for the user accepting it. For example, by fetching the invitation using the [find-by-token endpoint](/reference/authkit/invitation/find-by-token) and ensuring the email matches the email address of the accepting user. ### list ## Get user identities Get a list of identities associated with the user. A user can have multiple associated identities after going through [identity linking](/authkit/identity-linking). Currently only OAuth identities are supported. More provider types may be added in the future. ### Identities --- --- # Identities Represents [User](/reference/authkit/user) identities obtained from external identity providers. When a user authenticates using an external provider like [Google OAuth](/integrations/google-oauth), information from that provider will be made available as one of the user's Identities. You can read more about the process in our [identity linking guide](/authkit/identity-linking). > Applications should check the `type` before making assumptions about the shape of the identity. Currently only `OAuth` identities are supported, but more types may be added in the future. ### Email verification --- --- # Email verification Email verification is a security feature that requires users to verify their email address before they can sign in to your application. It is enabled by default. Users signing in with Magic Auth, Google OAuth, Apple OAuth, or SSO are automatically verified. For other authentication methods, an email verification flow is required to confirm that the user’s email address belongs to them. ### get ## Get an email verification code Get the details of an existing email verification code that can be used to send an email to a user for verification. ### CLI Auth --- # CLI Auth CLI Auth enables command-line applications to authenticate users through the web using the [OAuth 2.0 Device Authorization Flow](https://datatracker.ietf.org/doc/html/rfc8628). The CLI Auth flow involves two main endpoints: 1. The **device authorization URL** initiates the flow by obtaining a device code, user code, and verification URIs. 2. The **device access token URL** is where the device exchanges the device code for access and refresh tokens after the user authenticates. Read more about [CLI Auth here](/authkit/cli-auth). ### Get a device authorization URL Initiate the CLI Auth flow by obtaining a device code and verification URLs. ## Get device authorization URL Initiates the CLI Auth flow by requesting a device code and verification URLs. This endpoint implements the OAuth 2.0 Device Authorization Flow ([RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628)) and is designed for command-line applications or other devices with limited input capabilities. ### Device code Exchange a device code for access and refresh tokens during the CLI Auth flow. ## Device code Exchanges a device code for access and refresh tokens as part of the [CLI Auth](/authkit/cli-auth) flow. This endpoint should be polled repeatedly until the user authorizes the request, declines it, or the device code expires. ### error-codes ### Error codes When polling the device code endpoint, you may receive various error responses before the user completes authorization or if authorization fails. These errors help your application understand the current state and take appropriate action. Possible error codes and the corresponding descriptions are listed below. | Error code | Description | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `authorization_pending` | The authorization request is still pending as the user hasn't yet completed the user interaction flow. Continue polling at the specified interval. | | `slow_down` | The client is polling too frequently and should slow down. Increase your polling interval by at least 5 seconds and continue polling. | | `access_denied` | The user declined the authorization request. Stop polling and inform the user that authorization was denied. | | `expired_token` | The device code has expired (typically after 5 minutes). Stop polling and restart the authorization flow if needed. | | `invalid_request` | The request is missing a required parameter or includes an invalid parameter value. Check that `grant_type`, `device_code`, and `client_id` are provided and correct. | | `invalid_client` | Client authentication failed (e.g., unknown client, client authentication not included, or unsupported authentication method). | | `invalid_grant` | The provided device code is invalid, malformed, or has already been used. | | `unsupported_grant_type` | The grant type is not supported. Ensure you're using `urn:ietf:params:oauth:grant-type:device_code`. | ### Error response format All error responses are returned with a 400 status code and follow the OAuth 2.0 error response format. For example: ```json { "error": "authorization_pending", "error_description": "The authorization request is still pending as the user hasn't yet completed the user interaction flow." } ``` ### sso-required-error ## SSO required error This error indicates that a user attempted to authenticate into an organization that requires SSO using a different authentication method. It includes a list of SSO connections that may be used to complete the authentication. When this error occurs, you’ll need to use one of the SSO connections from the error to [get the authorization URL](/reference/authkit/authentication/get-authorization-url) and redirect the user to that URL to complete the authentication with the organization’s identity provider. ### organization-selection-error ## Organization selection required error This error indicates that the user is a member of multiple organizations and must select which organization to sign in to. It includes a list of organizations the user is a member of and a pending authentication token that should be used to complete the authentication. When this error occurs, you’ll need to display the list of organizations that the user is a member of and authenticate them with the [selected organization](/reference/authkit/authentication/organization-selection) using the pending authentication token from the error. ### organization-authentication-required-error ## Organization authentication required error This error indicates that a user attempted to authenticate with an authentication method that is not allowed by the organization that has a [domain policy](/authkit/organization-policies) managing this user. It includes all the possible methods the user can use to authenticate. When this error occurs, you’ll need to present the user with these options so they can choose which method to continue authentication. ### mfa-enrollment-error ## MFA enrollment error This error indicates that a user who is not enrolled into MFA attempted to authenticate in an environment where MFA is required. It includes a pending authentication token that should be used to authenticate the user once they enroll into MFA. When this error occurs, you’ll need to present an [MFA enrollment](/reference/authkit/mfa/enroll-auth-factor) UI to the user. Once the user has enrolled, present an MFA challenge UI to the user and authenticate them with their [TOTP code](/reference/authkit/authentication/totp) and the pending authentication token from this error. MFA can be enabled via the [Authentication page](https://dashboard.workos.com/authentication) in the WorkOS dashboard. ### mfa-challenge-error ## MFA challenge error This error indicates that a user enrolled into MFA attempted to authenticate in an environment where MFA is required. It includes a pending authentication token and a list of factors that the user is enrolled in that should be used to complete the authentication. When this error occurs, you’ll need to present an MFA challenge UI to the user and authenticate them with their [TOTP code](/reference/authkit/authentication/totp), the pending authentication token from this error, and a [challenge](/reference/mfa/challenge-factor) that corresponds to one of the authentication factors. MFA can be enabled via the [Authentication page](https://dashboard.workos.com/authentication) in the WorkOS dashboard. ### Authentication errors --- --- # Authentication errors Integrating the authentication API directly requires handling error responses for email verification, MFA challenges, identity linking, and organization selection. One or more of these responses may be returned for an authentication attempt with any authentication method. Hosted AuthKit handles authentication errors for you and may be a good choice if you prefer a simpler integration. ### email-verification-required-error ## Email verification required error This error indicates that a user with an unverified email address attempted to authenticate in an environment where email verification is required. It includes a pending authentication token that should be used to complete the authentication. When this error occurs and the [email setting](/authkit/custom-emails) for email verification is enabled, WorkOS will automatically send a one-time email verification code to the user’s email address and issue a pending authentication token. If the email setting is not enabled, [retrieve the email verification code](/reference/authkit/email-verification/get) to send the email verification email yourself. To complete the authentication process, use the pending authentication token from the error and the one-time code the user received to [authenticate](/reference/authkit/authentication) them and to verify their email address. The same applies when a user attempts to authenticate with OAuth or SSO, but there was already an account with a matching unverified email address. ### totp ## Authenticate with a time-based one-time password Authenticates a user enrolled into MFA using time-based one-time password (TOTP). Users enrolled into MFA are required to enter a TOTP each time they sign in. When they attempt to authenticate with their credentials, the API will return an [MFA challenge error](/reference/authkit/authentication-errors/mfa-challenge-error) that contains a pending authentication token. To continue with the authentication flow, [challenge](/reference/mfa/challenge-factor) one of the factors returned by the MFA challenge error response and present a UI to the user to enter the TOTP code. Then, authenticate the user with the TOTP code, the challenge from the factor, and the pending authentication token from the MFA challenge error. MFA can be enabled via the [Authentication page](https://dashboard.workos.com/authentication) in the WorkOS dashboard. ### session-cookie ## Authenticate with session cookie Authenticates a user using an AuthKit session cookie. This method does not make a network call, but simply unseals an existing session cookie and decodes the JWT claims from the [access token](/reference/authkit/session-tokens/access-token). ### refresh-token ## Authenticate with refresh token Use this endpoint to exchange a refresh token for a new access token. Refresh tokens may be rotated after use, so a replacement refresh token is also provided. ### refresh-and-seal-session-data ## Refresh and seal session data Unseals the provided session data from a user's session cookie, [authenticates with the existing refresh token](/reference/authkit/authentication/refresh-token), and returns the sealed data for the refreshed session. ### password ## Authenticate a user with password Authenticates a user with email and password. ### organization-selection ## Authenticate with organization selection Authenticates a user into an organization they are a member of. When a user who is a member of multiple organizations attempts to authenticate with their credentials, the API will return an [organization selection error](/reference/authkit/authentication-errors/organization-selection-error) that contains a pending authentication token. To continue with the authentication flow, your application should display the list of organizations for the user to choose. Use the pending authentication token from the error and the organization the user selected in your UI to complete the authentication. ### magic-auth ## Authenticate with Magic Auth Authenticates a user by verifying the [Magic Auth code](/reference/authkit/magic-auth) sent to the user’s email. ### Authentication --- --- # Authentication Authenticate a user with a specified authentication method. ### email-verification ## Authenticate with an email verification code Authenticates a user with an unverified email and verifies their email address. A user with an unverified email address won’t be able to authenticate right away. When they attempt to authenticate with their credentials, the API will return an [email verification required error](/reference/authkit/authentication-errors/email-verification-required-error) that contains a pending authentication token. If the [email setting](/authkit/custom-emails) for email verification is enabled, WorkOS will automatically send a one-time email verification code to the user’s email address. If the email setting is not enabled, [retrieve the email verification code](/reference/authkit/email-verification/get) to send the email yourself. Use the pending authentication token from the error and the one-time code the user received to authenticate them and to complete the email verification process. ### code ## Authenticate with code Authenticates a user using AuthKit, OAuth or an organization’s SSO connection. AuthKit handles all authentication methods, however it is conceptually similar to a social login experience. Like OAuth and SSO, AuthKit returns you a code that you can exchange for an authenticated user. See [Integrating with AuthKit](/authkit). ### redirect-uri ### Redirect URI In the [OAuth 2.0](/glossary/oauth-2-0) protocol, a redirect URI is the location that the user is redirected to once they have successfully authenticated with their identity provider. When redirecting the user, WorkOS will generate an authorization code and pass it to your redirect URI as a `code` query parameter, your app will use this code to [authenticate the user](/reference/authkit/authentication/code). Additionally, WorkOS can pass a `state` parameter back to your application that you may use to encode arbitrary information to restore your application state between the redirects. ```url title="Redirect URI with query parameters" https://your-app.com/callback?code=01E2RJ4C05B52KKZ8FSRDAP23J&state=dj1kUXc0dzlXZ1hjUQ== ``` You can use `state` to encode parameters like originating URL and query parameters. This is useful in a flow where unauthenticated users are automatically redirected to a login page. After successful sign in, users will be routed to your redirect URI callback route. From there you can extract the originating URL from `state` and redirect the user to their intended destination. You’ll need to configure the allowed redirect URIs for your application via the [Redirects](https://dashboard.workos.com/redirects) page in the dashboard. Without a valid redirect URI, your users will be unable to sign in. Make sure that the redirect URI you use as a parameter to get the authorization URL matches one of the redirect URIs you have configured in the dashboard. Redirect URIs follow stricter requirements in production environments: - `HTTPS` protocol is required in production environments - `HTTP` and `localhost` are allowed in staging environments - The sole exception is the use of `http://127.0.0.1` in production environments to support native clients. #### Wildcards WorkOS supports using wildcard characters in Redirect URIs. The `*` symbol can be used as a wildcard for subdomains; however, it must be used in accordance with the following rules in order to properly function. - The wildcard **must** be located in a subdomain within the hostname component. For example, `http://*.com` will not work. - The wildcard **must** be located in the subdomain which is furthest from the root domain. For example, `https://sub.*.example.com` will not work. - The URL **must not** contain more than one wildcard. For example, `https://*.*.example.com` will not work. - A wildcard character **may** be prefixed and/or suffixed with additional valid hostname characters. For example, `https://prefix-*-suffix.example.com` will work. - A URL with a valid wildcard **will not** match a URL more than one subdomain level in place of the wildcard. For example, `https://*.example.com` will not work with `https://sub1.sub2.example.com`. - In production environments, wildcards cannot be used with [public suffix domains](https://publicsuffix.org). For example, `https://*.ngrok-free.app` will not work. - The wildcard will match a sequence of letters (`A` through `Z`, and `a` through `z` ); digits (`0` through `9`), hyphens (`-`), and underscores (`_`). For example, `https://user:secret@foo.example.com` will not work with `https://*.example.com`. - A URL with a wildcard cannot be set as the default redirect URI. ### pkce ### PKCE The [Proof Key for Code Exchange](https://datatracker.ietf.org/doc/html/rfc7636) (PKCE) flow is an extension to the OAuth 2.0 Authorization Code flow. It enables public clients, like native apps or single-page apps, to perform the authorization code flow securely. If you are developing a client that makes API calls in public, you’ll need to use this flow. In this flow, your client generates a code verifier which is a high-entropy cryptographic random string. A code challenge is derived by hashing the code verifier. Instead of using a client secret, provide the code challenge when [getting the authorization URL](/reference/authkit/authentication/get-authorization-url) and the code verifier when [authenticating a User](/reference/authkit/authentication/code). ### get-authorization-url ## Get an authorization URL Generates an OAuth 2.0 authorization URL to authenticate a user with AuthKit or SSO. If you are using AuthKit, set the provider parameter to `"authkit"`, which will generate an authorization URL for your AuthKit domain. AuthKit will take care of detecting the user’s authentication method, such as identifying whether they use Email + Password or Single Sign-On,and direct them to the corresponding login flow. Otherwise, to generate an authorization URL for a WorkOS SSO connection, you’ll have to specify the user’s connection, organization, or OAuth provider as a parameter. These connection selectors are mutually exclusive, and exactly one must be provided. The generated URL automatically directs the user to their identity provider. Once the user authenticates with their identity provider, WorkOS then issues a redirect to your redirect URI to complete the sign-in flow. ### error-codes ### Error codes If there is an issue generating an authorization URL, the API will return the original redirect URI with `error` and `error_description` query parameters. If provided, the `state` value will also be included. ```url title="Redirect URI with an error code" https://your-app.com/callback?error=organization_invalid&error_description=No%20connection%20associated%20with%20organization&state=123456789 ``` Possible error codes and the corresponding descriptions are listed below. | Error code | Description | | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `access_denied` | The identity provider denied user access to the client application or the user denied an OAuth authorization request at the identity provider. | | `ambiguous_connection_selector` | A connection could not be uniquely identified using the provided connection selector (e.g., organization). This can occur when there are multiple SSO connections under the same organization. If you need multiple SSO connections for an organization, use the connection parameter to identify which connection to use for SSO. | | `connection_invalid` | There is no connection for the provided ID. | | `connection_strategy_invalid` | The provider has multiple strategies associated per environment. | | `connection_unlinked` | The connection associated with the request is unlinked. | | `invalid_connection_selector` | A valid connection selector query parameter must be provided in order to correctly determine the proper connection to return an authorization URL for. Valid connection selectors are either `connection`, `organization`, or `provider`. | | `organization_invalid` | There is no organization matching the provided ID. | | `oauth_failed` | An OAuth authorization request failed for a user. | | `server_error` | The SSO authentication failed for the user. More detailed errors and steps to resolve are available in the Sessions tab on the connection page in the WorkOS Dashboard. | ### Validate API key Validate an API key and retrieve associated metadata. ## Validate API key Validates an API key and returns its associated metadata if the key is valid. Your application's API uses this endpoint to authenticate incoming requests that include an API key. The endpoint returns the complete API key object when validation succeeds, allowing you to access the key's permissions and owner information for authorization purposes. If the key is invalid, the endpoint returns `null` for the `api_key` field. ### API Keys --- # API Keys API keys provide a secure way for your application's users to authenticate with your API. Organization admins create API keys through the [API Keys Widget](/widgets/api-keys), and your application can validate these keys to authenticate API requests. Read more about [API keys in AuthKit](/authkit/api-keys). ### Access Token --- --- # Access Token ### set-retention ## Set Retention Set the event retention period for the given Organization. ### list-schemas ## List Schemas Get a list of all schemas for the Audit Logs action identified by `:name`. ### list-actions ## List Actions Get a list of all Audit Log actions in the current environment. ### Audit Logs --- # Audit Logs Audit Logs are a collection of events that contain information relevant to notable actions taken by users in your application. Every event in the collection contains details regarding what kind of action was taken (`action`), who performed the action (`actor`), what resources were affected by the action (`targets`), and additional details of when and where the action took place. ### get-retention ## Get Retention Get the configured event retention period for the given Organization. ### get-export ## Get Export Get an Audit Log Export. > The URL will expire after 10 minutes. If the export is needed again at a later time, refetching the export will regenerate the URL. ### create-schema ## Create Schema Creates a new Audit Log schema used to validate the payload of incoming Audit Log Events. If the `action` does not exist, it will also be created. ### create-export ## Create Export Create an Audit Log Export. ### create-event ## Create Event Create an Audit Log Event. This API supports idempotency which guarantees that performing the same operation multiple times will have the same result as if the operation were performed only once. This is handy in situations where you may need to retry a request due to a failure or prevent accidental duplicate requests from creating more than one resource. To achieve idempotency, you can add `Idempotency-Key` request header to a Create Event request with a unique string as the value. Each subsequent request matching this unique string will return the same response. We suggest using [v4 UUIDs](https://en.wikipedia.org/wiki/Universally_unique_identifier) for idempotency keys to avoid collisions. Idempotency keys expire after 24 hours. The API will generate a new response if you submit a request with an expired key. ### audit-log-schema ## Audit Log Schema An object representing an Audit Log Schema. ### audit-log-export ## Audit Log Export An object representing an Audit Log Export. ### audit-log-configuration ## Get Audit Log Configuration The Audit Log Configuration endpoint provides a single view of an organization’s audit logging setup. It includes retention settings (how long audit logs are stored), the audit log state (active, inactive, or disabled), and—if configured—the audit log stream, which sends events to external destinations like Splunk, Datadog, S3, Google Cloud Storage, or a custom HTTPS endpoint. The log_stream field is optional and only appears if the organization has a stream configured. If no stream is set up, the response includes only the audit log retention and state information. ### Admin Portal --- # Admin Portal The Admin Portal is a standalone application where your users can configure and manage WorkOS resources such as [Connections](/reference/sso/connection) and [Directories](/reference/directory-sync/directory) that are scoped to their [Organization](/reference/organization). ### provider-icons ## Provider Icons Icons for third-party providers are available through the WorkOS CDN. These icons cover identity providers, Directory Sync, and domain verification services used within the Admin Portal. ### List Provider Icons Get a list of all of existing provider icons. ### Get a Provider Icon To use an icon in your project, you can reference the CDN link directly. You can alternate between light and dark mode icons by changing the path in the URL or using CSS media queries. ```html title="Example icon" ``` You can change the icons to grayscale by adding the `filter` CSS property. ```css title="Grayscale style" img { filter: grayscale(100%); } ``` ### portal-link ## Portal Link A Portal Link is a temporary endpoint to initiate an Admin Portal session. It expires five minutes after issuance. ```url title="Example Portal Link URL" https://setup.workos.com?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` ### generate ## Generate a Portal Link Generate a Portal Link scoped to an Organization. ## RBAC {#rbac} ### Quick Start Set up roles & permissions to model your authorization requirements. Then use the SDK to make access checks from your application. ## Before getting started To get the most out of this guide, you should have: - A [WorkOS account](https://dashboard.workos.com/) - Your WorkOS [API Key](/glossary/api-key) ## What you'll build In this guide, we’ll implement role-based access control for a simple B2B video sharing SaaS application, where users can view and create videos, and elevated roles can manage other users’ roles and application settings. We will: 1. Map your application’s access management model to a set of roles 2. Define permissions to control granular access to your application’s resources 3. Associate permissions with roles, and configure default roles and priority order 4. If using AuthKit, assign roles to organization memberships and determine access via the [session JWT](/reference/authkit/session-tokens) 5. If using standalone SSO, access user roles through the [SSO Profile object](/reference/sso/profile) 6. If using standalone Directory Sync, access user roles through the [Directory User object](/reference/directory-sync/directory-user) ## API resource definitions [Role](/reference/roles) : Represents a logical grouping of access management rules. --- ## (1) Create roles The first step to RBAC is to determine the application's access management hierarchy. --- ## (2) Create permissions The first step to RBAC is to define Get provider-specific instructions by selecting the directory provider you want to test: --- ## Summary That's it! We've now setup a powerful RBAC system for our application. ### Organization Roles Create and manage custom organization-scoped roles ## Overview Organization roles are custom roles scoped to a particular organization. They are managed via the _Roles_ tab under an organization in the [WorkOS Dashboard](https://dashboard.workos.com/). You can utilize organization roles regardless of whether you’re integrating with AuthKit, SSO, or Directory Sync. ![Roles tab for organization](https://images.workoscdn.com/images/5c09cd78-041f-4bb9-9e76-f7267106b22c.png?auto=format&fit=clip&q=50) ### Why might I use organization roles? In some cases, an application’s fixed set of roles may not meet the needs of certain organizations. For example, an organization may require a lesser privileged set of permissions for their members. Organization roles allow you to create custom roles, with the organization’s desired set of permissions, without affecting access control for other organizations. ### Creating organization roles By default, organizations have no custom organization roles and simply inherit the environment-level roles. You can create an organization role by clicking the "Create role" button on the organization’s _Roles_ tab. All organization role slugs are automatically prefixed with `org`. ![Create an organization role](https://images.workoscdn.com/images/90f3f3c0-3c66-48b2-b962-04b34f30599e.png?auto=format&fit=clip&q=50) ### Organization role configuration Once you create the first role for an organization, that organization will have its own [default role](/authkit/roles-and-permissions/configure-roles-and-permissions/default-role) and [priority order](/authkit/roles-and-permissions/configure-roles-and-permissions/priority-order), independent from the environment. New roles added to the environment will be available to the organization and placed at the bottom of the organization’s role priority order. ### Using organization roles Like environment-level roles, organization roles can be used in [role assignment](/authkit/roles-and-permissions/role-assignment), [sessions](/authkit/roles-and-permissions/role-aware-sessions), and the [organization membership API](/reference/authkit/organization-membership). No additional action is required to enable this behavior after creating organization roles. ### Deleting an environment role When attempting to delete an environment role that’s the default role for one or more organizations, you’ll be prompted to select a new default role for all affected organizations. Organization members previously assigned the deleted role will be assigned the new organization default role. ![Select a replacement role](https://images.workoscdn.com/images/5e6f3e51-5de5-4bb1-a850-52b2196282b9.png?auto=format&fit=clip&q=50) ### Integrating Role-Based Access Control Utilize Role-Based Access Control across WorkOS products ## Configure roles and permissions Before integrating with WorkOS Role-Based Access Control (RBAC), you’ll need to [configure roles and permissions](/rbac/configuration) for your application in the [WorkOS Dashboard](https://dashboard.workos.com/). --- ## Integrating with AuthKit WorkOS RBAC seamlessly integrates with AuthKit to provide a complete user management solution. Using AuthKit, you can assign roles directly to organization memberships, source roles from your customer’s identity provider (IdP), and read roles and permissions directly from session JWTs. ### Assigning roles In AuthKit, users are associated with [organizations](/reference/organization) via [organization memberships](/reference/authkit/organization-membership). Each organization membership has role(s), which represents a user’s access level for that particular organization. Every organization membership is automatically assigned the [default role](/rbac/configuration/configure-roles/default-role) when added to an organization. You can modify an organization membership’s role(s) via the [organization memberships API](/reference/authkit/organization-membership/create), [WorkOS Dashboard](https://dashboard.workos.com/), or via [IdP role assignment](/rbac/assignments/idp-role-assignment). [IdP role assignment](/rbac/idp-role-assignment) will always take precedence over roles assigned via API or the WorkOS Dashboard. For [SSO group role assignment](/sso/identity-provider-role-assignment/sso-group-role-assignment), the organization membership role updates each time the user authenticates. For [directory group role assignment](/directory-sync/identity-provider-role-assignment/directory-group-role-assignment) via [directory provisioning](/authkit/directory-provisioning), the organization membership’s role updates each time we receive a directory event for the user. ### Single vs. multiple roles AuthKit, Directory Sync, and Single Sign-On all support both single and [multiple role](/authkit/roles-and-permissions/multiple-roles) paradigms. There are two ways to assign multiple roles: - **Group-based assignment**: if a user is a member of multiple groups with role mappings, they will receive all the roles. This applies to directory users, SSO profiles, and organization memberships when using [directory](/authkit/directory-provisioning) or [SSO JIT provisioning](/authkit/jit-provisioning/sso-jit-provisioning) in AuthKit. - **Manual assignment**: multiple roles can be assigned to [organization memberships](/reference/authkit/organization-membership) directly via the WorkOS Dashboard or [API](/reference/authkit/organization-membership/create). Multiple roles helps to avoid needing to create roles for every possible combination of permissions e.g., designer-engineer. This model fits teams where users span functions or need additive, temporary access. For most apps, start with **single-role** assignments for simplicity and predictability, and adopt multiple roles only when overlapping permission sets become common. ### Using roles and permissions in your app Read a user’s role(s) from their [organization membership](/reference/authkit/organization-membership) or from an [AuthKit session access token](/authkit/sessions/integrating-sessions/access-token). --- ## Integrating with Directory Sync For [standalone Directory Sync](/directory-sync), organization administrators manage roles through [directory group role assignment](/directory-sync/identity-provider-role-assignment). Their assigned role defines the user’s access level for the particular [organization](/reference/organization) and is based on their directory group memberships. All [directory users](/reference/directory-sync/directory-user) have assigned roles. If no role is explicitly assigned through directory group role assignment, the user receives the [default role](/rbac/configuration/configure-roles/default-role). Roles are granted to directory users in real-time, when we receive updates to their group memberships. Role slugs are returned on [Directory User](/reference/directory-sync/directory-user) objects from the API. These can be used to assign a role to your internal user object. --- ## Integrating with Single Sign-On (SSO) For [standalone SSO](/sso), organization administrators manage roles via [SSO group role assignment](/sso/identity-provider-role-assignment). Their assigned role defines the user’s access level for the particular [organization](/reference/organization). All [SSO profiles](/reference/sso/profile) have assigned roles. If no role is explicitly assigned through SSO group role assignment, the user receives the [default role](/rbac/configuration/configure-roles/default-role). Roles are granted to SSO profiles when the user authenticates. Role slugs are returned on [SSO Profile](/reference/sso/profile) objects from the API. These can be used to assign a role to your internal user object based on group memberships. ### Role-Based Access Control (RBAC) Assign roles and manage access for users and organizations ## Introduction WorkOS Role-Based Access Control (RBAC) is an authorization system designed for managing access to applications using a flexible roles and permissions model. With WorkOS RBAC, teams can also define custom roles at the organization or tenant level, assign permissions to those roles, and enforce access policies at scale. RBAC also supports role assignment from identity provider (IdP) groups, making it easy to integrate with Single Sign-On (SSO) and Directory Sync workflows for seamless, enterprise-ready access control. ## Key features - Fully managed authorization service for defining and enforcing access controls across your application - Configure roles, permissions, and organization-level roles directly in the [WorkOS Dashboard](https://dashboard.workos.com) - Seamless integration with [AuthKit user management](/authkit) by assigning roles via API and enforcing access through session JWTs - Support for enterprise features like organization-scoped roles and IdP role assignment via SSO and Directory Sync allowing your customers to automatically map roles from their identity provider to streamline enterprise onboarding - Fully integrated with [WorkOS Widgets](/widgets), including role management through the User Management Widget ## Additional resources - [The developer's guide to RBAC](https://workos.com/guide/the-developers-guide-to-rbac) - [8 Role-Based Access Control (RBAC) examples in action](https://workos.com/blog/role-based-access-control-example) - [How to build RBAC with WorkOS and Node](https://workos.com/blog/rbac-with-workos-and-node) ### IdP Role Assignment Map identity provider groups to roles to automatically assign roles to users ## Overview Identity Provider (IdP) role assignment is the process of mapping identity provider groups to roles to automatically assign roles to users. Users are assigned to groups via the identity provider. Groups usually correspond to roles in your app. Therefore, IT admins will often map a group one-to-one to a role. This can be defined within the WorkOS dashboard or Admin Portal for your application to receive automatic role updates. ## Role assignment sources ### Directory Sync Roles can be assigned from the identity provider via Directory Sync through [directory group role assignment](/directory-sync/identity-provider-role-assignment/directory-group-role-assignment). Admins can map groups to roles in the Admin Portal during SCIM and Google Workspace directory setup. You can also manage these assignments in the [WorkOS Dashboard](https://dashboard.workos.com/). Enterprise organizations typically use SSO to manage user authentication and SCIM (Directory Sync) for user lifecycle management. While access management can be automated through either SSO or SCIM, SCIM is generally the preferred option due to its real-time synchronization capabilities. ### SSO Roles can be assigned from the identity provider via SSO through [SSO group role assignment](/sso/identity-provider-role-assignment/sso-group-role-assignment). Admins can map groups to roles in the Admin Portal during SSO connection setup. You can also manage these assignments in the [WorkOS Dashboard](https://dashboard.workos.com/). SSO group role assignment is supported in both SAML and OIDC-based connection types, except for Google OIDC due to [a limitation](https://issuetracker.google.com/issues/133774835?pli=1) with the groups claim. A key limitation of SSO-based role assignment is that changes made in the identity provider (IdP) only take effect after the user re-authenticates. In contrast, SCIM propagates changes immediately without requiring user interaction, enabling applications to revoke sessions and enforce access updates in real time. > If your organization has a directory connection configured, it is recommended to use the [directory for role assignment](/directory-sync/identity-provider-role-assignment/directory-group-role-assignment). ## AuthKit integration If you are [integrating with AuthKit](/authkit/roles-and-permissions/role-assignment), our full user management solution, roles are automatically assigned to the appropriate [organization membership](/reference/authkit/organization-membership). These roles are also reflected in the [user’s session token](/authkit/sessions/integrating-sessions/access-token), ensuring consistent access control across your application. When using SSO group role assignment, roles are populated on the organization membership through SSO groups, allowing role assignment based on your customer’s identity provider configuration each time a user authenticates. When using Directory Sync group role assignment, roles are populated on the organization membership through [directory provisioning](/authkit/directory-provisioning), allowing for seamless, real-time role assignment based on your customer’s identity provider configuration. ## Priority order If a user is provisioned from multiple groups with conflicting roles, the role with the highest priority will be assigned. If using multiple roles, priority order should be ignored. ![Edit role priority dialog](https://images.workoscdn.com/images/3c6946c2-4ff1-41e4-b10f-568339dc3a2b.png?auto=format&fit=clip&q=50) ## Multiple roles When [multiple roles is enabled](/rbac/configuration/configure-roles/multiple-roles), users can receive multiple roles through identity provider group memberships. This applies to both [SSO group role assignment](/sso/identity-provider-role-assignment) and [Directory Sync group role assignment](/directory-sync/identity-provider-role-assignment). ### How multiple roles work with IdP assignment - **All applicable roles assigned**: Users receive all roles from groups they belong to that have explicit role mappings - **Union of permissions**: Users get the combined permissions from all assigned roles - **Priority order ignored**: When multiple roles are enabled, priority order is not used since users receive all applicable roles - **Minimum one role**: Every user must have at least one role - if no groups have explicit mappings, the user receives the [default role](/rbac/configuration) ### Example scenario If a user is a member of both "Engineering" and "Design" groups in their identity provider: - **Single role mode**: User receives the highest priority role (e.g., "Engineering") - **Multiple roles mode**: User receives both "Engineering" and "Designer" roles This prevents "role explosion" where you would otherwise need to create hybrid roles like "designer-engineer" for every possible combination. ## Explicit vs. default role assignments Explicit role assignments are created by manually mapping an IdP group to a role in the WorkOS Admin Portal or Dashboard. Default role assignments are created for any IdP group that does not have an explicit role mapping. Default group role assignments are always mapped to the configured [default role](/rbac/configuration/configure-roles/default-role). ## Role assignment in Admin Portal You can choose to show or hide the role assignment step in Admin Portal, and whether to show the steps for Directory Sync or SSO at an environment level on the _Roles & Permissions_ page in the [WorkOS Dashboard](https://dashboard.workos.com/). ![Role assignment in Admin Portal dialog](https://images.workoscdn.com/images/fe19e3ac-6370-404e-9590-cdb06b3de127.png?auto=format&fit=clip&q=50) For your customers that may have a different setup, you can override the role assignment in Admin Portal setting per-organization, on the _Roles_ tab of the organization page in the [WorkOS Dashboard](https://dashboard.workos.com/). For example, if most customers use Directory Sync but a few only use SSO, select "Directory groups" role assignment at the environment level, and select "Single Sign-On groups" at the organization level for the exceptions. ### Configuration Configure roles and permissions ## Overview A role represents a logical grouping of permissions, defining access control levels for users within your application. Roles are identified by unique, immutable slugs and are assigned to users via [organization memberships](/authkit/users-organizations/organizations). Role assignments can be sourced manually or from Identity Provider (IdP) group mappings (SSO or Directory Sync). Permissions grant users privileged access to resources and actions in your application and are referenced in your code by unique, immutable slugs. A permission can be assigned to any number of roles. > Role and permission configuration applies to [all integrations](/rbac/integration). --- ## Configure roles Roles alone can be sufficient when your application only requires very coarse-grained access control. This is suitable if users only need to be separated into broad categories and there is minimal overlap between roles. Simple roles can be easier to manage, but are less flexible for complex access control scenarios. ![Roles section WorkOS Dashboard](https://images.workoscdn.com/images/09c8fb23-5748-4236-914e-79849ac03a9a.png?auto=format&fit=clip&q=50) You can manage roles in the _Roles & Permissions_ section of the [WorkOS Dashboard](https://dashboard.workos.com/environment/roles-and-permissions/). Role slugs are immutable and cannot be changed after creation. Environment role slugs are unique within an environment. [Organization role](/rbac/organization-roles) slugs are unique within an organization. ### Default role Role configuration occurs at the environment level. Each environment is seeded with a default `member` role, which is automatically assigned to every organization member. This default role cannot be deleted, but any role can be set as the default. If you need to set default roles or other role configurations at the organization level, refer to the [Organization roles](/authkit/roles-and-permissions/organization-roles) section. ### Multiple roles All [integrations](/rbac/integration) support multiple roles across directory users, SSO profiles, and organization memberships. For any user, if role(s) are not explicit set, they will receive the default role. Multiple roles is disabled by default. To manage this setting, open the [Roles & Permissions](https://dashboard.workos.com/environment/roles-and-permissions/configuration) configuration page and scroll to the _Multiple Roles_ section. > Multiple roles is an **environment-level** setting and applies to all organizations in that environment. ### Priority order Role priority order is used for [IdP role assignment](/rbac/idp-role-assignment) to resolve conflicts when a user belongs to multiple mapped groups. The highest-priority role wins. Priority order also determines which role will be assigned to users when migrating from a multiple roles to single role configuration in the environment. ### Delete roles When roles are deleted: - **Single-role (default):** All affected organization memberships, SSO profiles, and directory users are reassigned to the **default role**. - **Multiple-roles:** The deleted role is **removed** from each organization membership that has it, any other roles on the membership remain intact. Deletion is asynchronous, so updates may take a moment to propagate. > **Tip:** To migrate from one default role to another, set the new default, then delete the old one—users will be reassigned automatically. --- ## Configure permissions Permissions allow for more detailed and flexible management of access. They are particularly useful when: - You anticipate the need to frequently modify access rights or introduce new roles. - There is significant overlap in access rights between different roles, but with some variations. - You want to minimize code changes when modifying access rights. By abstracting access control checks to permissions, you can add or modify roles and their access rights without changing the application code. ### Create permissions You can manage permissions in the _Roles & Permissions_ section of the [WorkOS Dashboard](https://dashboard.workos.com/environment/roles-and-permissions/permissions). When configuring permissions, we recommend: - Defining a common naming scheme to use across all permissions for your application. Consider separating the resource and action with a delimiter, such as `users:view`. The following delimiters are permitted: `-.:_*`. - Keep permission slugs clear and concise. When assigned to roles, these slugs will included as part of session cookies in the [session JWT claims](/authkit/sessions/integrating-sessions/access-token), which is limited to a maximum size of 4KB in many modern web browsers. ### Assign permissions to roles Permissions can be assigned when creating a new role or when editing an existing role. ![Assign permissions to a role](https://images.workoscdn.com/images/f6fd6d9a-a7b0-4df7-908b-b657e669a3dc.png?auto=format&fit=clip&q=50) ## Pipes {#pipes} ### Pipes Enable your customers to connect their third-party accounts to your application. ## Introduction Pipes allows your users to securely connect their third-party accounts to your application. With Pipes, you can easily integrate with popular services like GitHub, Slack, Google, Salesforce, and many more without managing OAuth flows, token refresh logic, or credential storage. > Reach out to support via [email](mailto:support@workos.com) or Slack if you are interested in early access. ## Configuring providers To make an provider available to your users, you will need to configure it in the WorkOS Dashboard. Visit the _Pipes_ section of the WorkOS Dashboard to get started. Click _Connect provider_ then choose the provider from the list. If you don’t see the provider you need, please reach out to [our team](mailto:support@workos.com). ![A screenshot of a GitHub provider being configured via the Pipes page in the WorkOS Dashboard](https://images.workoscdn.com/images/88a1f135-53ba-4d26-92ef-6c61e924e178.png?auto=format&fit=clip&q=50) ### Shared Credentials For the fastest setup, you can use WorkOS-managed shared credentials in sandbox environments. This allows users to connect immediately without requiring you to create OAuth applications with each provider. 1. Specify the required **scopes** for your application. 2. Provide an optional **description**. This will be used in the widget to inform users on how your application will use their data from the provider. ### Custom Credentials For production applications, configure the provider with your own OAuth credentials: 1. **Create an OAuth application** within the provider's dashboard. 1. You can find instructions on setting up the provider in the documentation section of the setup modal. 1. Use the provided **redirect URI** when configuring the provider. 1. Set the **client ID and secret** from the provider. 1. Specify the required **scopes** for your application. 1. You may need to set these scopes in the provider configuration as well. 1. Provide an optional **description**. This will be used in the widget to inform users on how your application will use their data from the provider. Commonly used scopes are provided in-line, but you should consult each provider's documentation for the full list of available scopes. ## Provider management in your application The [Pipes Widget](/widgets/pipes) provides a pre-built UI for users to connect and manage their connected accounts. The widget shows the user which providers are available, and lets them easily initiate the authorization flow. It communicates with the WorkOS API and stores the connection information for the user. If there's ever a problem with the user’s access token, the widget will let them know they need to reauthorize. ![Pipes widget screenshot](https://images.workoscdn.com/images/e84a33bb-0510-4d85-9041-33b1a0ce938c.png?auto=format&fit=clip&q=50) > The description in the widget is set in the provider's configuration in the WorkOS Dashboard. ## Fetching access tokens Once a user has connected a provider, you can [fetch access tokens](/reference/pipes) from your backend to make API calls to the connected service on their behalf. Pipes takes care of refreshing the token if needed, so you’ll always have a fresh token. If there’s a problem with the token, the endpoint will return information about the issue so you can direct the user to the correct it. This may require sending the user to re-authorize directly or via the page with the Pipes widget. ## Migrations {#migrate} ### Migrate from Stytch Learn how to migrate users and organizations from Stytch. ## Introduction The WorkOS API allows you to migrate your existing user data from a variety of existing sources. In this guide, we will walk through the steps to export and import your B2B users, organizations, and enterprise configurations from Stytch. --- ## (1) Export data from Stytch Stytch allows customers to export organization and member data using their API endpoints. You can [export most data programmatically](https://stytch.com/docs/b2b/guides/migrations/exporting-from-stytch), though password hashes and complete SSO/SCIM connection configurations require contacting Stytch support. ### Exporting organizations and members Use the [Stytch Search Organizations API](https://stytch.com/docs/b2b/api/search-organizations) to retrieve all organizations in your Stytch project, then use the [Stytch Search Members API](https://stytch.com/docs/b2b/api/search-members) to export members for each organization. Both endpoints support pagination for projects with more than 1000 records and have a rate limit of 100 requests per minute. > The following exports B2B Users. To export Consumer Users, consult [this utility from Stytch](https://github.com/stytchauth/stytch-node-export-users). ```typescript title="Export organizations and members from Stytch" ; ; const client = new B2BClient({ project_id: process.env.STYTCH_PROJECT_ID, secret: process.env.STYTCH_SECRET, }); async function exportOrganizations() { const allOrganizations: any[] = []; let cursor = ''; do { const response = await client.organizations.search({ cursor, limit: 1000, }); allOrganizations.push(...response.organizations); cursor = response.results_metadata.next_cursor; } while (cursor); return allOrganizations; } async function exportMembers(organizationIds: string[]) { const allMembers: any[] = []; let cursor = ''; do { const response = await client.organizations.members.search({ organization_ids: organizationIds, cursor, limit: 1000, }); allMembers.push(...response.members); cursor = response.results_metadata.next_cursor; } while (cursor); return allMembers; } (async () => { const organizations = await exportOrganizations(); const organizationIds = organizations.map((org) => org.organization_id); console.log(`Found ${organizations.length} organizations`); const members = await exportMembers(organizationIds); console.log(`Found ${members.length} members`); // Export all data to a JSON file await writeFile( 'stytch-b2b-export.json', JSON.stringify({ organizations, members }, null, 2), ); })(); ``` The Organization object includes `organization_id`, `organization_name`, `email_allowed_domains`, `sso_active_connections`, and `scim_active_connection` fields. The Member object includes `member_id`, `email_address`, `name`, `status`, `oauth_registrations`, `sso_registrations`, and `roles` fields. ### Exporting passwords If your Stytch members sign in using password-based authentication, you will need to [contact Stytch support](mailto:support@stytch.com) to export password hashes. After opening a request, they will provide an export of your hashed password data. The timeline for this process can vary. Stytch uses the `scrypt` password hashing algorithm for password storage. When you export passwords through Stytch support, verify the hash format they provide, as WorkOS supports multiple algorithms including `scrypt`, `bcrypt`, and `argon2`. --- ## (2) Import data into WorkOS Once you've obtained the necessary export data from Stytch, you can import it into WorkOS via the API. We recommend importing organizations first, then users with their organization memberships. ### Creating organizations Use the [Create Organization API](/reference/organization/create) to import each Stytch organization. Map `organization_name` to `name` and `email_allowed_domains` to `domainData` (with appropriate `state` values). ```typescript title="Import organizations into WorkOS" ; const workos = new WorkOS(process.env.WORKOS_API_KEY); async function importOrganization(stytchOrg: any) { const domainData = stytchOrg.email_allowed_domains?.map((domain: string) => ({ domain, state: 'pending', // or 'verified' if domains are pre-verified })) || []; const org = await workos.organizations.createOrganization({ name: stytchOrg.organization_name, domainData, }); return org; } // Import all organizations const orgIdMapping = new Map(); for (const stytchOrg of stytchOrganizations) { try { const workosOrg = await importOrganization(stytchOrg); orgIdMapping.set(stytchOrg.organization_id, workosOrg.id); } catch (error: any) { console.error(`[FAILED] ${stytchOrg.organization_name}`, error.message); } } ``` ### Creating users and memberships Use the [Create User API](/reference/authkit/user/create) to import each Stytch member, then use the [Organization Membership API](/reference/authkit/organization-membership/create) to link users to their organizations. You should filter members by status—typically only importing `active` members and potentially re-inviting `invited` or `pending` members. ```typescript title="Import users and create memberships" async function importUser(stytchMember: any) { // Parse name into first and last name const nameParts = stytchMember.name?.split(' ') || []; const firstName = nameParts[0] || ''; const lastName = nameParts.slice(1).join(' ') || ''; const user = await workos.userManagement.createUser({ email: stytchMember.email_address, emailVerified: stytchMember.email_address_verified, firstName, lastName, }); return user; } async function createMembership( workosUserId: string, workosOrgId: string, roleSlug: string = 'member', ) { return await workos.userManagement.createOrganizationMembership({ userId: workosUserId, organizationId: workosOrgId, roleSlug, }); } const userIdMapping = new Map(); for (const stytchMember of stytchMembers) { try { const workosUser = await importUser(stytchMember); userIdMapping.set(stytchMember.member_id, workosUser.id); const workosOrgId = orgIdMapping.get(stytchMember.organization_id); if (workosOrgId) { await createMembership(workosUser.id, workosOrgId); } else { console.warn(`No WorkOS org found for ${stytchMember.email_address}`); } } catch (error: any) { console.error(`[FAILED] ${stytchMember.email_address}`, error.message); } } ``` > User creation is rate-limited. See the [rate limits documentation](/reference/rate-limits) for details. Consider implementing retry logic and batching for large imports, or reach out to [support@workos.com](mailto:support@workos.com) to process large datasets in the background. ### Importing passwords If you exported password hashes from Stytch, you can import them during user creation or later using the [Update User API](/reference/authkit/user/update). Pass the `passwordHashType` parameter (e.g., `'scrypt'`, `'bcrypt'`) and the `passwordHash` value from your Stytch export. Once imported, users can sign in with their existing passwords without performing a password reset. ```typescript title="Import user with password hash" const user = await workos.userManagement.createUser({ email: stytchMember.email_address, emailVerified: stytchMember.email_address_verified, firstName, lastName, passwordHash: stytchPasswordHash, // From Stytch support export passwordHashType: 'scrypt', // Verify the actual format with Stytch support }); ``` --- ## (3) SSO connections Enterprise SSO connections cannot be exported from Stytch, but you can manually reconfigure connections. You have two options: configure each connection through the dashboard, or use the [Admin Portal](/admin-portal) to let customers self-service their SSO setup. The Admin Portal approach is recommended for larger migrations, as it reduces manual work and provides a familiar self-service experience for IT administrators. To manually configure a SAML connection, create the organization (if not already created), then set up a new SAML connection in the dashboard. ```typescript title="Create SSO connection programmatically" ; const workos = new WorkOS(process.env.WORKOS_API_KEY); // Generate Admin Portal link for customer to self-configure SSO const { link } = await workos.portal.generateLink({ organization: 'org_12345', intent: 'sso', returnUrl: 'https://yourapp.com/admin', }); // Send this link to the customer's IT administrator console.log('Admin Portal link:', link); ``` The OIDC process is similar: create the organization, configure a new OIDC connection, obtain the callback URL, and work with the customer's IT team to update their OIDC application configuration. See the [OIDC integration guide](/integrations/oidc) for detailed instructions. For provider-specific guidance, consult the integration guides for [Okta SAML](/integrations/okta-saml), [Microsoft Entra ID SAML](/integrations/entra-id-saml), [Google Workspace SAML](/integrations/google-saml), or [Generic SAML](/integrations/saml). --- ## (4) Directory Sync Like SSO connections, SCIM directory sync connections must be reconfigured. [Directory Sync](/directory-sync) provides real-time user and group provisioning, automatic deprovisioning, custom attribute mapping, and support for 20+ identity providers including [Okta SCIM](/integrations/okta-scim), [Microsoft Entra ID SCIM](/integrations/entra-id-scim), [Google Workspace Directory](/integrations/google-saml), and [Custom SCIM v2.0](/integrations/scim) providers. For each Stytch SCIM connection, create a corresponding Directory Sync connection in the dashboard or using the [Admin Portal](/admin-portal) for self-service setup. ```typescript title="Generate Admin Portal link for Directory Sync" const { link } = await workos.portal.generateLink({ organization: 'org_12345', intent: 'dsync', returnUrl: 'https://yourapp.com/admin', }); ``` WorkOS sends webhooks for directory sync events like `dsync.user.created`, `dsync.user.updated`, `dsync.user.deleted`, and `dsync.group.updated`. Configure webhooks in the dashboard to receive these events and keep your application in sync with directory changes. ```typescript title="Handle directory sync events" app.post('/webhooks/workos', async (req, res) => { const event = req.body; switch (event.event) { case 'dsync.user.created': await createUserFromDirectory(event.data); break; case 'dsync.user.deleted': await deactivateUser(event.data.id); break; case 'dsync.group.updated': await syncGroupMemberships(event.data); break; } res.status(200).send(); }); ``` See the [Directory Sync guide](/directory-sync) for complete implementation details. --- ## (5) Authentication and access control Stytch B2B supports several authentication methods and access control features that have equivalent capabilities in AuthKit, though some migration adjustments are necessary. ### Authentication methods Both Stytch and WorkOS support traditional email and password authentication. After importing your users with their password hashes, users can sign in immediately with their existing credentials. Enable password authentication in the dashboard under the _Authentication_ tab and configure password strength requirements as needed. Stytch's magic link authentication can be replaced with [Magic Auth](/authkit/magic-auth). While Stytch sends clickable magic links via email, Magic Auth sends a six-digit one-time code that users enter manually. Magic Auth codes expire after 10 minutes and are automatically validated by AuthKit. Stytch's email OTP authentication is functionally identical to Magic Auth, so no application logic changes are needed. If your Stytch users sign in through OAuth providers like Google, Microsoft, or GitHub, they can continue using the same providers. After configuring OAuth providers in the dashboard, users can sign in with their social credentials and will be automatically linked to their user account based on email address matching. In the dashboard: 1. Navigate to Authentication > OAuth providers 2. Select the provider (Google, Microsoft, GitHub, etc.) 3. Add OAuth client credentials (Client ID and Secret) 4. Copy the redirect URI and add to your OAuth app configuration Users authenticate through AuthKit, which handles the OAuth flow. ```typescript title="Configure OAuth providers" const { user } = await workos.userManagement.authenticateWithCode({ code: authorizationCode, clientId: process.env.WORKOS_CLIENT_ID, }); ``` Check the [integrations page](/integrations) for the complete list of supported OAuth providers, including [Google OAuth](/integrations/google-oauth), [Microsoft OAuth](/integrations/microsoft-oauth), and [GitHub OAuth](/integrations/github-oauth). ### Multi-factor authentication Both Stytch and WorkOS support TOTP authenticators like Google Authenticator, Authy, and 1Password. WorkOS supports importing existing TOTP secrets during migration through the [developer-provided TOTP secrets](https://workos.com/changelog/developer-provided-totp-secrets) feature, which allows users to keep their existing authenticator app configurations without re-enrollment. However, [Stytch cannot export TOTP secrets](https://stytch.com/docs/guides/migrations/migrating-user-data-statically#adding-totp-or-biometrics-for-mfa). Users who have TOTP MFA enrolled in Stytch will need to re-enroll their authenticator apps with WorkOS during their next sign-in. Enable MFA in the dashboard under the _Authentication_ tab and configure whether MFA is optional or required. Communicate this change to your users before migration so they're prepared to scan a new QR code or enter a new secret key. While Stytch supports SMS-based MFA, WorkOS does not due to known security vulnerabilities with SMS (SIM swapping, interception, etc.). Users who currently have SMS-based MFA will need to switch to TOTP authenticators, email-based Magic Auth, or modern biometric [Passkeys](/authkit/passkeys). See the [MFA guide](/authkit/mfa) for enrollment flows and implementation details. ### Roles and sessions Stytch B2B provides RBAC with custom resources, roles, and actions. WorkOS offers similar capabilities through [roles and permissions](/authkit/roles-and-permissions). When migrating, identify your roles defined in Stytch, create equivalent roles in the dashboard, and assign roles during migration by specifying the `roleSlug` parameter when creating organization memberships. If your Stytch implementation uses complex RBAC policies with custom resources and actions, you may need to simplify to standard roles or implement custom authorization in your application logic. ```typescript title="Assign roles during migration" const roleMapping = { stytch_admin: 'admin', stytch_member: 'member', custom_role_123: 'manager', }; await workos.userManagement.createOrganizationMembership({ userId: workosUserId, organizationId: workosOrgId, roleSlug: roleMapping[stytchMember.roles[0].role_id] || 'member', }); ``` JWT-based session tokens are used for authentication state. Your application will need to handle these session tokens. Use [an SDK](/sdks) to verify, extract user context (user ID, organization ID, role), and implement token refresh logic if using long-lived sessions. ```typescript title="Handle WorkOS sessions" ; const workos = new WorkOS(process.env.WORKOS_API_KEY); const { user, organizationId, role } = await workos.userManagement.authenticateWithCode({ code: authorizationCode, clientId: process.env.WORKOS_CLIENT_ID, }); // Store session in your application req.session.userId = user.id; req.session.organizationId = organizationId; req.session.role = role; ``` See the [AuthKit guide](/authkit) for complete session management implementation. --- ## Next steps Be sure to understand how to [handle interim new users](/migrate/other-services/3-handling-interim-new-users) for managing users who sign up during your migration process. After completing your migration to WorkOS, you can take advantage of additional features: - **[Audit Logs](/audit-logs)**: Track security-relevant events across your application - **[Radar](/authkit/radar)**: Protect against bots, fraud, and abuse - **[Vault](/vault)**: Encrypt, store, and control access to sensitive data If you haven't already, check out the [AuthKit Quick Start guide](/authkit) to learn how to integrate WorkOS into your application. For questions or assistance with your migration, contact [support@workos.com](mailto:support@workos.com). ### Migrate from the standalone SSO API Learn how to migrate your code from an existing WorkOS SSO integration. ## Introduction The WorkOS AuthKit API supports all of the same social and enterprise identity providers, while providing higher level authentication features that most applications need. In this guide, we'll outline the steps to migrate an existing WorkOS SSO integration to the AuthKit API. > The existing standalone [WorkOS SSO API](/reference/sso) will continue to be supported. This is a viable option for you if you prefer to handle more of the authentication flow yourself. ## The new User resource The primary difference between existing integrations with [SSO](/sso) or [Directory Sync](/directory-sync) is the addition of a new resource: [Users](/reference/authkit/user). The WorkOS [User object](/reference/authkit/user) represents a single user in your application, and binds together information from all of the Directory and Identity providers that WorkOS supports into a single resource. As you migrate your existing integration, you can expect to replace references to WorkOS Profiles and Directory Users with instead references to Users. ## Switch to AuthKit API calls If you have built an integration with our standalone SSO API using [Get Authorization URL](/reference/sso/get-authorization-url), you will need to switch these calls with analogous calls to the AuthKit API. ### (1) Switch SSO initiation call When initiating SSO for one of your users, instead of calling the SSO [Get Authorization URL](/reference/sso/get-authorization-url) API, call the AuthKit [Get Authorization URL](/reference/authkit/authentication/get-authorization-url) API instead: The AuthKit Get Authorization API supports all of the same initiation parameters as the SSO API. In addition, it also supports an additional provider type, `authkit`, which will be covered later in this guide. ### (2) Switch API in Application Callback Similar to an SSO integration, your application will still have a callback identified by the Redirect URI passed during the previous initiation call. The contract with your callback is the same, where you should expect to be given a `code`, along with any `state` that was originally provided. However, instead of calling the SSO [Get a Profile and Token](/reference/sso/profile/get-profile-and-token) API, call the AuthKit [Authenticate](/reference/authkit/authentication) API instead, with the `grant_type` set to `authorization_code`: > **Important:** Instead of receiving a [Profile](/reference/sso/profile), your application now receives a full [User object](/reference/authkit/user). While many of the fields are similar, such as the user’s email or name, the **User ID’s will be different** than the Profile ID’s you may have previously persisted in your application. If email is a unique identifier in your application, you can use the WorkOS User’s email to identify the application-local user. WorkOS ensures that user email is verified before successfully completing an authentication request. When the API issues an email verification challenge, an [email verification response](/reference/authkit/authentication-errors/email-verification-required-error) is returned. ### Handling new authentication flows The AuthKit API offers a higher-level abstraction than the SSO API, offering more advanced [security features](/authkit/overview/security) like email verification and account Linking. This means that when your application attempts to exchange a code for a user object, it may return one of several new expected errors. These map to cases that were previously mentioned, like requiring that the user first verify their email, or enroll in MFA. If your application doesn’t require these extra settings, they can be disabled in the _Authentication_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). > If you are using AuthKit, you won’t need to handle error cases like required email verification, as AuthKit will automatically request this before a user is directed to their callback endpoint. ## AuthKit If you prefer to have full control over the authentication UI, you can choose to integrate with the AuthKit API directly. However, the easiest way to get started is to use AuthKit Hosted UI, a pre-built hosted authentication UI that guides users through all of the advanced flows, like email verification and MFA enrollment. You can enable AuthKit from the WorkOS dashboard, where you can also configure AuthKit branding and custom domains. Getting started with AuthKit is as simple as passing `authkit` as the `provider`: AuthKit can handle many of the concerns your application likely needed to previously, such as identifying which users sign in using enterprise SSO, and correctly routing them to their organization’s identity provider. ## Directory Sync Directory provisioning is also supported in AuthKit. See the [Directory Provisioning documentation](/authkit/directory-provisioning) to learn more. ## Next Steps Check out the [full guide](/authkit), along with the [API reference](/reference/authkit) to get an idea of all the ways your application’s user management needs can be solved by WorkOS. If you need help migrating your existing WorkOS integration, or have any other questions, please reach out to [WorkOS support](mailto:support@workos.com?subject=WorkOS%20Support). ### Migrate from other services Learn how to export and import users from your own data store. ## Introduction The WorkOS AuthKit API allows you to migrate your existing user data from a variety of sources. In this guide, we'll walk through the steps to export, and then import users from your own data store. ## (1) Exporting data While moving authentication related metadata to WorkOS, most applications will continue to store certain user information in their data store. This common subset of data will usually be the following: | Field | Description | Status | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------ | -------- | | Email | The user’s email address. Used for various authentication and verification purposes. | Required | | First Name | The user’s first, or given name. | Optional | | Last Name | The user’s last, or family name. | Optional | | Verification Status | The user’s email verification status if they have gone through a verification flow. Assumed as “not verified” unless supplied. | Optional | | Password | The user’s password hash, if they use password-based authentication. | Optional | While preparing the migration, you’ll want to ensure this information is programmatically available for use in the import step, this can mean: - Exporting the relevant data to a file such as JSON or CSV. - Allowing the data to be queried from the data store directly. After the data is accessible, we can configure the import. --- ## (2) Importing Users into WorkOS Now that the User data is available, we can import it into WorkOS. ### Creating users For each of your users, you can call the WorkOS [Create User API](/reference/authkit/user/create). This will create a matching [User object](/reference/authkit/user) within WorkOS. A successful response will include a new WorkOS user ID, most apps will want to persist this WorkOS user ID alongside the application-local user object. ```json { "object": "user", /* highlight-start */ "id": "user_01E4ZCR3C56J083X43JQXF3JK5", /* highlight-end */ "email": "marcelina.davis@gmail.com", "firstName": "Marcelina", "lastName": "Davis", "emailVerified": true, "createdAt": "2021-06-25T19:07:33.155Z", "updatedAt": "2021-06-25T19:07:33.155Z" } ``` > **Email addresses are unique** to each WorkOS environment. If you have a subset of users already in WorkOS, you may need to handle constraint violation errors. There are now several options on how to proceed, depending on your application’s needs: ### Importing passwords If your users currently use password-based authentication, you can import existing password hashes during the [users creation](/reference/authkit/user/create) process, or later using the WorkOS [Update User API](/reference/authkit/user/update). WorkOS currently supports the following password hashing algorithms: - `bcrypt` - `scrypt` - `firebase-scrypt` - `ssha` - `pbkdf2` - `argon2` For `scrypt` and `pbkdf2` passwords, use the PHC string format. The hash and salt should be B64 encoded: trim the `=` characters that represent Base64 padding. Using a PHC-formatting library, like Node's [`@phc/format`](https://www.npmjs.com/package/@phc/format), should handle this for you. The following table shows how to map the `scrypt` and `pbkdf2` parameters to the PHC parameters. #### scrypt | `Scrypt` value | | PHC hash parameter | | ----------------- | --- | ------------------ | | `key length` | → | `kl` | | `cost` | → | `n` | | `rounds` | → | `r` | | `parallelization` | → | `p` | A valid `scrypt` PHC formatted string looks like this: ```txt $scrypt$v=1$n=16384,r=8,p=1,kl=64$Swhqd4iUYTtWfbCYIPeuMw$q7pfdBQMJujd5FX/qX+ozM2O6aNqP+mo1ZnHGH15XM2vlhroQfPA037UpbdfpH4H66OrSPjsUhfkAMuNoBiQvw ``` #### pbkdf2 | `pbkdf2` value | | PHC hash parameter | | -------------- | --- | ------------------ | | `digest` | → | `d` | | `iterations` | → | `i` | For `pbkdf2` allowed values for digest are `sha256` or `sha512`. The value for iterations is dependent on digest. For `sha256` there is a minimum of 600,000 iterations and a max of 1,000,000. For `sha512` there is a minimum of 210,000 and a max of 1,000,000. A valid `pbkdf2` PHC formatted string looks like this: ```txt $pbkdf2$i=600000,d=sha256$T2ptRFh6MXhDQVh2SWZuUGdpQXBUTg$xXiyTisD7390NijyCv5ICMhFW4eDuMlzypRoLGLyIvA ``` #### argon2 | `argon2` value | | PHC hash parameter | | -------------- | --- | ------------------ | | `variant` | → | algorithm id | | `version` | → | `v` | | `memory` | → | `m` | | `time` | → | `t` | | `parallelism` | → | `p` | The variant should be `argon2id`, but older supported variants include `argon2d` and `argon2i`. The version must be `19`. The following memory, time (iterations), and parallelism settings are based on [OWASP recommendations](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id). Memory is specified in KiB with a minimum of 4,096 KiB (4 MiB) and maximum of 262,144 KiB (256 MiB). For time, there is a minimum of 1 iteration and a maximum of 5 iterations, except for `argon2i` which has a minimum of 3 iterations. Parallelism ranges from 1 to 8 threads. If your requirements fall outside of these guidelines, please [contact support](mailto:support@workos.com). A valid `argon2` PHC formatted string looks like this: ```txt $argon2id$v=19$m=65536,t=3,p=4$c29tZXNhbHQ$RdescudvJCsgt3ub+b+dWRWJTmaaJObG ``` For `firebase-scrypt` passwords, refer to the [Firebase Migration guide](/migrate/firebase) for an example of how to format the `password_hash`. For `ssha` passwords, use the following algorithm: 1. Generate a `salt`: random bytes 2. Hash the user’s password and the `salt` using the SHA1 algorithm 3. Base64 encode the hash followed by the salt 4. Prepend the string with `{SSHA}` A high-level representation is: `{SSHA}base64(sha1(password + salt) + salt)`. Once imported, users can continue to sign-in with their existing password, **without** having to go through a password reset flow. ### Triggering password resets If you are unable to export passwords from your existing data store, whether for security reasons or other limitations, you can programmatically trigger a password reset flow using the WorkOS [Password Reset API](/reference/authkit/password-reset). This process can be initiated at any time, and doesn’t need to happen during the user import process. Some applications may want to remove password-based authentication when switching to WorkOS, in favor of another method like Magic Auth. If this is the case for your application, you can skip dealing with passwords entirely. ### Migrating social auth users If you have users who previously signed in using social auth providers, such as [Google](/integrations/google-oauth) or [Microsoft](/integrations/google-oauth), those users can continue to sign in with those providers after you’ve migrated to WorkOS. Check out our [integrations](/integrations) page for guidance on configuring the relevant provider’s client credentials in WorkOS. After your provider is configured in WorkOS, users can sign in with their provider credentials and will be automatically linked to a WorkOS user. WorkOS uses the **email address** from the social auth provider to determine this match. > Some users may need to verify their email address through WorkOS if email verification is enabled in your WorkOS environment’s authentication settings. Email verification behavior varies depending on whether the provider is known to verify email addresses. For example, users signing in using Google OAuth and a `gmail.com` email domain will not need to perform the extra verification step. --- ## (3) Handling interim new users Many applications allow users to sign up at any time. If your app offers this feature, then you should consider the timing of your migration. If any users sign up after you’ve completed importing users into WorkOS, but before you’ve switched to WorkOS for authentication, then those users will have been omitted from the migration process. There are two main strategies to handle this: ### (A) Disable signups during migration The simplest solution is to schedule an appropriate time for the migration and disable signup while in progress. This may be done using temporary code added to your application and controlled by a feature flagging system. After the migration is complete, your application should be updated to perform authentication using WorkOS, and the signup flag block disabled. This helps to ensure the export/import process captures all active users. ### (B) Use a dual-write strategy For applications that want to avoid disabling signups, a “dual-write” strategy can be used. ![Diagram demonstrating the dual-write process.](https://images.workoscdn.com/images/656fbbac-adb1-4f99-b416-056d80e408ac.png?auto=format&fit=clip&q=80)[border=false] When a new user signs-up, in addition to creating a user record in the existing user store, the application should also create a matching record in WorkOS using the [Create User API](/reference/authkit/user/create). As time passes, WorkOS will stay consistent with future new users, but a migration will still need to be performed for the historical set of users. You will need to perform the same export and import process into WorkOS, but keeping in mind that some users will already exist in WorkOS as a result from the “dual-write”. While this minimizes forms of downtime for your application, there are other complications. For example, if a user updates their email or authentication method, you will need to perform the same update in WorkOS, at least until the migration process is complete. ### Which to choose? Your timeline for completing the migration, along with your user’s tolerances for disruption, will affect which strategy makes more sense for your application. Disabling signups, or even sign-in entirely, and doing a “big-bang” migration by moving all users at the same time, could be reasonable for a smaller application. However, larger applications that are on the critical path for their customers may need a more careful path in order to provide consistent access. ## Wrapping-up User management migration complexity can vary, so it is important to consider how existing application constraints will transfer to WorkOS. If you have any questions, reach out to [support@workos.com](mailto:support@workos.com) or via your team’s WorkOS Slack channel for more help planning your migration. ### Migrate from Firebase Learn how to migrate users to WorkOS from Firebase. ## Introduction The WorkOS AuthKit API allows you to migrate your existing user data from a variety of existing sources. In this guide, we'll walk through the steps to export your users from Firebase, and then import them into WorkOS. ## (1) Exporting Firebase user data Firebase customers can export their user data using either the [Firebase CLI](https://firebase.google.com/docs/cli/auth#auth-export) or the [Firebase API](https://firebase.google.com/docs/reference). In this guide we’ll be using the Firebase CLI, use the following command to retrieve a dump of all users in JSON or CSV format. ```bash title="Exporting users with the Firebase CLI" firebase auth:export --project= --format=json users.json ``` ## (2) Importing users into WorkOS After obtaining your user data from Firebase, it’s time to import it into WorkOS, mapping attributes from the [Firebase User format](https://firebase.google.com/docs/cli/auth#JSON) to WorkOS API parameters. Using the WorkOS [Create User API](/reference/authkit/user/create), you can create a corresponding record in WorkOS for each exported user. Use the following mapping from the Firebase format to parameters in your WorkOS Create User API calls: | Firebase | | WorkOS API | | --------------- | --- | ---------------- | | `email` | → | `email` | | `emailVerified` | → | `email_verified` | | `displayName` | → | `first_name` | | `displayName` | → | `last_name` | ### Importing passwords If your users sign in to your Firebase application using passwords, you can choose to also import those password hashes. Firebase uses a [forked version of `scrypt`](https://firebaseopensource.com/projects/firebase/scrypt/) which can be directly imported during the [user creation](/reference/authkit/user/create) process into WorkOS, or later using the [Update User API](/reference/authkit/user/update). First, retrieve your Firebase project's password hash parameters from the Firebase console following the [export documentation](https://firebase.google.com/docs/cli/auth#password_hash_parameters). These parameters are the `base64_signer_key`, `base64_salt_separator`, `rounds`, and `mem_cost`. Next, retrieve the password salts and hashes for each of your individual Firebase users by running the [Firebase CLI `auth:export` command](https://firebase.google.com/docs/cli/auth#auth-export). Your Firebase users that have a password set will have a `passwordHash` and `salt` field present which will be imported into WorkOS. Finally, you will need to format these parameters into a [PHC-compatible](https://github.com/P-H-C/phc-string-format/blob/5f1e4ec633845d43776849f503f8ce8314b5290c/phc-sf-spec.md) password hash following this Firebase to PHC hash parameter mapping: | Firebase value | | PHC hash parameter | | ----------------------- | --- | ------------------ | | `base64_signer_key` | → | `sk` | | `base64_salt_separator` | → | `ss` | | `rounds` | → | `r` | | `mem_cost` | → | `m` | The hash, salt, along with `sk` and `ss` parameters, should be [B64 encoded](https://github.com/P-H-C/phc-string-format/blob/5f1e4ec633845d43776849f503f8ce8314b5290c/phc-sf-spec.md#b64), which means trimming the `=` characters that represent base64 padding. Using a PHC-formatting library, like [`@phc/format`](https://www.npmjs.com/package/@phc/format) for Node, should handle this for you. ## Other authentication methods Firebase authentication methods vary depending on your specific usage, and corresponding connections can be easily configured in WorkOS. This allows users to continue signing in with the same authentication methods, matching the previous sign in experience. ### Social Auth Providers If your users “Sign in with Google” or similar, you can configure WorkOS to continue using those sign in methods. Migrating these connections involves providing the same client credentials (i.e. Client ID and Client Secret) to WorkOS as configured in Firebase. For more details on supported connections, see the provider-specific integration guides, such as for [Microsoft](/integrations/microsoft-oauth) and [Google](/integrations/google-oauth). Reach out to [support@workos.com](mailto:support@workos.com) if there are additional Social Auth providers you would like to see supported. ### Email Link If your users sign in using [Email Link](https://firebase.google.com/docs/auth/web/email-link-auth), sometimes called “passwordless”, you can achieve the same experience by adding WorkOS [Magic Auth](/reference/authkit/magic-auth) to your application. ### OIDC and SAML Enterprise authentication often uses standard protocols such as [OpenID Connect (OIDC)](https://firebase.google.com/docs/auth/web/openid-connect) or [SAML](https://firebase.google.com/docs/auth/web/saml) between your service and identity provider. The same identity providers can be configured in WorkOS, preserving the sign in process familiar to your users. For specific instructions, see the guides on setting up [OIDC](/integrations/oidc) and [SAML](/integrations/saml) connections with WorkOS. ### Migrate from Descope Learn how to migrate users and organizations from Descope. ## Introduction The AuthKit API allows you to migrate your existing user data from a variety of existing sources. In this guide, we will walk through the steps to export, and then import your users from Descope. --- ## (1) Export Descope data Descope allows you to export user data through their [Management API](https://docs.descope.com/api/management/users) or directly from the Descope console. You can export user data programmatically using the [Search Users endpoint](https://docs.descope.com/management/user-management/user-exporting). The `searchAll()` function in the Descope Backend SDKs retrieves a comprehensive list of users. Submitting an empty request payload will return all users: ```bash curl -X POST https://api.descope.com/v1/mgmt/user/search \ -H 'Authorization: Bearer :' \ -H 'Content-Type: application/json' \ -d '{}' ``` Alternatively, you can export users directly from the [Descope console](https://docs.descope.com/management/user-management/user-exporting) by selecting users on the users page and clicking the "Export CSV" button. ### Exporting passwords If your Descope users currently sign in using password-based authentication, and you'd like to import those passwords, you'll need to [contact Descope support](https://docs.descope.com/management/user-management/user-exporting). Descope does not make hashed passwords available through their Backend APIs. After opening a support ticket, Descope can generate a CSV file containing your users' data including password hashes and facilitate a secure data transfer. Descope supports multiple password hashing algorithms including bcrypt, argon2, pbkdf2, and others. When you receive the password export from Descope support, make note of which hashing algorithm was used, as you'll need this information when importing. --- ## (2) Import users into WorkOS Once you've obtained the necessary export data from Descope, you can import your users into WorkOS using the WorkOS APIs. ### Using WorkOS APIs With the data from Descope's user export, you can use the [Create User API](/reference/authkit/user/create) to import each user. The API is rate-limited, so for large migrations, you may want to implement batching with appropriate delays. You can view the [rate limits](/reference/rate-limits) documentation for more information. Using the fields from the Descope export, use the following mapping from Descope to parameters in your Create User API calls: | Descope | | WorkOS API | | --------------- | --- | ---------------- | | `email` | → | `email` | | `givenName` | → | `first_name` | | `familyName` | → | `last_name` | | `verifiedEmail` | → | `email_verified` | Here's an example migration script: ### Import passwords If you also exported passwords from Descope support, you can import them during the [user creation](/reference/authkit/user/create) process, or later using the [Update User API](/reference/authkit/user/update). WorkOS supports the following password hashing algorithms that Descope uses: - `bcrypt` - `argon2` - `pbkdf2` When importing passwords, pass the following parameters to the WorkOS API based on the hash format Descope provided: - The `password_hash_type` set to the appropriate algorithm (e.g., `'bcrypt'`, `'argon2'`, or `'pbkdf2'`) - The `password_hash` set to the password hash value from your Descope export For `argon2` and `pbkdf2` passwords, WorkOS expects the PHC string format. Refer to the [other services migration guide](/migrate/other-services/2-importing-users-into-workos/importing-passwords) for detailed formatting requirements for these hash types. - | Without passwords ```typescript ; const workos = new WorkOS(process.env.WORKOS_API_KEY); async function migrateUsers(descopeUsers) { for (const user of descopeUsers) { try { // In the JavaScript SDK, the property names are camelCase const workosUser = await workos.userManagement.createUser({ email: user.email, emailVerified: user.verifiedEmail, firstName: user.givenName, lastName: user.familyName, }); console.log(`Migrated user: ${user.email} -> ${workosUser.id}`); } catch (error) { console.error(`Failed to migrate user ${user.email}:`, error); } } } ``` - | With passwords ```typescript ; const workos = new WorkOS(process.env.WORKOS_API_KEY); async function migrateUsersWithPasswords(descopeUsers) { for (const user of descopeUsers) { try { const workosUser = await workos.userManagement.createUser({ email: user.email, emailVerified: user.verifiedEmail, firstName: user.givenName, lastName: user.familyName, // Include password hash if available from Descope export passwordHash: user.passwordHash, passwordHashType: user.passwordHashType, // 'bcrypt', 'argon2', or 'pbkdf2' }); console.log( `Migrated user with password: ${user.email} -> ${workosUser.id}`, ); } catch (error) { console.error(`Failed to migrate user ${user.email}:`, error); } } } ``` ### Migrate social auth users If you have users who previously signed in through Descope using social auth providers, such as [Google](/integrations/google-oauth) or [Microsoft](/integrations/microsoft-oauth), those users can continue to sign in with those providers after you've migrated. Check out the [integrations](/integrations) page for guidance on configuring the relevant provider's client credentials. After your provider is configured, users can sign in with their provider credentials and will be automatically linked to a WorkOS user. WorkOS uses the **email address** from the social auth provider to determine this match. > Some users may need to verify their email address through WorkOS if email verification is enabled in your environment's authentication settings. Email verification behavior varies depending on whether the provider is known to verify email addresses. For example, users signing in using Google OAuth and a `gmail.com` email domain will not need to perform the extra verification step. --- ## (3) Organizations Descope has a concept of ["Tenants"](https://docs.descope.com/b2b) which are analogous to [WorkOS Organizations](/reference/organization), in that both represent a B2B customer or organization within your application. ### Creating Organizations If you'd like to export your Descope tenants, you can use the [Descope Management API](https://docs.descope.com/management/tenant-management/sdks) to programmatically retrieve each tenant. You can then call the [Create Organization API](/reference/organization/create) to create matching Organizations in WorkOS. When creating Organizations in WorkOS, you can map the following fields from Descope tenants: | Descope Tenant | | WorkOS Organization | | -------------- | --- | ------------------- | | `name` | → | `name` | | `id` | → | `external_id` | Storing the Descope tenant ID as the `external_id` in WorkOS can help you maintain a reference between the two systems during migration. Here's an example migration script: ```typescript ; const workos = new WorkOS(process.env.WORKOS_API_KEY); async function migrateOrganizations(descopeTenants) { const orgIdMap = new Map(); for (const tenant of descopeTenants) { try { const workosOrg = await workos.organizations.createOrganization({ name: tenant.name, // Store the Descope tenant ID for reference externalId: tenant.id, }); console.log(`Migrated organization: ${tenant.name} -> ${workosOrg.id}`); // Store this mapping for migrating user memberships later orgIdMap.set(tenant.id, workosOrg.id); } catch (error) { console.error(`Failed to migrate organization ${tenant.name}:`, error); } } return orgIdMap; } ``` ### Adding user memberships Once you've created Organizations in WorkOS, you can add users to their respective organizations using the [Organization Membership API](/reference/authkit/organization-membership/create). In Descope, users can be associated with tenants, and this information is available when you export users via the Search Users API. Use this tenant association data to create the corresponding organization memberships in WorkOS. RBAC capabilities are available through [roles and permissions](/authkit/roles-and-permissions). When migrating, identify your roles defined in Descope, then create equivalent roles in [the dashboard](https://dashboard.workos.com/environment/roles-and-permissions), and assign roles during migration by specifying the `roleSlug` parameter when creating organization memberships. ```typescript async function migrateMemberships(descopeUserTenants, orgIdMap, userIdMap) { for (const userTenant of descopeUserTenants) { const orgId = orgIdMap.get(userTenant.tenantId); const userId = userIdMap.get(userTenant.userId); if (!orgId || !userId) { console.error(`Missing mapping for user-tenant relationship`); continue; } try { await workos.userManagement.createOrganizationMembership({ userId: userId, organizationId: orgId, // Map Descope roles to WorkOS roles as needed roleSlug: userTenant.roleNames?.[0] || 'member', }); console.log(`Migrated membership: ${userId} -> ${orgId}`); } catch (error) { console.error(`Failed to migrate membership:`, error); } } } ``` --- ## (4) Special considerations There are some differences between the authentication strategies offered by Descope and WorkOS that you should be aware of when planning your migration. ### Multi-Factor Auth Descope supports SMS-based one-time passwords (OTP) for authentication and multi-factor auth. However, WorkOS does not support SMS-based second factors due to known security issues with SMS. Users who have SMS-based authentication or second factors will need to switch to using [email-based Magic Auth](/authkit/magic-auth), or re-enroll in MFA using a [TOTP-based authenticator](/authkit/mfa) instead. ### Passkeys and advanced authentication Descope supports [passkeys](https://docs.descope.com/auth-methods/passkeys) (WebAuthn) for passwordless authentication. [Passkey authentication](/authkit/passkeys) is also available through AuthKit's hosted UI, using the WebAuthn standard. Passkeys offer: - **Progressive enrollment**: Users with password-based accounts can be prompted to create passkeys - **MFA integration**: Passkeys serve as both first and second factors when MFA is enabled - **Secure authentication**: Using biometric or PIN verification on the user's device Note that passkey authentication is currently available through the hosted UI. You'll need to configure a custom domain for your AuthKit environment before enabling passkeys in production. Descope also offers other authentication methods like Magic Links and Enchanted Links. [Magic Auth](/authkit/magic-auth) delivers a similar passwordless email-based authentication experience. ### Enterprise SSO and SCIM Both Descope and WorkOS provide robust enterprise authentication features. If you're currently using Descope's [SSO](https://docs.descope.com/auth-methods/sso) or [SCIM provisioning](https://docs.descope.com/b2b/scim) features, WorkOS offers equivalent capabilities: - [Single Sign-On (SSO)](/sso) - Support for SAML and OIDC providers - [Directory Sync](/directory-sync) - SCIM-based user provisioning from identity providers When migrating enterprise customers who use SSO, you'll need to coordinate with them to reconfigure their Identity Provider (IdP) to point to WorkOS instead of Descope. WorkOS provides [comprehensive documentation](/sso) for setting up SSO connections with various providers. ### Account linking behavior Descope has account linking capabilities that automatically link social accounts with matching verified email addresses. WorkOS also supports automatic account linking based on email addresses. When migrating users who have multiple linked accounts in Descope (e.g., password + Google OAuth), you should: 1. Import the user once with their primary email 2. Configure the relevant social providers 3. When users sign in with their social provider, they will automatically be linked with the accounts based on email match ### Handling interim new users If your application allows users to sign up at any time, you should [consider the timing of your migration](/migrate/other-services/3-handling-interim-new-users). Users who sign up after you've exported data from Descope but before you've switched to WorkOS for authentication will be omitted from the migration. There are two main strategies to handle this: #### (A) Disable signups during migration Schedule an appropriate time for the migration and temporarily disable signup functionality. This can be controlled using a feature flag in your application. After the migration is complete and your application is using WorkOS for authentication, re-enable signups. #### (B) Use a dual-write strategy For applications that cannot disable signups, implement a "dual-write" strategy. When a new user signs up, create records in both your Descope project and WorkOS using the [Create User API](/reference/authkit/user/create). This keeps WorkOS synchronized with new users, though you'll still need to perform the historical user migration. Be aware that you'll need to keep user updates (email changes, password changes) synchronized between both systems until the migration is complete. --- ## Next steps With your users now imported, you can start using WorkOS to manage authentication for your application. If you haven't already, take a look at the [AuthKit Quick Start guide](/authkit) to learn how to integrate AuthKit into your application. ### Migrate from Clerk Learn how to migrate users and organizations from Clerk. ## Introduction The WorkOS AuthKit API allows you to migrate your existing user data from a variety of existing sources. In this guide, we will walk through the steps to export, and then import your users from Clerk. --- ## (1) Export Clerk user data Clerk allows for exporting user data [directly from their API](https://clerk.com/docs/deployments/exporting-users) using their Backend SDK. ### Export passwords If your Clerk users currently sign in using password-based authentication, and you'd like to import those passwords into WorkOS, then you'll need to use the [Clerk backend API](https://clerk.com/changelog/2024-10-23-export-users) to export them with your user data as a CSV file. > Clerk does not make the plaintext passwords available for export. --- ## (2) Import users into WorkOS Once you’ve obtained the necessary export files, you have two options for importing your user data into WorkOS. ### (A) Using the WorkOS import tool WorkOS has a public [GitHub repository](https://github.com/workos/migrate-clerk-users) containing code that can be run to import users into WorkOS using the data retrieved from Clerk support in the previous step. If you’d rather write your own code, or if you chose to not export data via Clerk support, the same process can be completed using the public WorkOS APIs, as described below. ### (B) Using WorkOS APIs Using the data either from the Clerk API or from a JSON file received from their support team, you can use the WorkOS API to [create users](/reference/authkit/user/create) during the import. Keep in mind that user creation is rate-limited. You can view the docs on the [rate limits](/reference/rate-limits) for more information. Using the default fields from the [Clerk export](https://clerk.com/docs/deployments/exporting-users), use the following mapping from Clerk to parameters in your WorkOS Create User API calls: | Clerk | | WorkOS API | | ----------------- | --- | ------------ | | `email_addresses` | → | `email` | | `first_name` | → | `first_name` | | `last_name` | → | `last_name` | ### Handle users with multiple email addresses In the case of a user with multiple email addresses, Clerk separates them with a pipe symbol: ```json "email_addresses": "john@example.com|john.doe@example.com", ``` Unfortunately there's no way to know which email is the primary one from the export alone. Clerk does expose this information by retrieving the [User object from their API](https://clerk.com/docs/references/javascript/user/user#properties). ### Import passwords If you also exported passwords from Clerk, you can import them during the [user creation](/reference/authkit/user/create) process, or later using the WorkOS [Update User API](/reference/authkit/user/update). Clerk uses the `bcrypt` password hashing algorithm, which is supported by WorkOS. Make sure to pass the following parameters to the WorkOS API: - The `password_hash_type` set to `'bcrypt'` - The `password_hash` set to the `password_digest` field from your Clerk export ### Migrate social auth users If you have users who previously signed in through Clerk using social auth providers, such as [Google](/integrations/google-oauth) or [Microsoft](/integrations/google-oauth), those users can continue to sign in with those providers after you’ve migrated to WorkOS. Check out our [integrations](/integrations) page for guidance on configuring the relevant provider’s client credentials in WorkOS. After your provider is configured in WorkOS, users can sign in with their provider credentials and will be automatically linked to a WorkOS user. WorkOS uses the **email address** from the social auth provider to determine this match. --- ## (3) Create organizations Clerk’s [organizations](https://clerk.com/docs/organizations/overview) are analogous to WorkOS [organizations](/reference/organization) – both represent a B2B customer. ### Creating Organizations If you’d like to export your Clerk organizations, you can use the [Clerk Backend SDK](https://clerk.com/docs/references/backend/organization/get-organization-list) to programmatically paginate through each organization. You can then use the WorkOS API to [create matching organizations](/reference/organization/create). ### Adding user memberships You can export Clerk organization memberships using Clerk’s [Backend SDK](https://clerk.com/docs/references/backend/organization/get-organization-membership-list), and then use the WorkOS [Organization Membership API](/reference/authkit/organization-membership/create) to add each user to their respective organization. --- ## (4) Multi-Factor Auth There are some differences between the MFA strategies offered by Clerk and WorkOS. Clerk supports SMS-based second factors, however WorkOS does not due to known security issues with SMS. Users who have SMS-based second factors will need to switch to using email-based Magic Auth, or re-enroll in MFA using a TOTP-based authenticator instead. See the [MFA guide](/authkit/mfa) for more information on enrolling users. --- ## Next steps After the import, you can now start using WorkOS to manage your users. If you haven't, take a look at our [Quick Start guide](/authkit) to learn how to integrate WorkOS AuthKit into your application. ### Migrate from Better Auth Learn how to migrate users and organizations from Better Auth. ## Introduction You can migrate your existing user data from a variety of sources into WorkOS using the AuthKit API. This guide will walk you through the steps to export your data from Better Auth, and import into WorkOS. --- ## (1) Export Better Auth data Better Auth stores user data directly in your database, which means you have full control over exporting your data. Unlike hosted authentication services, Better Auth does not provide a built-in export tool, but you can access your data directly through your database. ### Accessing your database Better Auth uses [multiple database tables](https://www.better-auth.com/docs/concepts/database) to store authentication data. The main tables you'll need to export are: - **user**: Contains core user information (`id`, `name`, `email`, `emailVerified`, `image`, timestamps) - **account**: Stores provider-specific authentication data, including password hashes for credential-based accounts - **organization**: Available when using the [organization plugin](https://www.better-auth.com/docs/plugins/organization) - **member**: Mapping of users (and their roles) to organizations You can export this data using your database's native export tools, your ORM (for example, Prisma), or direct SQL queries. ### Exporting user data To export users, query the `user` table directly. ```sql SELECT * FROM user; ``` You can export this data to JSON, CSV, or any format that works for your migration script. ### Exporting passwords Better Auth stores password hashes in the `account` table with `providerId` set to `'credential'`. The passwords are hashed using [scrypt by default](https://www.better-auth.com/docs/authentication/email-password), though Better Auth supports custom hashing functions. To export password hashes, query the `account` table: ```sql SELECT userId, password FROM account WHERE providerId = 'credential'; ``` If you're using a custom password hashing algorithm in Better Auth, make note of the algorithm for the import step. The default is `scrypt`, which is supported by WorkOS. --- ## (2) Import users into WorkOS Once you've exported your user data from Better Auth, you can import it into WorkOS using the WorkOS APIs. ### Using WorkOS APIs With the data from your Better Auth database, you can use the [Create User API](/reference/authkit/user/create) to import each user. The API is rate-limited, so for large migrations, you may want to implement batching with appropriate delays. You can view the [rate limits](/reference/rate-limits) documentation for more information. Using the Better Auth user table schema, use the following mapping to Create User API parameters: | Better Auth | | WorkOS | | --------------- | --- | ---------------- | | `email` | → | `email` | | `emailVerified` | → | `email_verified` | | `name` | → | `first_name` | | `name` | → | `last_name` | | `image` | → | (not supported) | > Better Auth stores a single `name` field, while WorkOS has separate `first_name` and `last_name` fields. You'll need to parse the name field or use it entirely for `first_name`. Here's an example migration script: ```typescript ; const workos = new WorkOS(process.env.WORKOS_API_KEY); async function migrateUsers(betterAuthUsers) { for (const user of betterAuthUsers) { // Parse name into first and last name if possible const [firstName, ...lastNameParts] = user.name.split(' '); const lastName = lastNameParts.join(' ') || undefined; try { // In the JavaScript SDK, the property names are camelCase const workosUser = await workos.userManagement.createUser({ email: user.email, emailVerified: user.emailVerified, firstName: firstName, lastName: lastName, }); console.log(`Migrated user: ${user.email} -> ${workosUser.id}`); } catch (error) { console.error(`Failed to migrate user ${user.email}:`, error); } } } ``` ### Importing passwords If you exported password hashes from Better Auth, you can import them during the [user creation](/reference/authkit/user/create) process, or later using the [Update User API](/reference/authkit/user/update). Better Auth uses `scrypt` as the default password hashing algorithm, which is supported by WorkOS. Make sure to pass the following parameters: - The `password_hash_type` set to `'scrypt'` - The `password_hash` set to the password hash value from your Better Auth `account` table The password hash should be in PHC string format. If Better Auth is storing raw scrypt hashes, you'll need to convert them to PHC format. See the [other services migration guide](/migrate/other-services/2-importing-users-into-workos/importing-passwords) for detailed information about PHC format parameters for scrypt. If you configured Better Auth to use a different password hashing algorithm, such as bcrypt, argon2, or pbkdf2, WorkOS supports these as well. Refer to the [password hash types](/migrate/other-services/2-importing-users-into-workos/importing-passwords) documentation for format requirements. ### Migrating social auth users If you have users who previously signed in through Better Auth using social auth providers, such as [Google](/integrations/google-oauth) or [Microsoft](/integrations/microsoft-oauth), those users can continue to sign in with those providers after you've migrated. Better Auth stores social auth accounts in the `account` table with different `providerId` values (e.g., `'google'`, `'github'`, `'microsoft'`). These accounts are linked to users via the `userId` field. Check out our [integrations](/integrations) page for guidance on configuring the relevant provider's client credentials. After your provider is configured, users can sign in with their provider credentials and will be automatically linked to a user. The **email address** from the social auth provider is used to determine this match. > Some users may need to verify their email address through WorkOS if email verification is enabled in your environment's authentication settings. Email verification behavior varies depending on whether the provider is known to verify email addresses. For example, users signing in using Google OAuth and a `gmail.com` email domain will not need to perform the extra verification step. --- ## (3) Organizations Better Auth has an [organization plugin](https://www.better-auth.com/docs/plugins/organization) that allows you to manage organization members and teams. If you're using this plugin, you can migrate your organizations to WorkOS, which has native support for [Organizations](/reference/organization) as a core B2B feature. ### Creating Organizations Better Auth stores organizations in an `organization` table with fields like `id`, `name`, `slug`, `logo`, and `metadata`. To migrate these, you'll need to: 1. Export organizations from your Better Auth database: ```sql SELECT * FROM organization; ``` 2. Create matching organizations using the [Create Organization API](/reference/organization/create): ```typescript ; const workos = new WorkOS(process.env.WORKOS_API_KEY); async function migrateOrganizations(betterAuthOrgs) { for (const org of betterAuthOrgs) { try { const workosOrg = await workos.organizations.createOrganization({ name: org.name, // You may want to store the Better Auth slug in organization metadata metadata: { betterAuthSlug: org.slug, }, }); console.log(`Migrated organization: ${org.name} -> ${workosOrg.id}`); // Store this mapping for migrating user memberships later orgIdMap.set(org.id, workosOrg.id); } catch (error) { console.error(`Failed to migrate organization ${org.name}:`, error); } } } ``` ### Adding organization memberships Better Auth stores organization memberships in a `member` table that links users (and their roles) to organizations. ```sql SELECT * FROM member; ``` Then use the [Organization Membership API](/reference/authkit/organization-membership/create) to add each user to their respective organization. WorkOS offers RBAC capabilities through [roles and permissions](/authkit/roles-and-permissions). When migrating, identify your roles defined in Better Auth, then create equivalent roles in the WorkOS Dashboard, and assign roles during migration by specifying the `roleSlug` parameter when creating organization memberships. If your Better Auth implementation uses complex RBAC policies with custom resources and actions, you may need to simplify to standard roles or implement custom authorization in your application logic. ```typescript async function migrateMemberships(betterAuthMemberships, orgIdMap, userIdMap) { for (const membership of betterAuthMemberships) { const orgId = orgIdMap.get(membership.organizationId); const userId = userIdMap.get(membership.userId); if (!orgId || !userId) { console.error(`Missing mapping for membership: ${membership.id}`); continue; } try { await workos.userManagement.createOrganizationMembership({ userId: userId, organizationId: orgId, // Better Auth uses custom role strings; map these to WorkOS roles as needed roleSlug: getRole(membership.role), }); console.log(`Migrated membership: ${membership.userId} -> ${orgId}`); } catch (error) { console.error(`Failed to migrate membership:`, error); } } } ``` ### Migrating teams If you're using the teams feature within Better Auth (an optional hierarchical level within organizations), note that there is not a directly corresponding "teams" concept. However, you have several options: 1. **Convert to organizations**: Create separate organizations for each Better Auth team 2. **Use organization metadata**: Store team information in organization metadata 3. **Use RBAC roles**: Represent team membership through custom roles in [role-based access control](/rbac/quick-start) For most B2B applications, flattening teams into separate organizations provides the cleanest migration path and takes full advantage of enterprise features like SSO and Directory Sync, which operate at the organization level. --- ## (4) Special considerations There are several differences between Better Auth and WorkOS that you should be aware of during migration. ### Multi-Factor Authentication Better Auth offers a [Two-Factor Authentication plugin](https://www.better-auth.com/docs/plugins/2fa) that supports TOTP-based authenticators. If your Better Auth users have enrolled in 2FA, they will need to re-enroll in MFA after migrating, as MFA secrets cannot be migrated for security reasons. See the [MFA guide](/authkit/mfa) for information on enrolling users in MFA. > WorkOS does not support SMS-based factors due to known security vulnerabilities with SMS. ### Account linking behavior Better Auth has sophisticated [account linking capabilities](https://www.better-auth.com/docs/concepts/users-accounts#account-linking) that automatically link social accounts with matching verified email addresses. WorkOS also supports automatic account linking based on email addresses. When migrating users who have multiple linked accounts in Better Auth (e.g., password + Google OAuth), you should: 1. Import the user once with their primary email 2. Configure the relevant social providers 3. When users sign in with their social provider, they will automatically be linked with the accounts based on email match ### Handling interim new users If your application allows users to sign up at any time, you should [consider the timing of your migration](/migrate/other-services/3-handling-interim-new-users). Users who sign up after you've exported data from Better Auth but before you've switched to WorkOS for authentication will be omitted from the migration. There are two main strategies to handle this: #### (A) Disable signups during migration Schedule an appropriate time for the migration and temporarily disable signup functionality. This can be controlled using a feature flag in your application. After the migration is complete and your application is using WorkOS for authentication, re-enable signups. #### (B) Use a dual-write strategy For applications that cannot disable signups, implement a "dual-write" strategy. When a new user signs up, create records in both your Better Auth database and WorkOS using the [Create User API](/reference/authkit/user/create). This keeps WorkOS synchronized with new users, though you'll still need to perform the historical user migration. Be aware that you'll need to keep user updates (email changes, password changes) synchronized between both systems until the migration is complete. ### Database-specific considerations Since Better Auth stores data in your own database, you have flexibility in how you structure the migration: - You can keep Better Auth tables in your database during a transition period - Consider implementing a gradual rollout where some users authenticate via WorkOS while others continue using Better Auth - Database schema is extensible, so custom fields will need to be handled separately (consider using [user metadata](/authkit/metadata) for custom data) --- ## Next steps With your users and organizations now imported, you can start using WorkOS to manage authentication for your application. If you haven't already, take a look at our [Quick Start guide](/authkit) to learn how to integrate AuthKit into your application. These enterprise-ready features go beyond basic authentication: - **[Single Sign-On](/sso)**: Enable SAML and OIDC SSO for enterprise customers - **[Directory Sync](/directory-sync)**: Automatically provision and deprovision users from identity providers - **[Admin Portal](/admin-portal)**: Allow your customers to self-serve SSO and Directory Sync configuration - **[Audit Logs](/audit-logs)**: Track security-relevant events in your application If you have questions about your migration or need assistance, reach out to [support@workos.com](mailto:support@workos.com). ### Migrate from AWS Cognito Learn how to migrate users to WorkOS from AWS Cognito. ## Introduction The WorkOS AuthKit API allows you to migrate your existing user data from a variety of existing sources. In this guide, we’ll walk through the steps to export, and then import your users from AWS Cognito. > AWS Cognito does not offer exports of user password hashes or MFA keys. This means that your imported users will need to reset their passwords and reconfigure any required MFA. ## (1) Exporting Cognito user data User data in an AWS Cognito User Pool can be exported using the AWS CLI’s [list-users command](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/list-users.html). To retrieve the first page of results, use the command: ```bash title="List users using the Cognito CLI" aws cognito-idp list-users --user-pool-id --region ``` Add the `--pagination-token ` argument to paginate subsequent requests: ```bash title="export-aws-cognito-users.sh" #!/bin/bash user_pool_id="" region="" output_dir="cognito_exports" file_index=1 mkdir -p "$output_dir" export_users() { aws cognito-idp list-users --user-pool-id "$user_pool_id" --region "$region" $1 | \ jq '.' > "$output_dir/users_$2.json" } next_token="" while true; do next_token=$(export_users "${next_token:+--pagination-token $next_token}" "$file_index" | jq -r '.PaginationToken // empty') [ -z "$next_token" ] && break ((file_index++)) done echo "Export complete." ``` ## (2) Importing users into WorkOS After obtaining your user data from Cognito, it’s time to import them into WorkOS, mapping attributes from the AWS Cognito User format to WorkOS API parameters. ```json title="Example AWS Cognito list-users response object" { "Users": [ { "Username": "22704aa3-fc10-479a-97eb-2af5806bd327", "Enabled": true, "UserStatus": "FORCE_CHANGE_PASSWORD", "UserCreateDate": 1548089817.683, "UserLastModifiedDate": 1548089817.683, "Attributes": [ { "Name": "sub", "Value": "22704aa3-fc10-479a-97eb-2af5806bd327" }, { "Name": "family_name", "Value": "Mouse" }, { "Name": "given_name", "Value": "Mickey" }, { "Name": "email_verified", "Value": "true" }, { "Name": "email", "Value": "mary@example.com" } ] } ] } ``` Using the WorkOS [Create User API](/reference/authkit/user/create), you can create a corresponding record in WorkOS for each exported user. Use the following mapping from the AWS Cognito object to parameters in your WorkOS Create User API calls: | AWS Cognito | | WorkOS API | | --------------- | --- | ---------------- | | `email` | → | `email` | | `emailVerified` | → | `email_verified` | | `given_name` | → | `first_name` | | `family_name` | → | `last_name` | > Migrated users **must reset their passwords** before they can sign in. ### Triggering password resets It’s important to have a strategy for triggering password resets after importing your users into WorkOS. You may want to ask users to reset their password the next time they attempt to sign in, or proactively send them password reset emails. In either case, you can trigger the password reset flow by using the WorkOS [Send Password Reset Email API](/reference/authkit/password-reset/create). ## Other authentication methods In addition to migrating username and password users to WorkOS, you can migrate users who authenticate using third-party identity providers, such as Google, without re-obtaining access. Ensure you use the same credentials (i.e. Client ID and Client Secret) in WorkOS as those used for your connection in AWS Cognito. For OAuth providers, you will need to add WorkOS as an additional Redirect URI. See the [Google OAuth integration guide](/integrations/google-oauth/customize-google-oauth-domain-optional/3-add-new-redirect-uri-to-google) as an example of what this process looks like. ### Migrate from Auth0 Learn how to migrate users and organizations from Auth0. ## Introduction The WorkOS AuthKit API allows you to migrate your existing user data from a variety of existing sources. In this guide, we will walk through the steps to export, and then import your users from Auth0. ## (1) Exporting Auth0 user data Auth0 allows their customers to export user data using several tools, which are outlined in [Auth0’s export documentation](https://auth0.com/docs/troubleshoot/customer-support/manage-subscriptions/export-data). A combination of exports may be necessary to retrieve all of the desired user information, including passwords. The first tool is [Auth0’s “Bulk User Export” jobs](https://auth0.com/docs/manage-users/user-migration/bulk-user-exports). These export jobs can be created programmatically using the [Auth0 Management API](https://auth0.com/docs/api/management/v2/jobs/post-users-exports), or through the official [Auth0 "User Import / Export Extension"](https://auth0.com/docs/customize/extensions/user-import-export-extension). In both cases, an Auth0 customer can request which fields they’d like exported for each user, with the final output of the process being a newline-delimited JSON file. ### Exporting passwords If your Auth0 users currently sign-in using password-based authentication, and you’d like to import those passwords into WorkOS, then you will need to [contact Auth0 support](https://auth0.com/docs/troubleshoot/customer-support). After opening a ticket with Auth0, it can take up to a week or more for your request to be processed. At the end you’ll be given another newline-delimited JSON file, containing a subset of user data such as ID, but more importantly the password hash. > Auth0 does not make the plaintext passwords available for export. --- ## (2) Importing Users into WorkOS Once you’ve obtained the necessary export files, you have two options for importing your user data into WorkOS. ### (A) Using the WorkOS import tool WorkOS has a public [GitHub repository](https://github.com/workos/migrate-auth0-users) containing code that can be run to import users into WorkOS using the data retrieved in the previous step. If you’d rather write your own code, the same process can be completed using the public WorkOS APIs, as described below. ### (B) Using WorkOS APIs With the data from Auth0’s “Bulk User Export” job, you can use the WorkOS [Create User API](/reference/authkit/user/create) to import each of the users. Using the default fields from the [Auth0 export](https://auth0.com/docs/customize/extensions/user-import-export-extension#export-users), use the following mapping from Auth0 to parameters in your WorkOS Create User API calls: | Auth0 | | WorkOS API | | -------------- | --- | ---------------- | | Email | → | `email` | | Email Verified | → | `email_verified` | | Given Name | → | `first_name` | | Family Name | → | `last_name` | ### Importing passwords If you also exported passwords from Auth0, you can import them during the [user creation](/reference/authkit/user/create) process, or later using the WorkOS [Update User API](/reference/authkit/user/update). Auth0 uses the `bcrypt` password hashing algorithm, which is supported by WorkOS. Make sure to pass the following parameters to the WorkOS API: - The `password_hash_type` set to `'bcrypt'` - The `password_hash` set to the `passwordHash` field from your Auth0 export ### Migrating social auth users If you have users who previously signed in through Auth0 using social auth providers, such as [Google](/integrations/google-oauth) or [Microsoft](/integrations/google-oauth), those users can continue to sign in with those providers after you’ve migrated to WorkOS. Check out our [integrations](/integrations) page for guidance on configuring the relevant provider’s client credentials in WorkOS. After your provider is configured in WorkOS, users can sign in with their provider credentials and will be automatically linked to a WorkOS user. WorkOS uses the **email address** from the social auth provider to determine this match. > Some users may need to verify their email address through WorkOS if email verification is enabled in your WorkOS environment’s authentication settings. Email verification behavior varies depending on whether the provider is known to verify email addresses. For example, users signing in using Google OAuth and a `gmail.com` email domain will not need to perform the extra verification step. --- ## Organizations Auth0 has a concept of [“Organizations”](https://auth0.com/docs/manage-users/organizations) which are analogous to [WorkOS Organizations](/reference/organization), in that both represent a B2B customer. ### Creating Organizations If you’d like to export your Auth0 organizations, you can use the [Auth0 Management API](https://auth0.com/docs/api/management/v2/organizations/get-organizations) to programmatically paginate through each Organization. You can then call the WorkOS [Create Organization API](/reference/organization/create) to create matching Organizations in WorkOS. ### Adding user memberships You can export Auth0 organization memberships using Auth0’s “Bulk User Export” as described in the [Exporting Auth0 user data](/migrate/auth0/1-exporting-auth0-user-data) step, and then use the WorkOS [Organization Membership API](/reference/authkit/organization-membership/create) to add each user to their respective organization. ## Multi-Factor Auth There are some differences between the Multi-Factor Auth (MFA) strategies offered by Auth0 and WorkOS. Auth0 supports SMS-based second factors, however WorkOS does not due to known security issues with SMS. Users who have SMS-based second factors will need to switch to using email-based Magic Auth, or re-enroll in MFA using a TOTP-based authenticator instead. ## Wrapping-up With your users now imported, you can now start using WorkOS to manage your Auth0 users. If you haven't, take a look at our [Quick Start guide](/authkit) to learn how to integrate WorkOS AuthKit into your application. ## Multi-Factor Auth {#mfa} ### Multi-Factor Authentication A composable API for implementing multi-factor authentication. ## Introduction The Multi-Factor Authentication (MFA) API is intended to be a composable, unopinionated set of endpoints that can be integrated into existing application/session management strategies. The available types of authentication factors are: - `totp` – Time-based one-time password - `sms` – One-time password via SMS message > The MFA API is not intended to be used with the WorkOS SSO feature. It’s recommended to leverage the MFA features of the Identity Provider that is powering your SSO implementation. ## What you’ll build In this guide, we’ll walk you through the process of enrolling new authentication factors for a user, and the challenge/verification process for existing authentication factors. This guide will show you how to: 1. Create an Authentication Factor 2. Challenge the Authentication Factor 3. Verify the Challenge ## Before getting started To get the most out of this guide, you’ll need: - A [WorkOS account](https://dashboard.workos.com/) ## API object definitions [Authentication Factor](/reference/mfa/authentication-factor) : A factor of authentication that can be used in conjunction with a primary factor to provide multiple factors of authentication. [Authentication Challenge](/reference/mfa/authentication-challenge) : A request for an Authentication Factor to be verified. ## (1) Create an Authentication Factor We’ll first need to enroll a new Authentication Factor. ### Install the WorkOS SDK WorkOS offers native SDKs in several popular programming languages. Choose a language below to see instructions in your application’s language. ### Set secrets To make calls to WorkOS, provide the API key and, in some cases, the client ID. Store these values as managed secrets, such as `WORKOS_API_KEY` and `WORKOS_CLIENT_ID`, and pass them to the SDKs either as environment variables or directly in your app's configuration based on your preferences. ```plain title="Environment variables" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' ``` ### Enroll the Authentication Factor - | Using TOTP Use the TOTP type when the user is using a third-party authenticator app such as Google Authenticator or Authy. The response returns a `qr_code` and a secret. The `qr_code` value is a base64 encoded data URI that is used to [display the QR code](https://css-tricks.com/data-uris/) in your application for enrollment with an authenticator application. The `secret` can be entered into some authenticator applications in place of scanning a QR code. - | Using SMS Use the SMS type when the user wants to receive one time passwords as SMS messages to their mobile device. Phone number must be valid. An error will be returned for malformed or invalid phone numbers. Now that we’ve successfully created an authentication factor, we’ll need to save the ID for later use. It’s recommended that you persist the factor ID in your own user model according to your application’s needs. ## (2) Challenge the Authentication Factor Next we’ll initiate the authentication process for the newly created factor which we’ll refer to as a challenge. - | Create Authentication Challenge - | Sending Custom SMS Message When challenging an SMS authentication factor, you can pass an optional SMS template to customize the SMS message that is sent to the end user. Use the `{{code}}` token to inject the one time password into the message. Now that we’ve successfully challenged the authentication factor, we’ll need to save the challenge ID for the last step, challenge verification. ## (3) Verify the Challenge The last step in the authentication process is to verify the one time password provided by the end-user. ### Verification Response If the challenge is successfully verified `valid` will return `true`. Otherwise it will return `false` and another verification attempt must be made. ### Already Verified Error If a challenge was already successfully verified, it cannot be used a second time. If further verification is needed in your application, create a new challenge. ### Expired Error For SMS authentication factors, challenges are only available for verification for 10 minutes. After that they are expired and cannot be verified. We’ve now successfully verified an end-user’s authentication factor. This authentication factor can now be used as a second factor of authentication in your application’s existing authentication strategy. The ID of the authentication factor should be persisted in your application for future authentication challenges. ### Example Apps View sample Multi-Factor Auth apps for each SDK. You can view minimal example apps that demonstrate how to use the WorkOS SDKs to authenticate users via MFA: ### Sign-In UX User experience considerations for MFA sign-in. ## Introduction Once a user has setup two-factor authentication, their sign-in process will be different from the standard sign-in flow. This guide will walk you through the adjustments you need to make to support this in your application. ## Prompt user to verify the extra factor At the very least, assuming the user has enrolled in one method (e.g. SMS/Text message) you should present the user with a new screen for the extra verification step after they have entered their username and password. ## When the user has enrolled in multiple methods If the user has enrolled in multiple methods, consider including both methods in the verification step after they have entered their username and password. Following what we discussed in the [enrollment guide](mfa/ux/enrollment/let-users-choose-their-primary-method), consider presenting the user with their primary method first as well as letting them switch. --- ## Full interactive UI example The following interactive example shows a full UI for signing-in using MFA encompassing all the considerations mentioned above. ### Enrollment UX User experience considerations for MFA enrollment. ## Introduction Now that we've seen how the MFA APIs work, you may want to consider how you want to present the MFA enrollment experience to your users. This guide will cover some of the considerations you should take into account when designing your enrollment experience. ## Provide multiple methods The MFA APIs support multiple methods of authentication. Consider providing your users with multiple options for enrolling in MFA. Adding flexibility will reduce friction in users adoption. ## Let users choose their primary method If a user has enrolled in multiple methods, consider letting them select a primary. This will allow you to challenge them with the method they are most comfortable, whilst still benefiting from the security of a backup in case they lose access. ## Setup a `totp` factor accessibly As we have previously seen, [when enrolling a `totp` factor using the MFA API](mfa/1-create-an-authentication-factor/enroll-the-authentication-factor), the response returns a `qr_code` and a `secret`. The `qr_code` value can be passed directly to the source on an image tag as follows: However, some users may not be able to scan the QR code. Consider providing the `secret` value in the UI as an alternate way to set up their authenticator app. Additionally, consider describing the QR code for assistive technologies: ## Interoperable one-time-passcode input In order to make the experience as smooth as possible for your users, there are a few things to consider regarding the input they will use to fill in their one-time-passcode. ### Provide the right affordance You may be tempted to use [a number input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number) as it will show the mobile keyboard for numbers only. This is not recommended because a browser expects a number input to be countable, rather than a sequence of multiple numbers, which can cause unexpected behavior. Instead, we recommend using a text input (`type="text"`) with the `inputmode="numeric"` attribute to provide mobile devices with the expected numerical keyboard prompt. ### Autofill Setting `autocomplete="one-time-code"` will enable autofill with in any user-agent that supports it. This will for example ensure Safari on iOS/MacOS can suggest/auto-fill the one-time-code received via SMS. Consider also submitting the form automatically as soon as the passcode length has been met. This should help reduce the friction of using two-factor authentication for your users. ### Validation Consider using client-side validation to ensure the user enters a valid one-time-passcode. This will reduce the number of requests to the server and improve the user experience. `pattern="^\d{6}$"` can be used to validate the length of the one-time-passcode. Here is a code example implementing the above considerations: --- ## Full UI interactive example The following interactive example shows a full UI for enrolling in MFA, and encompasses all of the considerations mentioned above. ## Magic Link {#magic-link} ### Launch Checklist Make sure you’re ready to take your app to production. ## Create 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 redirect requests, you can use the IP Ranges listed in the [Cloudflare documentation](https://www.cloudflare.com/ips/). ## Go-live checklist - [ ] Unlock your Production environment by adding your billing information > Only enterprise connections in your Production environment will be charged. Any Google OAuth or Magic Link connections in Production will be free. - [ ] Configure a production redirect URI in your Production project - [ ] Secure your Production project’s API key - [ ] 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`. ## Frequently asked questions ### Can I customize the email sent via Magic Link? Yes, you can use your own email service and custom branded email template to send the authentication link to the user. See the custom email code snippet in the [create passwordless session section](/magic-link/1-add-magic-link-to-your-app/create-a-passwordless-session-and-email-the-user) for an example. ### Magic Link The fastest way to securely enable authentication – passwordless sign-in via email in a couple lines of code. > **Deprecated:** Magic Link is not recommended due to issues with email clients or other security software visiting the links and invalidating them. Instead, use [Magic Auth](/authkit/magic-auth), which provides a more secure passwordless authentication method. ## Introduction Managing password authentication entails significant overhead for engineering teams and opens up many risks for breaches. Magic Link from WorkOS gives you the ability to build a secure passwordless authentication flow utilizing email. Send users a one-time-use link and let them sign in with a single click. > Magic Link sets you up to handle Single Sign-On via the [WorkOS SSO API](/sso). The redirect URI / profile retrieval process is identical between Magic Link and SSO. ![Diagram showing Magic Link flow which emphasizes that WorkOS does not manage the session.](https://images.workoscdn.com/docs/guides/magic-link/v1/magic-link-diagram.png?auto=format&fit=clip&q=50)[border=false] Magic Link is not a session management solution – instead it is an authentication solution. You as the developer have the ability to manage user sessions as you see fit. This means you determine how long a session is valid for, as well as how to store and invalidate a session. Magic Links are single use, meaning that they will immediately expire after they are first clicked. If end users have security checks included with their email provider that test all embedded URLs, it can cause the Magic Links to expire before they reach the user’s inbox. To work around this, we recommend that end users add these Magic Link emails to an allowlist in order to bypass these security checks. ## What you’ll build In this guide, we’ll take you from learning about passwordless authentication all the way through to building production-ready passwordless authentication flows with the WorkOS Magic Link API. This guide will show you how to: 1. Add Magic Link to your app 2. Configure a redirect URI 3. Create a new Magic Link Connection ## Before getting started To get the most out of this guide, you’ll need: - A [WorkOS account](https://dashboard.workos.com/) ## API object definitions [Passwordless Session](/reference/magic-link/passwordless-session) : Represents a passwordless authentication session. [Profile](/reference/sso/profile) : Represents an authenticated user. The Profile object contains information relevant to a user in the form of normalized and raw attributes. ## (1) Add Magic Link to your app ### Install the WorkOS SDK WorkOS offers native SDKs in several popular programming languages. Choose a language below to see instructions in your application’s language. ### Set secrets To make calls to WorkOS, provide the API key and, in some cases, the client ID. Store these values as managed secrets, such as `WORKOS_API_KEY` and `WORKOS_CLIENT_ID`, and pass them to the SDKs either as environment variables or directly in your app's configuration based on your preferences. ```plain title="Environment variables" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' ``` ### Add a callback endpoint Let’s first add the redirect endpoint which will handle the callback from WorkOS after a user has authenticated via a magic link. This endpoint should exchange the authorization code (valid for 10 minutes) returned by WorkOS with the authenticated user’s Profile. ### Create a Passwordless Session and email the user Create a Passwordless Session to generate an authentication link for a user. An authentication link is valid for 15 minutes and can be sent via the WorkOS API or using your own email service. You can use the optional `state` parameter to encode arbitrary information to help restore application state between redirects. You can use the optional `redirect_uri` parameter to override the default [Redirect URI](/glossary/redirect-uri) set in the dashboard. > A Magic Link Connection will be automatically created if there isn’t already one for the domain specified when creating a new Passwordless Session. - | WorkOS email Use the WorkOS API to send the authentication link to the user. The email sent will be WorkOS branded. - | Custom email Use your own email service and custom branded email template to send the authentication link to the user. --- ## (2) Configure a redirect URI You should set a redirect URI (i.e. the callback endpoint from [Add a callback endpoint](/magic-link/1-add-magic-link-to-your-app/add-a-callback-endpoint)) via the Configuration page in the WorkOS Dashboard – be sure not to include wildcard subdomains or query parameters. ![A screenshot showing where to add a callback in the WorkOS Dashboard.](https://images.workoscdn.com/images/43ffd916-890b-4f1f-8767-0b70113288d9.png?auto=format&fit=clip&q=50) ### Example Apps View sample Magic Link apps for each SDK. You can view minimal example apps that demonstrate how to use the WorkOS SDKs to authenticate users via Magic Link: ## Integrations {#integrations} ### Xero OAuth Learn how to set up OAuth with Xero ## Introduction The Xero OAuth integration allows your users to authenticate using their Xero credentials through the "Sign in with Xero" flow. The configuration process involves creating an OAuth application in Xero and configuring the client credentials in your WorkOS Dashboard. --- ## What WorkOS provides When setting up Xero OAuth, WorkOS provides one key piece of information that needs to be configured in your Xero OAuth application: - [Redirect URI](/glossary/redirect-uri): The endpoint where Xero will send authentication responses after successful login The Redirect URI is available in the [WorkOS Dashboard](https://dashboard.workos.com/). In the left navigation menu, select the **Authentication** tab and the **OAuth providers** sub-tab. Locate the **Xero** section. ![The Xero OAuth section in the WorkOS Dashboard.](https://images.workoscdn.com/images/ea385495-75f6-4357-b16a-97c1383bbc9b.png?auto=format&fit=clip&q=50) Click **Enable**. The **Xero OAuth** configuration dialog will open. Locate the **Redirect URI**. ![Xero OAuth Redirect URI in the WorkOS Dashboard.](https://images.workoscdn.com/images/75e4e68e-cf07-4277-8979-7cd81f82f68f.png?auto=format&fit=clip&q=50) The **Redirect URI** serves as the destination for authentication responses and must be configured in your Xero application's OAuth settings. --- ## What you'll need You will need to obtain two pieces of information from a Xero Developer application: - **Xero Client ID**: Application identifier from Xero - **Xero Client Secret**: Authentication secret for the application The following sections will guide you through creating an OAuth application in your Xero Developer account and generating these credentials. --- ## (1) Create the Xero OAuth application Log in to your [Xero developer account](https://developer.xero.com) and create a new application. ![The Xero developer homepage.](https://images.workoscdn.com/images/58e9b3af-7442-45e7-8be2-cb1fa9ab39a2.png?auto=format&fit=clip&q=80) In the top right corner, select **New app**. Fill out the form starting with the application name. ![The Xero form to create a new OAuth application.](https://images.workoscdn.com/images/f78a99b4-f004-4437-9612-6d97ef49bf3d.png?auto=format&fit=clip&q=50) For the **Integration type**, select **Web app**. For **Company or application URI**, use your application's homepage URI. For **Redirect URI**, use the **Redirect URI** from the Xero OAuth configuration in the WorkOS Dashboard. ![OAuth client credentials in the Xero application settings.](https://images.workoscdn.com/images/9a0c3175-3af3-4613-a9f9-c9e6851507fe.png?auto=format&fit=clip&q=50) Agree to Xero's Developer Platform Terms & Conditions and click **Create app**. --- ## (2) Generate client credentials On the next page, you will see the Xero **App details** for your new OAuth application. From the left navigation menu, navigate to the **Configuration** page. ![OAuth client credentials in the Xero application settings before creating a client secret.](https://images.workoscdn.com/images/5ec780c3-c325-4455-992e-20727c39f8f9.png?auto=format&fit=clip&q=50) Select **Generate a secret** to create a client secret. ![OAuth client credentials in the Xero application settings after creating a client secret.](https://images.workoscdn.com/images/58158b26-0854-496f-9ccc-660955735463.png?auto=format&fit=clip&q=50) Copy the **Client ID** and **Client secret 1** as you'll need them for the WorkOS configuration. --- ## (3) Configure Xero credentials in WorkOS Now that you have the **Xero Client ID** and **Xero Client Secret** from the previous steps, return to the [WorkOS Dashboard](https://dashboard.workos.com). In the **Xero OAuth** configuration dialog, enable the integration. Paste the credentials from Xero into their respective fields in the WorkOS Dashboard. ![OAuth client credentials in the WorkOS Xero setup modal filled with client id and client secret.](https://images.workoscdn.com/images/9bb1cd53-a5cc-4a04-b7d4-2fd9791ad499.png?auto=format&fit=clip&q=50) Click **Save** to complete the configuration. You are now ready to start authenticating with Xero OAuth. You will use the `provider` query parameter in the Get Authorization URL API endpoint to support global Xero OAuth for any domain. The `provider` query parameter should be set to `XeroOAuth`. --- ## Configure Additional OAuth Scopes (Optional) WorkOS will request the OAuth scopes that are required for authentication by default. You can optionally configure your integration to request additional OAuth scopes as needed. When the **Return Xero OAuth tokens** option is selected, the access token and refresh token from Xero will be included in the response from the [Authenticate with code API](/reference/authkit/authentication/code). ![A screenshot showing Xero OAuth scopes configuration in the WorkOS Dashboard](https://images.workoscdn.com/images/a39beaaf-faf4-4fcf-98b7-eeb54f0135fb.png?auto=format&fit=clip&q=50) Any scopes configured here will be included on every Xero OAuth request. To specify additional scopes dynamically, use the `provider_scopes` query parameter on the [Get Authorization URL API endpoint](/reference/authkit/authentication/get-authorization-url). For more information, see Xero's OAuth scopes [documentation](https://developer.xero.com/documentation/oauth2/scopes). --- ## Frequently asked questions ### How is the WorkOS Xero OAuth integration different from implementing regular Xero OAuth flow? It's the same Xero OAuth flow as you could build yourself, but it's encapsulated within WorkOS SSO. This means you don't need to build it yourself. In addition to Xero OAuth, you can use WorkOS SSO to support other identity providers, all with a single integration. ### What is the provider query parameter and how is it used in the Xero OAuth integration? You can use the `provider` query parameter in the [Get Authorization URL API endpoint](/reference/sso/get-authorization-url) to support global Xero OAuth for any domain. The `provider` query parameter should be set to `XeroOAuth`. ### What type of Xero integration should I select? You should select **Web app** as the integration type when creating your Xero OAuth application. This is the correct type for OAuth integrations that will work with WorkOS. ### Where can I find my Xero application after creation? After creating your Xero application, you can find it in your [Xero Developer Portal](https://developer.xero.com) under your apps list. From there, you can access the **Configuration** page to manage your OAuth settings and regenerate credentials if needed. ### Workday Learn about syncing your user list with Workday. ## Introduction This guide outlines how to synchronize your application’s Workday directories. To synchronize an organization’s users and groups provisioned for your application, you’ll need the following information from the organization: - The Workday Custom Report JSON endpoint - The Workday Custom Group Report JSON endpoint - Username for accessing the Custom Report endpoint - Password for accessing the Custom Report endpoint > Note: The Workday integration isn't enabled by default in the WorkOS Dashboard or Admin Portal. Please reach out to [support@workos.com](mailto:support@workos.com) or via your team’s WorkOS Slack channel if you would like Workday enabled. --- ## (1) Create an Integration System User It’s recommended that the organization creates an Integration System User within Workday. The Integration System User will be used to access Custom Reports. ![A screenshot of the "Create Integration System User" form in the Workday Dashboard.](https://images.workoscdn.com/images/24b0561d-cd74-46a1-939e-3c76ead90c89.png?auto=format&fit=clip&q=50) > If you’ve finished the setup, and everything works as expected but fields are missing from the Report, ensure that the user created has access to access to the fields. ![A screenshot showing user access to a report in the Workday Dashboard.](https://images.workoscdn.com/images/7e3e33f1-3724-4ff9-a4b6-ad2ac475ccb3.png?auto=format&fit=clip&q=50) --- ## (2) Create a Security Group Create a new security group in Workday. Set the Type of Tenanted Security Group to Integration System Security Group (Unconstrained). Then add a name for the Security Group and select OK. ![A screenshot showing the "Create Security Group" form in the Workday Dashboard.](https://images.workoscdn.com/images/5e24e9d0-fba3-4e1d-8782-67c6491b3652.png?auto=format&fit=clip&q=50) Next, for Integration System Users, add the integration system user you created in the previous step, and select OK. ![A screenshot showing where to add the Integration System User in the Workday Dashboard.](https://images.workoscdn.com/images/5483b3eb-3995-48b6-8718-a4eb07ccf681.png?auto=format&fit=clip&q=50) --- ## (3) Add domain security policies to the Security Group Next, you’ll need to add domain security policies to the newly created security group. You can access this on the Security Group Settings → Maintain Domain Permissions for Security Group page. ![A screenshot showing where to find the "Maintain Domain Permissions for Security Group" option in the Workday Dashboard.](https://images.workoscdn.com/images/592f1450-d6d4-4a47-adef-6d1ce9007f4a.png?auto=format&fit=clip&q=50&w=2048) You’ll need to permit the following domain security policies to have “Get” access under Integration Permissions: - Person Data: Work Contact Information - Workday Accounts - Worker Data: Active and Terminated Workers - Worker Data: All Positions - Worker Data: Business Title on Worker Profile - Worker Data: Current Staffing Information - Worker Data: Public Worker Reports - Worker Data: Workers ![A screenshot showing Integration Permissions in the Workday Dashboard.](https://images.workoscdn.com/images/32f4bae2-9ef0-4a7b-a27e-6c28268298d6.png?auto=format&fit=clip&q=50) To activate these new security settings, you need to go to the Activate Pending Security Policy Changes page and click OK. ![A screenshot showing the Activate Pending Security Policy Changes page in the Workday Dashboard.](https://images.workoscdn.com/images/2c708837-b39d-454f-90b0-acfe377d4ad5.png?auto=format&fit=clip&q=50) Then, select the Confirm checkbox to finish activating. ![A screenshot showing where to confirm the Active Pending Security Policy Changes in the Workday Dashboard.](https://images.workoscdn.com/images/664f3905-d9e6-4390-b210-1e7eaffa25c2.png?auto=format&fit=clip&q=50) --- ## (4) Create and Populate Custom Reports You will need to create two Custom Reports. The first Custom Report will be used for syncing User information. The second report will be used for syncing Group information. When creating the report, make sure to select the Advanced report type and to have the Enable as Web Service box checked. ![A screenshot showing the "Create Custom Report" page in the Workday Dashboard.](https://images.workoscdn.com/images/8fa8ffb7-e377-4289-a130-3719646dea8a.png?auto=format&fit=clip&q=50) You need to add information for certain fields to the report. You can do this by directly adding columns to the report for the attributes in Workday with column heading names specified as follows: ![A screenshot showing an example of Custom User Report in the Workday Dashboard.](https://images.workoscdn.com/images/d3d4bb22-b4c8-467a-a3b4-bd0e6b4d2aea.png?auto=format&fit=clip&q=50) Along the same lines as the User Report, WorkOS looks for the following information in the Group Report: --- ## (5) Add an authorized user If an Integration System User was created, the organization will want to have that user added as an authorized user. This can be found under the **Share** tab from within a Report. ![A screenshot showing the "Share" tab in the Workday Dashboard.](https://images.workoscdn.com/images/8794da9c-89ca-4b84-842b-3f3fe6648d39.png?auto=format&fit=clip&q=50) --- ## (6) Get the RaaS endpoint Now that the Report itself is setup and access to it had been configured, the organization will need to get the RaaS endpoint. The page with the endpoints can be found under **Actions → Web Service → View URLs**. ![A screenshot showing where to find the view URLs option in the Workday Dashboard.](https://images.workoscdn.com/images/d212438c-951b-464f-aa42-2bebd0e2bdf2.png?auto=format&fit=clip&q=50) Once on the URLs page, the one that WorkOS will need is listed under the **JSON** section. ![A screenshot showing the View URLs Web Service page in the Workday Dashboard.](https://images.workoscdn.com/images/8698f25c-22bc-48ee-82c7-5fa885b20215.png?auto=format&fit=clip&q=50) --- ## (7) Create your Directory Sync Connection Login to your WorkOS Dashboard and select “Organizations” from the left hand navigation bar. Select the organization you’ll be configuring a new Directory Sync Connection with. Click “Add Directory”. ![A screenshot showing where to find the "Add Directory" button in the WorkOS Dashboard.](https://images.workoscdn.com/images/6244ae58-85a4-4c14-b6c0-c12bca04408e.png?auto=format&fit=clip&q=50) Select “Workday” as the directory type, and then input the Company Name. Click the “Create Directory” button. ![A screenshot showing the "Create Directory" button in the WorkOS Dashboard.](https://images.workoscdn.com/images/27e9b01f-52e6-433b-af33-38eb3961dc70.png?auto=format&fit=clip&q=50) --- ## (8) Setup your Directory Sync Connection Click “Update Directory” to input the organization's Custom Report JSON endpoints, username and password. ![A screenshot showing where to find the "Update Directory" button in the WorkOS Dashboard.](https://images.workoscdn.com/images/0c51f74e-8705-4193-93db-126a61bb367c.png?auto=format&fit=clip&q=50) Then, click “Save Directory Details”. --- ## (9) View users and groups in your dashboard Now, whenever the organization assigns users or groups to your application, you’ll receive Dashboard updates based on changes in their directory. A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) ## Frequently asked questions ### How often does the Workday directory perform a sync? The Workday directory polls in every 30 minutes starting from the time of the initial sync. ### VMware Learn how to configure a connection to VMware via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. --- ## What WorkOS provides WorkOS provides the [SP Metadata](/glossary/sp-metadata) link. It’s readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot showing where to find the SP Metadata in the WorkOS dashboard.](https://images.workoscdn.com/images/e253ad08-a85b-4586-bf8c-970059eb286c.png?auto=format&fit=clip&q=50) --- ## What you’ll need Next, you will provide the Metadata URL from VMware. Normally, this information will come from the organization's IT Management team when they set up your application’s SAML 2.0 configuration in their VMware admin dashboard. But, should that not be the case during your setup, here’s how to obtain it. --- ## (1) Create a new SaaS Application In your Workspace ONE Catalog, click “New”. Give your application a descriptive name. ![A screenshot showing how to create new application in VMware.](https://images.workoscdn.com/images/576ed672-e030-4f1e-936e-c04d33ff7dfd.png?auto=format&fit=clip&q=50) --- ## (2) Basic SAML Configuration Click the “Configuration” tab from the left sidebar. Copy the SP Metadata Link from your VMware connection in the WorkOS dashboard and paste it in the URL/XML field under Configuration in Workspace One. ![A screenshot showing where to input WorkOS SP metadata when configuring VMware application.](https://images.workoscdn.com/images/6d7bace5-a513-4782-ac18-8327b5e364a3.png?auto=format&fit=clip&q=50) --- ## (3) Advanced SAML Configuration Continue scrolling and expand “Advanced Properties”. ![A screenshot showing where to find "Advanced Properties" dropdown in VMware application.](https://images.workoscdn.com/images/dc6d711a-104c-4cd6-bca7-dff852dbb2c9.png?auto=format&fit=clip&q=50) Enable “Sign Assertion” and “Include Assertion Signature”. ![A screenshot showing where to enable "Sign Assertion" and "Include Assertion Signature" in VMware application.](https://images.workoscdn.com/images/98b0a17a-51a4-41c4-87be-1ffadfce96aa.png?auto=format&fit=clip&q=50) --- ## (4) Configure Attribute Map Continue scrolling until “Custom Attribute Mapping”. ![A screenshot showing where to find "Custom Attribute Mapping" in VMware application.](https://images.workoscdn.com/images/d35112ac-5d76-47c4-aa6c-436321d30b06.png?auto=format&fit=clip&q=50) Fill in the following attribute mappings and select “Next” until you are prompted to “Save”. - `id` → `${user.objectGUID}` - `firstName` → `${user.firstName}` - `lastName` → `${user.lastName}` - `email` → `${user.email}` ![A screenshot showing how to configure attribute mappings in VMware application.](https://images.workoscdn.com/images/2ef20a4a-9095-4c35-85b8-cf4e16c79da9.png?auto=format&fit=clip&q=50) Some VMware configurations use `user.ExternalId` instead of `user.objectGUID`. In this case, you would map the id attribute to `user.ExternalId`. ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, map the groups in your identity provider to a SAML attribute named `groups`. > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (5) Upload Metadata URL After saving your SaaS Application, click “Settings” then “SAML Metadata”. Click on “Copy URL” next to “Identity Provider (IdP) metadata”. ![A screenshot showing where to find metadata URL in VMware application.](https://images.workoscdn.com/images/f99932ab-8828-4b78-a044-0c19c35859dd.png?auto=format&fit=clip&q=50) Back in the WorkOS Dashboard, click on “Edit Metadata Configuration” in the “Metadata Configuration” section of the Connection. ![A screenshot showing where to edit the IdP metadata URL in the WorkOS dashboard.](https://images.workoscdn.com/images/d743c922-1517-4dd2-80ab-cab5e4a9c53f.png?auto=format&fit=clip&q=50) Finally, input the Metadata URL and click “Save Metadata Configuration”. Your Connection will then be linked and good to go! ![A screenshot showing how to configure IdP metadata URL in the WorkOS dashboard.](https://images.workoscdn.com/images/30130529-4132-45f6-aa33-70d8760612fd.png?auto=format&fit=clip&q=50) ### Vercel OAuth Learn how to set up OAuth with Vercel ## Introduction The Vercel OAuth integration allows your users to authenticate using their Vercel credentials. The configuration process involves creating an OAuth application in Vercel and configuring the client credentials in your WorkOS Dashboard. --- ## What WorkOS provides When setting up Vercel OAuth, WorkOS provides one key piece of information that needs to be configured in your Vercel OAuth application: - [Redirect URI](/glossary/redirect-uri): The endpoint where Vercel will send authentication responses after successful login The Redirect URI is available in the [WorkOS Dashboard](https://dashboard.workos.com/). In the left navigation menu, select the **Authentication** tab and the **Providers** sub-tab. Locate the **Vercel** section. ![The Vercel OAuth section in the WorkOS Dashboard](https://images.workoscdn.com/images/fbd35719-bb0d-4ccc-a613-a63dc3ba97b5.png?auto=format&fit=clip&q=50) Click **Enable**. The **Vercel OAuth** configuration dialog will open. Locate the **Redirect URI**. ![The Vercel OAuth configuration modal in the WorkOS Dashboard](https://images.workoscdn.com/images/648eb886-837f-4eb2-a366-6d6094187a5d.png?auto=format&fit=clip&q=50) The **Redirect URI** serves as the destination for authentication responses and must be configured in your Vercel OAuth application as the Authorization Callback URL. --- ## What you'll need You will need to obtain two pieces of information from a Vercel OAuth application: - **Vercel Client ID**: Application identifier from Vercel - **Vercel Client Secret**: Authentication secret for the application The following sections will guide you through creating an OAuth application in your Vercel account and generating these credentials. --- ## (1) Create the Vercel OAuth application Log in to your [Vercel account](https://vercel.com/login) and navigate to your team Settings tab. In the left navigation menu, scroll down to select **Apps**. Click **Create** to create a new application. ![Vercel Apps page with Create button](https://images.workoscdn.com/images/1c5a34a7-64c1-42d1-b2e8-363b3e14a1be.png?auto=format&fit=clip&q=50) Choose a name for your app, optionally add a logo, and click Save. --- ## (2) Configure the Vercel OAuth application In the left navigation menu, ensure that the **General** tab is selected. Scroll down to the **Authorization Callback URLs** section, and enter the **Redirect URI** from the Vercel OAuth configuration in the WorkOS Dashboard. Click **Save**. ![Configuring Redirect URI in Vercel](https://images.workoscdn.com/images/b9e526f1-099b-472b-9a46-e9504ae2c106.png?auto=format&fit=clip&q=50) In the left navigation menu, select the **Authentication** tab. In the **Client Authentication Methods** section, make sure that **client_secret_post** is selected. ![Configuring Client Authentication Methods in Vercel](https://images.workoscdn.com/images/65baf589-746b-4b33-b648-36f1d8b57c5d.png?auto=format&fit=clip&q=50) In the left navigation menu, select the **Permissions** tab. In the **Scopes** section, enable the **openid**, **email**, and **profile** scopes to allow the application to read basic user profile information. Click **Save**. ![Configuring Scopes in Vercel](https://images.workoscdn.com/images/7240cd69-de9b-4a20-9f1a-13ed6beaf825.png?auto=format&fit=clip&q=50) --- ## (3) Generate client credentials In the left navigation menu, select the **General** tab and view your Client ID in the **Details** section. ![View Client ID in Vercel](https://images.workoscdn.com/images/fef2735e-9a66-47f0-a0d5-e6d402a3ae7d.png?auto=format&fit=clip&q=50) In the left navigation menu, select the **Authentication** tab. Scroll down to the **Client Secrets** section and click **Generate** to generate a new Client Secret. ![Generate Client Secret in Vercel](https://images.workoscdn.com/images/72e4b918-80ec-4aa8-b54a-349ca6d3bff2.png?auto=format&fit=clip&q=50) Note the **Client ID** and **Client Secret** values as you'll need them for the WorkOS configuration. > **Important**: The Client Secret is only shown once. Make sure to copy and store it securely. --- ## (4) Configure Vercel credentials in WorkOS Now that you have the **Vercel Client ID** and **Vercel Client Secret** from the previous step, return to the [WorkOS Dashboard](https://dashboard.workos.com). In the **Vercel OAuth** configuration dialog, enable the integration. Paste the credentials from Vercel into their respective fields in the WorkOS Dashboard. ![Entering Vercel Credentials in WorkOS Dashboard](https://images.workoscdn.com/images/ff653223-0ace-4f91-85f5-48e238e48666.png?auto=format&fit=clip&q=50) Click **Save changes** to complete the configuration. You are now ready to start authenticating with Vercel OAuth. If you are using AuthKit's [Hosted UI](/authkit/hosted-ui), a Continue with Vercel button will be added to your login page. If you are building your own authentication flows outside of AuthKit's hosted UI, you will use the `provider` query parameter in the [Get Authorization URL API endpoint](/reference/authkit/authentication/get-authorization-url) to support global Vercel OAuth for any domain. The `provider` query parameter should be set to `VercelOAuth`. --- ## Frequently asked questions ### How is the WorkOS Vercel OAuth integration different from implementing regular Vercel OAuth flow? It's the same Vercel OAuth flow as you could build yourself, but it's encapsulated within WorkOS SSO. This means you don't need to build it yourself. In addition to Vercel OAuth, you can use WorkOS SSO to support other identity providers, all with a single integration. ### What is the provider query parameter and how is it used in the Vercel OAuth integration? If you are building your own authentication flows outside of AuthKit's hosted UI, you can use the `provider` query parameter in the [Get Authorization URL API endpoint](/reference/authkit/authentication/get-authorization-url) to support global Vercel OAuth for any domain. The `provider` query parameter should be set to `VercelOAuth`. ### What scopes are required for Vercel OAuth? The **openid**, **profile**, and **email** scopes are required to allow the application to read user profile information necessary for authentication. These scopes provide access to the user's basic profile data and email address. ### Supabase + WorkOS SSO Learn how to use WorkOS for SSO with your Supabase application. ## Introduction This guide outlines the steps to make WorkOS SSO connections available to your application using Supabase Auth. It will require a few changes to your existing Supabase application code. If you are wanting to instead use AuthKit with your Supabase application, check out our [Supabase + AuthKit guide](/integrations/supabase-authkit). --- ## (1) Copy WorkOS Client ID and API Key Supabase uses the WorkOS Client ID and API Key to initiate the authentication flow and to return the SSO user profile. The first step is finding the Client ID and the API Key in the WorkOS dashboard. In the WorkOS dashboard, go to **Configuration** and under the "Settings" tab and copy the Client ID. ![A screenshot showing where to find the Client ID in the WorkOS dashboard configurations page.](https://images.workoscdn.com/images/5cdbbd7e-2141-470c-8b86-b0876974e58a.png?auto=format&fit=clip&q=50) Select **API Keys** on the left-side navigation bar and either copy an existing API Key or create a new API Key and copy it. ![A screenshot showing where the WorkOS API Key is in the dashboard.](https://images.workoscdn.com/images/fe6c9ad1-f04a-4335-9752-4ef149fa3147.png?auto=format&fit=clip&q=50) --- ## (2) Add your WorkOS credentials into your Supabase Project and configure the Redirect URL Sign in to Supabase and then go to your Supabase Project Dashboard. Navigate to **Authentication** → **Explore Auth**. ![A screenshot showing when to the Authentication section is in the Supabase project dashboard.](https://images.workoscdn.com/images/f773aeb8-5bee-4eba-89a0-62441a79be11.png?auto=format&fit=clip&q=50) Select the Providers tab and scroll down to WorkOS and enter the WorkOS URL as **https://api.workos.com**. Then enter the Client ID and API Key copied from the WorkOS Dashboard, toggle to enable WorkOS as a provider and click **Save**. ![A screenshot showing how to enable WorkOS as a provider in Supabase and input the WorkOS URL, Client ID and Secret Key.](https://images.workoscdn.com/images/c275b3f4-807c-4961-916b-c0ed2d6717dd.png?auto=format&fit=clip&q=50) Copy the Redirect URL from the WorkOS provider section. In the WorkOS dashboard navigate to **Configuration** → **Settings** → **Redirect URIs** and click **Edit Redirect URIs** to input the copied Redirect URL. ![A screenshot showing where to add the WorkOS Redirect URL.](https://images.workoscdn.com/images/27ad127c-3631-45d0-aedc-39ab90f03ed6.png?auto=format&fit=clip&q=50) --- ## (3) Add login code to your client app When a user signs in, call `signInWithOAuth` with `workos` as the provider. Pass in a Connection ID, Organization ID, or provider type (for OAuth) under `queryParams`. --- ## Summary With a few lines of code, you can add WorkOS as an SSO provider and enable features like the admin portal and dozens of integrations within your Supabase application. ### Supabase + AuthKit Learn how to use AuthKit with your Supabase application. ## Introduction This guide outlines the steps to use WorkOS as a Supabase [third-party auth provider](https://supabase.com/docs/guides/auth/third-party/overview). This will allow you to authenticate users with AuthKit and use AuthKit access tokens to access Supabase's REST and GraphQL APIs in your app. ## (1) Add a WorkOS third-party auth integration Configure a WorkOS integration in the [Supabase dashboard](https://supabase.com/dashboard/project/_/auth/third-party). ![Supabase 3rd party auth dashboard](https://images.workoscdn.com/images/6494746d-f6d2-46a1-bf26-f4fe7370e12b.png?auto=format&fit=clip&q=50) Your issuer URL is: ```txt title="WorkOS Issuer" https://api_workos_com/user_management/client_123456789 ``` ![Supabase WorkOS Connection dialog](https://images.workoscdn.com/images/e4d5c238-a217-4c9c-a955-a882074919bb.png?auto=format&fit=clip&q=50) ## (2) Set up a JWT Template Supabase RLS policies expect a `role` claim in the access token that corresponds to a database role. WorkOS already adds a `role` claim corresponding to the user's role in an organization. Set up a JWT template in the WorkOS dashboard (Authentication → Sessions) so that the role works with Supabase: We add a `user_role` claim so that your application can still determine the role assigned to that user. ## (3) Pass the access token to Supabase APIs Pass in your WorkOS client ID and auth domain when initializing the [Supabase client library](https://supabase.com/docs/guides/auth/third-party/workos#setup-the-supabase-client-library). That's it! Supabase will now accept the access tokens returned by AuthKit. ### Slack OAuth Learn how to set up OAuth with Slack ## Introduction The Slack OAuth integration allows your users to authenticate using their Slack credentials through the "Sign in with Slack" flow. The configuration process involves creating or configuring a Slack App and setting up OAuth permissions with the client credentials in your WorkOS Dashboard. --- ## What WorkOS provides When setting up Slack OAuth, WorkOS provides one key piece of information that needs to be configured in your Slack App: - [Redirect URI](/glossary/redirect-uri): The endpoint where Slack will send authentication responses after successful login The Redirect URI is available in the [WorkOS Dashboard](https://dashboard.workos.com/). In the left navigation menu, select the **Authentication** tab and the **OAuth providers** sub-tab. Locate the **Slack** section. ![The Slack OAuth section in the WorkOS Dashboard.](https://images.workoscdn.com/images/9c70cdb3-0b02-4529-919a-3d91235e78cf.png?auto=format&fit=clip&q=50) Click **Enable**. The **Slack OAuth** configuration dialog will open. Locate the **Redirect URI**. ![Slack OAuth Redirect URI in the WorkOS Dashboard.](https://images.workoscdn.com/images/c7800ed9-c9b9-4893-8821-e3af465362c5.png?auto=format&fit=clip&q=50) The **Redirect URI** serves as the destination for authentication responses and must be configured in your Slack App's OAuth & Permissions settings. --- ## What you'll need You will need to obtain two pieces of information from a Slack App: - **Slack Client ID**: Application identifier from Slack - **Slack Client Secret**: Authentication secret for the application The following sections will guide you through creating or configuring a Slack App and generating these credentials. --- ## (1) Create or open your Slack App Navigate to the [Slack App management page](https://api.slack.com/apps). If you don't already have a Slack App, click **Create an App**, provide a name, and choose the development workspace where you'll test. ![The Slack API portal showing the create new app button.](https://images.workoscdn.com/images/127f704d-ce13-49e0-9d82-2ba123547e3e.png?auto=format&fit=clip&q=80) Once created, open your new Slack App to configure it. --- ## (2) Configure OAuth & Permissions In your Slack App's settings, go to **OAuth & Permissions** in the left-hand navigation menu. Under **Redirect URLs**, add the **Redirect URI** from the WorkOS Dashboard. ![The Slack API portal showing where to configure your redirect URI.](https://images.workoscdn.com/images/f0e7d586-a8e1-4a67-8c06-085dc4009b32.png?auto=format&fit=clip&q=80) Click **Save URLs** to confirm. Under **Scopes**, ensure you request the standard OpenID scopes (e.g., `openid`, `profile`, `email`), which Slack requires for Sign in with Slack using OIDC. --- ## (3) Retrieve Slack credentials Still in your Slack App's settings, find your **Client ID** and **Client Secret**. Copy both values as you'll need them for the WorkOS configuration. --- ## (4) Configure Slack credentials in WorkOS Now that you have the **Slack Client ID** and **Slack Client Secret** from the previous steps, return to the [WorkOS Dashboard](https://dashboard.workos.com). In the **Slack OAuth** configuration dialog, enable the integration. Paste the credentials from Slack into their respective fields in the WorkOS Dashboard. ![The WorkOS dashboard with the Slack OAuth connection enabled.](https://images.workoscdn.com/images/c9c7c0de-c1f1-4d73-8f68-1b415d3dc5cb.png?auto=format&fit=clip&q=50) Click **Save** to complete the configuration. --- ## Frequently asked questions ### How is the WorkOS Slack OAuth integration different from implementing regular Slack OAuth flow? It's the same Slack OAuth flow as you could build yourself, but it's encapsulated within WorkOS SSO. This means you don't need to build it yourself. In addition to Slack OAuth, you can use WorkOS SSO to support other identity providers, all with a single integration. ### What is the provider query parameter and how is it used in the Slack OAuth integration? You can use the `provider` query parameter in the [Get Authorization URL API endpoint](/reference/sso/get-authorization-url) to support Slack OAuth for any domain. The `provider` query parameter should be set to `SlackOAuth`. ### What scopes are required for Slack OAuth? The standard OpenID scopes (`openid`, `profile`, `email`) are required for Sign in with Slack using OIDC. These scopes provide access to the user's basic profile information necessary for authentication. ### SimpleSAMLphp Learn how to configure a SimpleSAMLphp connection. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a SimpleSAMLphp SAML Connection, you’ll need the Identity Provider Metadata URL that is available from the organization's SimpleSAMLphp instance. --- ## What WorkOS provides WorkOS provides the [ACS URL](/glossary/acs-url), the [SP Metadata](/glossary/sp-metadata) Link and the [SP Entity ID](/glossary/sp-entity-id). They are readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot showing where to find the ACS URL, SP Metadata and SP Entity ID in the WorkOS dashboard.](https://images.workoscdn.com/images/e2c962f1-2fe9-470f-af1f-684fe651fcbc.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. The SP Metadata link contains a metadata file that the organization can use to set up the SAML integration. The SP Entity ID is a URI used to identify the issuer of a SAML request, response, or assertion. --- ## What you’ll need In order to integrate, you’ll need the [IdP Metadata URL](/glossary/idp-metadata). Normally, this will come from the organization's IT Management team when they set up your application’s SAML configuration in their SimpleSAMLphp instance. But, should that not be the case during your setup, here’s how to obtain it. --- ## (1) Configure SAML Application with Service Provider Details Follow the [SimpleSAMLphp documentation](https://simplesamlphp.org/docs/stable/simplesamlphp-idp.html) to set up SimpleSAMLphp as an Identity Provider and add a new SP. Copy and paste the ACS URL and SP Entity ID into the corresponding fields for Service Provider configuration. You can find more on how to structure this under “Adding SPs to the IdP” in the SimpleSAMLphp documentation linked above. The necessary SP metadata can also be found in the SP metadata URL provided in the WorkOS Dashboard. --- ## (2) Configure SAML Attributes You will need to send the following 4 required attributes in the SAML Response: `firstName`, `lastName`, `email`, and `id`. Ensure the following attribute mapping is set: - A user’s first name → `firstName` - A user’s last name → `lastName` - A user’s email address → `email` - A unique identifier representing a user → `id` ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, map the groups in your identity provider to a SAML attribute named `groups`. > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (3) Obtain Identity Provider Metadata Obtain the IdP Metadata URL. As noted in the ["Adding this IdP to other SPs" section of the SimpleSAMLphp documentation](https://simplesamlphp.org/docs/stable/simplesamlphp-idp.html), the IdP metadata URL should be available from `/saml2/idp/metadata.php`. ![A screenshot showing where to edit the IdP metadata URL in the WorkOS dashboard.](https://images.workoscdn.com/images/07f6f9a0-4331-4124-b90e-dc8d24f7e2ea.png?auto=format&fit=clip&q=50) Alternatively, you can manually configure the connection by providing the IdP URI (Entity ID), [IdP SSO URL](/glossary/idp-sso-url) and X.509 Certificate. ![A screenshot showing how to switch to manual IdP metadata configuration in the WorkOS dashboard.](https://images.workoscdn.com/images/07c47c03-354d-4df4-bdb9-bc25573aeb25.png?auto=format&fit=clip&q=50) ![A screenshot showing how to manually configure the IdP metadata in the WorkOS dashboard.](https://images.workoscdn.com/images/d838649f-ee75-429e-94b2-c1693294b81c.png?auto=format&fit=clip&q=50) Your Connection will then be Active and good to go! ### Shibboleth Unsolicited SAML Learn how to configure a Shibboleth Unsolicited connection via SAML. ## Introduction These instructions are for connecting to Shibboleth using the [UnsolicitedSSOConfiguration](https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631696/UnsolicitedSSOConfiguration). If the organization requires the [generic SAML 2.0 configuration](https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631694/SAML2SSOConfiguration) instead, please use the [Shibboleth Generic SAML provider documentation](/integrations/shibboleth-generic-saml). Each SSO Identity Provider requires specific information to create and configure a new [connection](/glossary/connection). Often, the information required to create a connection will differ by Identity Provider. To create a Shibboleth Unsolicited SAML connection, you’ll need the Identity Provider metadata that is available from the organization's Shibboleth instance. Start by logging in to your WorkOS dashboard and browse to the “Organizations” tab on the left hand navigation bar. Select the organization you wish to configure a Shibboleth Unsolicited SAML connection for, and select “Manually Configure Connection” under “Identity Provider”. ![Create New Connection in WorkOS Dashboard](https://images.workoscdn.com/images/c4cf0500-9155-42dd-aa2d-fd40fbbc79bc.png?auto=format&fit=clip&q=50) Select “Shibboleth Unsolicited SAML” from the Identity Provider dropdown, enter a descriptive name for the connection, and then select the “Create Connection” button. ![Select Shibboleth Unsolicited SAML Provider](https://images.workoscdn.com/images/8a32ce47-1087-420d-87b3-49e031308ae7.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides Once you’ve created your connection, WorkOS provides the [ACS URL](/glossary/acs-url), [SP Metadata](/glossary/sp-metadata) link, and [SP Entity ID](/glossary/sp-entity-id). It’s readily available in your connection settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot showing where to find the ACS URL, SP Metadata and SP Entity ID in the WorkOS dashboard.](https://images.workoscdn.com/images/a19338a8-f7a4-432a-8e7f-0f1b27a5422e.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. The SP Metadata link contains a metadata file that the organization can use to set up the Shibboleth Unsolicited SAML integration. The SP Entity ID is a URI used to identify the issuer of a SAML request and the audience of a SAML response. In this case, the SP Entity ID is used to communicate that WorkOS will be the party performing SAML requests to the organization's Shibboleth instance, and that WorkOS is the intended audience of the SAML responses from the Shibboleth instance. --- ## What you’ll need In order to integrate you’ll need the Shibboleth IdP metadata. Normally, this information will come from the organization's IT Management team when they set up your application’s Shibboleth configuration. But, should that not be the case during your setup, here’s how to obtain them. --- ## (1) Enter Service Provider Details Copy and Paste the “ACS URL” and “SP Entity ID” into the corresponding fields for Service Provider details and configuration. For some Shibboleth setups, you can use the metadata found at the SP Metadata link to configure the Shibboleth connection. --- ## (2) Obtain Identity Provider Metadata Download the IdP metadata from the Shibboleth instance. Refer to the [Shibboleth documentation](https://shibboleth.atlassian.net/wiki/spaces/CONCEPT/pages/928645275/MetadataForIdP) for more information on this metadata file. Keep in mind where the file was saved, as we’ll be uploading it later to configure the connection. --- ## (3) Configure Attribute Mapping At a minimum, the Attribute Statement in the SAML Response should include `id`, `email`, `firstName`, and `lastName` attributes. Refer to the [Shibboleth documentation](https://shibboleth.atlassian.net/wiki/spaces/CONCEPT/pages/928645122/SAMLAttributeNaming) for more information on adding and mapping attributes. ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, map the groups in your identity provider to a SAML attribute named `groups`. > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (4) Upload Metadata File In the connection settings in the WorkOS dashboard, click “Edit Metadata Configuration”. ![A screenshot showing where to edit the IdP metadata URL in the WorkOS dashboard.](https://images.workoscdn.com/images/eaf5a624-5a5a-4702-a4f8-1cb3d55ed6e9.png?auto=format&fit=clip&q=50) Upload the XML metadata file from Shibboleth into the “Metadata File” field and select “Save Metadata Configuration”. Your connection will then be linked and good to go! ![A screenshot showing where to upload and how to save the IdP metadata URL in the WorkOS dashboard.](https://images.workoscdn.com/images/ad7fc5c3-f3cf-4860-a219-00838ee5e766.png?auto=format&fit=clip&q=50) ### Shibboleth Generic SAML Learn how to configure a Shibboleth Generic connection via SAML. ## Introduction These instructions are for connecting to Shibboleth using the [generic SAML 2.0 configuration](https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631694/SAML2SSOConfiguration). If the organization requires the [UnsolicitedSSOConfiguration](https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631696/UnsolicitedSSOConfiguration) instead, please use the [Shibboleth Unsolicited SAML provider documentation](/integrations/shibboleth-unsolicited-saml). Each SSO Identity Provider requires specific information to create and configure a new [connection](/glossary/connection). Often, the information required to create a connection will differ by Identity Provider. To create a Shibboleth Generic SAML connection, you’ll need the Identity Provider metadata that is available from the organization's Shibboleth instance. Start by logging in to your WorkOS dashboard and browse to the “Organizations” tab on the left hand navigation bar. Select the organization you wish to configure a Shibboleth Generic SAML connection for, and select “Manually Configure Connection” under “Identity Provider”. ![A screenshot showing where to find "Manually Configure Connection" in the WorkOS Dashboard.](https://images.workoscdn.com/images/f07dc8e4-e97c-4bd0-9dbd-14915cd46e40.png?auto=format&fit=clip&q=50) Select “Shibboleth Generic SAML” from the Identity Provider dropdown, enter a descriptive name for the connection, and then select the “Create Connection” button. ![A screenshot showing "Create Connection" details in the WorkOS Dashboard.](https://images.workoscdn.com/images/640b70d1-60ce-48c7-865f-2441325a078c.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides Once you’ve created your connection, WorkOS provides the [ACS URL](/glossary/acs-url), [SP Metadata](/glossary/sp-metadata) link, and [SP Entity ID](/glossary/sp-entity-id). It’s readily available in your connection settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot showing where to find the ACS URL, SP Metadata and SP Entity ID in the WorkOS Dashboard.](https://images.workoscdn.com/images/efd8ea95-9dbd-4a18-b961-7d9d1b4bc3ce.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. The SP Metadata link contains a metadata file that the organization can use to set up the Shibboleth Generic SAML integration. The SP Entity ID is a URI used to identify the issuer of a SAML request and the audience of a SAML response. In this case, the SP Entity ID is used to communicate that WorkOS will be the party performing SAML requests to the organization's Shibboleth instance, and that WorkOS is the intended audience of the SAML responses from the Shibboleth instance. --- ## What you’ll need In order to integrate you’ll need the Shibboleth IdP metadata. Normally, this information will come from the organization's IT Management team when they set up your application’s Shibboleth configuration. But, should that not be the case during your setup, here’s how to obtain them. --- ## (1) Enter Service Provider Details Copy and Paste the “ACS URL” and “SP Entity ID” into the corresponding fields for Service Provider details and configuration. For some Shibboleth setups, you can use the metadata found at the SP Metadata link to configure the Shibboleth connection. --- ## (2) Obtain Identity Provider Metadata Download the IdP metadata from the Shibboleth instance. Refer to the [Shibboleth documentation](https://shibboleth.atlassian.net/wiki/spaces/CONCEPT/pages/928645275/MetadataForIdP) for more information on this metadata file. Keep in mind where the file was saved, as we’ll be uploading it later to configure the Connection. --- ## (3) Configure Attribute Mapping At a minimum, the Attribute Statement in the SAML Response should include `id`, `email`, `firstName`, and `lastName` attributes. Refer to the [Shibboleth documentation](https://shibboleth.atlassian.net/wiki/spaces/CONCEPT/pages/928645122/SAMLAttributeNaming) for more information on adding and mapping attributes. ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, map the groups in your identity provider to a SAML attribute named `groups`. Once your SAML app is configured to return groups, navigate to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (4) Upload Metadata File In the connection settings in the WorkOS Dashboard, click “Edit Metadata Configuration”. ![A screenshot showing where to edit the IdP metadata URL in the WorkOS Dashboard.](https://images.workoscdn.com/images/8fb3610f-15a3-4e10-8441-50121bd32609.png?auto=format&fit=clip&q=50) Upload the XML metadata file from Shibboleth into the “Metadata File” field and select “Save Metadata Configuration”. Your connection will then be linked and good to go! ![A screenshot showing where to upload and how to save the IdP metadata URL in the WorkOS Dashboard.](https://images.workoscdn.com/images/d9745f3c-4b3f-4e43-aea2-1b21e7160909.png?auto=format&fit=clip&q=50) ### SFTP Learn about syncing users with an SFTP connection ## Introduction To set up an SFTP (Secure File Transfer Protocol) directory sync connection, you'll need to provide the organization's IT team with specific configuration details from WorkOS. This allows them to upload CSV files containing user and group information via SFTP. WorkOS maintains a receiving SFTP server that the organization's HRIS provider or SFTP client can connect to. If the organization's HRIS has a built-in SFTP client, SFTP will allow them to automatically sync their data and ensure their data is always up to date. An SFTP integration allows for provider-agnostic ingestion of employee data into your product ecosystem. Once the integration is set up, WorkOS automatically creates and hosts an SFTP folder for the organization's HRIS provider to upload files at a regular cadence. An SFTP integration has the following advantages: - Works with any system that has the ability to export CSVs - Has an easy integration path for an organization comfortable working with CSVs and SFTP - Allows a custom cadence of updates for your customer Your application interfaces with an SFTP directory the same as with other directories; receiving [events](/events) when the directory is created or updated: --- ## What WorkOS provides When setting up an SFTP directory sync connection, WorkOS provides two key pieces of information that you'll need to share with the organization: - **SFTP Server URL**: The location where the organization will upload user and group CSV files - **Username**: Authentication credentials for SFTP access These are available in your directory’s settings in the [WorkOS Dashboard](https://dashboard.workos.com/) once the connection is configured. ![SFTP directory details in the WorkOS Dashboard.](https://images.workoscdn.com/images/46c63f08-579e-4e60-8cb6-b20d6f95ff8b.png?auto=format&fit=clip&q=50) The SFTP server uses public key authentication, providing secure file transfer capabilities for user and group data synchronization. --- ## What you will need The organization will need to provide a public key for authentication and prepare their user and group data in the required CSV format. You will need to obtain from the organization: - **Public Key**: For SFTP authentication (maximum key length is 2048 bytes; supported keys are: `ED25519`, `RSA`, and `ECDSA`) The organization will need to export their users and groups as CSV files with the structure below. ### `users.csv` This file is required. ### `user_groups.csv` This file is _optional_. ### `groups.csv` This file is _optional_. Additional metadata may be also included in this file. --- ## (1) Set up your directory sync endpoint Login to the [WorkOS Dashboard](https://dashboard.workos.com/). In the left navigation menu, select the **Organizations** tab. Select the appropriate organization for which you will enable a SFTP directory sync connection. On the organization's page, scroll down to the **Directory Sync** section. Click **Configure manually**. ![WorkOS Dashboard showing directory sync card with configure manually button highlighted](https://images.workoscdn.com/images/ebf08eb3-a698-4498-adde-1b551ab0f519.png?auto=format&fit=clip&q=50) Select **SFTP** as the directory type. Input an appropriate name for the connection. Click **Create Directory**. ![The WorkOS Dashboard with a create directory dialog](https://images.workoscdn.com/images/e1010105-9c22-4d20-88d0-8b316df97ad2.png?auto=format&fit=clip&q=50) --- ## (2) Configure SFTP authentication Obtain the public key from the organization’s admin that will be used for SFTP authentication. From the directory page in the WorkOS Dashboard, in the **Directory details** section click the **Update Directory** button. ![A screenshot showing where to find "Update directory" for an Organization in the WorkOS Dashboard.](https://images.workoscdn.com/images/d0847fd0-b9c9-4ec2-aa1e-b69c6aac1fa5.png?auto=format&fit=clip&q=50) Paste the organization's public key into the input field. The SSH public key format should include the key type (e.g. `ssh-rsa`, `ssh-ed25519`), base64 encoded body, and an optional comment, with spaces between each element. For example, `ssh-rsa AAAABB1 keycomment`. RSA, ECDSA, and ED25519 keys are accepted: - For RSA keys, the key type is `ssh-rsa`. - For ED25519 keys, the key type is `ssh-ed25519`. - For ECDSA keys, the key type is either `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, or `ecdsa-sha2-nistp521`, depending on the size of the key generated. ![A screenshot showing how to update SFTP directory details in the WorkOS Dashboard.](https://images.workoscdn.com/images/77a535f1-87d4-410f-bd7c-09a4535e53c2.png?auto=format&fit=clip&q=50) --- ## (3) Provide SFTP configuration to the organization After adding the public key, WorkOS generates a username. You will see the green **Linked** icon appear. Copy the **Username** and SFTP server URL from the WorkOS Dashboard. Share these values with the organization so they can configure their SFTP client: - **SFTP Server**: `sftp.workos.com` - **Username**: The generated username from the WorkOS Dashboard - **Authentication**: Their private key (corresponding to the public key you uploaded) Instruct the organization to upload their CSV files using these credentials. --- ## (4) Confirm users and groups are synced Now, whenever your customer uploads updated CSV files via SFTP, you’ll receive updates based on the changes in their directory data. The **Users** tab within the SFTP connection displays synced users. A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) ## SFTP Security ### How is my organization’s data protected in transit? SFTP uses SSH (Secure Shell protocol) to symmetrically encrypt traffic after an asymmetric key negotiation for authentication. Our solution leverages the [AWS Transfer Family](https://docs.aws.amazon.com/transfer/latest/userguide/how-aws-transfer-works.html), so that we can support a common, secure protocol (SSH) with modern, isolated data storage (AWS S3). We leverage the default security policy ([security-policy-transfer-2020-06](https://docs.aws.amazon.com/transfer/latest/userguide/security-policies.html#security-policy-transfer-2020-06)) for the choice of SSH cipher-suites, which determines the strength of cryptographic protection for data in transit. ### How is my organization’s data protected at rest? As the data is stored in an AWS S3 bucket the default (since January 2023) is that it is encrypted at rest ([SSE-S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html)). The symmetric encryption used is AES-256, more information is available in [the FAQ](https://docs.aws.amazon.com/AmazonS3/latest/userguide/default-encryption-faq.html). ### How does WorkOS isolate one of my organization’s data from the other? Each of the organizations you onboard will [create an SSH key pair](/integrations/sftp/what-you-will-need), this consists of a public key, and a private key. They will retain the private key, ensuring that only they can authenticate. The public key uploaded to WorkOS will be used to authenticate the organization's connection via SFTP. Each of your organizations is mapped to a distinct S3 bucket based on an internal (cryptographically random) identifier for the SSH key pair. ### When does WorkOS dispose of the data and how is this done? In either of the following events your organization’s data, and the S3 bucket will be deleted: 1. You off-board the organization from your product/service. 2. You no longer use the WorkOS Directory Sync service. --- ## Frequently asked questions ### How often do SFTP directories perform a sync? SFTP directories will sync automatically whenever file changes are detected and every 30 minutes following the initial synchronization. ### SCIM Learn about syncing users with a custom SCIM provider ## Introduction To set up a SCIM v2.0 directory sync connection, you'll need to provide the organization’s IT team with specific configuration details from WorkOS. This allows their SCIM server to synchronize users and groups with your application. --- ## What WorkOS provides When setting up a SCIM directory sync connection, WorkOS provides two key pieces of information that you'll need to share with the organization: - [Endpoint](/glossary/endpoint): The URL where the SCIM server will send requests - [Bearer Token](/glossary/bearer-token): Authentication credentials for the endpoint requests Both of these are available in the **Directory details** section of the directory sync connection in the [WorkOS Dashboard](https://dashboard.workos.com/). ![The WorkOS dashboard, highlights the directory details card with filled endpoint and bearer token inputs](https://images.workoscdn.com/images/1ae8c088-07d6-4512-9abf-1adec38f6b0b.png?auto=format&fit=clip&q=50) These settings enable the organization’s SCIM server to securely send user and group data to your application through WorkOS. --- ## What you will need The organization’s IT team will handle the SCIM server configuration on their end. You simply need to provide them with the endpoint URL and bearer token from the WorkOS Dashboard. Typically, the organization's IT team will use these values to configure your application within their SCIM server or identity provider admin dashboard. --- ## (1) Set up your directory sync endpoint Login to the [WorkOS Dashboard](https://dashboard.workos.com/). In the left navigation menu, select the **Organizations** tab. Select the appropriate organization for which you will enable a SCIM directory sync connection. On the organization’s page, scroll down to the **Directory Sync** section. Click **Configure manually**. ![WorkOS Dashboard showing directory sync card with configure manually button highlighted](https://images.workoscdn.com/images/ebf08eb3-a698-4498-adde-1b551ab0f519.png?auto=format&fit=clip&q=50) Select **Custom SCIM v2.0** as the directory type. Input an appropriate name for the connection. Click **Create Directory**. ![The WorkOS Dashboard with a create directory dialog showing directory type and name inputs](https://images.workoscdn.com/images/aa5a17d9-0990-4af6-a61f-1640658650e1.png?auto=format&fit=clip&q=50) The directory sync connection will now display the endpoint for the SCIM server and the bearer token. > We have support for custom labeled URLs for directory sync endpoints. [Contact us](mailto:support@workos.com) for more info! --- ## (2) Provide SCIM configuration to the organization Copy the **Endpoint** and **Bearer Token** from the **Directory details** section on the directory page of the WorkOS Dashboard. Provide these values to the organization’s IT team so they can configure the application within their SCIM server or identity provider admin dashboard: - **Endpoint URL**: The destination where their SCIM server will send user and group data - **Bearer Token**: Authentication credentials for secure communication Once the organization has configured these values in their SCIM server, your application will be ready to receive real-time user and group synchronization. --- ## (3) Assign users and groups to your application Now, whenever the organization assigns users or groups to your application in their directory, you’ll receive real-time dashboard updates based on changes in their system. A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) ### SAML Learn how to configure a new custom SAML connection ## Introduction To set up a SAML connection on behalf of an organization, you'll need the identity provider metadata or manual configuration details from the organization's IT team. --- ## What WorkOS provides When setting up a SAML connection, WorkOS provides three key pieces of information in the **Service Provider Details** section for an SSO connection within the [WorkOS Dashboard](https://dashboard.workos.com/): - [SP Entity ID](/glossary/sp-entity-id): A unique identifier that represents your application in SAML communications - [ACS URL](/glossary/acs-url): The endpoint where identity providers send authentication responses - [SP Metadata](/glossary/sp-metadata): A configuration file containing all necessary SAML settings ![WorkOS Settings](https://images.workoscdn.com/images/bc0ebb05-e918-4217-8435-bfd1c73dd1f6.png?auto=format&fit=clip&q=80) These settings are required to configure a SAML integration. The **ACS URL** serves as the destination for authentication responses, while the **SP Entity ID** uniquely identifies your application in SAML requests and responses. The **SP Metadata** URL provides a complete configuration file that simplifies the setup process for the organization. --- ## What you will need You will need to obtain one of the following from the organization: - [Identity Provider Metadata URL](/glossary/idp-metadata): Configuration URL containing SAML metadata (preferred) - Manual configuration details: SSO URL, Entity ID, and X.509 Certificate (if metadata URL is not available) Typically, the organization's IT team will provide these values when they configure your application in their identity provider admin dashboard. However, if you need to guide them through the process, the following sections will help. --- ## (1) Configure Service Provider Details For SSO to properly function, the organization needs to create and configure a SAML application in their identity provider. Copy the **ACS URL** and **SP Entity ID** from the **Service Provider Details** section in the WorkOS Dashboard. Instruct the organization admin to paste these values into the corresponding fields in their identity provider's admin dashboard. Alternatively, they can use the service provider metadata URL to automatically configure the SAML connection if their identity provider supports metadata-based configuration. --- ## (2) Obtain identity provider metadata After the organization creates a SAML application, their identity provider will provide either a metadata URL or manual configuration details. If they have a metadata URL, in the WorkOS Dashboard, navigate to the **Identity Provider Configuration** section. Click **Edit Configuration**. ![Open Identity Provider Configuration in WorkOS Dashboard](https://images.workoscdn.com/images/a33cc226-7167-4450-8879-9f123fc8ffeb.png?auto=format&fit=clip&q=80) Paste the metadata URL from the organization's IT team into the input field. Your connection will be automatically configured once the metadata is processed. ![Upload identity provider metadata URL to WorkOS Dashboard](https://images.workoscdn.com/images/4d25d1a1-57a0-464d-95d7-a33eb85d2e0f.png?auto=format&fit=clip&q=80) If the organization's identity provider doesn't provide a metadata URL, you'll need to manually configure the connection by clicking the **Switch to Manual Configuration** option and entering the SSO URL, Entity ID, and X.509 Certificate provided by their IT team. ![Switch to Manual Configuration](https://images.workoscdn.com/images/7384d9b7-b918-4778-ac1f-2b389cf73241.png?auto=format&fit=clip&q=80) ![Manually configure connection in WorkOS Dashboard](https://images.workoscdn.com/images/37eaf62e-dd9f-41b0-9e91-221256318298.png?auto=format&fit=clip&q=80) --- ## (3) Configure attribute mapping The organization's SAML provider needs to include specific attributes in the SAML response. Instruct them to configure their SAML application to include the following attributes in the Attribute Statement: - `id`: Maps to the `idp_id` attribute in WorkOS user profiles - `email`: Maps to the `email` attribute in WorkOS user profiles - `firstName`: Maps to the `first_name` attribute in WorkOS user profiles - `lastName`: Maps to the `last_name` attribute in WorkOS user profiles ### Role assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To enable this functionality, instruct the organization to add a `groups` attribute to the SAML response that maps to a list of the user's group memberships. > Finish role assignment set-up by navigating to the SSO connection page in the **Organizations** section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. ### Salesforce SAML Learn how to configure a connection to Salesforce via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [connection](/glossary/connection). And often, the information required to create a connection will differ by Identity Provider. To create an Salesforce SAML connection, you’ll need three pieces of information: an [ACS URL](/glossary/acs-url), an [SP Entity ID](/glossary/sp-entity-id), and a [Metadata URL](/glossary/idp-metadata). --- ## What WorkOS provides WorkOS provides the ACS URL and SP Entity ID. It’s readily available in your Connection Settings in the [WorkOS dashboard](https://dashboard.workos.com/). ![A screenshot showing where to find the ACS URL and SP Entity ID in the WorkOS dashboard.](https://images.workoscdn.com/images/134a9a2e-3409-4969-9048-01be960c7d93.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. In Salesforce’s case, it needs to be set by the organization when configuring Salesforce as an Identity Provider. The Entity ID is a URI used to identify the issuer of a SAML request, response, or assertion. In this case, the entity ID is used to communicate that WorkOS will be the party performing SAML requests to the organization's Salesforce instance. Specifically, the ACS URL and SP Entity ID will need to be set in the Connected Apps setup in Salesforce. ![A screenshot showing where to place the WorkOS ACS URL and SP Entity ID in the Salesforce dashboard.](https://images.workoscdn.com/images/98390601-4c8a-42f4-9965-52ddcd28ff45.png?auto=format&fit=clip&q=50) --- ## What you’ll need In order to integrate you’ll need the Salesforce Metadata URL. Normally, the this will come from the organization's IT Management team when they set up your application’s SAML client in their Salesforce instance. But, should that not be the case during your setup, here’s how to obtain it. --- ## (1) Generate Certificate Log in to your Salesforce Account, click the Settings cog icon on the top right, and select “Setup”. Once in setup mode you can use the search bar to easily navigate around between settings pages. The first page to navigate to is the “Certificate and Key Management” page. ![A screenshot showing how to navigate to the "Certificate and Key Management" page in the Salesforce dashboard.](https://images.workoscdn.com/images/769b9580-ffc1-46d6-b382-4b5a83222dd8.png?auto=format&fit=clip&q=50) Once in setup mode you can use the search bar to easily navigate around between settings pages. The first page to navigate to is the “Certificate and Key Management” page. If a key does not exist that you would like to use, click “Create Self-Signed Certificate” to generate a new one. ![A screenshot showing how to generate a Self-Signed Certificate in the Salesforce dashboard.](https://images.workoscdn.com/images/fc278a8b-3398-46ff-9a58-143dc127d0e6.png?auto=format&fit=clip&q=50) Give the Certificate a meaningful label and unique name and select the Key Size you’d like to use. It’s not necessary to have an Exportable Private Key, but if you are using a key-certificate store you can choose this option. ![A screenshot showing how to configure the Self-Signed Certificate details in the Salesforce dashboard.](https://images.workoscdn.com/images/936558fc-d9c3-4075-a139-3cea3d3854dc.png?auto=format&fit=clip&q=50) --- ## (2) Enable Salesforce as an IdP From the setup search bar browse to the “Identity Provider” portal in Salesforce. If it has not already been done, select “Enable Identity Provider”. ![A screenshot showing how to enable Salesforce as an Identity Provider in the Salesforce dashboard.](https://images.workoscdn.com/images/f890533c-dd88-4b05-9cbe-e47b3a416906.png?auto=format&fit=clip&q=50) You will need to select the correct certificate from the previous step. ![A screenshot showing how to select the SAML certificate for the Identity Provider setup in the Salesforce dashboard.](https://images.workoscdn.com/images/f332f289-dad3-491d-a1c3-67e14e381cfc.png?auto=format&fit=clip&q=50) Additionally this page will display the Metadata URL. You will need to copy this URL and in a later step it will be uploaded into WorkOS. ![A screenshot showing where to copy the IdP Metadata URL from in the Salesforce dashboard.](https://images.workoscdn.com/images/e5088944-d7b5-4e3f-8072-d672bbd88f26.png?auto=format&fit=clip&q=50) --- ## (3) Configure SAML Application Next from the setup search bar browse to the “App Manager” portal. Once here you will want to select the option for “New Connected App”. ![A screenshot showing how to create a new Connected App in the Salesforce dashboard.](https://images.workoscdn.com/images/af73f2b9-6c91-4b45-87aa-b0e15a2d9a0d.png?auto=format&fit=clip&q=50) Give the App and API a meaningful name and set a contact email that corresponds to who you’d reach out to for support should there be an issue. You can always opt to use `support@workos.com`. ![A screenshot showing how to configure the name and contact email for the new Connected App in the Salesforce dashboard.](https://images.workoscdn.com/images/03a48352-2825-4c6d-aa8d-bfb57f03159f.png?auto=format&fit=clip&q=50) Scroll down further to the “Web App Settings” and check the box for “Enable SAML”. Enter the Entity ID and ACS URL into their respective places within the Settings. The “Subject Type” should be set to “User ID” and the “Name ID Format” should be set to `urn:oasis:names:tv:SAML:1.1:nameid-format:emailAddress`. The “Issuer” should populate correctly with your Salesforce subdomain. For the IdP Certificate, select the certificate that matches the one previously used when enabling the Identity Provider, and for the “Signing Algorithm for SAML Messages” choose “SHA256”. ![A screenshot showing how to configure the Connected App's Web App Settings in the Salesforce Dashboard.](https://images.workoscdn.com/images/98390601-4c8a-42f4-9965-52ddcd28ff45.png?auto=format&fit=clip&q=50) Save the configurations and you should now see the new Connected App listed under “App Manager”. --- ## (4) Configure User Attributes and Claims In the Setup search bar browse to the “Manage Connected Apps” portal. Click on your application and this will open the view where you can configure the attribute mapping, and later on the user profile access permissions. ![A screenshot showing how to open the configurations for the new Connected App in the Salesforce dashboard.](https://images.workoscdn.com/images/6d1dc5a0-d7a5-4e68-a596-5e69f0cb1d52.png?auto=format&fit=clip&q=50) Viewing the app, scroll down to the “Custom Attributes” section and select “New”. ![A screenshot showing how to create new Custom Attribute mapping in the Salesforce dashboard.](https://images.workoscdn.com/images/716f679d-907f-42b9-8024-ff74ecff82cc.png?auto=format&fit=clip&q=50) Salesforce automatically includes email as an Attribute so we will need to add three fields: - `id` - `firstName` - `lastName` Configure the fields so the mapping matches the following: ![A screenshot showing how to configure SAML attribute mapping in the Salesforce dashboard.](https://images.workoscdn.com/images/0dfb70bf-744f-4021-ae20-c06ade8f792d.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, create a new custom attribute with a key of `groups`. Map this attribute to a value that contains a user’s group membership or role information, such as `$UserRole.Name` in the example below. ![A screenshot showing where to add the groups attribute in the Salesforce dashboard.](https://images.workoscdn.com/images/0f2abfab-25c9-4ce4-aeb4-7f0f3fae8038.png?auto=format&fit=clip&q=50) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (5) Manage Profiles With Application Access Similarly, viewing the app, there is a “Manage Profiles” section for granting access to control who can log into the application. Select “Manage Profiles” and grant access to the appropriate profiles that should have access to the application in the "Application Profile Assignment" wizard. Select "Save" when complete. ![A screenshot showing how to configure the "Application Profile Assignments" in the Salesforce dashboard.](https://images.workoscdn.com/images/26cdf036-5428-4ccf-b320-f9d1e41250e2.png?auto=format&fit=clip&q=50) Here is an example of a successfully configured “Connected Application” allowing access to anyone with an “End User” Profile. ![A screenshot showing the completed "Application Profile Assignments" in the Salesforce dashboard.](https://images.workoscdn.com/images/fdc0584a-1350-42d7-8816-c8255e307db6.png?auto=format&fit=clip&q=50) --- ## (6) Obtain Identity Provider Details Finally, return to the WorkOS dashboard. Within your connection settings, select "Edit Metadata Configuration" under "Identity Provider Configuration" and provide the Metadata URL you obtained from Salesforce. Your connection will then be verified and good to go! ![A screenshot showing where to add the IdP Metadata URL in the WorkOS dashboard.](https://images.workoscdn.com/images/ff29bcdd-a7df-47d3-88fc-f001a3dae23d.png?auto=format&fit=clip&q=50) ### Salesforce OAuth Learn how to set up OAuth with Salesforce. ## Introduction The Salesforce OAuth integration allows your users to authenticate using their Salesforce credentials. The configuration process involves creating an External Client App in Salesforce and configuring the client credentials in the WorkOS Dashboard. --- ## What WorkOS provides When setting up Salesforce OAuth, WorkOS provides one key piece of information that needs to be configured in your Salesforce External Client App: - [Redirect URI](/glossary/redirect-uri): The endpoint where Salesforce will send authentication responses after successful login The Redirect URI is available in the [WorkOS Dashboard](https://dashboard.workos.com/). In the left navigation menu, select the **Authentication** tab and the **OAuth providers** sub-tab. Locate the **Salesforce** section. ![Open the Salesforce configuration dialog](https://images.workoscdn.com/images/27840df3-434d-4fc0-bae3-aa3dee021f2a.png?auto=format&fit=clip&q=50) Click **Manage**. The **Salesforce OAuth** configuration dialog will open. Locate the **Redirect URI**. ![Salesforce OAuth Redirect URI in the WorkOS Dashboard](https://images.workoscdn.com/images/387b564f-7c4c-4b94-aece-7dc3eb862058.png?auto=format&fit=clip&q=50) The **Redirect URI** serves as the destination for authentication responses and must be configured in your Salesforce External Client App as the authorization callback URL. --- ## What you'll need You will need to obtain two pieces of information from a Salesforce External Client App: - **Salesforce Consumer Key**: Application identifier from Salesforce - **Salesforce Consumer Secret**: Authentication secret for the application The following sections will guide you through creating an External Client App in your Salesforce instance and generating these credentials. --- ## (1) Create the Salesforce External Client App Sign in to Salesforce and navigate to Setup. On the sidebar, select **Apps**, then **External Client Apps**, then **External Client App Manager**. Create a new External Client App. ![The New External Client App button in Salesforce](https://images.workoscdn.com/images/e17fec69-13b5-4281-8311-5854ac1007af.png?auto=format&fit=clip&q=50) --- ## (2) Configure External Client App Fill out the External Client App form. Expand the **API (Enable OAuth Settings)** section, and check the **Enable OAuth** checkbox. For the **Callback URL** input, enter the **Redirect URI** from the WorkOS Dashboard. It is also required to add the "Access the identity URL service" and "Access unique user identifiers" scopes to your app. ![The Salesforce form to create a new External Client App](https://images.workoscdn.com/images/f1ce3367-fc4f-4be6-9529-49835431c38e.png?auto=format&fit=clip&q=50) Under **Security** deselect the **Require Proof Key for Code Exchange (PKCE) extension for Supported Authorization Flows** option, as WorkOS does not currently support PKCE for Salesforce OAuth. Click **Create**. ![The option to disable the PCKE requirement for a Salesforce External Client App](https://images.workoscdn.com/images/7e9a2bda-0ba4-4d33-a5f4-3ae07909a67e.png?auto=format&fit=clip&q=50) After creating your External Client App, click the **Settings** tab, and then expand **OAuth Settings**. Click on **Consumer Key and Secret**. You'll be given the Consumer Key and Secret for your External Client App. Note these values as you'll need them for the WorkOS configuration. --- ## (3) Configure Salesforce credentials in WorkOS Now that you have the **Salesforce Consumer Key** and **Salesforce Consumer Secret** from the previous step return to the [WorkOS Dashboard](https://dashboard.workos.com/). In the **Salesforce OAuth** configuration dialog, paste the credentials from Salesforce into the Client ID and Client Secret fields. ![Where to enter the Salesforce Consumer Key and Salesforce Consumer Secret in the WorkOS Dashboard](https://images.workoscdn.com/images/f65f7819-f9c9-4321-9ba5-9365fa51f4e8.png?auto=format&fit=clip&q=50) Click **Save changes** to complete the configuration. You're now able to authenticate users with Salesforce OAuth. If you are using AuthKit's [Hosted UI](/authkit/hosted-ui), the Login with Salesforce button will be added to your login page. If you are building your own authentication flows outside of AuthKit's hosted UI, you will use the `provider` query parameter in the [Get Authorization URL API endpoint](/reference/authkit/authentication/get-authorization-url) to support global Salesforce OAuth for any domain. The `provider` query parameter should be set to `SalesforceOAuth`. --- ## Configure Additional OAuth Scopes (Optional) WorkOS will request the OAuth scopes that are required for authentication by default. You can optionally configure your integration to request additional OAuth scopes as needed. When the **Return Salesforce OAuth tokens** option is selected, the access token from Salesforce will be included in the response from the [Authenticate with code API](/reference/authkit/authentication/code). ![A screenshot showing Salesforce OAuth scopes configuration in the WorkOS Dashboard](https://images.workoscdn.com/images/f1a87bc5-71b3-48fb-b2cf-3052ee39d4b4.png?auto=format&fit=clip&q=50) Any scopes configured here will be included on every Salesforce OAuth request. To specify additional scopes dynamically, use the `provider_scopes` query parameter on the [Get Authorization URL API endpoint](/reference/authkit/authentication/get-authorization-url). You will also have to update your External Client App's configured scopes to include these additional scopes. For more information, see Salesforce's OAuth scopes [documentation](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_tokens_scopes.htm). ## Frequently asked questions ### How is the WorkOS Salesforce OAuth integration different from implementing regular Salesforce OAuth flow? It's the same Salesforce OAuth flow as you could build yourself, but it's encapsulated within WorkOS SSO. This means you don't need to build it yourself. In addition to Salesforce OAuth, you can use WorkOS SSO to support other identity providers, all with a single integration. ### What is the provider query parameter and how is it used in the Salesforce OAuth integration? You can use the `provider` query parameter in the [Get Authorization URL API endpoint](/reference/authkit/authentication/get-authorization-url) to support global Salesforce OAuth for any domain. The `provider` query parameter should be set to `SalesforceOAuth`. ### What scopes are required for Salesforce OAuth? The **openid**, **profile**, and **email** scopes are required to allow the application to read user profile information necessary for authentication. These scopes provide access to the user's basic profile data. ### Rippling SCIM Learn about syncing your user list with Rippling SCIM v2.0. ## Introduction This guide outlines how to synchronize your application’s Rippling directories using SCIM. To synchronize an organization’s users and groups provisioned for your application, you’ll need to provide the organization with two pieces of information: - An [Endpoint](/glossary/endpoint) that Rippling will make requests to. - A [Bearer Token](/glossary/bearer-token) for Rippling to authenticate its endpoint requests. Both of these are available in your Endpoint’s Settings in the [WorkOS Dashboard](https://dashboard.workos.com). > Steps 2, 3, and 4 below will need to be carried out by the organization when configuring your application in their Rippling instance. --- ## (1) Set up your Directory Sync endpoint Login to your WorkOS Dashboard and select “Organizations” from the left hand navigation bar. Select the organization you’ll be configuring a new Directory Sync for. Under “Actions” click “Add Directory”. ![A screenshot showing where to click "Add Directory" in the WorkOS dashboard.](https://images.workoscdn.com/images/0f13d97a-b2a8-4263-ad11-e8e7633f3ae5.png?auto=format&fit=clip&q=50) Select “Rippling” from the dropdown, and enter the organization name. Then, click “Create Directory.” ![A screenshot showing where to name and create a Rippling Directory in the WorkOS dashboard.](https://images.workoscdn.com/images/83cd8619-6ccd-4d49-9a69-5c0cd04dd8d6.png?auto=format&fit=clip&q=50) Your Rippling directory sync has now been created successfully with an Endpoint and Bearer Token. ![A screenshot showing where to locate the Rippling directory details in the WorkOS dashboard.](https://images.workoscdn.com/images/98b1e1f1-b601-4df0-97bc-cfa824a7559e.png?auto=format&fit=clip&q=50) > We have support for custom URLs for Directory Sync endpoints. [Contact us](mailto:support@workos.com) for more info! --- ## (2) Create your Rippling application Log in to the Rippling admin dashboard and select the “Custom App” option in the menu under the “Identity Management” category. ![A screenshot showing where to select the "Custom App" option in the "Identity Management" menu in Rippling.](https://images.workoscdn.com/images/2851bbb9-a486-4e51-90c1-6265959cb336.png?auto=format&fit=clip&q=50) Select “Create New App” in the Custom App page. ![A screenshot showing where to select "Create New App" in Rippling.](https://images.workoscdn.com/images/bd2b1fba-2433-4fc2-b20b-7a0ca712dd20.png?auto=format&fit=clip&q=50) Fill out the application’s name, select categories, upload an image for the logo, and check the “User Management via SCIM” box. Click “Continue” and the next page will populate more option fields regarding SCIM setup. ![A screenshot showing where to fill in the name, categories, logo, and type of custom app in Rippling.](https://images.workoscdn.com/images/74bf5e11-239e-4cf4-b3ce-af819d3c7b95.png?auto=format&fit=clip&q=50) ## (3) Configure your integration Set the SCIM version to 2.0. Fill in the endpoint into the “SCIM Base URL” field. ![A screenshot showing where to set the SCIM version and "SCIM Base URL" in Rippling.](https://images.workoscdn.com/images/a4fce113-4383-42b4-9d46-eac1e2ec6941.png?auto=format&fit=clip&q=50) Set the SCIM authorization method to “Bearer Token” in the "SCIM Authorization Method" dropdown list. Check off features for groups, pagination, delete groups and PATCH groups. ![A screenshot showing the SCIM authorization method and configuration options in Rippling.](https://images.workoscdn.com/images/9c9c19cc-0836-4aa9-90e0-fb42d751594b.png?auto=format&fit=clip&q=50) Add SCIM attributes `externalId`, `emails.primary`, `name.givenName`, `name.familyName` to the "Supported SCIM Attributes" input box. If you have additional custom attributes, add the appropriate corresponding Rippling values of the custom attributes. Click “Continue” to move to the next step. ![A screenshot showing the "Supported SCIM Attributes" field in Rippling.](https://images.workoscdn.com/images/566a60cf-044e-423e-b1ee-d1cbee96440b.png?auto=format&fit=clip&q=50) Rippling will then prompt you to install the app. Click "Install now" and proceed through the next step. Then, copy and paste the Bearer Token into the “Bearer Token” field and click “Continue”. ![A screenshot showing where to enter the Bearer Token in Rippling.](https://images.workoscdn.com/images/bb2ce893-3c9e-4d97-a7f8-4e0bb7128843.png?auto=format&fit=clip&q=50) ## (4) Assign users and groups to your application After entering the Bearer Token, the following two pages “App Access Rules” and “Provision Time”, can be filled out by your own preference. You should then arrive at the “Account Matching” page. In order for your users and groups to be synced, you will need to assign them to your Rippling Application. Match the Rippling users to the account, or create a new application account for the user(s). ![A screenshot showing where to match Rippling users to an account in Rippling.](https://images.workoscdn.com/images/c95d76d4-721a-4626-9ee7-6e33c124bf91.png?auto=format&fit=clip&q=50) Create groups for the application as needed. ![A screenshot showing where to create a group in Rippling.](https://images.workoscdn.com/images/49677af7-9dce-48cb-b32b-94df728644f0.png?auto=format&fit=clip&q=50) Name the group. ![A screenshot showing where to name a group in Rippling.](https://images.workoscdn.com/images/073ca80c-42c2-4f65-abd2-50e8af89dd2b.png?auto=format&fit=clip&q=50) Assign Rippling users/groups to the newly created application group. ![A screenshot showing where to assign users and groups to a newly created application in Rippling.](https://images.workoscdn.com/images/aa94731f-f5c3-4517-818f-383a64924dc3.png?auto=format&fit=clip&q=50) Make sure all attributes previously added are enabled, and that their cadence is set to “On user creation and updates”. Then, click “Save” and “Continue” to finish setup. ![A screenshot showing where to ensure that all attributes are enabled in Rippling.](https://images.workoscdn.com/images/aa067d8d-b62f-459d-b640-e577a2050b67.png?auto=format&fit=clip&q=50) In your WorkOS dashboard, you should now see the users and groups synced over. ![A screenshot showing a successfully synced user from Rippling in the WorkOS dashboard.](https://images.workoscdn.com/images/c38e1ba8-90e3-4cf0-a008-443f8c77f6a2.png?auto=format&fit=clip&q=50) A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) ## Frequently asked questions ### Can I add additional custom fields to this SCIM integration? Yes, however Rippling allows only a limited set of custom fields in SCIM applications. - #### Available custom fields - `addresses.home.country` - `addresses.home.formatted` - `addresses.home.locality` - `addresses.home.postalCode` - `addresses.home.region` - `addresses.home.streetAddress` - `addresses.work.country` - `addresses.work.formatted` - `addresses.work.locality` - `addresses.work.postalCode` - `addresses.work.region` - `addresses.work.streetAddress` - `department` - `displayName` - `emails.primary` - `employeeNumber` - `externalId` - `manager.displayName` - `manager.email` - `manager.managerId` - `name.familyName` - `name.formatted` - `name.givenName` - `phoneNumbers.mobile` - `phoneNumbers.work` - `photos.photo` - `title` - `userType` ### Rippling SAML Learn how to configure a connection to Rippling via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a Rippling SAML Connection, you’ll need the Identity Provider metadata that is available from creating an app within the Rippling instance. Start by logging in to your WorkOS dashboard and browse to the “Organizations” tab on the left hand navigation bar. Select the organization you wish to configure a Rippling SAML Connection for, and select “Manually Configure Connection” under “Identity Provider”. ![A screenshot showing where to select "Manually Configure Connection" in the WorkOS dashboard.](https://images.workoscdn.com/images/8fb3c79a-f154-4e74-ac23-0330f36dbb62.png?auto=format&fit=clip&q=80) Select “Rippling SAML” from the Identity Provider dropdown, enter a descriptive name for the connection, and then select the “Create Connection” button. ![A screenshot showing the "Create Connection" modal with options configured in the WorkOS dashboard.](https://images.workoscdn.com/images/75e3d01e-a653-4ab5-a460-caced555226f.png?auto=format&fit=clip&q=80) --- ## Introduction WorkOS provides the [ACS URL](/glossary/acs-url) and [SP Entity ID](/glossary/sp-entity-id). They’re readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/) ![A screenshot showing the "ACS URL" and "SP Entity ID" in the WorkOS dashboard.](https://images.workoscdn.com/images/b1d10058-5f92-441f-8f3d-615983e93489.png?auto=format&fit=clip&q=80) The ACS URL is the location an Identity Provider redirects its authentication response to. The Entity ID is a URI used to identify the issuer of a SAML request, response, or assertion. In this case, the Entity ID is used to communicate that WorkOS will be the party performing SAML requests to the organization's Rippling instance. --- ## What you’ll need In order to integrate you’ll need the Rippling IdP metadata. Normally, this information will come from the organization's IT Management team when they set up your application’s Rippling configuration. But, should that not be the case during your setup, here’s how to obtain them. --- ## (1) Create A New SAML Application In Rippling Log in to Rippling as an administrator and select “IT Management” then “Custom App” from the left-side navigation bar. !["A screenshot showing where to select "Custom App" in the Rippling dashboard.](https://images.workoscdn.com/images/a56252d2-4e9a-4839-b540-0239b0360756.png?auto=format&fit=clip&q=80) Select “Create New App” to begin creating a new SAML application. ![A screenshot showing where to select "Create New App" in the Rippling dashboard.](https://images.workoscdn.com/images/49a2345a-bacc-4332-ad2d-a43f4884279f.png?auto=format&fit=clip&q=80) Give the app a descriptive name, select a category, and upload a logo file. Make sure to check the box for “Single Sign-On (SAML)”, then click “Continue”. ![A screenshot showing where to configure the new app's "Name", "Categories", and app type in the Rippling dashboard.](https://images.workoscdn.com/images/f2d7947a-81eb-459d-b823-a84fc2e031ed.png?auto=format&fit=clip&q=80) Select the option confirming that you are the Application Admin. Rippling will display a new page with “SSO Setup Instructions” we will use in the next step. ![A screenshot showing the configuration of the "Who should install the SAML App?" setting in the Rippling dashboard.](https://images.workoscdn.com/images/2a71a48e-3765-4d85-8cb2-a0111ff2c28a.png?auto=format&fit=clip&q=80) ## (2) Download IdP Metadata From Rippling Rippling will present the SSO Setup instructions which will include the [IdP Metadata](/glossary/idp-metadata) XML file. Click to download the file from Rippling. ![A screenshot showing where to download the IdP Metadata in the Rippling dashboard.](https://images.workoscdn.com/images/b58647d3-283c-4151-b714-9b0c5c8c33b3.png?auto=format&fit=clip&q=80) Save this file in a memorable place, as we will upload it to the WorkOS dashboard in a later step. --- ## (3) Enter Service Provider Details and Configure App Settings Scrolling down on the SSO Setup Instructions, Rippling will request the ACS URL and Service Provider Entity ID. Input the ACS URL and SP Entity ID from the WorkOS dashboard into the respective fields. Once complete, click the “Move to Next Step Button”. ![A screenshot showing where to input the WorkOS ACS URL and SP Entity ID in the Rippling dashboard.](https://images.workoscdn.com/images/482b6b5e-8c29-4675-8de9-a3bbe1240c3c.png?auto=format&fit=clip&q=80) Select your desired Access Rules. ![A screenshot showing where to select SSO Access Rules in the Rippling dashboard.](https://images.workoscdn.com/images/f0833317-cb61-4b92-894d-c2c66a0d1af3.png?auto=format&fit=clip&q=80) Select your desired Provision Time. ![A screenshot showing where to select Provision Time in the Rippling dashboard.](https://images.workoscdn.com/images/98f45313-64ab-4bc5-b1c9-aabfa4ef3478.png?auto=format&fit=clip&q=80) Configure SSO for Admins if necessary. ![A screenshot showing where to configure Admin SSO in the Rippling dashboard.](https://images.workoscdn.com/images/9b5ac438-7bc6-4e76-92b5-db21ce8e79ba.png?auto=format&fit=clip&q=80) Configure Group Attributes if necessary. ![A screenshot showing where to configure Group Attributes in the Rippling dashboard.](https://images.workoscdn.com/images/8c0b2600-a5b7-46df-80d1-347daff1840c.png?auto=format&fit=clip&q=80) Verify your SSO integration if you want to test the connection. ![A screenshot showing where to verify an SSO connection in the Rippling dashboard.](https://images.workoscdn.com/images/0d1c0474-ae85-46a9-982b-0eec7f8ab4e0.png?auto=format&fit=clip&q=80) Click “Visit the app”. The application settings will be presented, here we will configure the SAML attribute mapping in the next step. ![A screenshot showing where to select "Visit the app" in the Rippling dashboard.](https://images.workoscdn.com/images/f67e94c8-99db-462c-943a-98e58c086fd6.png?auto=format&fit=clip&q=80) --- ## (4) Configure Attribute Mapping Select the “Settings” tab then on the left navigation select “SAML Attributes” and use the "Create new" button. Add attributes as "Global attributes". ![A screenshot showing where to select "Create New" in the "SAML Attributes" in the Rippling dashboard.](https://images.workoscdn.com/images/8b900811-0089-4e56-a770-06bae8d097b6.png?auto=format&fit=clip&q=80) Input the attributes as follows: - `id` → `User’s ID` - `email` → `User’s email address` - `firstName` → `User’s Legal first name` - `lastName` → `User’s Legal last name` Here is a screenshot showing the proper final configuration: ![A screenshot showing the proper configuration of the "SAML Attributes" in the Rippling dashboard.](https://images.workoscdn.com/images/73bc17dc-fc0f-43f6-901f-a6bcd92caf17.png?auto=format&fit=clip&q=80) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, follow the guidance below. Create a new SAML attribute and select the "Group attribute" type. Click "Continue". ![A screenshot showing how to add a group attribute in the Rippling dashboard.](https://images.workoscdn.com/images/1d904a73-9e49-4e44-b0fe-e8a2bdb9203d.png?auto=format&fit=clip&q=80) Enter `groups` for the "Group attribute name". ![A screenshot showing what to name a group attribute in the Rippling dashboard.](https://images.workoscdn.com/images/3bbab635-f5e1-48b0-b39f-11ec75669d68.png?auto=format&fit=clip&q=80) Select the attribute values to map to the group attribute. The example below shows two values, "Admins" and "Engineers", that map to the "All Admins" user group and the "Engineering Department" user group, respectively. ![A screenshot showing how to map the group attribute for Admins in the Rippling dashboard.](https://images.workoscdn.com/images/5a113ba9-0874-4574-95ab-a7e462dd856a.png?auto=format&fit=clip&q=80) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (5) Disable the 'InResponseTo' Field In the “Settings” tab, on the left navigation select “Advanced SAML Settings” and use the “Edit” button to set "Disable 'InResponseTo' field in assertions for IdP initiated SSO" to true by checking the box to enable the setting. ![A screenshot showing where to enable the "Disable 'InResponseTo' field in assertions for IdP initiated SSO" setting in the Rippling dashboard.](https://images.workoscdn.com/images/46ec2824-7e3d-4b9f-93c1-56042e268477.png?auto=format&fit=clip&q=80) The 'InResponseTo' field is primarily used for IdP-initiated SSO and enabling this setting allows WorkOS to accept both SP and IdP initiated SSO from Rippling. Click the “Save” button to save this setting. In the next step, we will complete the integration by uploading the Metadata XML file to the WorkOS Dashboard. --- ## (6) Update Metadata File Return to the Rippling connection in the WorkOS dashboard and select “Edit Metadata Configuration”. ![A screenshot showing where to select "Edit Metadata Configuration" in the WorkOS dashboard.](https://images.workoscdn.com/images/418a58ed-1370-4243-8c93-400c5c19d0b0.png?auto=format&fit=clip&q=80) Upload the XML metadata file from Rippling into the “Metadata File” field and select “Save Metadata Configuration”. ![A screenshot showing where to select “Save Metadata Configuration” in the "XML File Metadata Configuration" modal in the WorkOS dashboard.](https://images.workoscdn.com/images/234fcc8b-e96a-4c66-8f7f-d2750ba337da.png?auto=format&fit=clip&q=80) Your Connection will then be linked and good to go! ### React Native Expo Learn how to integrate WorkOS SSO into a React Native Expo app. ## Introduction When it comes to combining the WorkOS SSO solution with mobile applications, our advice on the general flow tends to go like this: 1. Make an API call to generate an Authorization URL. 2. Send the end user to the generated URL within their mobile browser. 3. Deep-link the end user back into your native application upon successful authentication. With Expo, you’re able to integrate the WorkOS API with the Expo AuthSession and WebBrowser libraries, which adds web browser based authentication to your app. --- ## (1) Add AuthSession Package To get started, you’ll want to add the `AuthSession` package to your React Native Expo project using the following: ```bash title="Install Expo’s AuthSession Package" expo install expo-auth-session expo-random ``` We'll be using the `AuthSession.makeRedirectUri()` method to generate a RedirectUri for us to use. ## (2) Add WebBrowser Package You’ll also want to add the `WebBrowser` package to your React Native Expo project using the following: ```bash title="Install Expo’s WebBrowser Package" expo install expo-web-browser ``` For our purposes, we’ll specifically be using the `WebBrowser.openAuthSessionAsync()` method, which you can read more about [here](https://docs.expo.dev/versions/latest/sdk/webbrowser/#webbrowseropenauthsessionasyncurl-redirecturl-options). We will be using two arguments: - `url`: This will be the Authorization URL we generate using the WorkOS API - `redirect`: This will be the link back into your native Expo application once authentication is complete ## (3) Get Authorization URL The first step in the authentication process will be to Get the Authorization URL and use it as the `url` argument in the `openAuthSessionAsync()` method. In the code, it would look something like this: ```js title="Get Authorization URL Call" // Generate the RedirectUri and save it to a redirect variable // You will also need to add this redirect URI to the allow list in the WorkOS Dashboard const redirect = AuthSession.makeRedirectUri().toString(); // Pull Connection ID from environment variables const connection_id = process.env.WORKOS_CONNECTION_ID; // Pull Client ID from evnironment variables const client_id = process.env.WORKOS_CLIENT_ID; // Format the URL for the Get Authorization URL call and pass in the Client ID, Redirect URI, and Connection ID const url = `https://api.workos.com/sso/authorize?response_type=code&client_id=${client_id}&redirect_uri=${redirect}&state=&connection=${connection_id}`; // Call openAuthSessionAsync with the url and redirect from above, and save the returned object to a variable const result = await WebBrowser.openAuthSessionAsync(url, redirect); // Pull the code returned in the result stored as a param in the url field. In this case, we are using a regular expression pattern to pull it from the url. const codeRegex = /code=([^&]+)/; const matches = result.url.match(codeRegex); const code = matches ? matches[1] : null; ``` ## (4) Exchange OAuth Code for User Profile and Token Once the above is in place, you will ultimately have a code which you can then exchange in one more API call for the user profile of the authenticating user. You’ll be making a POST request to Get a Profile and Token with the token, as shown here using Axios: ```js title="Exchange OAuth Code for Profile and Token" // Use the profile returned in response.data as you need! axios({ method: 'post', url: `https://api.workos.com/sso/token?client_id=${client_id}&client_secret=${apiKey}&grant_type=authorization_code&code=${code}`, }).then((response) => {}); ``` From the end user’s side, they will be sent to the native UI of their Identity Provider in their mobile browser. After they authenticate with their credentials, they will be dropped back into the native application, ready to go. --- ## Conclusion That’s all there is to it! By combining WorkOS SSO with React Native Expo AuthSession, adding Single Sign-On to your Expo app is a total breeze with minimal code needed. To test the React Native Expo flow for yourself, head over to the GitHub repository of our example React Native Expo application and give it a whirl for yourself! ### PingOne SAML Learn how to configure a connection to PingOne via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a PingOne SAML Connection, you’ll need two pieces of information: an [SP Metadata URL](/glossary/sp-metadata) from WorkOS, and an [IdP Metadata URL](/glossary/idp-metadata) from PingOne. --- ## What WorkOS provides WorkOS provides the SP Metadata URL. It is readily available in your Connection settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot showing where to find the SP Metadata URL in the WorkOS Dashboard.](https://images.workoscdn.com/images/30a33416-afd5-4c8a-b629-392fb4666ef3.png?auto=format&fit=clip&q=50) The SP Metadata link contains a metadata file the organization can use to set up the SAML integration. In PingOne’s case, the SP Metadata URL needs to be set by the organization when configuring your application in their PingOne instance. Specifically, the SP Metadata URL will need to be set on the SAML Configuration page: ![A screenshot showing where the SP Metadata URL needs to be set in the PingOne settings.](https://images.workoscdn.com/images/01d0b62a-de8b-426e-a89e-f94a4f4fc721.png?auto=format&fit=clip&q=50) --- ## What you’ll need Next, provide the PingOne IdP Metadata URL. Normally, this information will come from the organization's IT Management team when they set up your application’s SAML 2.0 configuration in their PingOne admin dashboard. However, should that not be the case during your setup, here’s how to obtain them: --- ## (1) Log In and Select Your Application In the PingOne Admin Console, select "Applications" (under "Connections") in the side menu. Then, select your application. ![A screenshot showing where to select a SAML app in PingOne.](https://images.workoscdn.com/images/5eecf339-0475-441c-af8b-4f7bab95d8f4.png?auto=format&fit=clip&q=50) --- ## (2) Configure Attribute Mapping In the "Attribute Mapping" section of the PingOne SAML app, add the following field-value parameter pairs: - `email` → `Email Address` - `firstName` → `Given Name` - `id` → `User ID` - `lastName` → `Family Name` ![A screenshot showing where to configure SAML attributes in PingOne.](https://images.workoscdn.com/images/1ad40d3f-dea4-4ebc-af6f-85bfc81cce30.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, follow the guidance below. Select the `+ Add` button once. To return the names of all groups a user is a member of, add "groups" in the "Attributes" column mapped to the "Group Names" PingOne attribute. Click "Save". ## ![A screenshot showing where to configure SAML groups attribute in PingOne.](https://images.workoscdn.com/images/750a99c5-ac7b-40b2-86fe-bb579c151606.png?auto=format&fit=clip&q=50) Add a new `groups` attribute mapped to the "Group Names" PingOne attribute. > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (3) Obtain Identity Provider Metadata In the "Configuration" tab, copy the "IdP Metadata URL". You’ll need this in the next step. Enable the SAML app to allow users to authenticate. ![A screenshot showing where to copy the IdP Metadata URL from in PingOne.](https://images.workoscdn.com/images/e6e6f666-d67e-4a96-b1be-d9bf015e8d62.png?auto=format&fit=clip&q=50) --- ## (4) Upload IdP Metadata URL Finally, upload the IdP Metadata URL you saved earlier in your WorkOS Connection settings. Your Connection will then be linked and good to go! ![A screenshot showing where to upload the IdP Metadata URL in the WorkOS Dashboard.](https://images.workoscdn.com/images/0eccd480-bbb3-4ee3-8c9a-d0c65934fd15.png?auto=format&fit=clip&q=50) ### PingFederate SCIM Learn about syncing your user list with PingFederate SCIM. ## Introduction The PingFederate SCIM Connector can be used to enable a directory sync connection with WorkOS. Follow the steps below to set up this integration. To synchronize an organization’s users and groups provisioned for your application, you’ll need two pieces of information: - An [Endpoint](/glossary/endpoint) that PingFederate will make requests to - A [Bearer Token](/glossary/bearer-token) for PingFederate to authenticate it’s endpoint requests After completing step 1 below, both of these are available in your Endpoint’s Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). > The rest of the steps after the first will need to be carried out by the organization when configuring your application in their PingFederate instance. --- ## (1) Set up your directory in the WorkOS Dashboard Login to your WorkOS Dashboard and select “Organizations” from the left hand navigation bar. Select the organization you’ll be configuring a new Directory Sync with. Click “Add Directory”. ![A screenshot showing where to add a directory in the WorkOS dashboard.](https://images.workoscdn.com/images/1bb63451-a696-4f69-9707-fa46e0b17f36.png?auto=format&fit=clip&q=50) Select “PingFederate“ from the dropdown, and give the connection a descriptive name. Click “Create Directory”. ![A screenshot showing where to select PingFederate SCIM v2.0 as the Directory Provider in the WorkOS dashboard.](https://images.workoscdn.com/images/8809c25e-da19-4cca-8947-b92a4105e67c.png?auto=format&fit=clip&q=50) Save the Endpoint and Bearer Token, you’ll need those in the next section when you configure the SCIM Connector application in PingFederate. ![A screenshot showing where to locate the Endpoint and Bearer Token in the WorkOS dashboard.](https://images.workoscdn.com/images/5de04f00-938d-4b1e-bced-fa342cdb1f6c.png?auto=format&fit=clip&q=50) > We have support for custom labeled URLs for Directory Sync endpoints. [Contact us](mailto:support@workos.com) for more info! --- ## (2) Install the SCIM Connector in PingFederate This step will take place in PingFederate. First, download and install the SCIM Connector [following the setup guide from PingFederate](https://docs.pingidentity.com/bundle/pingfederate-scim-connector/page/ulk1563995050657.html). Next, deploy the SCIM Connector files to your PingFederate directory following [the provider’s documentation](https://docs.pingidentity.com/bundle/pingfederate-scim-connector/page/dcn1563995073633.html). Finally, enable provisioning in PingFederate using [the documentation from PingFederate](https://docs.pingidentity.com/r/en-us/pingfederate-112/help_spconnectionconfigtasklet_saasprovisioningstate). Once that setup has been completed, continue on to step 3. --- ## (3) Select or create your PingFederate SCIM Connector Application Log in as an admin to your PingFederate instance, and select “Applications” → “SP Connections”. ![A screenshot showing where to locate the SP Connections area in PingFederate.](https://images.workoscdn.com/images/a3c7e38f-7184-460e-8405-9d9f7c7883df.png?auto=format&fit=clip&q=50) Select “Create Connection”. ![A screenshot showing where to create a connection in PingFederate.](https://images.workoscdn.com/images/a5f103e4-f3b5-4808-ac9f-22ad33b3dc35.png?auto=format&fit=clip&q=50) On the Connection Template page, select “Use a Template for this Connection” and then select “SCIM Connector” from the dropdown list. If you don’t see the SCIM Connector option, go back to the [Install SCIM Connector in PingFederate step](/integrations/pingfederate-scim/2-install-the-scim-connector-in-pingfederate). Click “Next”. ![A screenshot showing how to select the SCIM Connector template in PingFederate.](https://images.workoscdn.com/images/f3f55f2e-6a1c-4727-9c15-5e76abe9dfe7.png?auto=format&fit=clip&q=50) On the Connection Type page, make sure Outbound Provisioning is checked with the SCIM Connector Type. Click “Next”. ![A screenshot showing where to configure outbound provisioning in PingFederate.](https://images.workoscdn.com/images/68968637-291d-472b-84fa-eb095ddcf13f.png?auto=format&fit=clip&q=50) On the General Info page, give this connection a descriptive name, and click “Next”. ![A screenshot showing where to give the connection a name in PingFederate.](https://images.workoscdn.com/images/08096d8a-ad68-4682-bbb8-9449b9e57780.png?auto=format&fit=clip&q=50) --- ## (4) Configure Outbound Provisioning for your PingFederate application On the Outbound Provisioning page, select the “Configure Provisioning” button. ![A screenshot showing where to click "Configure Provisioning" in PingFederate.](https://images.workoscdn.com/images/c390a6e3-bf41-4507-8b31-7d0798cfbbb1.png?auto=format&fit=clip&q=50) On the Target page, paste in the Endpoint from your WorkOS Directory Sync Connection in the SCIM URL field. Make sure SCIM Version is set as `2.0` and the Authentication Method is set as `OAuth 2 Bearer Token`. Paste in the Bearer Token from your WorkOS Directory Sync Connection in the Access Token field. Select “Next”. ![A screenshot showing where to input provisioning settings in PingFerderate.](https://images.workoscdn.com/images/8c8fdbb5-5ebe-4a40-90b8-8c5820ba2eac.png?auto=format&fit=clip&q=50) On the Manage Channels page, select “Create”. ![A screenshot showing where to create a channel in PingFederate.](https://images.workoscdn.com/images/a38da71d-4d75-4a43-a1a8-859988ad5cac.png?auto=format&fit=clip&q=50) On the Channel Info page, add a descriptive name and click “Next”. ![A screenshot showing where to configure the channel name in PingFederate.](https://images.workoscdn.com/images/18896d5c-4499-4f1b-a989-be530b0a3dda.png?auto=format&fit=clip&q=50) Select an “Active Data Store” from the dropdown menu. In this example, This example uses a PingDirectory LDAP instance, but this may be different depending on the type of data store used in each case. Please refer to the [PingFederate documentation](https://docs.pingidentity.com/bundle/pingfederate-103/page/vbe1564003005413.html) for specific settings on your type of data store. Click “Next”. ![A screenshot showing where to configure the channel source in PingFederate.](https://images.workoscdn.com/images/b7c8af75-69e0-49dd-a094-1ef29c005043.png?auto=format&fit=clip&q=50) On the Source Settings page, make any modifications needed for your data store. In this example, the default values for the LDAP data store did not need to be modified, so the default settings were used. After configuring the source settings specific to your use case, click “Next” to go to the Source Location page. ![A screenshot showing where to configure the source settings in PingFederate.](https://images.workoscdn.com/images/dc7af973-ceae-449a-831e-f9dd9065a719.png?auto=format&fit=clip&q=50) On the Source Location page, input a Base DN and either a Group DB or Filter for the Users. This tells your application where to look for the users to sync from your active data store. The setup used in each case may be different depending on the type of data store being used and which users and groups are to be provisioned. Please reference [PingFederate documentation](https://docs.pingidentity.com/bundle/pingfederate-103/page/jqa1564003005539.html) for specific steps. When this is complete, click “Next”. ![A screenshot showing where to configure the source location in PingFederate.](https://images.workoscdn.com/images/fa42db05-c78f-459c-ba6b-49ca4df104bd.png?auto=format&fit=clip&q=50) --- ## (5) Configure attribute mapping in PingFederate On the Attribute Mapping page, configure the mapping of attributes in the data store to the SCIM attributes. The exact configuration will depend on the specific setup in each unique situation. For this PingDirectory LDAP example, the default settings are used. When finished, Click “Next”. ![A screenshot showing where to configure attribute mapping in PingFederate.](https://images.workoscdn.com/images/081f7d7c-b0fa-4595-adbf-ca6d0270bf8e.png?auto=format&fit=clip&q=50) On the Activation & Summary page, check that the settings are complete, then toggle the “Channel Status” to “Active” and select “Done”. ![A screenshot showing where to check the settings and set the channel status to active in PingFederate.](https://images.workoscdn.com/images/36d37973-301d-4b36-b408-8e5dd16cc6ec.png?auto=format&fit=clip&q=50) You are directed back to the Manage Channels page, where you can select “Done”. ![A screenshot showing where to finish the channel setup in PingFederate.](https://images.workoscdn.com/images/67eabbed-36f4-4e95-8312-210f2cb24b65.png?auto=format&fit=clip&q=50) You’re then directed to the Outbound Provisioning page, where you can select “Next”. ![A screenshot showing where to finish the outbound provisioning setup in PingFederate.](https://images.workoscdn.com/images/8a60ece6-4ac2-4db9-993e-4aa70ac912c8.png?auto=format&fit=clip&q=50) --- ## (6) Activate the SP Connection in PingFederate On the Activation & Summary page, turn on provisioning with the toggle at the top, and then select “Save”. ![A screenshot showing where to activate the PingFederate app.](https://images.workoscdn.com/images/cc0c979a-1444-4e8b-bd7e-925d3a834333.png?auto=format&fit=clip&q=50) You’ll now see your SCIM application listed in the SP Connections page. ![A screenshot showing where to view the completed app in PingFederate.](https://images.workoscdn.com/images/88f2b484-d308-45ac-8e5f-64239a40e2be.png?auto=format&fit=clip&q=50) The provisioning will automatically begin when the connection is activated through outbound requests from Ping Federate. It may take a few minutes for this process to start. Once it is synced, you’ll see a Linked status in the Directory settings in the WorkOS Dashboard. ![A screenshot showing a linked PingFederate SCIM connection in the WorkOS dashboard.](https://images.workoscdn.com/images/70241625-42f1-4a02-ba0e-5fe9f4e843eb.png?auto=format&fit=clip&q=50) A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) ### PingFederate SAML Learn how to configure a connection to PingFederate via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a PingFederate SAML Connection, you’ll need the Identity Provider metadata that is available from your PingFederate instance. --- ## What WorkOS provides WorkOS provides the [ACS URL](/glossary/acs-url) and [SP Entity ID](/glossary/sp-entity-id). It’s readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/get-started). ![A screenshot showing where to find the ACS URL and SP Entity ID in the WorkOS Dashboard.](https://images.workoscdn.com/images/f0528e51-bb50-438c-b837-f355af202b60.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. In PingFederate’s case, the ACS URL needs to be set by the organization when configuring your application in their PingFederate instance. Specifically, the ACS URL needs to be set as the “Endpoint URL” when defining the Protocol Settings in the SP Connection for WorkOS. ![A screenshot showing where the ACS URL needs to be set in the PingFederate settings.](https://images.workoscdn.com/images/7c626b2d-59be-489f-9890-4758e287dfbb.png?auto=format&fit=clip&q=50) The SP Entity ID is a URI used to identify the issuer of a SAML request, response, or assertion. In this case, the entity ID is used to communicate to that WorkOS will be the party performing SAML requests to the organization's PingFederate instance. Specifically, the SP Entity ID needs to be set as the “Partner’s Entity ID (Connection ID)” when defining the General Info Settings in the SP Connection for WorkOS. ![A screenshot showing where to set the SP Entity ID in the PingFederate settings.](https://images.workoscdn.com/images/09d9fda5-5f4f-4920-ab96-951e0a44d158.png?auto=format&fit=clip&q=50) --- ## What you’ll need In order to integrate you’ll need the PingFederate IdP metadata. Normally, this information will come from the organization's IT Management team when they set up your application’s SAML 2.0 configuration in their PingFederate admin dashboard. However, that should not be the case during your setup. Here’s how to obtain them: --- ## (1) Log In and Select Your Application Log in to your PingFederate instance, go to the admin dashboard, select “Applications” at the top, and select the “SP Connections” menu option. ![A screenshot showing where to find the SP Connections section in the PingFederate admin dashboard.](https://images.workoscdn.com/images/6b0049f8-faf1-45d5-b352-58215cfc3f4a.png?auto=format&fit=clip&q=50) --- ## (2) Obtain Identity Provider Metadata On the SP Connection list, find your WorkOS SAML 2.0 connection. Click on the “Select Action” menu and then select “Export Metadata” to download the IdP metadata. ![A screenshot showing where to download the IdP metadata file in PingFederate.](https://images.workoscdn.com/images/6fece896-4310-40fc-9b40-be471f5ea85b.png?auto=format&fit=clip&q=50) Keep in mind where the file was saved, as we’ll be later uploading it to configure the Connection. --- ## (3) Configure Attribute Mapping In the SP Connections dashboard, click into your desired connection. From there, click into the "Activation & Summary" tab, then click "Attribute Contract". You will need to add `id`, `email`, `firstName`, and `lastName` as attributes. Once configured, click "Next". ![A screenshot showing where to configure attribute mapping in PingFederate.](https://images.workoscdn.com/images/c6568ddb-76f4-4da1-80c4-d0964ae469dc.png?auto=format&fit=clip&q=50) You will now need to configure an Authentication Policy Contract. To do so, click "Map New Authentication Policy", then click "Manage Policy Contracts" and "Create New Contract". Name your contract, then go to the next step and add the same four attributes we configured above. Continue through the steps, then click "Save". ![A screenshot showing where to extend the Authentication Policy Contract in PingFederate.](https://images.workoscdn.com/images/c6fb23be-81b2-4415-9fb5-655e58e60490.png?auto=format&fit=clip&q=50) On the "Authentication Policy Mapping" page, select the Authentication Policy Contract you just made and click "Next". In the "Attribute Contract Fulfillment" tab, How you map values to the attributes listed above may differ based on how your PingFederate instance is set up. Below is an example of mapped values from both an Authentication Policy Contract and an LDAP directory. From there, save your settings on the "Summary" tab to lock in the configuration. ![A screenshot showing an example of Authentication Policy Mappings in PingFederate.](https://images.workoscdn.com/images/2141c568-0821-4aa1-899c-3fca01ecf596.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, follow the guidance below. Navigate back to the "Attribute Contact" page and define a `groups` attribute. ![A screenshot showing where to define a groups attribute in PingFederate.](https://images.workoscdn.com/images/0aa645c4-a588-4044-aaab-a57f3e546bdc.png?auto=format&fit=clip&q=50) Then, navigate to the "Attribute Contract Fulfillment" page and map the new `groups` attribute to the data in your provider that includes group memberships, such as the `isMemberOf` LDAP attribute in the example below. ![A screenshot showing a mapped groups attribute in the Attribute Contract Fulfillment area in PingFederate.](https://images.workoscdn.com/images/6115e8ae-c34e-4131-9d94-e6adfd94e9c1.png?auto=format&fit=clip&q=50) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (4) Upload Metadata File In the connection settings of the WorkOS Dashboard, click “Edit Metadata Configuration”. ![A screenshot showing where to edit the Metadata Configuration in the WorkOS Dashboard.](https://images.workoscdn.com/images/2b0764f7-e045-435d-a7ed-05283f7432ac.png?auto=format&fit=clip&q=50) In the modal, upload the PingFederate Metadata file and then select “Save Metadata Configuration”. Once the file is uploaded into WorkOS, your connection will then be linked and good to go! ![A screenshot showing where to upload the Metadata file in the WorkOS Dashboard.](https://images.workoscdn.com/images/5145a2f5-63d4-43c6-97a5-c86819d0c94b.png?auto=format&fit=clip&q=50) ### Oracle SAML Learn how to configure a connection to Oracle via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [connection](/glossary/connection). Often, the information required to create a connection will differ by Identity Provider. To create an Oracle SAML connection, you’ll need the Identity Provider Metadata URL that is available from the organization's Oracle SAML instance. --- ## What WorkOS provides WorkOS provides the [ACS URL](/glossary/acs-url) and the [SP Entity ID](/glossary/sp-entity-id). They are readily available in your connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot showing where to obtain the SP Entity ID and ACS URL in the WorkOS Dashboard.](https://images.workoscdn.com/images/c1b55179-b848-40c5-b56f-dc15eb325a34.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. The SP Entity ID is a URI used to identify the issuer of a SAML request, response, or assertion. --- ## What you’ll need In order to integrate you’ll need the IdP Metadata URL. Normally, this will come from the organization's IT management team when they set up your application’s SAML configuration in their Oracle instance. But, should that not be the case during your setup, here’s how to obtain it. --- ## (1) Configure SAML Application with Service Provider Details Follow the [Oracle Cloud documentation](https://docs.oracle.com/en/cloud/paas/identity-cloud/uaids/add-saml-application.html) to create a new SAML application. Copy and paste the ACS URL and SP Entity ID into the corresponding fields for Service Provider details and configuration. In the Advanced Settings of the SSO Configuration page, ensure that you select Signed SSO for Assertion and Response, and Include Signing Certificate in Signature. --- ## (2) Configure SAML Attributes Expand the Attribute Configuration section on the SSO Configuration page and add the following 4 required attributes: `firstName`, `lastName`, `email`, and `id`. Ensure the following attribute mapping is set: - A user’s first name → `firstName` - A user’s last name → `lastName` - A user’s email address → `email` - A unique identifier representing a user → `id` ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, map the groups in your identity provider to a SAML attribute named `groups`. > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (3) Obtain Identity Provider Metadata Obtain the IdP Metadata URL following the [instructions from Oracle](https://docs.oracle.com/en/cloud/paas/identity-cloud/uaids/access-saml-metadata.html). ![A screenshot showing where the IdP Metadata URL is entered in the WorkOS Dashboard.](https://images.workoscdn.com/images/52e3e5ff-d0da-481e-8e40-a614a9c964a5.png?auto=format&fit=clip&q=50) Alternatively, you can manually configure the connection by providing the IdP URI (Entity ID), [IdP SSO URL](/glossary/idp-sso-url) and X.509 Certificate. ![A screenshot showing the manual configuration details in the WorkOS Dashboard](https://images.workoscdn.com/images/94f7c669-02a8-4d30-9e4f-86ae58b0f318.png?auto=format&fit=clip&q=50) Your connection will then be Active and good to go! ### OneLogin SCIM Learn about syncing your user list with OneLogin SCIM. ## Introduction This guide outlines how to synchronize your application’s OneLogin directories using SCIM. To synchronize an organization’s users and groups provisioned for your application, you’ll need to provide the organization with two pieces of information: - An [Endpoint](/glossary/endpoint) that OneLogin will make requests to. - A [Bearer Token](/glossary/bearer-token) for OneLogin to authenticate its endpoint requests. Both of these are available in your Endpoint’s Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). > Steps 2, 3, and 4 below will need to be carried out by the organization when configuring your application in their OneLogin instance. --- ## (1) Set up your directory sync endpoint Login to your WorkOS Dashboard and select “Organizations” from the left hand navigation bar. Select the Organization you’ll be configuring a new Directory Sync for. Click “Add Directory”. ![A screenshot showing where to find “Add Directory” in the WorkOS Dashboard.](https://images.workoscdn.com/images/2c4f3933-c473-458b-97be-ea22c70f84f0.png?auto=format&fit=clip&q=50) Select “OneLogin” from the dropdown and enter the organization name. Then, click “Create Directory.” ![A screenshot showing "Create Directory" details in the WorkOS Dashboard.](https://images.workoscdn.com/images/0e8ef0ef-5030-46c1-a0fa-65540bc67dc5.png?auto=format&fit=clip&q=50) Your OneLogin directory sync has now been created successfully with an Endpoint and Bearer Token. ![A screenshot showing where to find the "Endpoint" and "Bearer Token" for an organization in the WorkOS Dashboard.](https://images.workoscdn.com/images/7bad6045-0611-4c6d-8d11-754f3d878bbb.png?auto=format&fit=clip&q=50) > We have support for custom labeled URLs for Directory Sync endpoints. [Contact us](mailto:support@workos.com) for more info! --- ## (2) Select or create your OneLogin application Log in to the OneLogin admin dashboard, select the “Applications” tab at the top. If the application has already been created, select it and move to step 3. Otherwise, select “Add App”. ![A screenshot showing where to select "Add App" in OneLogin](https://images.workoscdn.com/images/c5f77445-e09f-4e21-8911-a240e6deee26.png?auto=format&fit=clip&q=50) Search for “SCIM” in the text field and select the Application with type “SCIM Provisioner with SAML (SCIM V2 Enterprise)”. ![A screenshot showing where to search for “SCIM” and select the application “SCIM Provisioner with SAML (SCIM V2 Enterprise)”](https://images.workoscdn.com/images/a47d721e-db6f-490b-b3e0-9ac284bd3464.png?auto=format&fit=clip&q=50) Give your Application a descriptive Display Name and hit “Save”. ![A screenshot showing where to add a "Display Name" to your App in OneLogin](https://images.workoscdn.com/images/4dd4042a-847e-4fde-b835-750a2f0c5644.png?auto=format&fit=clip&q=50) --- ## (3) Configure your integration Within the SCIM Application, select the “Configuration” tab on the left. Copy and paste the Endpoint from your [WorkOS Dashboard](https://dashboard.workos.com/) into the “SCIM Base URL” field. Then, copy and paste the Bearer Token from your [WorkOS Dashboard](https://dashboard.workos.com/) into the “SCIM Bearer Token” field. Hit “Enable” under “API Status” and then hit “Save”. ![A screenshot showing where to select the "Configure" tab and input your "SCIM Base URL" and "SCIM Bearer Token" in your SCIM App in OneLogin](https://images.workoscdn.com/images/12411c31-4662-4da1-9e94-7348e46ddc50.png?auto=format&fit=clip&q=50) Select the “Provisioning” tab on the left. Check the “Enable provisioning” box and hit “Save”. ![A screenshot showing where to select "Provisioning" tab select "Enable Provisioning" in OneLogin](https://images.workoscdn.com/images/94f76ad5-30ad-4d65-a3c7-6a18ec0e0683.png?auto=format&fit=clip&q=50&w=2048) Select the “Parameters” tab on the left. Then select “Groups”. ![A screenshot showing where to select the "Parameters" then select the "Groups" in OneLogin SCIM App](https://images.workoscdn.com/images/54c10855-69e5-4484-8ccd-44f2fe89baf3.png?auto=format&fit=clip&q=50) In the modal that pops up, check the box next to “Include in User Provisioning” and hit “Save”. ![A screenshot showing how to select "Include in User Provisioning" in the "Parameters" tab in OneLogin](https://images.workoscdn.com/images/09795f59-f7c0-4b04-97d5-9044fb05d987.png?auto=format&fit=clip&q=50) --- ## (4) Assign users and groups to your application In order for your users and groups to be synced, you will need to assign them to your OneLogin Application. Select “Users” from the top navigation menu. Next, find a user you’d like to provision to the SCIM app. Within that user profile, select the “Applications” tab on the left. Then, click the “+” symbol. ![A screenshot showing where to select "+" in the "Applications" tab in OneLogin](https://images.workoscdn.com/images/ee1e01fa-26f3-49e1-8515-3fedfbdee14b.png?auto=format&fit=clip&q=50) Select the appropriate app and hit “Continue”. ![A screenshot showing how to select SCIM App to assign OneLogin User](https://images.workoscdn.com/images/f00d45d9-7128-43dd-8bdb-cc48e7eebf7b.png?auto=format&fit=clip&q=50) Select “Save” in the next modal to confirm the change. ![A screenshot showing how to save User Assignment in OneLogin](https://images.workoscdn.com/images/e9e5ef85-5efb-4b71-8283-e8d570f3103e.png?auto=format&fit=clip&q=50) There are many ways to provision groups in OneLogin. Below is one method that we recommend, but other methods can be used. In the top navigation, Select “Users” and then “Roles” from the dropdown. Select “New Role”. ![A screenshot showing how to create a "New Role" in OneLogin](https://images.workoscdn.com/images/ecb269b5-bfe0-41f7-b73f-11a152ac0197.png?auto=format&fit=clip&q=50) Give the Role a name (this will be the name of the group), select the appropriate SCIM application, and hit “Save”. ![A screenshot showing how to configure and save the "Role" in OneLogin](https://images.workoscdn.com/images/9924f509-c60a-47b5-ae30-017c361d1b55.png?auto=format&fit=clip&q=50) Click the “Users” tab for the role. Search for any users you’d like to assign to that role and hit “Add To Role”. Then hit “Save”. ![A screenshot showing how to add Users to "Role" in OneLogin](https://images.workoscdn.com/images/b4a4be2a-f75f-4dfe-adb9-dea585be0fce.png?auto=format&fit=clip&q=50&w=2048) Click “Save” in the next modal to confirm. ![A screenshot showing where to click "Save" assignments to "Role" in OneLogin](https://images.workoscdn.com/images/0a6ebdb2-3896-4481-8e11-ca9f1a23ecd0.png?auto=format&fit=clip&q=50&w=2048) Navigate back to your SCIM app and click on the “Rules” tab on the left. Then, hit “Add Rule”. ![A screenshot showing the "Rule" tab where you can then click "Add Rule" in OneLogin](https://images.workoscdn.com/images/317311e1-4fac-487f-a30e-2aeeb6e0d30a.png?auto=format&fit=clip&q=50&w=2048) Give your Rule a name. Under “Actions”, select “Set Groups in your-app-name”. Then, set it to “For each role with value that matches your-role-name”. Hit “Save”. ![A screenshot showing how to configure a "New Mapping" in OneLogin](https://images.workoscdn.com/images/02d19425-34e2-45b3-bb64-bc3962714493.png?auto=format&fit=clip&q=50) Within your SCIM app under the "Users" tab, you may then need to click on any “Pending” notifications to confirm the update for users. ![A screenshot showing how to confirm updates for Users under the "Users" tab in OneLogin](https://images.workoscdn.com/images/3aa55536-48e8-4322-9e5e-7227c4099f9c.png?auto=format&fit=clip&q=50) Begin provisioning users and groups and witness realtime changes in your [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot showing a linked Directory in the WorkOS Dashboard](https://images.workoscdn.com/images/d33ff319-a791-4ed0-9df4-e7fba02bcce5.png?auto=format&fit=clip&q=50) A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) ## Frequently asked questions ### When a group is removed, I don't see a `dsync.group.deleted` or `dsync.group.user_removed` events - is this expected? It is a known issue with OneLogin SCIM that when a group is removed from the application, any user that is _only_ provisioned through that group will be "inactive" but otherwise no indication is received that the group has changed. The users of the group must be cleaned up before the group itself is removed from the SCIM application. ### OneLogin SAML Learn how to configure a connection to OneLogin via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create an OneLogin SAML Connection, you’ll need three pieces of information: an [ACS URL](/glossary/acs-url), an [SP Entity ID](/glossary/sp-entity-id), and the [OneLogin SAML Metadata file](/glossary/idp-metadata). Start by logging into your [WorkOS Dashboard](https://dashboard.workos.com/) and selecting “Organizations” from the left hand navigation bar. Click on the organization you’d like to configure a OneLogin SAML connection for and select “Manually Configure Connection”. ![A screenshot showing where to find “Manually Configure Connection” for an Organization in the WorkOS Dashboard.](https://images.workoscdn.com/images/9013d473-bfeb-4078-865b-7d40bc853748.png?auto=format&fit=clip&q=50) Select “OneLogin SAML” from the Identity Provider dropdown, enter a descriptive name for the connection, and then select the “Create Connection” button. ![A screenshot showing how to create a connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/15df7299-f83b-4f48-be6b-b2ab6bfe228c.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides WorkOS provides the [ACS URL](/glossary/acs-url) and [SP Entity ID](/glossary/sp-entity-id). They are readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). The ACS URL is the location an Identity Provider redirects its authentication response to. In OneLogin’s case, it needs to be set by the organization when configuring your application in their OneLogin instance. The SP Entity ID is a URI used to identify the issuer of a SAML request and the audience of a SAML response. In this case, the SP Entity ID is used to communicate that WorkOS will be the party performing SAML requests to the organization's OneLogin instance, and that WorkOS is the intended audience of the SAML responses from the OneLogin instance. ![A screenshot showing where to find the ACS URL and SP Entity ID in the WorkOS Dashboard.](https://images.workoscdn.com/images/5b7bc86b-bdcb-4ac5-a76a-a508e2d6ec0a.png?auto=format&fit=clip&q=50) --- ## What you’ll need Next, provide the [OneLogin SAML Metadata file](/glossary/idp-metadata). Normally, this will come from the organization's IT Management team when they set up your application’s SAML 2.0 configuration in their OneLogin admin dashboard. But, should that not be the case during your setup, the next steps will show you how to obtain it. ![A screenshot showing the “Edit Metadata Configuration” button in the WorkOS Dashboard.](https://images.workoscdn.com/images/017ac221-c3bf-40bd-8606-a04c1d41c377.png?auto=format&fit=clip&q=50) --- ## (1) Log in Log in to [OneLogin](https://app.onelogin.com/login), go to the admin dashboard, and select “Applications” in the navigation bar. ![A screenshot showing the "Applications" button in the OneLogin Dashboard.](https://images.workoscdn.com/images/6d7cdbdf-29aa-4076-aeb3-1d055a6e76ce.png?auto=format&fit=clip&q=50) --- ## (2) Select your application Select your application from the list of applications. ![A screenshot showing your application selection in the OneLogin Dashboard.](https://images.workoscdn.com/images/0d165d03-b73d-4e39-a85d-c81d27affd60.png?auto=format&fit=clip&q=50) --- ## (3) Configure application Select “Configuration” from the left-hand navigation: - Enter the SP Entity ID as the Audience (EntityID) e.g. `https://auth.workos.com/wz5SpShhRIcSEyMM` - Enter the ACS URL as the Recipient e.g. `https://auth.workos.com/sso/saml/acs/wz5SpShhRIcSEyMM` - Enter your ACS URL Validator e.g. `^https:\/\/auth\.workos\.com\/sso\/saml\/acs\/wz5SpShhRIcSEyMM$` - Enter your ACS URL e.g. `https://auth.workos.com/sso/saml/acs/wz5SpShhRIcSEyMM` - Enter your application’s login URL ![A screenshot showing how to configure URLs in your OneLogin SAML Application within the OneLogin Dashboard.](https://images.workoscdn.com/images/c9c6e8c0-fece-49c0-a72f-9bb9e087cb66.png?auto=format&fit=clip&q=50) - Select “Service Provider” from the “SAML Initiator” dropdown menu - Select “Assertion” from the “SAML Signature Element” dropdown menu ![A screenshot showing SAML Configuration in the SAML Application within the OneLogin Dashboard.](https://images.workoscdn.com/images/6beae398-67d7-4a3e-91cd-52e669af9ffa.png?auto=format&fit=clip&q=50) --- ## (4) Set up attribute mapping parameters Select “Parameters” from the left-hand navigation and add the following field-value parameter pairs: - `email` → `Email` - `firstName` → `First Name` - `id` → `UUID` - `lastName` → `Last Name` Check the “Include in SAML assertion” flag for each pair. ![A screenshot showing how to configure SAML Attribute Mapping in OneLogin Dashboard.](https://images.workoscdn.com/images/de9efebf-5767-4547-8877-02560c185b5b.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, follow the guidance below. Add a new parameter, and set the "Field name" to `groups`. Under "Flags", click the checkboxes for both "Include in SAML assertion" and "Multi-value parameter". ![A screenshot showing where to add a groups parameter in the OneLogin Dashboard.](https://images.workoscdn.com/images/c29bb81b-3d04-4adf-8dd9-944f7ccbbc14.png?auto=format&fit=clip&q=50) Map the `groups` field to the attribute in OneLogin containing a user’s group membership, such as "MemberOf", shown in the example below. For more information on sending group information, refer to the [OneLogin documentation](https://onelogin.service-now.com/support?id=kb_article&sys_id=6561990adb5374101c167e77f496191d). ![A screenshot showing how to map the groups parameter in the OneLogin Dashboard.](https://images.workoscdn.com/images/a70cf3c0-3d41-41d7-9c30-ee81ad497acb.png?auto=format&fit=clip&q=50) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (5) Upload Metadata File Select “SSO” from the left-hand navigation. Select the “More Actions” dropdown and click on “SAML Metadata”. This will download an XML metadata file. ![A screenshot showing how to download Metadata File in OneLogin Dashboard.](https://images.workoscdn.com/images/9a6cfe8d-62a7-4d2a-a1af-d57b3c02eb2e.png?auto=format&fit=clip&q=50) In the Connection Settings of the WorkOS Dashboard, click “Edit Metadata Configuration”. ![A screenshot showing the “Edit Metadata Configuration” button in the WorkOS Dashboard. ](https://images.workoscdn.com/images/017ac221-c3bf-40bd-8606-a04c1d41c377.png?auto=format&fit=clip&q=50) In the modal that pops up, upload the OneLogin Metadata file and then select “Save Metadata Configuration”. ![A screenshot showing the pop-up after clicking the “Edit Metadata Configuration” button in the WorkOS Dashboard.](https://images.workoscdn.com/images/cb8e0b46-b7e0-47e4-81cf-20601612b31e.png?auto=format&fit=clip&q=50) Once the file has uploaded, your Connection will then be linked and good to go! ### Okta SCIM Learn about syncing your user list with Okta SCIM. ## Introduction This guide outlines how to synchronize your application’s Okta directories using SCIM. To synchronize an organization’s users and groups provisioned for your application, you’ll need to provide the organization with two pieces of information: - An [Endpoint](/glossary/endpoint) that Okta will make requests to. - A [Bearer Token](/glossary/bearer-token) for Okta to authenticate its endpoint requests. After completing step 1 below, both of these are available in your Endpoint’s Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). > The rest of the steps below will need to be carried out by the organization when configuring your application in their Okta instance. --- ## (1) Set up your Directory Sync endpoint Login to your WorkOS Dashboard and select “Organizations” from the left hand navigation bar. Select the organization you’ll be configuring a new Directory Sync with. Scroll to the “User provisioning“ section. Then, click ”Configure manually“ within the ”Directory Sync” section. ![A screenshot showing where to click "Configure manually" in the WorkOS dashboard.](https://images.workoscdn.com/images/a700462c-afd2-4c12-a6cb-59bfc0d34c13.png?auto=format&fit=clip&q=50) Select “Okta” from the Directory Provider dropdown and provide the Name for the Directory Sync connection. Then, click “Create Directory”. ![A screenshot showing where to name and create an Okta directory in the WorkOS dashboard.](https://images.workoscdn.com/images/7e564f43-2328-4c0d-a9ab-b7cf3ec7dbeb.png?auto=format&fit=clip&q=50) You’ll see WorkOS has created the Endpoint and Bearer Token which you will provide to Okta in the steps below. ![A screenshot showing the Okta directory details in the WorkOS dashboard.](https://images.workoscdn.com/images/de45d3de-7ffc-46e0-b61c-4e8b1b9fce2e.png?auto=format&fit=clip&q=50) > We have support for custom labeled URLs for Directory Sync endpoints. [Contact us](mailto:support@workos.com) for more info! --- ## (2) Select or create your Okta application Log in to [Okta](https://login.okta.com/), go to the Okta admin dashboard and select “Applications” in the navigation bar. ![A screenshot showing where to select "Applications" in Okta.](https://images.workoscdn.com/images/81f7f92f-9cc1-441d-b270-6a7c794122c1.png?auto=format&fit=clip&q=50) If your application is already created, select it from the list of applications and move to Step 3. ![A screenshot showing where to select an already created application in Okta.](https://images.workoscdn.com/images/98447a34-3e6a-404d-8419-b9f105657d1d.png?auto=format&fit=clip&q=50) If you haven’t created a SCIM application in Okta, select “Browse App Catalog”. ![A screenshot showing where to select "Browse App Catalog" in Okta.](https://images.workoscdn.com/images/312382ac-4381-4a9b-9407-3bd5d1655a3e.png?auto=format&fit=clip&q=50) From your Okta Application dashboard, search for “SCIM 2.0 Test App (OAuth Bearer Token)” and select the corresponding result. ![A screenshot showing where to search for "SCIM 2.0 Test App (OAuth Bearer Token)" in the App Integration Catalog in Okta.](https://images.workoscdn.com/images/12e0e6f9-1de0-49f7-95ba-960c0512387c.png?auto=format&fit=clip&q=50&w=1080) On the following page, click “Add Integration”. ![A screenshot showing where to click "Add" in the SCIM 2.0 Test App (OAuth Bearer Token) overview page in Okta.](https://images.workoscdn.com/images/553af5dc-242b-4cf5-86e1-fe570f7b7acf.png?auto=format&fit=clip&q=50&w=1200) Enter a descriptive App name, then click “Next”. ![A screenshot showing where to enter a name in the "Application label" field in Okta.](https://images.workoscdn.com/images/18c46d9e-e177-46b4-a462-c302b284daed.png?auto=format&fit=clip&q=50&w=1080) Many applications will work with the default configuration that is set on your new application. If you require any additional configuration for your directory such as configuring Attribute Statements, do so on the Sign-On Options page. Click “Done” to complete creating your application. --- ## (3) Configure your Okta provisioning API integration In your application’s Enterprise Okta admin panel, click the “Provisioning” tab. Then, click “Configure API Integration”. ![A screenshot showing where to navigate to the "Provisioning" tab to click "Configure API Integration" in Okta.](https://images.workoscdn.com/images/b78d814a-b58d-47df-9523-0bff7e7b2a42.png?auto=format&fit=clip&q=50&w=1080) Check “Enable API Integration”. After that, copy and paste the Endpoint from your [WorkOS Dashboard](https://dashboard.workos.com/) in the SCIM 2.0 Base URL field. Then, copy and paste the Bearer Token from your [WorkOS Dashboard](https://dashboard.workos.com/) into the OAuth Bearer Token field. Click “Test API Credentials”, and then click “Save”. ![A screenshot showing where to configure the provisioning credentials in the "Provisioning" tab in Okta.](https://images.workoscdn.com/images/dbeae5e9-e0b8-402a-9330-4a9eaf82f05b.png?auto=format&fit=clip&q=50) The provisioning tab will now show a new suite of options which we’ll utilize in the next Guide Section to continue provisioning your application. --- ## (4) Select options to provision to your application In the “To App” navigation section, check to enable: - Create Users - Update User Attributes - Deactivate Users Click “Save”. ![A screenshot showing where to enable "Create Users", "Update User Attributes", and "Deactivate Users" in the "To App" tab in Okta.](https://images.workoscdn.com/images/a148a5b7-9685-4034-b871-7f0908764617.png?auto=format&fit=clip&q=50&w=1080) --- ## (5) Assign users and groups to your application To assign users to the SCIM Application, navigate to the “Assignments” tab, from the “Assign” dropdown, select “Assign to People”. ![A screenshot showing where to select "Assign to People" in the "Assign" dropdown in the "Assignments" tab in Okta.](https://images.workoscdn.com/images/ad17bd85-3a0c-4bda-b2af-001c3451ea75.png?auto=format&fit=clip&q=50&w=1080) Select users you’d like to provision and select “Assign”. ![A screenshot showing where to select "Assign" for specific users in Okta.](https://images.workoscdn.com/images/24edda3d-d8ea-4b4c-8bc4-23ff389baca9.png?auto=format&fit=clip&q=50&w=1080) When you click “Assign” a lengthy form will open where you can populate all of the user’s metadata. Confirm the metadata fields, scroll down to the bottom, and press “Save and Go Back”. Repeat this for all users and select “Done”. ![A screenshot showing where to select "Save and Go Back" to complete user assignment in Okta.](https://images.workoscdn.com/images/f91bc47f-f734-453a-8bba-f3cf92d13c9e.png?auto=format&fit=clip&q=50&w=1080) To push groups in order to sync group membership, navigate to the “Push Groups” tab, from the “Push Groups” dropdown, select: “Find groups by name”. ![A screenshot showing where to select "Find groups by name" in the "Push Groups" dropdown in the "Push Groups" tab in Okta.](https://images.workoscdn.com/images/0640cdd8-631e-4f7c-9483-c3f00f93be2f.png?auto=format&fit=clip&q=50&w=1080) Search for the group you’d like to push and select it. Make sure the box is checked for “Push Immediately” and click “Save”. ![A screenshot showing where to search for groups to push in the "Push Groups" tab in Okta.](https://images.workoscdn.com/images/5ac81a96-1849-4c5b-8833-fa6a110e3da9.png?auto=format&fit=clip&q=50&w=1080) In the WorkOS dashboard, you should now see the users and groups synced over. ![A screenshot showing a successfully synced user from an Okta directory in the WorkOS dashboard.](https://images.workoscdn.com/images/3bcbe3b4-e17c-40ac-8dcd-f098b52d8e8a.png?auto=format&fit=clip&q=50) A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) --- ## Configuring user attribute mappings For any non-standard attributes used by the application, some configuration may be required in Okta. Below is a guide on configuring user attribute mappings, so they propagate via SCIM. ### (1) Viewing application attributes From the Okta administrator portal, navigate to Directory → Profile Editor, and find the application for which you'd like to edit mappings. ![Okta profile editor](https://images.workoscdn.com/images/6c58b92b-233c-4329-af2e-d024d7715081.png?auto=format&fit=clip&q=50) Clicking into the application will bring you to a Profile Editor page: ![Okta application profile editor](https://images.workoscdn.com/images/b68c705c-b08d-4d7c-a923-41e0cf7cbfed.png?auto=format&fit=clip&q=50) You'll likely see several attributes listed, which are scoped to the application. If you see an attribute listed you're looking to map to an application, there's no need to create a new attribute and you can skip to [step 3](/integrations/okta-scim/configuring-user-attribute-mappings/3-mapping-an-attribute). ### (2) Adding an attribute If a desired attribute is missing from your application, click the "Add Attribute" button to create a new attribute. ![Okta profile editor add attribute](https://images.workoscdn.com/images/34a7d5da-885c-481a-b44d-60f631c7711c.png?auto=format&fit=clip&q=50) Enter a display name and variable name of your choosing, and ensure the external name matches the key required by the third-party application. For example, if the third-party application pulls the manager value from `manager.value`, the external name should be `manager.value`. For attributes included as part of the SCIM enterprise extension, enter the external namespace as `urn:ietf:params:scim:schemas:extension:enterprise:2.0:User`. ![Okta add attribute dialog](https://images.workoscdn.com/images/d4a7cff9-0226-4462-ab11-c086b4b4533e.png?auto=format&fit=clip&q=50) Once you’ve entered the required information, click "Save". ### (3) Mapping an attribute To map Okta user profile attributes to your application users, click on the “Mappings” button. ![Okta profile editor mappings](https://images.workoscdn.com/images/542ba367-6147-4ea5-bb18-4d55e13232ea.png?auto=format&fit=clip&q=50) Mappings can be bidirectional, either from the application to the Okta user or from the Okta user to the application. This guide will focus on mapping from the Okta user to the application. Click the "Okta User to (name of application)" tab. ![Okta to application mapping tab](https://images.workoscdn.com/images/de8218c4-b96b-4761-85e9-6843b200e445.png?auto=format&fit=clip&q=50) Find the name of the attribute you’d like to map in the right column. In the corresponding row's left column, enter the name of the Okta user profile attribute you’d like to map over. For example, if you’re looking to map manager email in the application, select `managerId` in the left column. ![Okta mapping select attribute](https://images.workoscdn.com/images/97fafcf8-0845-4e09-8699-7ec5560255ce.png?auto=format&fit=clip&q=50) Ensure the apply mappings setting is set to "Apply mapping on user create and update". ![Okta apply mappings selection](https://images.workoscdn.com/images/d1a3c86a-36e9-49ba-bf5a-7538c0992aa5.png?auto=format&fit=clip&q=50) Once your mappings are configured, click "Save Mappings" and "Apply updates now". These new attribute mappings will now propagate to the application. ## Frequently asked questions ### When a user is assigned to the SCIM app via a group, I don’t see a user removed webhook if the user is removed from the group – is this expected? It is a known issue with Okta SCIM that if a user is assigned to a SCIM app via a group, you won’t see a `dsync.group.user_removed` event if the user is removed from the group. This is a limitation in Okta, where group memberships are not updated in this case. The user needs to be assigned directly to the SCIM app, and the group needs to be pushed in the SCIM app. If those two conditions are met, Okta will send the correct group membership updates. ### How often do the Okta SCIM 2.0 directories perform a sync? The Okta SCIM 2.0 directory syncs events in real time. ### Why is a user suspended in Okta still active in WorkOS? Suspending a User in Okta will only affect their login and will not alter their status in any connected applications. Deactivating or Deleting a User in Okta will result in a `inactive` status in connected applications (i.e., WorkOS). For more details, please refer to Okta's official documentation [User Suspension](https://help.okta.com/en-us/content/topics/users-groups-profiles/usgp-suspend.htm) [User Deactivation and Deletion](https://help.okta.com/en-us/content/topics/users-groups-profiles/usgp-deactivate-user-account.htm). ### What is the `idp_id` for directory groups from Okta? Okta only provides a group display name as a group identifier, so this display name is persisted as the `idp_id` and `name` for [directory groups](/reference/directory-sync/directory-group) in WorkOS. ### Okta SAML Learn how to configure a connection to Okta via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create an Okta Connection, you’ll need three pieces of information: an [ACS URL](/glossary/acs-url), an [SP Entity ID](/glossary/sp-entity-id), and an [IdP Metadata URL](/glossary/idp-metadata). Start by logging in to your WorkOS dashboard and browse to the “Organizations” tab on the left hand navigation bar. Select the organization you’d like to configure an Okta Connection for, and select “Manually Configure Connection” under “Identity Provider”. ![A screenshot showing where to find "Manually Configure Connection" in the WorkOS Dashboard.](https://images.workoscdn.com/images/9270090d-4f59-4b7b-95e9-1132a6bee872.png?auto=format&fit=clip&q=50) Select “Okta SAML” from the Identity Provider dropdown, enter a descriptive name for the connection, and then select the “Create Connection” button. ![A screenshot showing "Create Connection" details in the WorkOS Dashboard.](https://images.workoscdn.com/images/287303da-4bbd-433b-bdd2-06f5002dd5ca.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides WorkOS provides the ACS URL and the SP Entity ID. It’s readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/get-started). ![A screenshot showing where to find the ACS URL and SP Entity ID in the WorkOS Dashboard.](https://images.workoscdn.com/images/ad4ef355-6ea7-4e27-9762-91309c34dc2d.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. In Okta’s case, it needs to be set by the organization when configuring your application in their Okta instance. The SP Entity ID is a URI used to identify the issuer of a SAML request, response, or assertion. In this case, the entity ID is used to communicate that WorkOS will be the party performing SAML requests to the organization's Okta instance. Specifically, the ACS URL will need to be set as the “Single Sign-On URL” and the SP Entity ID will need to be set as the “Audience URI (SP Entity ID)” in the “Configure SAML” step of the Okta “Edit SAML Integration” wizard: ![A screenshot showing where to place the WorkOS Single Sign-On URL and SP Entity ID in the Okta Dashboard.](https://images.workoscdn.com/images/52be9941-9e43-4f70-a65e-d4cd8883579c.png?auto=format&fit=clip&q=50) ## What you’ll need Next, provide the [IdP Metadata URL](/glossary/idp-metadata). Normally, this information will come from the organization's IT Management team when they set up your application’s SAML 2.0 configuration in their Okta admin dashboard. But, should that not be the case during your setup, the next steps will show you how to obtain it. --- ## (1) Log in Log in to [Okta](https://login.okta.com), go to the admin dashboard, and select “Applications” in the navigation bar. ![A screenshot showing how to navigate to existing applications in the Okta Dashboard.](https://images.workoscdn.com/images/b4f8bd68-3265-4ef6-8916-1f9e7eb241a1.png?auto=format&fit=clip&q=50) --- ## (2) Select or create your application If your application is already created, select it from the list of applications and move to Step 7. ![A screenshot showing existing applications in the Okta Dashboard.](https://images.workoscdn.com/images/f763ab3c-0ffc-49b7-8212-f988d0738e94.png?auto=format&fit=clip&q=50) If you haven’t created a SAML application in Okta, select “Create App Integration”. ![A screenshot showing how to select "Create App Integration" in the Okta Dashboard.](https://images.workoscdn.com/images/cf63d4f1-3929-4426-a0df-959bbd06ce13.png?auto=format&fit=clip&q=50) --- ## (3) Initial SAML Application Setup Select “Create New App”, then select “SAML 2.0” as a Sign on method, then click “Next”. ![A screenshot showing the sign-in method selection in the Okta Dashboard.](https://images.workoscdn.com/images/036519d9-1d5a-462f-8d36-e87b618a3e94.png?auto=format&fit=clip&q=50) Enter a descriptive App name, then click “Next”. ![A screenshot showing App name creation in the Okta Dashboard.](https://images.workoscdn.com/images/facbcbea-3ce0-421e-9725-e05e49bc056a.png?auto=format&fit=clip&q=50) --- ## (4) Configure SAML Application Input the ACS URL from your WorkOS Dashboard as the “Single Sign-On URL” and input the SP Entity ID from your WorkOS Dashboard as the “Audience URI (SP Entity ID)”. ![A screenshot showing where to place the WorkOS Single Sign-On URL and SP Entity ID in the Okta Dashboard.](https://images.workoscdn.com/images/52be9941-9e43-4f70-a65e-d4cd8883579c.png?auto=format&fit=clip&q=50) Scroll down to the “Attribute Statements” section and use the “Add Another” button to add the following key-value pairs. - `id` → `user.id` - `email` → `user.email` - `firstName` → `user.firstName` - `lastName` → `user.lastName` ![A screenshot showing the "Attribute Statements" configuration in the Okta Dashboard.](https://images.workoscdn.com/images/93f6811f-9f56-47a2-bfa0-d4babc91f66e.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, follow the guidance below. Scroll down to the Group Attribute Statements configuration. The Name should be set to `groups`, and you can define a filter to map the necessary Okta groups. To map all groups, filter by matching the regex `.*`, as shown in the screenshot below. You can preview the SAML Assertion to check that all attributes have been mapped correctly. Then, click “Next”. ![A screenshot showing the "Groups Attribute Statement" configuration in the Okta Dashboard.](https://images.workoscdn.com/images/723c0734-a8cc-4903-a90d-273dfe282886.png?auto=format&fit=clip&q=50) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (5) Submit Application Feedback Select “I’m an Okta customer adding an internal app” from the options menu. Complete the form with any comments and select “Finish”. ![A screenshot showing where to submit application feedback in the Okta Dashboard.](https://images.workoscdn.com/images/734d5229-1913-4cfb-b366-295104da4123.png?auto=format&fit=clip&q=50) --- ## (6) Add Users to SAML Application To give users permission to authenticate via this SAML app, you will need to assign individual users and/or groups of users to the Okta app. Click on the “Assignments” tab, and select either “Assign to People” or “Assign to Groups”. ![A screenshot showing the Okta Application "Assignments" tab in the Okta Dashboard.](https://images.workoscdn.com/images/a8380fe9-9e90-48ff-b665-8313311c28d1.png?auto=format&fit=clip&q=50) Find the individual user(s) and/or group(s) that you would like to assign to the app, and click “Assign” next to them. Click “Done” when you are finished. ![A screenshot showing the selecting of groups to add to the Application in the Okta Dashboard.](https://images.workoscdn.com/images/c4fddfdc-35b2-4a4f-9d84-1a7e94968d24.png?auto=format&fit=clip&q=50) --- ## (7) Upload Metadata URL Click on the “Sign On” tab of the SAML app you just created. Click the “Actions” dropdown for the correct certificate and select “View IdP Metadata." ![A screenshot showing the "View IdP Metadata" selection in the Okta Dashboard.](https://images.workoscdn.com/images/e98e855e-6733-4f6e-96da-5c993cebd21b.png?auto=format&fit=clip&q=50&w=2048) A separate tab will open. Copy the link in the browser. ![A screenshot of the IdP Metadata XML URL in the Okta Dashboard.](https://images.workoscdn.com/images/eab81ff3-8037-4cd6-94ef-b00962084ad0.png?auto=format&fit=clip&q=50) Back in the WorkOS Dashboard, click on “Edit Metadata Configuration” in the “Identity Provider Configuration” section of the Connection. Input the Metadata URL and click “Save Metadata Configuration”. Your Connection will then be linked and good to go! ![A screenshot showing where to place the Okta IdP Metadata URL in the WorkOS Dashboard.](https://images.workoscdn.com/images/a08a0c17-d510-4410-91cb-4477cfe310c8.png?auto=format&fit=clip&q=50) ### Okta OIDC Learn how to configure a connection to Okta via OIDC. ## Introduction Each SSO identity provider requires specific information to create and configure a new [SSO connection](/glossary/connection). Often, the information required to create an SSO connection will differ by identity provider. To create an Okta OIDC SSO connection, you'll need four pieces of information: a [redirect URI](/glossary/redirect-uri), [client ID](/glossary/client-id), [client secret](/glossary/client-secret), and [discovery endpoint](/glossary/discovery-endpoint). Start by logging in to your WorkOS dashboard and navigate to the **Organizations** page from the left-hand navigation bar. Select the organization you'd like to configure an Okta OIDC SSO connection for, and select **Configure manually** under **Single Sign-On**. ![WorkOS Dashboard Organizations tab with "Configure manually" button highlighted](https://images.workoscdn.com/images/d577cfbe-028b-48cf-8cc0-4cd5d3adf853.png?auto=format&fit=clip&q=50) Select **Okta OIDC** from the identity provider dropdown, enter a descriptive name for the connection, click **Create Connection**. ![Create Connection form with Okta OIDC selected as Identity Provider](https://images.workoscdn.com/images/6e60c859-936e-4894-ac88-0524565ef8c8.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides WorkOS provides the Redirect URI, which can be found in the **Service Provider Details** section on the SSO connection page in the [WorkOS Dashboard](https://dashboard.workos.com/). - [Redirect URI](/glossary/redirect-uri): The endpoint where identity providers send authentication responses after successful login ![The Redirect URI of a OIDC connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/99a7c7d5-50a9-4bff-a3f3-22dc1cfeca58.png?auto=format&fit=clip&q=50) The Redirect URI is the location an identity provider redirects its authentication response to. In Okta's case, it needs to be set as the **Sign-in redirect URI** when configuring your OIDC application in their Okta instance. Specifically, the Redirect URI will need to be added to the **Sign-in redirect URIs** section in the **Create OpenID Connect Integration** wizard, which is outlined in [step 2](/integrations/okta-oidc/2-configure-the-integration). --- ## What you'll need You will need to obtain three pieces of information from the organization: - [Client ID](/glossary/client-id): Application identifier from the OIDC provider - [Client secret](/glossary/client-secret): Authentication secret for the application - [Discovery endpoint](/glossary/discovery-endpoint): Configuration URL containing OIDC metadata Normally, this information will come from the organization's IT Management team when they set up your application's OIDC configuration in their Okta admin dashboard. But, should that not be the case during your setup, the next steps will show you how to obtain it. --- ## (1) Create OIDC integration Log in to the Okta admin console, and select **Applications** in the left-hand sidebar. ![Okta admin console navigation menu with Applications tab highlighted](https://images.workoscdn.com/images/d3e05208-2c35-4cba-a592-62aadf2752a1.png?auto=format&fit=clip&q=50) Click **Create App Integration**. ![Okta Applications page with "Create App Integration" button](https://images.workoscdn.com/images/8059f5a3-0c46-45fb-a4db-30c13c0fc0de.png?auto=format&fit=clip&q=50) In the **Create a new app integration** dialog, select **OIDC - OpenID Connect** and **Web Application**. ![Create app integration dialog with OIDC - OpenID Connect and Web Application selected](https://images.workoscdn.com/images/d6b2f9e8-42f4-4279-9adf-6954644a9758.png?auto=format&fit=clip&q=50) Click **Next**. --- ## (2) Configure the integration Enter a descriptive App name, then configure the Sign-in redirect URI. ![OIDC app configuration form with app name field and sign-in redirect URI section](https://images.workoscdn.com/images/7ed6bf17-6839-48f2-b796-883b181c1e79.png?auto=format&fit=clip&q=50) Locate the **Sign-in redirect URIs** section and click **Add URI**. Copy the [Redirect URI](/integrations/okta-oidc/what-workos-provides) from the SSO connection page in your WorkOS Dashboard and paste it into this field. ![Sign-in redirect URIs configuration with WorkOS redirect URI entered](https://images.workoscdn.com/images/fa2cc4f3-a11a-4612-8b58-4739385babac.png?auto=format&fit=clip&q=50) Scroll down to the **Assignments** section. Select **Limit access to selected groups** and assign the appropriate groups to the application. This can be edited later. ![Assignments section with "Limit access to selected groups" option selected](https://images.workoscdn.com/images/743f90a9-aa9d-48a1-94e4-05b1743f9e81.png?auto=format&fit=clip&q=50) Click **Save**. --- ## (3) Obtain configuration details On the **General** tab, locate the **Client ID** and **Client secret**. Back in the WorkOS Dashboard, enter the client ID, and client secret into the respective fields in the **Identity Provider Configuration** section of the SSO connection. ![Okta app General tab showing Client ID and Client secret fields](https://images.workoscdn.com/images/20ac0b30-2575-401c-973d-016c8a18efe9.png?auto=format&fit=clip&q=50) In the top right-hand navigation, click your user email and locate the **Okta tenant domain** which usually ends with `.okta.com`. Copy this value and define the discovery endpoint in the format: `https://{tenant-domain}/.well-known/openid-configuration`. Enter this URL in the **Discovery Endpoint** field in the WorkOS dashboard. ![WorkOS Dashboard Identity Provider Configuration with client ID, client secret, and discovery endpoint fields](https://images.workoscdn.com/images/24179b09-b86d-46f8-9375-95b9ff9abd36.png?auto=format&fit=clip&q=50) Click **Save Configuration**. --- ## (4) Role assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. Users will automatically be granted the assigned roles within your application when they authenticate. To enable this functionality: ### Set groups claim in Okta Navigate to the **Sign On** tab of your OIDC application, locate the **Claims** section, and click **Edit**. ![Okta app Sign On tab with Claims section and Edit button](https://images.workoscdn.com/images/d699c5cb-c4f1-4299-acbe-7ed4cc1dfee9.png?auto=format&fit=clip&q=50) Set the **Groups claim type** to **Filter**. Define the **Groups claim filter** as `groups` and set a filter to match the appropriate Okta groups. To match all groups, use the regex `.*` as shown below. ![Groups claim configuration with claim type set to Filter and groups claim filter field](https://images.workoscdn.com/images/4face13e-e7e3-48dd-8a8e-7938c93840d6.png?auto=format&fit=clip&q=50) ### Configure role assignment in WorkOS In Okta, navigate to the **Assignments** tab in the application. Locate the **Filters** sidebar, click on **Groups** to filter and display all the assigned groups available to map. ![Okta dashboard showing assigned groups](https://images.workoscdn.com/images/17d32c5b-fc4b-458b-98f6-99c774af1522.png?auto=format&fit=clip&q=50) From the SSO connection page in the [WorkOS Dashboard](https://dashboard.workos.com/), scroll to the **Groups and role assignments** section. ![WorkOS dashboard highlighting create group button](https://images.workoscdn.com/images/c29ef1a7-d873-49f6-ad43-8c945245a033.png?auto=format&fit=clip&q=50) For each group you want to assign a role, click the **Create group** button and enter the following: 1. Copy the group name from Okta into the **IdP ID** field. 2. Optionally, enter a group name into the **Name** field. 3. Assign the appropriate role to the group. ![WorkOS dashboard with open create group dialog and idp_id, name, and role assignment inputs](https://images.workoscdn.com/images/d542c8c3-e032-41a6-ae72-c8dc586ec88d.png?auto=format&fit=clip&q=50) > Group members without an explicit role will receive the default role. --- ## Next steps Your Okta OIDC connection is now configured and ready to use. Users assigned to the application in Okta will be able to authenticate through WorkOS using their Okta credentials. To start using this connection in your application, refer to the [SSO guide](/sso) for implementation details. ### OpenID Connect Learn how to configure a new generic OIDC connection ## Introduction To set up an OpenID Connect (OIDC) connection on behalf of an organization, you'll need the client credentials and the discovery endpoint of their OIDC provider from the organization's IT team. --- ## What WorkOS provides When setting up an OIDC connection, WorkOS provides one key piece of information in the **Service Provider Details** section for an SSO connection within the [WorkOS Dashboard](https://dashboard.workos.com/): - [Redirect URI](/glossary/redirect-uri): The endpoint where identity providers send authentication responses after successful login ![The Redirect URI of a OIDC connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/99a7c7d5-50a9-4bff-a3f3-22dc1cfeca58.png?auto=format&fit=clip&q=50) The **Redirect URI** serves as the destination for authentication responses and must be configured in the organization's identity provider admin dashboard. --- ## What you will need You will need to obtain three pieces of information from the organization: - [Client ID](/glossary/client-id): Application identifier from the OIDC provider - [Client Secret](/glossary/client-secret): Authentication secret for the application - [Discovery Endpoint](/glossary/discovery-endpoint): Configuration URL containing OIDC metadata Typically, the organization's IT team will provide these values when they configure your application in their identity provider admin dashboard. However, if you need to guide them through the process, the following sections will help. --- ## (1) Create an application with the identity provider For SSO to properly function, the organization needs to create and configure an OpenID Connect application in their identity provider that supports the authorization code grant type. Copy the **Redirect URI** from the WorkOS Dashboard connection settings. Instruct the organization admin to paste this value as the login redirect URI in their OIDC application configuration. This ensures authentication responses are sent to the correct WorkOS endpoint. --- ## (2) Configure ID token claims The organization's OIDC provider needs to include specific claims in the user ID token. Instruct them to add the following claims to their OIDC provider settings: - `sub`: Maps to the `idp_id` attribute in WorkOS user profiles - `email`: Maps to the `email` attribute in WorkOS user profiles - `given_name`: Maps to the `first_name` attribute in WorkOS user profiles - `family_name`: Maps to the `last_name` attribute in WorkOS user profiles For many providers, these claims are included by default, but some providers require manual configuration. ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To enable this functionality, instruct the organization to add the `groups` claim to the user ID token in their OIDC provider settings. This claim should map to a list of the user's group memberships. > Finish role assignment set-up by navigating to the SSO connection page in the **Organizations** section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (3) Obtain client credentials and discovery endpoint After the organization creates an OpenID Connect application, their identity provider will provision client credentials and a discovery endpoint. The discovery endpoint will always end with `/.well-known/openid-configuration` as described in the [OpenID Provider Configuration Request documentation](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest). You can confirm that the discovery endpoint is correct by entering it in a browser window. If there is a JSON object with metadata about the connection returned, the endpoint is correct. In the WorkOS Dashboard, navigate to your connection settings. Paste the **Client ID**, **Client Secret**, and **Discovery Endpoint** values from the organization's IT team into their respective input fields. Click **Update connection**. ![Input the Client ID, Client Secret, and Discovery Endpoint in the WorkOS Dashboard](https://images.workoscdn.com/images/ed603b39-a06e-4c2f-b96f-7cadaa793be4.png?auto=format&fit=clip&q=50) ### NextAuth.js Create a Next.js application with WorkOS SSO and NextAuth.js. ## Introduction In this guide, you’ll learn how to use WorkOS to add Single Sign-On (SSO) to a Next.js app that uses [NextAuth.js](https://next-auth.js.org/) for handling authentication. You can check out the [complete source code](https://github.com/workos/workos-next-auth) of this guide on GitHub. ## Before getting started To get the most out of this guide, you’ll need: - A [WorkOS account](https://dashboard.workos.com/) - An IdP (e.g. Okta) account ## (1) Install sample application In your a terminal, browse to the directory of your choice and run the following command to clone the starter project: ```bash title="Clone the Sample App" git clone -b start-branch https://github.com/workos-inc/workos-next-auth ``` And install the dependencies ```bash title="Install the Dependencies" npm install ``` This is a basic Next.js app built using TypeScript and styled using TailwindCSS. ## (2) Configuring the environment variables In the project’s root folder, rename the `.env.example` file to `.env`. You can find down below the values for the WorkOS client ID and API key. ```plain title=".env" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' ``` 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](/glossary/client-id) should also be set dynamically based on the release environment. ## (3) SSO Setup with WorkOS The first step is to create an organization, which can be done using the dashboard or [via the API](/reference/organization/create). By default, WorkOS creates a demo organization called “foo-corp.com” which you can use for testing purposes. Take note of the “Organization ID” which can be found in the organization’s detailed view. You’re going to need it to make SSO work. ![A screenshot highlighting the "Organization ID" in the WorkOS dashboard.](https://images.workoscdn.com/images/af4ef014-f6c4-44b2-b7cc-ccf2db24bde5.png?auto=format&fit=clip&q=50) ## (4) Configure redirect URIs In the “Configuration” tab in the dashboard, add `http://localhost:3000/api/auth/callback/workos` to the list of redirect URIs to test the SSO login flow locally. You’ll also need to add the domain of your application when deploying to production. ![A screenshot highlighting the redirect URIs in the "Configuration" tab in the WorkOS dashboard.](https://images.workoscdn.com/images/7005a351-b083-4a08-a096-cb227c21caa5.png?auto=format&fit=clip&q=50) ## (5) Create an API endpoint The next step is to create a `pages/api/auth/[...nextauth].ts` file which will contain all of your NextAuth.js configurations: ```js title="pages/api/auth/[...nextAuth].ts" ; ; export default NextAuth({ providers: [ WorkOSProvider({ clientId: process.env.WORKOS_CLIENT_ID, clientSecret: process.env.WORKOS_API_KEY, client: { token_endpoint_auth_method: 'client_secret_post', }, }), ], pages: { signIn: '/login', }, debug: true, secret: process.env.SECRET, }); ``` You’re first configuring WorkOS by passing the necessary options to the `WorkOSProvider()` function. You’re then defining a custom login page using the pages option which will be located at `/login`. You then need to wrap the global `App` component with `SessionProvider` from `NextAuth.js`. Add the following code to the `pages/_app.tsx` file: ```js title="pages/_app.tsx" import '../styles/index.css'; ; ; export default function App({ Component, pageProps: { session, ...pageProps }, }: AppProps) { return ( ); } ``` ## (6) Creating a custom login page In this step, you’ll create a custom login page. To do that, create a new file located at `pages/login.tsx` and add the following code to it: ```js title="pages/login.tsx" ; ; ; ; const Login = () => { const { register, handleSubmit, formState: { errors }, } = useForm(); const { data: session } = useSession(); const onSubmit = async ({ team }) => { // TODO: send a request to the get-organization endpoint and return the // organizationId from your database const organization = 'ORGANIZATION_ID'; signIn('workos', undefined, { organization, }); }; return ( <> {session && ( Signed in as {session.user.email} signOut()} className="max-w-sm flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" > Sign out )} {!session && ( Continue using enterprise SSO Team name Sign in )} ); }; export default Login; ``` Next, start the development server by running the following command: ```bash title="Start Server" npm run dev ``` The application will be running at `http://localhost:3000/login` and you’ll be able to see the following page: ![A screenshot showing the landing page of the example application.](https://images.workoscdn.com/images/af8ddee4-e7f1-49a1-9e7c-05e190b31d6e.png?auto=format&fit=clip&q=50) ## (7) Testing the Single Sign-On flow You should persist The Organization ID in your application’s database and associate it with your enterprise customer. Then when a user tries to log in, you first check if they’re an enterprise customer and then use the `signIn()` function from NextAuth.js to start the login flow. To test the login flow, hardcode the Organization ID in the form submission handler. ```js title="pages/login.tsx" // code above unchanged const onSubmit = async ({ team }) => { // TODO: create an endpoint that returns the // organizationId from your database /* +diff-start */ const organization = 'ORGANIZATION_ID'; /* +diff-end */ signIn('workos', undefined, { organization, }); }; // code below unchanged ``` If you type anything in the login form and click submit, you’ll be redirected to Okta. You’ll then need to use your IdP login credentials. After you complete the login process you’ll see the logged-in user’s email and a “Sign out” button ![A screenshot showing the example application with a successfully logged in user.](https://images.workoscdn.com/images/7fd5daef-1cd9-401d-9884-3130b7b3a095.png?auto=format&fit=clip&q=50) If you’re interested in setting up a different Identity Provider, check out the [full list of tutorials](/sso) for setting up an SSO connection. ### NetIQ Learn how to configure a connection to NetIQ via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a NetIQ SAML Connection, you’ll need the Identity Provider metadata that is available from the organization's NetIQ instance. Start by logging in to your WorkOS dashboard and browse to the “Organizations” tab on the left hand navigation bar. Select the organization you’d like to configure an NetIQ SAML Connection for, and select “Manually Configure Connection” under “Identity Provider”. ![A screenshot showing where to find "Manually Configure Connection" in the WorkOS Dashboard.](https://images.workoscdn.com/images/c6f1423d-020f-4560-aed0-ca4895b5fbc1.png?auto=format&fit=clip&q=50) Select "NetIQ SAML” from the Identity Provider dropdown, enter a descriptive name for the connection, and then select the “Create Connection” button. ![A screenshot showing "Create Connection" details in the WorkOS Dashboard.](https://images.workoscdn.com/images/5c854a7c-0180-45de-aeda-8b52d8275b75.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides WorkOS provides the [ACS URL](/glossary/acs-url), the [SP Metadata](/glossary/sp-metadata) link and the [SP Entity ID](/glossary/sp-entity-id). They are readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot showing where to find the ACS URL and SP Entity ID in the WorkOS Dashboard.](https://images.workoscdn.com/images/e102db99-be9d-4aa5-b250-a690ce57d16e.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. The SP Metadata link contains a metadata file that the organization can use to set up the SAML integration. The SP Entity ID is a URI used to identify the issuer of a SAML request, response, or assertion. --- ## What you’ll need In order to integrate you’ll need the [IdP Metadata URL](/glossary/idp-metadata). Normally, this will come from the organization's IT Management team when they set up your application’s SAML 2.0 configuration in their NetIQ instance. But, should that not be the case during your setup, here’s how to obtain it. --- ## (1) Enter Service Provider Details Copy and paste the “ACS URL” and “SP Entity ID” into the corresponding fields for Service Provider details and configuration. For some setups, you can use the metadata found at the SP Metadata link to configure the SAML connection. --- ## (2) Obtain Identity Provider Metadata Copy the IdP Metadata URL from your NetIQ SAML settings and upload it to your WorkOS Connection settings. Your Connection will then be linked and good to go! ![A screenshot showing where to place the NetIQ IdP Metadata URL in the WorkOS Dashboard.](https://images.workoscdn.com/images/e26ae490-1f53-4d88-8c0e-50bb8ed2be64.png?auto=format&fit=clip&q=50) Alternatively, you can manually configure the connection by providing the IdP URI (Entity ID), [IdP SSO URL](/glossary/idp-sso-url) and X.509 Certificate. ![A screenshot showing where to switch to Manual Configuration in the connections detail page.](https://images.workoscdn.com/images/20ea5490-7344-43f4-95bb-129e3aa44595.png?auto=format&fit=clip&q=50) ![A screenshot showing to click "Save Configuration" upon entering the Metadata data.](https://images.workoscdn.com/images/1a39b96e-3564-43b2-82e7-082f74ff4713.png?auto=format&fit=clip&q=50) --- ## (3) Configure Attribute Mapping At minimum, the Attribute Statement in the SAML Response should include `id`, `email`, `firstName`, and `lastName` attributes. ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, map the groups in your identity provider to a SAML attribute named `groups` to return this information in the attribute statement. Once your SAML app is configured to return groups, navigate to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. ### miniOrange Learn how to configure a connection to miniOrange via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a miniOrange SAML Connection, you’ll need an IdP Metadata URL. Start by logging in to your WorkOS dashboard and browse to the “Organizations” tab on the left hand navigation bar. Select the organization you’d like to configure a miniOrange SAML Connection for, and select “Manually Configure Connection” under “Identity Provider”. ![A screenshot showing the Manual Configure Connection option in the WorkOS Dashboard.](https://images.workoscdn.com/images/24066931-e200-4e59-9996-3e28738a5b48.png?auto=format&fit=clip&q=50) Select “miniOrange SAML” from the Identity Provider dropdown, enter a descriptive name for the connection, and then select the “Create Connection” button. ![A screenshot showing a miniOrange connection being created in the WorkOS Dashboard.](https://images.workoscdn.com/images/08437cb1-adc7-422e-83d9-4886cba0ece3.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides WorkOS provides the [ACS URL](/glossary/acs-url), [SP Entity ID](/glossary/sp-entity-id) and [SP Metadata URL](/glossary/sp-metadata). They’re readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). For this configuration, you should only need to use the SP Metadata URL, but other fields are provided should you choose to do a more manual configuration. ![A screenshot showing the Service Provider Details provided by WorkOS for a miniOrange connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/0cf5969a-7cc5-4646-89bb-b19a7c54ec60.png?auto=format&fit=clip&q=50) --- ## What you’ll need Next, provide the IdP Metadata URL. Normally, this information will come from the organization's IT Management team when they set up your application’s SAML 2.0 configuration in their miniOrange admin dashboard. But, should that not be the case during your setup, the next steps will show you how to obtain it. --- ## (1) Select or create your application Log in to [miniOrange](https://login.xecurify.com/moas/login), go to the admin dashboard and select “Apps” on the left side navigation. If your application is already created, select it from the list of applications and move to Step 2. Otherwise, select “Add Application”. ![A screenshot showing where to select Add Application in the miniOrange dashboard.](https://images.workoscdn.com/images/d7abb7b9-41ad-4a8a-80e9-9f13fbfe7cc0.png?auto=format&fit=clip&q=50) Under “SAML/WS-FED”, select “Create App”. ![A screenshot showing where to select Create App in the miniOrange dashboard.](https://images.workoscdn.com/images/036c42e8-fe89-4699-8149-878fa27cc3bb.png?auto=format&fit=clip&q=50) Search for “custom” in the search box and select “Custom SAML App”. ![A screenshot showing where to select Custom SAML App in the miniOrange dashboard.](https://images.workoscdn.com/images/7b5b3d54-f81b-4c72-a883-8d02f72c742e.png?auto=format&fit=clip&q=50) --- ## (2) Initial SAML Application Setup Under the “Basic Settings” tab of the SAML app, select “Import SP Metadata”. ![A screenshot highlighting the "Import SP Metadata" button in the miniOrange Dashboard.](https://images.workoscdn.com/images/e162dc6c-3b87-4811-935f-99c6625ac45a.png?auto=format&fit=clip&q=50) Give the SAML app a descriptive name under “App Name”. Under “SP Metadata”, select “URL” and input the SP Metadata URL from your SSO Connection settings in the WorkOS Dashboard. Then, hit “Import”. ![A screenshot showing how to enter an App name and input a metadata URL in the miniOrange dashboard.](https://images.workoscdn.com/images/fe57d767-efc5-4e64-8a11-cd3b1d939eb5.png?auto=format&fit=clip&q=50) Make sure that you have the “Sign Assertion” field toggled on. ![A screenshot showing the "Sign Assertion" toggle activated in the miniOrange dashboard.](https://images.workoscdn.com/images/3100fed7-3173-4679-8151-2f30da20a062.png?auto=format&fit=clip&q=50) Select “Next”. ![A screenshot highlighting the "Next" button in the miniOrange dashboard.](https://images.workoscdn.com/images/91e21543-19e0-4c50-b9e9-dd5f954ef4b7.png?auto=format&fit=clip&q=50) --- ## (3) Configure SAML Application Under the “Attribute Mapping” section of the SAML app, select “Add Attribute”. ![A screenshot showing where to select "Add Attribute" in the miniOrange dashboard.](https://images.workoscdn.com/images/d72f5337-e2ee-412e-b3b4-153e4e406526.png?auto=format&fit=clip&q=50) Map the following four attributes as shown below, and the select “Save”. - `id` → `Username` - `email` → `E-Mail Address` - `firstName` → `First Name` - `lastName` → `Last Name` ![A screenshot showing how to input user attribute mapping in the miniOrange dashboard.](https://images.workoscdn.com/images/66a87e11-ce03-4426-b7b1-044a2c8e9f9a.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, follow the guidance below. On your SAML app's Settings page, scroll down to "Attributes" and add a new attribute. Set the attribute's name to `groups` and map it to the "User Groups" field. Click "Save". ![A screenshot showing how to add a groups attribute in the miniOrange dashboard.](https://images.workoscdn.com/images/6ca4414d-fc41-455c-812f-353eb4e77459.png?auto=format&fit=clip&q=50) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (4) Upload Metadata URL Back on the “Apps” tab of the miniOrange Dashboard, click “Select” next to the app you’ve created. From the dropdown, select “Metadata”. ![A screenshot highlighting where to select "Metadata" in the miniOrange dashboard.](https://images.workoscdn.com/images/39c6b33f-f3f3-4728-a70d-27672ae2e9f7.png?auto=format&fit=clip&q=50) Under the “Information required to set miniOrange as IdP” section, click the icon next to “Metadata URL” to copy it to your clipboard. ![A screenshot showing where to copy the Metadata URL in the miniOrange dashboard.](https://images.workoscdn.com/images/42746ff9-c33a-4c14-85c0-273cb5a1939d.png?auto=format&fit=clip&q=50) In the Connection settings in the WorkOS Dashboard, click “Edit Metadata Configuration”. ![A screenshot highlighting the "Edit Metadata Configuration" button in a Connection details view in the WorkOS Dashboard.](https://images.workoscdn.com/images/5ad0b7db-f33a-4a06-acf5-83809feaa2ad?auto=format&fit=clip&q=50) Paste the Metadata URL from miniOrange into the “Metadata URL” field and select “Save Metadata Configuration”. ![A screenshot showing how to input the Metadata URL into the Connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/13ae3b21-964f-471b-972f-f5fc2b570ccd.png?auto=format&fit=clip&q=50) Your Connection will then be linked and good to go! ### Microsoft OAuth Learn how to set up OAuth with Microsoft ## Introduction The Microsoft OAuth integration allows your users to authenticate using their Microsoft credentials through the "Sign in with Microsoft" flow. The configuration process involves creating or configuring an application in Microsoft Azure and setting up OAuth permissions with the client credentials in the WorkOS Dashboard. --- ## Testing with default credentials in the staging environment WorkOS provides a default Microsoft Client ID and Client Secret combination, which allows you to quickly enable and test Microsoft OAuth. Use the [WorkOS API to initiate SSO](/sso/1-add-sso-to-your-app/add-an-endpoint-to-initiate-sso), setting the `provider` parameter to `MicrosoftOAuth`, and WorkOS will automatically use the default credentials until you add your own Microsoft Client ID and Client Secret to the configuration in the WorkOS Dashboard. > The default credentials are only intended for testing and therefore only available in the Staging environment. For your production environment, please follow the steps below to create and specify your own Microsoft Client ID and Client Secret. Please note that when you are using WorkOS default credentials, Microsoft's authentication flow will display WorkOS' name, logo, and other information to users. Once you register your own application and use its Microsoft Client ID and Client Secret for the OAuth flow, you will have the opportunity to customize the app, including its name, logo, contact email, etc. --- ## What WorkOS provides When setting up Microsoft OAuth, WorkOS provides one key piece of information that needs to be configured in your Microsoft Azure application: - [Redirect URI](/glossary/redirect-uri): The endpoint where Microsoft will send authentication responses after successful login The Redirect URI is available in the [WorkOS Dashboard](https://dashboard.workos.com/). In the left navigation menu, select **Authentication** tab and the **OAuth providers** sub-tab. Locate the **Microsoft** section. ![Open the Microsoft configuration dialog](https://images.workoscdn.com/images/c1518c6e-a765-4101-90eb-0795763aff92.png?auto=format&fit=clip&q=50) Click **Manage**. The **Microsoft OAuth** configuration dialog will open. Locate the **Redirect URI**. ![Microsoft OAuth Redirect URI in the WorkOS Dashboard.](https://images.workoscdn.com/images/ba067eab-be24-404e-9d15-d1cc87720a57.png?auto=format&fit=clip&q=50) The **Redirect URI** serves as the destination for authentication responses and must be configured in your Microsoft Azure application's authentication settings. --- ## What you'll need You will need to obtain two pieces of information from a Microsoft Azure application: - **Microsoft Client ID**: Application identifier from Microsoft Azure - **Microsoft Client Secret**: Authentication secret for the application The following sections will guide you through creating an application in your Microsoft Azure Portal and generating these credentials. > IMPORTANT: When registering your app, select **Personal Microsoft accounts only** for **Supported Account Types**. ![The "Supported Account Types" setting in the Microsoft Azure Dashboard.](https://images.workoscdn.com/images/67aea66f-d0f3-45f1-a314-06b3ae570e24.png?auto=format&fit=clip&q=50) --- ## (1) Create or access Microsoft Azure application Sign in to the [Microsoft Azure Portal](https://portal.azure.com/) and navigate to **Microsoft Entra ID** from the left hand navigation. If you don't already have an application, click **App registrations** and then **New registration** to create one. When registering, you must select **Personal Microsoft accounts only** for **Supported Account Types**. If you already have an application, select **App registrations** and then select your relevant application. ![Where to select an application in the Azure Portal.](https://images.workoscdn.com/images/334e0a97-80d5-4458-a3d7-6b4ec3f8f584.png?auto=format&fit=clip&q=50) --- ## (2) Configure authentication settings Select the **Authentication** option for the application. In the **Redirect URIs** section, add the **Redirect URI** from the WorkOS Dashboard. When selecting a platform, choose **Web**. ![Where to enter the Redirect URI in the Azure App Settings.](https://images.workoscdn.com/images/b320ec4d-7dbb-4026-8bdb-7c6235dddb77.png?auto=format&fit=clip&q=50) --- ## (3) Configure token claims Under **Token configuration**, select **Add optional claim**. Select **email**, **family_name** and **given_name**. If shown, select the **Turn on the Microsoft Graph email, profile permission** checkbox. In order for the email claim to come through, the **Email** field for the user in Azure needs to be populated. ![Where to add claims in the Azure App Settings.](https://images.workoscdn.com/images/afe439ec-5d81-474f-9877-3657c3d50d1a.png?auto=format&fit=clip&q=50) --- ## (4) Generate client credentials To get the Microsoft Client Secret, navigate to **Certificates & secrets** and click on **New client secret**. Give the client secret a description and select **Add**. Microsoft's client secrets have an expiration date, with the highest value being 24 months. You will need to track these and rotate them before the expiration time. ![Where to create a client secret in the Entra ID App Settings.](https://images.workoscdn.com/images/1f7eca0b-700d-42f8-911a-238a3dee3df8.png?auto=format&fit=clip&q=50) Copy the **value** of the new client secret as you'll need it for the WorkOS configuration. ![Where to copy the Entra ID Client Secret.](https://images.workoscdn.com/images/98510fb9-db6c-43c6-9a79-85284916b169.png?auto=format&fit=clip&q=50) To obtain the Microsoft Client ID, navigate to the **Overview** tab of your application and copy the **Application (client) ID**. ![Where to copy the Entra ID Client ID.](https://images.workoscdn.com/images/6c79e0bc-9560-4a27-96f3-64569da1aa0e.png?auto=format&fit=clip&q=50) --- ## (5) Configure Microsoft credentials in WorkOS Now that you have the **Microsoft Client ID** and **Microsoft Client Secret** from the previous steps, return to the [WorkOS Dashboard](https://dashboard.workos.com). In the **Microsoft OAuth** configuration dialog, select **Your app's credentials**. Paste the credentials from Microsoft into their respective fields in the WorkOS Dashboard. ![Where to enter Microsoft OAuth client credentials into the WorkOS Dashboard.](https://images.workoscdn.com/images/2d7e1ea9-ea44-439c-bbaf-f4c19569b7aa.png?auto=format&fit=clip&q=50) Click **Save** to complete the configuration. After that, you're now able to authenticate users with Microsoft OAuth. You will use the `provider` query parameter in the Get Authorization URL API endpoint to support global Microsoft OAuth for any domain. The `provider` query parameter should be set to `MicrosoftOAuth`. --- ## Configure Additional OAuth Scopes (Optional) WorkOS will request the OAuth scopes that are required for authentication by default. You can optionally configure your integration to request additional OAuth scopes as needed. When the **Return Microsoft OAuth tokens** option is selected, the access token and refresh token from Microsoft will be included in the response from the [Authenticate with code API](/reference/authkit/authentication/code). ![A screenshot showing Microsoft OAuth scopes configuration in the WorkOS Dashboard](https://images.workoscdn.com/images/af28d982-0bc2-4240-be1a-9f97068d036f.png?auto=format&fit=clip&q=50) Any scopes configured here will be included on every Microsoft OAuth request. To specify additional scopes dynamically, use the `provider_scopes` query parameter on the [Get Authorization URL API endpoint](/reference/authkit/authentication/get-authorization-url). Any additional scopes that you plan to request should also be configured as API permissions on your Microsoft Azure application. For more information, see Microsoft's OAuth scopes [documentation](https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc). ![A screenshot showing Microsoft OAuth scopes configuration in Azure App Registration](https://images.workoscdn.com/images/537b2f36-cfb0-4c35-83a6-7fee760418d5.png?auto=format&fit=clip&q=50) > IMPORTANT: Your users may see errors during sign-in if the scopes included on an authorization request are not included in the API permissions configured on your Microsoft Azure application. Changes to scopes should be tested in a staging environment before applying them to production. --- ## Frequently asked questions ### How is the WorkOS Microsoft OAuth integration different from implementing regular Microsoft OAuth flow? It's the same Microsoft OAuth flow as you could build yourself, but it's encapsulated within WorkOS SSO. This means you don't need to build it yourself. In addition to Microsoft OAuth, you can use WorkOS SSO to support other identity providers, all with a single integration. ### What is the provider query parameter and how is it used in the Microsoft OAuth integration? You can use the `provider` query parameter in the [Get Authorization URL API endpoint](/reference/sso/get-authorization-url) to support global Microsoft OAuth for any domain. The `provider` query parameter should be set to `MicrosoftOAuth`. This is necessary because Microsoft OAuth does not take a user's domain into account when logging in with a "Sign in with Microsoft" button. ### Why do I need to select "Personal Microsoft accounts only" for account types? This setting is required for the WorkOS integration to function properly. It ensures that the OAuth flow works with personal Microsoft accounts rather than organizational accounts, which have different authentication requirements. ### How long do Microsoft client secrets last? Microsoft's client secrets have an expiration date, with the maximum value being 24 months. You will need to track these and rotate them before the expiration time to maintain continuous authentication functionality. ### Microsoft AD FS SAML Configure a connection to Microsoft Active Directory Federation Services. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create an AD FS SAML Connection, you’ll need two pieces of information: an [SP Metadata](/glossary/sp-metadata) file and an IdP Metadata URL. --- ## (1) Configure a Relying Party Trust Open the AD FS Management console. ![A screenshot showing the AD FS Management Console.](https://images.workoscdn.com/images/39b62cf2-a830-4cfc-b057-1717cec6e870.png?auto=format&fit=clip&q=50&w=1200) Click “Relying Party Trusts” on the left sidebar. Click “Add Relying Party Trust...” on the right sidebar to open the “AD FS Relying Party Trust Wizard”. ![A screenshot showing where to add the AD FS Relying Party Trust.](https://images.workoscdn.com/images/b99f15c0-ac9d-4cd4-bd78-38f00cd3cfee.png?auto=format&fit=clip&q=50&w=1200) Select “Claims aware” and then “Start”. ![A screenshot showing where to select claims in the AD FS Relying Party Trust Wizard.](https://images.workoscdn.com/images/1aaf2490-580f-4930-91b4-258326b751c3.png?auto=format&fit=clip&q=50&w=1200) Download the provided Metadata file from WorkOS by heading to the SP Metadata link in the Dashboard. Select “Import data about the relying party from a file” then select the SP Metadata file you downloaded, and click “Next”. ![A screenshot showing where to import the WorkOS Metadata File.](https://images.workoscdn.com/images/9cf7ee4f-09d8-4dcc-ab92-29732ca3c691.png?auto=format&fit=clip&q=50&w=1200) Select “Permit everyone” and then “Next”. ![A screenshot showing where to configure access control permissions in the AD FS Relying Party Trust Wizard.](https://images.workoscdn.com/images/94d90815-ef73-4cf5-9a8e-9b85108163d3.png?auto=format&fit=clip&q=50&w=1200) --- ## (2) Choose Access Policy Click the “Endpoints” tab and confirm that the “SAML Assertion Consumer Endpoints” matches the SAML Assertion Consumer Endpoint `https://auth.workos.com/sso/saml/acs/:id` and click “Next”. ![A screenshot showing where to check the ACS URL in AD FS.](https://images.workoscdn.com/images/c0c58966-3656-4079-b9c4-1ed01e2d2412.png?auto=format&fit=clip&q=50&w=1200) Select “Configure claims issuance policy for this application” and “Close”. ![A screenshot showing where to configure the AD FS claims.](https://images.workoscdn.com/images/a786ee79-750e-464f-ad4c-bdf685a7aec0.png?auto=format&fit=clip&q=50&w=1200) --- ## (3) Configure Claims Issuance Policy Click “Add Rule” in the “Edit Claims Issuance Policy” window. ![A screenshot showing where to add a rule in the Edit Claims Issuance Policy window.](https://images.workoscdn.com/images/b0ce3aa1-5a5c-498a-8b40-f9297ed03a29.png?auto=format&fit=clip&q=50&w=1200) Select “Send LDAP Attributes as Claims” and then “Next”. ![A screenshot showing where to select a rule template in the Transform Claim Rule Wizard.](https://images.workoscdn.com/images/753196aa-ebd0-4456-a961-4faacbfddbd2.png?auto=format&fit=clip&q=50) Submit “Attributes” as “Claim rule name”, then select “Active Directory” as “Attribute Store”, and configure the following attribute mappings. Then click “OK”. - `E-Mail-Addresses` → `E-Mail Address` - `Given-Name` → `Given Name` - `Surname` → `Surname` - `User-Principal-Name` → `UPN` ![A screenshot showing where to map attributes in the Transform Claim Rule Wizard.](https://images.workoscdn.com/images/e835b332-47de-43e5-a34d-0031395dee9c.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, follow the guidance below. Select "Group" as the "Outgoing Claim Type" and map an LDAP Attribute to send groups. For example, to send all groups, map the "Token-Groups - Unqualified Names" attribute. ![A screenshot showing how to map the Group claim.](https://images.workoscdn.com/images/72de6a78-46cc-4499-8ef6-f7c05fa0a087.png?auto=format&fit=clip&q=50) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (4) Upload Metadata URL Next you will want to obtain the Metadata URL from your AD FS server. AD FS publishes its metadata to a standard URL by default: `https://SERVER/federationmetadata/2007-06/federationmetadata.xml` where “SERVER” is your federation service FQDN. You can also find your ADFS Federation Metadata URL through the AD FS Management in “AD FS → Service → Endpoints” and navigate to the Metadata section. ![A screenshot showing where to find the AD FS Metadata URL.](https://images.workoscdn.com/images/f9c91a23-847c-4032-9bbb-888d071db27d.png?auto=format&fit=clip&q=50) Once you have obtained the Metadata URL you will then navigate to the connection settings in WorkOS, click “Edit Metadata configuration”, and upload the Metadata URL. ![A screenshot showing where to upload the AD FS Metadata URL in the WorkOS Dashboard.](https://images.workoscdn.com/images/0ab739ca-8edd-436d-b6a6-4efe3cf598fc.png?auto=format&fit=clip&q=50) Once uploaded the connection will be verified and linked! ### Login.gov OpenID Connect Learn how to configure a connection to Login.gov via OIDC. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. > Note: [Login.gov](http://login.gov/) is used for government agencies. You will need to go through Login.gov to obtain a test account and get your application cleared for production. Please reference [Login.gov’s developer documentation](https://developers.login.gov/testing/) for more information. To create a Login.gov OpenID Connect (OIDC) Connection, you’ll need four pieces of information: a [Redirect URI](/glossary/redirect-uri), a Public Certificate, a [Client ID](/glossary/client-id), and a Discovery Endpoint. Start by logging in to your WorkOS dashboard and browse to the “Organizations” tab on the left-hand navigation bar. Select the organization you’d like to configure a Login.gov OIDC Connection for, and select “Manually Configure Connection” under “Identity Provider”. ![A screenshot showing where to find "Manually Configure Connection" in the WorkOS Dashboard.](https://images.workoscdn.com/images/32e5ff2f-4756-48ab-8c01-9ea6c04a0162.png?auto=format&fit=clip&q=50) Select “Login.gov OpenID Connect” from the Identity Provider dropdown, enter a descriptive name for the connection, and then select the “Create Connection” button. ![A screenshot showing "Create Connection" details in the WorkOS Dashboard.](https://images.workoscdn.com/images/59b7ae81-487d-4e3b-a1d7-d6e293452d1b.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides WorkOS provides the Redirect URI and the Public Certificate. They are readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/get-started). ![A screenshot showing where to find the Redirect URI and Public Certificate in the WorkOS Dashboard.](https://images.workoscdn.com/images/cabe8cea-016e-4070-abe9-43b19b86699d.png?auto=format&fit=clip&q=50) The Redirect URI is the location Login.gov redirects its authentication and token responses to, and the Public Certificate is used by Login.gov to verify the signed request from WorkOS. Specifically, the Redirect URI will need to be set as one of the “Redirect URIs” and the Public Certificate will need to be set as one of the “Public Certificates” in the Login.gov application settings: ![A screenshot showing where to upload the Public Certificate and Redirect URI within the Login.gov dashboard.](https://images.workoscdn.com/images/2c615ec0-e266-492f-a32b-07d55c04b0ad.png) ## What you’ll need In order to integrate you’ll need the [Client ID](/glossary/client-id) and the Discovery Endpoint. Normally, this information will come from the organization's IT Management team when they set up your application’s Login.gov OpenID Connect configuration in their Identity Provider admin dashboard. But, should that not be the case during your setup, here’s how to obtain them. --- ## (1) Access the Login.gov Developer Sandbox Login to your [Login.gov sandbox dashboard](https://dashboard.int.identitysandbox.gov), and select “Apps” from the top menu. ![A screenshot showing the Login.gov sandbox dashboard and how to select the App menu option.](https://images.workoscdn.com/images/21a33031-818d-4b44-8646-648a45fc4e5a.png) > Note: Login.gov is used exclusively by government agencies. If you don’t have dashboard access for your Sandbox account, please reach out to the government agency you’re working with to get access to their sandbox dashboard. Please reference [Login.gov’s developer documentation](https://developers.login.gov/testing/) for more information. --- ## (2) Select or create your application If your application is already created, select it from the list of applications and move to Step 4. If you haven’t created an application, select “Create a new test app.” ![A screenshot showing where to find the “Create a new test app” button in Login.gov "My app" listing.](https://images.workoscdn.com/images/96e14854-9acc-4ddd-8339-4312b80f7883.png) --- ## (3) Application Setup On the New test app page, select “Yes” under the Production configuration setting. Then, add an App name, Friendly name, and Description for the app. Next, assign an agency team to this client. ![A screenshot showing where to select “Yes” under the Production configuration setting as well as the add an App name, Friendly name, Description, and Team for the Login.gov app during setup.](https://images.workoscdn.com/images/ac9a9962-4058-4876-8fd8-4542f2b93711.png) Select "OpenID Connect Private Key JWT" as the Authentication protocol. Select the appropriate Level of Service, Default Authentication Assurance Level (AAL), and Attribute bundle for your application. ![A screenshot showing where to setup the Application protocol, Level of Service, Default Authentication Assurance Level, and Attributes Bundle during Login.gov application setup.](https://images.workoscdn.com/images/42b994de-61ac-4856-b954-12503cc3e45f.png) Next, you’ll need to define an Issuer - something like `urn:gov:gsa:openidconnect.profiles:sp:sso:agency_name:app_name` - replacing your agency and app name. Then, upload a logo and the public certificate file you downloaded from the WorkOS dashboard. ![A screenshot showing where to set the Issuer and upload a Logo and Public Certificate during Login.gov application setup.](https://images.workoscdn.com/images/f20e0870-1ec9-41d4-be5c-76103d177400.png) Finally, you’ll need to add the Redirect URIs. The first one you’ll need to add is the Redirect URI you copied from the WorkOS Dashboard. You’ll also need to add the [Redirect URI for your application](/sso/redirect-uris). There is a Content Security Policy (CSP) check from Login.gov, so all URIs that could potentially be redirected to the authentication flow should be listed here. ![A screenshot showing where to upload the Redirect URI during Login.gov application setup.](https://images.workoscdn.com/images/2fd99552-43e3-4a74-b211-97619af4f7de.png) Scroll down to the bottom of the page and select “Create test app” to finish the setup. --- ## (4) Provide the Client ID and Discovery Endpoint Enter the Issuer you created in the previous step as the Client ID in the WorkOS Dashboard. Additionally, add the discovery endpoint, which for production accounts in Login.gov is: `https://secure.login.gov/.well-known/openid-configuration`. Click “Update connection". ![A screenshot showing where to add the Client ID and Discovery Endpoint and Update Connection within the WorkOS Dashboard.](https://images.workoscdn.com/images/986718f3-0007-4894-9bd2-29892ff955d5.png?auto=format&fit=clip&q=50) --- ## (5) Request Production Deployment Please follow the [Login.gov docs to request a production deployment](https://developers.login.gov/production/) and finish your Login.gov application. ### LinkedIn OAuth Learn how to set up OAuth with LinkedIn ## Introduction The LinkedIn OAuth integration allows your users to authenticate using their LinkedIn credentials. The configuration process involves creating an OAuth application in LinkedIn and configuring the client credentials in your WorkOS Dashboard. --- ## What WorkOS provides When setting up LinkedIn OAuth, WorkOS provides one key piece of information that needs to be configured in your LinkedIn OAuth application: - [Redirect URI](/glossary/redirect-uri): The endpoint where LinkedIn will send authentication responses after successful login The Redirect URI is available in the [WorkOS Dashboard](https://dashboard.workos.com/). In the left navigation menu, select the **Authentication** tab and the **OAuth providers** sub-tab. Locate the **LinkedIn** section. ![The LinkedIn OAuth section in the WorkOS Dashboard.](https://images.workoscdn.com/images/d9cc3fce-75fc-410e-91d4-5706c88c609f.png?auto=format&fit=clip&q=50) Click **Enable**. The **LinkedIn OAuth** configuration dialog will open. Locate the **Redirect URI**. ![The LinkedIn OAuth configuration modal in the WorkOS Dashboard.](https://images.workoscdn.com/images/3b7a3d3e-391d-401f-92a4-74bfd57b0dc5.png?auto=format&fit=clip&q=50) The **Redirect URI** serves as the destination for authentication responses and must be configured in your LinkedIn OAuth application as an authorized redirect URL. --- ## What you'll need You will need to obtain two pieces of information from a LinkedIn Developer application: - **LinkedIn Client ID**: Application identifier from LinkedIn - **LinkedIn Client Secret**: Authentication secret for the application (called Primary Client Secret in LinkedIn) The following sections will guide you through creating an OAuth application in your LinkedIn Developer account and generating these credentials. --- ## (1) Create the LinkedIn OAuth application Log in to your LinkedIn account and navigate to the [LinkedIn Developer Portal](https://developer.linkedin.com). Click **Create app**. ![The LinkedIn page to register a new OAuth application.](https://images.workoscdn.com/images/75a8bb4c-8df2-4c9d-b205-5e9e07d31501.png?auto=format&fit=clip&q=80) Fill out the form with the required details about your application, including the application name, LinkedIn page, and app logo. ![The LinkedIn form to create a new OAuth application.](https://images.workoscdn.com/images/7da6ffdf-adda-4218-ac93-c2b211bfb12e.png?auto=format&fit=clip&q=80) Click **Create app** to create the application. --- ## (2) Configure OAuth settings and obtain client credentials On the application page, click the **Auth** tab. Copy the **Client ID** and **Primary Client Secret** as you'll need them for the WorkOS configuration. ![OAuth client credentials in the LinkedIn developer settings.](https://images.workoscdn.com/images/da63c1b4-44d3-43ca-a962-a1f7e641dc0e.png?auto=format&fit=clip&q=80) Click the pencil button next to **OAuth 2.0 settings** > **Authorized redirect URLs for your app**. Click **Add redirect URL** and paste the **Redirect URI** from the WorkOS Dashboard. Click **Update**. ![OAuth redirect URL in the LinkedIn developer settings.](https://images.workoscdn.com/images/9e838b55-e2c7-4b30-bf68-8531e7bf376a.png?auto=format&fit=clip&q=80) --- ## (3) Add OIDC support Click the **Products** tab and add the **Sign In with LinkedIn using OpenID Connect** product to enable OIDC authentication capabilities. ![The LinkedIn OIDC configuration dashboard.](https://images.workoscdn.com/images/f629579e-0ff1-42da-b1fc-40f577ae6723.png?auto=format&fit=clip&q=80) --- ## (4) Configure LinkedIn credentials in WorkOS Now that you have the **LinkedIn Client ID** and **LinkedIn Client Secret** (Primary Client Secret) from the previous steps, return to the [WorkOS Dashboard](https://dashboard.workos.com). In the **LinkedIn OAuth** configuration dialog, enable the integration. Paste the credentials from LinkedIn into their respective fields in the WorkOS Dashboard. ![The LinkedIn OAuth configuration modal in the WorkOS Dashboard.](https://images.workoscdn.com/images/053443da-9ab9-45a3-b345-4bc1cf0c6fd6.png?auto=format&fit=clip&q=50) Click **Save** to complete the configuration. You are now ready to start authenticating with LinkedIn OAuth. You will use the `provider` query parameter in the Get Authorization URL API endpoint to support global LinkedIn OAuth for any domain. The `provider` query parameter should be set to `LinkedInOAuth`. --- ## Frequently asked questions ### How is the WorkOS LinkedIn OAuth integration different from implementing regular LinkedIn OAuth flow? It's the same LinkedIn OAuth flow as you could build yourself, but it's encapsulated within WorkOS SSO. This means you don't need to build it yourself. In addition to LinkedIn OAuth, you can use WorkOS SSO to support other identity providers, all with a single integration. ### What is the provider query parameter and how is it used in the LinkedIn OAuth integration? You can use the `provider` query parameter in the [Get Authorization URL API endpoint](/reference/sso/get-authorization-url) to support global LinkedIn OAuth for any domain. The `provider` query parameter should be set to `LinkedInOAuth`. ### Do I need a LinkedIn Company Page to create an OAuth application? Yes, LinkedIn requires that OAuth applications be associated with a LinkedIn Company Page. This is a requirement from LinkedIn to ensure applications are associated with legitimate businesses or organizations. ### What is the difference between Client ID and Primary Client Secret in LinkedIn? The **Client ID** is the public identifier for your LinkedIn application, while the **Primary Client Secret** is the private authentication key that must be kept secure. The Primary Client Secret is what WorkOS refers to as the LinkedIn Client Secret. ### Why do I need to add the "Sign In with LinkedIn using OpenID Connect" product? This product enables OIDC (OpenID Connect) authentication capabilities for your LinkedIn application, which is required for the WorkOS integration to function properly. Without this product, the OAuth flow will not work correctly. ### LastPass Learn how to configure a connection to LastPass via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a LastPass SAML Connection, you’ll need an IdP Metadata XML file. Start by logging in to your WorkOS dashboard and browse to the “Organizations” tab on the left hand navigation bar. Select the organization you’d like to configure a LastPass SAML Connection for, and select “Manually Configure Connection” under “Identity Provider”. ![A screenshot showing where to find "Manually Configure Connection" in the WorkOS Dashboard.](https://images.workoscdn.com/images/ff2ce096-00e1-4d34-8523-23a01ebf4642.png?auto=format&fit=clip&q=50) Select “LastPass SAML” from the Identity Provider dropdown, enter a descriptive name for the connection, and then select the “Create Connection” button. ![A screenshot showing "Create Connection" details in the WorkOS Dashboard.](https://images.workoscdn.com/images/5866a365-5f51-4f58-9124-a4c0653831a5.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides WorkOS provides the [ACS URL](/glossary/acs-url), [SP Entity ID](/glossary/sp-entity-id), and [SP Metadata URL](/glossary/sp-metadata). They’re readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot showing where to find the ACS URL, SP Metadata, and SP Entity ID in the WorkOS Dashboard.](https://images.workoscdn.com/images/93089510-e362-47c9-9844-4eefd70e18ca.png?auto=format&fit=clip&q=50) --- ## What you’ll need Next, provide the [IdP Metadata](/glossary/idp-metadata) file. Normally, this information will come from your enterprise customer’s IT Management team when they set up your application’s SAML 2.0 configuration in their LastPass admin console. But, should that not be the case during your setup, the next steps will show you how to obtain it. --- ## (1) Select or create your application Log in to [LastPass](https://admin.lastpass.com/applications/saml), go to the admin console and select “Applications” on the top navigation. Then select “SSO apps” from the left side navigation. If your application is already created, select it from the list of applications and move to Step 2. Otherwise, select “Add app”. ![A screenshot showing "Add app" in the "SSO apps" section of the Applications tab in the LastPass admin dashboard.](https://images.workoscdn.com/images/e6cc5fbc-e802-4cd4-b3d6-786c31ee7db2.png?auto=format&fit=clip&q=50) In the modal that pops up, click on “Add an unlisted app”. ![A screenshot showing the selection of "Add an Unlisted App" for the creation of a new SSO app.](https://images.workoscdn.com/images/fad2dc44-73a1-4b98-b8bb-ee02e7293dfd.png?auto=format&fit=clip&q=50) Give your SAML App a descriptive name and select “Continue”. ![A screenshot showing how to add the name for a new SSO app.](https://images.workoscdn.com/images/839575b4-8b1c-45e5-ab10-8fcc509fc1be.png?auto=format&fit=clip&q=50) --- ## (2) Initial SAML Application Setup Under the “Set up LastPass” section of the “Configure app” modal, input the ACS URL from the WorkOS Dashboard Connection details under “ACS”. Then click on “Advanced Settings”. ![A screenshot showing where to add the ACS URL during the configuration app step in LastPass SAML Settings.](https://images.workoscdn.com/images/01e69cb0-8c93-474f-ad15-6cde111ac699.png?auto=format&fit=clip&q=50) Under “Entity ID”, input the SP Entity ID from the WorkOS Dashboard Connection details. Next, under “SAML signature method”, select “SHA256”. ![A screenshot showing where to add the Entity ID during the configuration app step in LastPass SAML Settings.](https://images.workoscdn.com/images/4b80975b-c0bb-4efd-80dd-3a3c52836ec5.png?auto=format&fit=clip&q=50) Under “Signing and encryption”, ensure that you have at least selected “Sign assertion”. Then, click on “Add SAML attribute”. ![A screenshot showing to select "Sign assertion" checkbox option for "Signing and encryption" in LastPass SAML Settings.](https://images.workoscdn.com/images/0e2a022f-444b-468b-91ad-cb2078142425.png?auto=format&fit=clip&q=50) --- ## (3) Configure SAML Application Map the following four attributes as shown below, and select “Save & assign users”. - First Name → `firstName` - Last Name → `lastName` - Email → `email` - User ID → `id` ![A screenshot showing hot to add Attribute Mapping for a LastPass SAML app.](https://images.workoscdn.com/images/3e75c892-a7cc-4167-9e45-c046232c1231.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, add a new SAML attribute for the "Groups" field and input `groups` as the attribute name, as shown below. Then, select "Save & assign users". ![A screenshot showing how to add a groups attribute to a LastPass SAML app.](https://images.workoscdn.com/images/611cd4d7-715b-423c-b110-323f00d7ad8c.png?auto=format&fit=clip&q=50) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (4) Add Users and Groups to SAML Application On the “Users, groups & roles” page, click on “Assign users, groups & roles”. ![A screenshot showing to select "Assign users, groups & roles" for your LastPass SAML app.](https://images.workoscdn.com/images/cec59ee3-85f1-45cd-8ed5-03dfef194de9.png?auto=format&fit=clip&q=50) Search and select any users or groups that you would like to provision to this SAML app. Then, click “Assign”. ![A screenshot showing to select Users and Groups in LastPass.](https://images.workoscdn.com/images/fc3fd859-1092-45a8-922f-38b4619863d8.png?auto=format&fit=clip&q=50) Click on “Save & continue”. ![A screenshot showing where to save and move to next steps in LastPass.](https://images.workoscdn.com/images/4b775f48-9045-4122-8c9c-4770370edd4b.png?auto=format&fit=clip&q=50) --- ## (5) Upload Metadata file Back on the “SSO apps” tab of the LastPass admin console, select the SAML app that you just created. !A screenshot showing where how to select SAML App in LastPass.](https://images.workoscdn.com/images/99a9a771-02bc-4817-b576-414bafa2d6f2.png?auto=format&fit=clip&q=50) On the “Configure app” modal, click on “Expand” to the right of “Set up app”. ![A screenshot showing how to expand Set Up App in LastPass.](https://images.workoscdn.com/images/e717af8d-f5aa-4629-ae38-d5d0376d57dd.png?auto=format&fit=clip&q=50) At the bottom of the “Set up app” section, click on “Download metadata (XML)”. Save the downloaded XML metadata somewhere accessible. ![A screenshot showing where to download Metadata File in LastPass.](https://images.workoscdn.com/images/bbd5f4bc-8386-4650-9559-f072b265d71b.png?auto=format&fit=clip&q=50) In the Connection settings in the WorkOS Dashboard, click “Edit Metadata Configuration”. ![A screenshot showing where to edit Metadata Configuration in WorkOS Dashboard.](https://images.workoscdn.com/images/c485258c-6762-4ea7-9999-a2a43767de23.png?auto=format&fit=clip&q=50) Upload the XML metadata file from LastPass into the “Metadata File” field and select “Save Metadata Configuration”. ![A screenshot showing a successful upload of the Metadata File in WorkOS Dashboard.](https://images.workoscdn.com/images/dd796b97-442e-4b74-a6ae-c5f2642b717a.png?auto=format&fit=clip&q=50) Your Connection will then be linked and good to go! ### Keycloak Learn how to configure a connection to Keycloak via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). And often, the information required to create a Connection will differ by Identity Provider. To create an Keycloak SAML Connection, you’ll need three pieces of information: an [ACS URL](/glossary/acs-url), an Identity Provider Issuer (also known as an Entity ID), and a Metadata URL. --- ## What WorkOS provides WorkOS provides the ACS URL and [IdP URI (Entity ID)](/glossary/idp-uri-entity-id). It’s readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot highlighting the "Service Provider Details" generated by WorkOS in the WorkOS Dashboard.](https://images.workoscdn.com/images/1ee74820-5075-4f2b-a1da-25f2c86204d4.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. In Keycloak’s case, it needs to be set by the organization when configuring your application in their Keycloak instance. Specifically, the ACS URL will need to be set as the “Valid Redirect URI” and "Master SAML Processing URL" in the SAML client setup in Keycloak. The Entity ID is a URI used to identify the issuer of a SAML request, response, or assertion. In this case, the entity ID is used to communicate that WorkOS will be the party performing SAML requests to the organization's Keycloak instance. Specifically, the Entity ID will need to be set as the “Client ID” when creating a SAML client in Keycloak. --- ## What you’ll need In order to integrate you’ll need the Keycloak Metadata URL. Normally, the this will come from the organization's IT Management team when they set up your application’s SAML client in their Keycloak instance. But, should that not be the case during your setup, here’s how to obtain it. --- ## (1) Log in Log in to your Keycloak Admin Console, and navigate to the Realm you want to set up the SAML client in. Select “Clients” from the side menu. If your client is already created, select it from the list of and move to Step 4. If you haven’t created a SAML client in Keycloak, select “Create client”. ![A screenshot highlighting the "Create client" button in the Keycloak dashboard.](https://images.workoscdn.com/images/ab144a33-174d-4699-83ad-fa5e59b9b31d.png?auto=format&fit=clip&q=50) --- ## (2) Initial SAML Application Setup On the Create Client setup step, select `SAML` as the "Client type", input the IdP URI (Entity ID) from your WorkOS Dashboard as the “Client ID”, and set a name for your Client. Click "Save". ![A screenshot highlighting the input fields "Client type", "Client ID" and "Name" in the Keycloak dashboard.](https://images.workoscdn.com/images/9365694a-b125-47e0-8d2e-1e49425e157b.png?auto=format&fit=clip&q=50) --- ## (3) Configure SAML Application On the Settings page, scroll down and input the ACS URL from your WorkOS Dashboard in the “Valid Redirect URIs” and "Master SAML Processing URL" boxes. ![A screenshot highlighting the fields "Valid redirect URIs" and "Master SAML Processing URL in the Keycloak dashboard.](https://images.workoscdn.com/images/a1dea2f2-ea25-44c9-b88e-39b689a37de2.png?auto=format&fit=clip&q=50) Scroll down further on the Settings page to "Signature and Encryption", and make sure that "Sign assertions" is toggled `On`. Click “Save”. ![A screenshot highlighting the "Sign documents" and "Sign assertions" toggles switched on in the Keycloak dashboard.](https://images.workoscdn.com/images/dfd9fc38-79b8-4c7d-8ca7-17d1925e8fa2.png?auto=format&fit=clip&q=50) --- ## (4) Configure User Attributes and Claims Click the “Client scopes” top menu option and click into your Client. ![A screenshot highlighting the "Client scopes" tab and "Assigned client scope" field in the Keycloak dashboard.](https://images.workoscdn.com/images/cc6c1ce7-229f-4d1e-90b2-ecf060649018.png?auto=format&fit=clip&q=50) Click "Configure a new mapper". ![A screenshot highlighting the "Configure a new mapper" button in the Keycloak dashboard.](https://images.workoscdn.com/images/3ed96fbb-d089-49ed-979b-2b360a498db0.png?auto=format&fit=clip&q=50&w=2048) Then select "User Property". ![A screenshot highlighting the "User Property" field in the Keycloak dashboard.](https://images.workoscdn.com/images/6f82859d-a433-4e3c-bde4-10b4700e5ba0.png?auto=format&fit=clip&q=50&w=2048) You’ll need to create a “User Property” mapper for the following four attributes: - `id` - `email` - `firstName` - `lastName` This is an example of how to fill out the fields for `id`: ![A screenshot showing the proper mapping for the "id" property in the Keycloak dashboard.](https://images.workoscdn.com/images/1d966f7c-358b-46a6-b8d5-cbcb6f80c192.png?auto=format&fit=clip&q=50&w=2048) Also do this for the `email`, `firstName`, and `lastName` attributes: ![A screenshot showing the proper mapping for the "email" property in the Keycloak dashboard.](https://images.workoscdn.com/images/7f753d8c-a7f3-4250-a772-0fb31bddfb03.png?auto=format&fit=clip&q=50&w=2048) ![A screenshot showing the proper mapping for the first name property in the Keycloak dashboard.](https://images.workoscdn.com/images/d037d45f-9d80-4594-b0d2-4ec65dd76d96.png?auto=format&fit=clip&q=50&w=2048) ![A screenshot showing the proper mapping for the last name property in the Keycloak dashboard.](https://images.workoscdn.com/images/0df763a9-7ca9-4bfb-870b-472bc3ef4b8b.png?auto=format&fit=clip&q=50&w=2048) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, follow the guidance below. On the "Dedicated scopes" page, select "Add mapper" and then "By configuration". ![A screenshot showing how to add a new groups attribute mapper.](https://images.workoscdn.com/images/6475d3b7-33b2-47f5-a55e-efd13600b1e0.png?auto=format&fit=clip&q=50) You can choose either "Group list" or "Role list", whichever option best fits your use case. The example below uses "Group list". For more information on sending group information, refer to the [Keycloak documentation](https://www.keycloak.org/docs/latest/server_admin/#assigning-permissions-using-roles-and-groups). ![A screenshot showing what type of mapper to choose for a groups attribute.](https://images.workoscdn.com/images/42a1cfbd-2499-46a7-bc3c-39b284f25e74.png?auto=format&fit=clip&q=50) Set the Name and the Group attribute name to "groups", and make sure the Single Group Attribute toggle is On. Select "Save". ![A screenshot showing how to configure the groups attribute mapper.](https://images.workoscdn.com/images/d95229b8-a5e1-4543-8047-077a38570b01.png?auto=format&fit=clip&q=50) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. ## (5) Obtain Identity Provider Details Select “Realm Settings” in the left sidebar navigation menu, and copy the “SAML 2.0 Identity Provider Metadata” link on the General page. ![A screenshot highlighting the "SAML 2.0 Identity Provider Metadata" button in the Keycloak dashboard.](https://images.workoscdn.com/images/166ae678-b776-470e-bf66-62bf202207e1.png?auto=format&fit=clip&q=50) Next, within your connection settings, edit the Metadata Configuration and provide the Metadata URL you obtained from Keycloak. Your Connection will then be verified and good to go! ![A screenshot highlight the "URL Metadata Configuration" input in the WorkOS Dashboard.](https://images.workoscdn.com/images/2579b65a-3d39-4344-8df4-6cdf80506c34.png?auto=format&fit=clip&q=50) ### JumpCloud SCIM Learn about syncing your user list with JumpCloud SCIM. ## Introduction This guide outlines how to synchronize your application’s JumpCloud directories using SCIM. To synchronize an organization’s users and groups provisioned for your application, you’ll need to provide the organization with two pieces of information: - An [Endpoint](/glossary/endpoint) that JumpCloud will make requests to. - A [Bearer Token](/glossary/bearer-token) for JumpCloud to authenticate its endpoint requests. Both of these are available in your Endpoint’s Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). > Steps 2, 3, and 4 below will need to be carried out by the organization when configuring your application in their JumpCloud instance. --- ## (1) Set up your Directory Sync endpoint Login to your WorkOS Dashboard and select “Organizations” from the left hand navigation bar. Select the organization you’ll be configuring a new Directory Sync for. Under “Actions” click “Add Directory”. ![A screenshot highlighting the "Add Directory" option within an Organization in the WorkOS Dashboard.](https://images.workoscdn.com/images/5411a8c2-cc56-4593-bc7c-c21c84443dfc.png?auto=format&fit=clip&q=50) Select “JumpCloud” from the dropdown, and enter the organization name. Then, click “Create Directory.” ![A screenshot highlighting the "Create Directory" modal for creating a JumpCloud directory in the WorkOS Dashboard.](https://images.workoscdn.com/images/6aaf218c-8d81-4ed6-aa8f-682dd3235dc2.png?auto=format&fit=clip&q=50) Your JumpCloud directory sync has now been created successfully with an Endpoint and Bearer Token. ![A screenshot highlighting the "Directory Details" for a JumpCloud directory in the WorkOS Dashboard.](https://images.workoscdn.com/images/eaad1aef-522e-4f01-a298-3a6b093aa8a1.png?auto=format&fit=clip&q=50) > We have support for custom labeled URLs for Directory Sync endpoints. [Contact us](mailto:support@workos.com) for more info! --- ## (2) Select or create your JumpCloud application Log in to the JumpCloud admin dashboard, select “SSO” on the left and select your Application. ![Select or Create JumpCloud App](https://images.workoscdn.com/images/26901dbc-8236-46b4-a46f-8c828152fe60.png?auto=format&fit=clip&q=50) If you haven’t created an application, you’ll need to first create a custom SAML application in JumpCloud. JumpCloud only supports configuring SCIM provisioning in an existing SAML application. You can use our JumpCloud SAML documentation to configure your SAML application before moving on to SCIM provisioning. --- ## (3) Configure your integration Select “Identity Management” from the top navigation menu. ![A screenshot highlighting the "SSO" tab and app selection in the JumpCloud admin dashboard.](https://images.workoscdn.com/images/58194668-19eb-4b3b-b07d-a5023d05e766.png?auto=format&fit=clip&q=50) Scroll down to the “Configuration settings” section. Make sure SCIM 2.0 is selected as the SCIM version. Copy and paste the Endpoint from your [WorkOS Dashboard](https://dashboard.workos.com/) in the “Base URL” field. Then, copy and paste the Bearer Token from your [WorkOS Dashboard](https://dashboard.workos.com/) into the “Token Key” field. Next, test the connection to confirm the configuration settings. ![A screenshot highlighting the "Base URL" and "Token Key" input fields in the JumpCloud admin dashboard.](https://images.workoscdn.com/images/6096c0db-b7f6-45ea-aa44-b1f53f167d12.png?auto=format&fit=clip&q=50) After you receive a success message for the configuration, make sure the Group Management toggle is “On”, and then activate the settings. ![A screenshot highlight the "Group Management" field toggled on in the JumpCloud admin dashboard.](https://images.workoscdn.com/images/aa71e757-ec72-4f72-9551-cd43e72cf44b.png?auto=format&fit=clip&q=50) After the activation step is successful, save the configuration. ![A screenshot highlighting the "Save" button in the JumpCloud admin dashboard.](https://images.workoscdn.com/images/3a8a81bc-e204-4368-b281-6aec5666b817.png?auto=format&fit=clip&q=50) --- ## (4) Assign users and groups to your application In order for your users and groups to be synced, you will need to assign them to your JumpCloud Application. Select “User Groups” from the top navigation menu. Select the groups of users you would like to sync and save your changes. ![A screenshot highlighting the User Groups tab in the JumpCloud admin dashboard.](https://images.workoscdn.com/images/505e3ec4-0f83-4e68-a384-1d056f674b23.png?auto=format&fit=clip&q=50) Begin provisioning users and groups and witness realtime changes in your [WorkOS Dashboard](https://dashboard.workos.com/). A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) ## Frequently asked questions ### When a group is disconnected from the SCIM application in JumpCloud, I still see users that are a part of that disconnected group in WorkOS and my application – is this expected? Instead of individually assigning users to a SCIM application, JumpCloud SCIM requires that users are assigned to the application through group membership. To reflect valid user membership in your application, users should be removed from a group while the group is connected to the SCIM application rather than removing them directly from the application. To remove an entire group, the group can be deleted from the JumpCloud User Management area while it is connected to the SCIM application. ### What is the `idp_id` for directory groups from JumpCloud? JumpCloud provides a unique identifier for each group through the SCIM `externalId` field. This is persisted as the `idp_id` for [directory groups](/reference/directory-sync/directory-group) in WorkOS. ### JumpCloud SAML Learn how to configure a connection to JumpCloud via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a JumpCloud SAML Connection, you’ll need to upload a JumpCloud Metadata file. --- ## What WorkOS provides WorkOS provides the [ACS URL](/glossary/acs-url) and [SP Entity ID](/glossary/sp-entity-id). They’re readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot of the "Service Provider Details" of a JumpCloud Connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/77d299b3-4e00-4259-9580-3a5d47518f7a.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. In JumpCloud’s case, the ACS URL and Entity ID need to be set by the organization when configuring your application in their JumpCloud instance. Specifically, the ACS URL and Entity ID will need to be set in the “Single Sign-On Configuration” section of the SAML app. You will input the ACS URL for “ACS URL” and the Entity ID as both “IdP Entity ID” and “SP Entity ID”: ![A screenshot highlighting the fields "IdP Entity ID", "SP Entity ID" and "ACS URL" in the JumpCloud dashboard.](https://images.workoscdn.com/images/5897416a-465f-4e71-a2f8-2c12329338b9.png?auto=format&fit=clip&q=50) --- ## What you’ll need In order to integrate you’ll need the JumpCloud Metadata file. Here’s how to obtain it: --- ## (1) Log in Log in to the JumpCloud admin dashboard, select “SSO” on the left and select your Application. ![A screenshot highlighting the SSO tab and app selection in the JumpCloud dashboard.](https://images.workoscdn.com/images/e144fd63-e8a0-40e3-9d6d-db113396b7f8.png?auto=format&fit=clip&q=50) --- ## (2) Configure Attribute Mapping In the “User Attributes” section of the Single Sign-On Configuration page for the SAML app, add the following field-value parameter pairs: - `id` → `email` - `email` → `email` - `firstName` → `firstname` - `lastName` → `lastname` ![A screenshot showing user attribute mapping in the JumpCloud dashboard.](https://images.workoscdn.com/images/47100088-c7b5-4352-96e1-9709f7808b6b.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, follow the guidance below. In the "Group Attributes" section, select the checkbox to "include group attribute", and then set the attribute name to `groups`. ![A screenshot showing 'Group Attributes' in the JumpCloud Admin Console.](https://images.workoscdn.com/images/b6f9fdc0-c660-41ce-8f8e-a99a8c5a4cf0.png?auto=format&fit=clip&q=50) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. ### Check "Sign Assertion" Be sure to check the “Sign Assertion” box shown below. ![A screenshot highlighting the checked "Sign Assertion" box in the JumpCloud dashboard.](https://images.workoscdn.com/images/e4cca1f9-3f24-45d6-80f7-3ef318eb4ba2.png?auto=format&fit=clip&q=50) --- ## (3) Upload Metadata File Be sure to check “Declare Redirect Endpoint”. ![A screenshot highlighting the checked "Declare Redirect Endpoint" box in the JumpCloud dashboard.](https://images.workoscdn.com/images/3a24425c-dd94-4b86-8b3a-f476b6f55665.png?auto=format&fit=clip&q=50) > NOTE: The "Declare Redirect Endpoint" setting needs to be enabled prior to exporting the IdP metadata below as this will alter the metadata. Click the “Export Metadata” button under “JumpCloud Metadata”. This will download an XML metadata file. ![A screenshot highlighting the "Export Metadata" button in the JumpCloud dashboard.](https://images.workoscdn.com/images/abd1a6ff-ec7b-427b-b7d5-0813af0107ee.png?auto=format&fit=clip&q=50) In the Connection Settings of the WorkOS Dashboard, click “Edit Metadata Configuration”. ![A screenshot highlighting the "Edit Metadata Configuration" button in the WorkOS Dashboard.](https://images.workoscdn.com/images/ead92f35-be05-431f-a987-e4a71745eb3f.png?auto=format&fit=clip&q=50) In the modal that pops up, upload the JumpCloud Metadata file and then select “Save Metadata Configuration”. ![A screenshot showing the "XML File Metadata Configuration" modal in the WorkOS Dashboard.](https://images.workoscdn.com/images/060d5353-64ca-426a-a4f2-1b9290aad3f5.png?auto=format&fit=clip&q=50) Once the file has uploaded, your Connection will then be linked and good to go! ### HiBob Learn about syncing your user list with HiBob. ## Introduction This guide outlines how to synchronize your application’s HiBob directories. To synchronize an organization’s users and groups provisioned for your application, you’ll need the enterprise IT admin to provide you: - A HiBob Service User ID. - The HiBob Service User’s Token. We will provide instructions below on the process in HiBob to create a Service User and collect those parameters. > Note: The HiBob integration isn't enabled by default in the WorkOS Dashboard or Admin Portal. Please reach out to [support@workos.com](mailto:support@workos.com) or via your team’s WorkOS Slack channel if you would like HiBob enabled. --- ## (1) Set up your Directory Login to your WorkOS dashboard and select “Organizations” from the left hand Navigation bar Select the Organization you’d like to enable a HiBob Directory Sync connection for. On the Organization’s page click “Manually Configure Directory”. ![A screenshot highlighting the "Manually Configure Directory" button in the Organization view of the WorkOS Dashboard.](https://images.workoscdn.com/images/66f8d2e8-6337-4e67-97cf-1fcf9ae0a8cb.png?auto=format&fit=clip&q=50) You’ll be prompted to select “HiBob” from the “Directory Type Dropdown”, as well as enter the name of the directory. Then click “Create Directory”. ![A screenshot highlighting the "Create Directory" modal for creating a HiBob directory in the WorkOS Dashboard.](https://images.workoscdn.com/images/0b8c4bdb-e745-4285-a208-3463631766c0.png?auto=format&fit=clip&q=50) WorkOS will create a Directory Sync Connection where you will input a “Service User ID” and an “API Token”. The next step will walk you through how an organization IT admin can generate and gather these details. ![A screenshot highlighting the "Update Directory" button in a HiBob directory in the WorkOS Dashboard.](https://images.workoscdn.com/images/f47caea6-5218-4957-b8a1-3c3512ec52f0.png?auto=format&fit=clip&q=50) --- ## (2) Create a Service User in HiBob HiBob uses a system called Service Users to utilize API actions. These steps walkthrough creating a Service User and obtaining the credentials needed by WorkOS to link with HiBob successfully. Login to HiBob and navigate to “Settings” and then selecting the “Integrations” tab. There will be a tile called Service Users, click on that. ![A screenshot highlighting the "Integrations" tab in the HiBob dashboard.](https://images.workoscdn.com/images/e240994a-4968-40ce-a75b-e3951ce0ac81.png?auto=format&fit=clip&q=50) Press on the New Service user Button The user will be prompted to enter a name (and display name, these can be the same) for the new service user, we recommend something like “WorkOS SCIM User”. ![A screenshot showing the "Create a new Service User" modal in the HiBob dashboard.](https://images.workoscdn.com/images/03b23b02-f8d2-4b33-b7f3-02db9dfaee15.png?auto=format&fit=clip&q=50) HiBob will then present you with an ID and a Token, which will be populated into WorkOS, so make sure to inform the customer to provide these. ![A screenshot highlighting the "ID" and "Token" fields for a Service User in the HiBob dashboard.](https://images.workoscdn.com/images/81d6408a-0f04-4486-8864-cf9c08928d86.png?auto=format&fit=clip&q=50&w=2048) The enterprise IT admin should make sure that the Service User has permissions to “View selected employees lifecycle sections”. --- ## (3) Input the HiBob Service User details in WorkOS Back in the connection that was created in your WorkOS dashboard, enter these two fields and press “Save Directory Details.” ![A screenshot highlighting the Directory Details modal of a HiBob directory in the WorkOS Dashboard.](https://images.workoscdn.com/images/8bd8dd85-864f-4712-98ac-788821b3b705.png?auto=format&fit=clip&q=50) You should see the connection now displays “Linked” in green. --- ## (4) View users and groups in your dashboard You will now see updates to the users in the directory under the “Users” tab in the HiBob Directory Sync page in WorkOS. ![A screenshot showing the "Users" view of a HiBob directory in the WorkOS Dashboard.](https://images.workoscdn.com/images/8474708e-dd99-472e-aba4-337c8463551d.png?auto=format&fit=clip&q=50) --- ## Frequently asked questions ### What if the directory user profiles from HiBob aren't showing all of the expected user attributes, such as the user address? If some user attributes are not being sent along in the profile, you’ll want to start by checking the permissions of the Service User you created in step 2. You can see more about accessing Service User permissions [here](https://apidocs.hibob.com/docs/api-service-users) and some relevant FAQs from HiBob [here](https://help.hibob.com/hc/en-us/articles/4409776408209#how-to-review-permission-group-changes-0-4). ### How often do HiBob directories perform a sync? HiBob directories poll every 30 minutes starting from the time of the initial sync. ### Google SAML Learn how to configure a connection to Google Workspace via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [connection](/glossary/connection). Often, the information required to create a connection will differ by Identity Provider. To create a Google SAML connection, you’ll need three pieces of information: an [ACS URL](/glossary/acs-url), a [SP Entity ID](/glossary/sp-entity-id), and an [IdP Metadata URL](/glossary/idp-metadata). Start by logging into your [WorkOS Dashboard](https://dashboard.workos.com/) and selecting “Organizations” from the left hand navigation bar. Click on the organization you’d like to configure a Google SAML connection for and select “Manually Configure Connection”. ![A screenshot showing where to find “Manually Configure Connection” for an Organization in the WorkOS Dashboard.](https://images.workoscdn.com/images/26e7f2ca-7d61-4f02-9a67-f3bfbc254ba3.png?auto=format&fit=clip&q=50) Select “Google Workspace SAML” from the Identity Provider dropdown, enter a descriptive name for the connection, and then select the “Create Connection” button. ![A screenshot showing how to create a connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/7f2f8f2b-22d1-443c-a692-5eb7fa506042.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides WorkOS provides the ACS URL and the SP Entity ID. It’s readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot showing where to find the ACS URL and SP Entity ID in the WorkOS Dashboard.](https://images.workoscdn.com/images/1d07cb61-b23a-4894-ab9b-fd97d5bc6d6b.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. In Google’s case, it needs to be set by the organization when configuring your application in their Google admin dashboard. The SP Entity ID is a URI used to identify the issuer of a SAML request, response, or assertion. In this case, the entity ID is used to communicate that WorkOS will be the party performing SAML requests to the organization's Google instance. Specifically, the ACS URL will need to be set as the “ACS URL” and the SP Entity ID will need to be set as the “Entity ID” in the “Service Provider Details” step of the Google SAML setup. --- ## What you’ll need In order to integrate you’ll need the metadata XML file from Google. Normally, this information will come from the organization's IT Management team when they set up your application’s SAML 2.0 configuration in their Google admin dashboard. But, should that not be the case during your setup, here’s how to obtain it. --- ## (1) Log in Log in to the Google Admin dashboard, select “Apps” from the sidebar menu, and then select “Web and Mobile Apps” from the following list. If your application is already created, select it from the list of applications and move to Step 7. If you haven’t created a SAML application, select “Add App” and then “Add custom SAML app”. ![A screenshot showing where to find "Add custom SAML app" in the Google Dashboard.](https://images.workoscdn.com/images/1a0abd99-4e2c-403f-89b9-a3fd11d6fb9a.png?auto=format&fit=clip&q=50) --- ## (2) Enter Your App’s Information Give the app a descriptive name and upload an icon, if applicable. Click “Continue”. ![A screenshot showing where to add app name in the Google Dashboard.](https://images.workoscdn.com/images/89ae0c9e-becf-4076-8178-7d4535eac778.png?auto=format&fit=clip&q=50) --- ## (3) Obtain Identity Provider Details Select the “Download Metadata” button to download the metadata file. Save this file, as you’ll upload it to the WorkOS Dashboard in Step 7. Click “Continue”. ![A screenshot showing where to find "Download Metadata" in the Google Dashboard.](https://images.workoscdn.com/images/92b16c09-8b06-4b8b-b4a0-2f441fd3d878.png?auto=format&fit=clip&q=50) --- ## (4) Enter Service Provider Details Copy and the “ACS URL” from your WorkOS Dashboard and paste it into the “ACS URL” field, and copy the “SP Entity ID” from your WorkOS Dashboard and paste it into the “Entity ID” field in the Google SAML “Service provider details” modal. Select “Continue.” ![A screenshot showing where to enter "Entity ID" and "ACS URL" in the Google Dashboard.](https://images.workoscdn.com/images/946113dc-812e-446d-b466-32eec2b27629.png?auto=format&fit=clip&q=50) --- ## (5) Configure Attribute Mapping Provide the following Attribute Mappings and select “Finish”. Google SAML does not provide the option to map a user’s id attribute claim. ![A screenshot showing completed Attribute Mappings in the Google Dashboard.](https://images.workoscdn.com/images/dcf0968a-346c-4a58-bd76-8e0a87d92d66.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, follow the guidance below. Scroll down to the "Group membership" section. Add any groups you'd like to send under "Google groups", and set the "App attribute" to "groups". Then, select "Finish". ![A screenshot showing how to add a group attribute in the Google dashboard.](https://images.workoscdn.com/images/b7a6e5f7-aaf1-4756-9fc9-04f70f1c8a67.png?auto=format&fit=clip&q=50) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (6) Configure User Access In the created SAML app’s landing page, select the “User Access Section”. ![A screenshot showing where to find the "User Access Section" in the Google Dashboard.](https://images.workoscdn.com/images/57080072-5a42-4463-897b-2382c643082a.png?auto=format&fit=clip&q=50) Turn this service ON for the correct organizational units in your Google Directory setup. Save any changes. Google may take up to 24 hours to propagate these changes. The connection in WorkOS will be inactive until then. --- ## (7) Upload Metadata File If you haven’t already downloaded the metadata file, select your SAML application, and click “Download Metadata”. In the modal, again click “Download Metadata”. ![A screenshot showing where to find "Download Metadata" in the Google Dashboard.](https://images.workoscdn.com/images/7e1a8f1f-fb44-435d-961a-d71eff48d207.png?auto=format&fit=clip&q=50) In the connection Settings of the WorkOS Dashboard, click “Edit Metadata Configuration”. ![A screenshot showing the “Edit Metadata Configuration” button in the WorkOS Dashboard.](https://images.workoscdn.com/images/afe34aca-df4f-4005-b71e-bf528916a491.png?auto=format&fit=clip&q=50) In the modal, upload the Google Metadata file and then select “Save Metadata Configuration”. Once the file is uploaded into WorkOS, your connection will then be linked and good to go! ![A screenshot showing a linked Google SAML connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/9c497a05-f823-4c51-ab54-e5b6feed53fa.png?auto=format&fit=clip&q=50) --- ## Frequently asked questions ### Where is the Relay State in Google SAML? Within the Google SAML setup, there will be a field called “Start URL” which is referred to as the Relay State. ### Google OIDC Learn how to configure a connection to Google via OIDC. ## Introduction Each SSO identity provider requires specific information to create and configure a new [SSO connection](/glossary/connection). Often, the information required to create an SSO connection will differ by identity provider. To create a Google OIDC SSO connection, you'll need three pieces of information: a [redirect URI](/glossary/redirect-uri), [client ID](/glossary/client-id), and [client secret](/glossary/client-secret). Start by logging in to your WorkOS dashboard and navigate to the **Organizations** page from the left-hand navigation bar. Select the organization you'd like to configure a Google OIDC SSO connection for, and select **Configure manually** under **Single Sign-On**. ![WorkOS Dashboard Organizations tab with "Configure manually" button highlighted](https://images.workoscdn.com/images/d577cfbe-028b-48cf-8cc0-4cd5d3adf853.png?auto=format&fit=clip&q=50) Select **Google OIDC** from the identity provider dropdown, click **Create Connection**. ![Create Connection form with Google OIDC selected as Identity Provider](https://images.workoscdn.com/images/35cfe8ab-1825-4f0d-ab93-7c0eb6e0d742.png?auto=format&fit=clip&q=50) > Google OIDC is not available when [SSO group role assignment](/sso/identity-provider-role-assignment) is enabled due to [a limitation](https://issuetracker.google.com/issues/133774835?pli=1) with the groups claim. --- ## What WorkOS provides WorkOS provides the Redirect URI, which can be found in the **Service Provider Details** section on the SSO connection page in the [WorkOS Dashboard](https://dashboard.workos.com/). - [Redirect URI](/glossary/redirect-uri): The endpoint where identity providers send authentication responses after successful login ![The Redirect URI of a OIDC connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/99a7c7d5-50a9-4bff-a3f3-22dc1cfeca58.png?auto=format&fit=clip&q=50) The Redirect URI is the location an identity provider redirects its authentication response to. In Google's case, it needs to be set as an **Authorized redirect URI** when configuring your OAuth client in the Google Cloud Console. Specifically, the Redirect URI will need to be added to the **Authorized redirect URIs** section when creating your OAuth client, which is outlined in [step 3](/integrations/google-oidc/3-create-oauth-client) below. --- ## What you'll need You will need to obtain two pieces of information from the organization: - [Client ID](/glossary/client-id): Application identifier from the OIDC provider - [Client secret](/glossary/client-secret): Authentication secret for the application Normally, this information will come from the organization's IT management team when they set up your application's OAuth configuration in their Google Cloud Console. But, should that not be the case during your setup, the next steps will show you how to obtain it. --- ## (1) Create a Google Cloud project (optional) > If you already have a Google Cloud project, skip this step. Sign in to the [Google Cloud Console](https://console.cloud.google.com). From the top left navigation, click **Select a project**. Select an organization and then click **Create project**. ![Google Cloud Console project selector with "Create project" option](https://images.workoscdn.com/images/941eaf2f-b6a3-4c86-83aa-4cb005dbc1e4.png?auto=format&fit=clip&q=50) Enter a project name. Update the project organization and location if needed. Click **Create**. ![Google Cloud project creation form with project name, organization, and location fields](https://images.workoscdn.com/images/b7cd689d-0e89-4eee-8f32-f6b93522fed1.png?auto=format&fit=clip&q=50) --- ## (2) Configure OAuth app From the top left navigation, click **Select a project**. Select the project you created in the previous step or one that is already set up. ![Google Cloud Console project selector dropdown with available projects](https://images.workoscdn.com/images/675794e5-9a6d-42cc-8d68-46e58a29caab.png?auto=format&fit=clip&q=50) Search for **Google Auth Platform** and select it from the results list. ![Google Cloud Console search results showing Google Auth Platform service](https://images.workoscdn.com/images/ef574ce6-3402-4dbe-9e3e-4d3d00d82212.png?auto=format&fit=clip&q=50) Click **Get started**. ![Google Cloud OAuth App dashboard with highlighted get started button](https://images.workoscdn.com/images/2e35fd83-74db-45b4-ad13-510fb52b57b0.png?auto=format&fit=clip&q=50) On the **App Information** step, enter an app name, such as your organization name. Select a user support email from the dropdown. Click **Next**. ![OAuth consent screen App Information step with app name and user support email fields](https://images.workoscdn.com/images/2365ee0a-497b-4235-9d08-e9e740a140f0.png?auto=format&fit=clip&q=50) On the **Audience** step, select **Internal** and click **Next**. ![OAuth consent screen Audience step with Internal option selected](https://images.workoscdn.com/images/e3689b48-4ada-43a6-818f-244cfebf0393.png?auto=format&fit=clip&q=50) On the **Contact Information** step, enter a contact email and click **Next**. ![OAuth app information screen with contact information field highlighted and demo@foo-corp.com email filled in, next button is highlighted](https://images.workoscdn.com/images/7ef6519e-dc76-473b-901f-388e69762433.png?auto=format&fit=clip&q=50) Agree to the terms of service, click **Continue** and then **Create**. ![OAuth consent screen terms of service acceptance and Create button](https://images.workoscdn.com/images/e211e959-1325-4dfc-8a8c-96d4ee0030cf.png?auto=format&fit=clip&q=50) --- ## (3) Create OAuth client From the left-hand sidebar navigation, click **Clients** and then click **Create client**. ![Google Auth Platform Clients page with "Create client" button](https://images.workoscdn.com/images/24e008c1-4a8e-4bfe-8603-1074453a815b.png?auto=format&fit=clip&q=50) From the **Application type** dropdown, select **Web application**. ![OAuth client creation form with Web application selected as application type](https://images.workoscdn.com/images/17bc8607-23be-457f-9cf1-995730748d55.png?auto=format&fit=clip&q=50) Under the **Authorized redirect URIs** section, click **Add URI**. Copy the Redirect URI from your WorkOS Dashboard and paste it into the new redirect URI field. ![Authorized redirect URIs section with Add URI button and WorkOS redirect URI field](https://images.workoscdn.com/images/b98e091f-9005-4a1f-bfb9-56eb26a88844.png?auto=format&fit=clip&q=50) Click **Create**. --- ## (4) Add organization settings From the **OAuth client created** modal, copy the **Client ID** and **Client Secret** values. ![OAuth client created modal displaying Client ID and client secret](https://images.workoscdn.com/images/51a44c08-a559-456b-926f-33334d7cb755.png?auto=format&fit=clip&q=50) Back in the WorkOS Dashboard, enter the client ID, and client secret you obtained from Google into the respective fields in the **Identity Provider Configuration** section of the SSO connection. Enter `https://accounts.google.com/.well-known/openid-configuration` in the **Discovery Endpoint** field, this is the same value for all Google Cloud Console projects. ![WorkOS Dashboard Identity Provider Configuration with Client ID, Client Secret, and Discovery Endpoint fields](https://images.workoscdn.com/images/d3305808-a772-4f2a-a7e1-c862b9274975.png?auto=format&fit=clip&q=50) Click **Save Configuration**. --- ## Next steps Your Google OIDC connection is now configured and ready to use. Users within your organization will be able to authenticate through WorkOS using their Google credentials. To start using this connection in your application, refer to the [SSO guide](/sso) for implementation details. ### Google OAuth Learn how to set up OAuth with Google Workspace ## Introduction The Google OAuth integration allows your users to authenticate using their Google Workspace credentials. The configuration process involves obtaining client credentials from your Google Cloud Platform Console and configuring them in the WorkOS Dashboard. --- ## Testing with default credentials in the staging environment WorkOS provides a default Google Client ID and Client Secret combination, which allows you to quickly enable and test Google OAuth. Use the [WorkOS API to initiate SSO](/sso/1-add-sso-to-your-app/add-an-endpoint-to-initiate-sso), setting the `provider` parameter to `GoogleOAuth`, and WorkOS will automatically use the default credentials until you add your own Google Client ID and Client Secret to the configuration in the WorkOS Dashboard. > The default credentials are only intended for testing and therefore only available in the Staging environment. For your production environment, please follow the steps below to create and specify your own Google Client ID and Client Secret. Please note that when you are using WorkOS default credentials, Google's authentication flow will display WorkOS' name, logo, and other information to users. Once you register your own application and use its Google Client ID and Client Secret for the OAuth flow, you will have the opportunity to customize the app, including its name, logo, contact email, etc. --- ## What WorkOS provides When setting up Google OAuth, WorkOS provides one key piece of information that needs to be configured in your Google Cloud Platform project: - [Redirect URI](/glossary/redirect-uri): The endpoint where Google will send authentication responses after successful login The Redirect URI is available in the [WorkOS Dashboard](https://dashboard.workos.com/). In the left navigation menu, select the **Authentication** tab and the **OAuth providers** sub-tab. Locate the **Google** section. ![Open the Google configuration dialog](https://images.workoscdn.com/images/1e400f3e-1885-481f-8840-4a3a9f8c7f97.png?auto=format&fit=clip&q=50) Click **Manage**. The **Google OAuth** configuration dialog will open. Locate the **Redirect URI**. ![Google OAuth Redirect URI in the WorkOS Dashboard.](https://images.workoscdn.com/images/020273f1-d216-4aca-8ddd-8963accd7517.png?auto=format&fit=clip&q=50) The **Redirect URI** serves as the destination for authentication responses and must be configured in your Google Cloud Platform project as an authorized redirect URI. --- ## What you'll need You will need to obtain two pieces of information from a Google Cloud Platform project: - **Google Client ID**: Application identifier from Google Cloud Platform - **Google Client Secret**: Authentication secret for the application The following sections will guide you through generating these credentials in your Google Cloud Platform Console. --- ## (1) Access Google Cloud Platform Console Sign in to the [Google Cloud Platform Console Dashboard](https://console.cloud.google.com/) and select your application's project from the project selection dropdown menu in the navigation bar. ![How to select your application in the Google Cloud Platform Console Dashboard.](https://images.workoscdn.com/images/45adf7cf-78e0-4c5a-a6c1-7b3eee62c723.png?auto=format&fit=clip&q=50) --- ## (2) Configure OAuth consent screen In the left navigation menu, select **APIs & Services** and then **OAuth Consent Screen**. ![Where to find the OAuth Consent Screen option in the Google Cloud Platform Console Dashboard.](https://images.workoscdn.com/images/c37375e2-6ef2-41ba-9b65-a125501bfd5a.png?auto=format&fit=clip&q=50) Now within the **Google Auth Platform**, in the left navigation menu, select **Clients**. Click **Create client**. ![How to create a new client in the Google Cloud Platform Console Dashboard.](https://images.workoscdn.com/images/c5ffe36c-e471-4b27-a6b9-936d26837e93.png?auto=format&fit=clip&q=50) In the **Application type** dropdown, select **Web application**. Provide an appropriate name for your OAuth client ID. > As a best practice, your OAuth client ID's name should be different from your application's name. It will not be shown to end users. Under the **Authorized redirect URIs** section, click **Add URI**. Add the **Redirect URI** from the WorkOS Dashboard. ![Where to enter your WorkOS Redirect URI in the Google Cloud Platform Console Dashboard.](https://images.workoscdn.com/images/e18673f7-e490-46a7-ad0c-f71d5ddcb08a.png?auto=format&fit=clip&q=50) Scroll down and click **Create**. It may take up to 5 minutes, but once your OAuth client is created, you'll be presented with your application's client ID and client secret. Be sure to copy these values as they may not be available after closing the dialog. ![The client ID and client secret in the Google Cloud Platform Console Dashboard.](https://images.workoscdn.com/images/13a05048-c45c-43c5-9d56-39faf53ab479.png?auto=format&fit=clip&q=50) --- ## (4) Configure Google credentials in WorkOS Now that you have the **Google Client ID** and **Google Client Secret** from the previous step return to the [WorkOS Dashboard](https://dashboard.workos.com). In the **Google OAuth** configuration dialog, select **Your app's credentials**. Paste the credentials from Google into their respective fields in the WorkOS Dashboard. ![Where to enter the Google Client ID and Google Client Secret in the WorkOS Dashboard.](https://images.workoscdn.com/images/6c209570-926d-49bf-9189-0e2f705e70ee.png?auto=format&fit=clip&q=50) Click **Save** to complete the configuration. --- ## (5) Publish the Google OAuth application In the left navigation menu of the Google Cloud Platform Console, select the **Audience** tab. If your application is not **In production**, click **Publish app**. In the **Push to Production?** dialog that opens, click **Confirm**. If your application is still in testing mode, users will likely get an "Access Blocked" error when attempting to log into your app. ![The publishing status of your Google OAuth application](https://images.workoscdn.com/images/564bc12f-0abb-4866-8a48-eb9451b851fb.png?auto=format&fit=clip&q=50) After that, you're now able to authenticate users with Google OAuth. You will use the `provider` query parameter in the Get Authorization URL API endpoint to support global Google OAuth for any domain. The `provider` query parameter should be set to `GoogleOAuth`. --- ## Customize Google OAuth Domain (Optional) This optional process requires access to your Google Cloud Console and your domain's DNS settings. After implementing the steps above, you'll notice that the Google OAuth sign in form displays "Choose an account to continue to workos.com". This is based on the Authorized Redirect URI in Google. To set this to a domain other than workos.com, Google will ask for proof of ownership of your domain. To help guide you through this process we have a self-service flow. ### (1) Add your custom Google OAuth domain In the **Authentication** tab of the WorkOS Dashboard, find the **Google OAuth** section. Depending on which WorkOS products have been enabled, the **Google OAuth** section may be under the **Methods** or **OAuth providers** sub-tabs in the left navigation menu. Click **Setup Custom Domain**. > Note: This button will only appear if your environment has a valid Google OAuth configuration and a custom domain has not already been configured. ![Where to find the Set Up Custom Domain button in the WorkOS Dashboard.](https://images.workoscdn.com/images/9ba10d03-c0af-41e6-b090-884ba1cddca4.png?auto=format&fit=clip&q=50) Under **Add Custom Domain**, input the domain that you wish to use in place of `auth.workos.com`. This is often a subdomain such as `auth.example.com`. Click on **Set Domain**. ![Where to add a custom domain in the WorkOS Dashboard.](https://images.workoscdn.com/images/d233701c-74c5-4a42-a063-9eaa680dc7c9.png?auto=format&fit=clip&q=50) ### (2) Add CNAME target Add a new CNAME target inside your domain's DNS settings. Set the host to match the domain you set in the previous step and set the value to `cname.workosdns.com`. Once the above is complete, click **Verify DNS**. This verification often takes less than a minute, but is dependent on how long your DNS record takes to propagate. The page will continue polling to check the status of your verification until it is successful. ![The CNAME target of cname.workosdns.com in the WorkOS Dashboard.](https://images.workoscdn.com/images/feebf1a1-1f42-4c0b-b1fc-67d37745b948.png?auto=format&fit=clip&q=50) ### (3) Add new redirect URI to Google Once the DNS has been successfully verified, WorkOS will provide a URI starting with your subdomain in the **Add redirect URI to Google** section. Click on the clipboard icon to copy the URL. ![The clipboard icon in the WorkOS Dashboard.](https://images.workoscdn.com/images/95060659-da91-40d8-849b-9718ef7b00fc.png?auto=format&fit=clip&q=50) In the Google Cloud Platform Console, under your project's **APIs & Services** → **Clients** section, add the URL copied above in the **Authorized redirect URIs** section. To ensure your Google OAuth integration continues to work without any gaps in service, leave your existing redirect URI in place for now. ![Where to enter the redirect URI in the Google Cloud Platform Console.](https://images.workoscdn.com/images/548b4e3e-164e-4358-ab1d-58c5d3071731.png?auto=format&fit=clip&q=50) ### (4) Test Google redirect URI Once the URL has been added and saved on the Google side, navigate back to the WorkOS Dashboard and click on **Test Google Redirect URI**. ![The Test Google Redirect URI button in the WorkOS Dashboard.](https://images.workoscdn.com/images/1e191eb9-a316-407e-ae63-69be88ac3665.png?auto=format&fit=clip&q=50) If the test is successful, you will see a **Successfully tested** message displayed. Click **Save custom Google OAuth settings**. Once these updates have been saved, test out your Google OAuth sign in flow to ensure everything is working properly and your domain is displayed on the form. If everything is looking good, it is safe to remove the old `auth.workos.com` URL from your Google Authorized redirect URIs, and `workos.com` from your Google Authorized domains. --- ## Configure Additional OAuth Scopes (Optional) WorkOS will request the OAuth scopes that are required for authentication by default. You can optionally configure your integration to request additional OAuth scopes as needed. When the **Return Google OAuth tokens** option is selected, the access token and refresh token from Google will be included in the response from the [Authenticate with code API](/reference/authkit/authentication/code). ![A screenshot showing Google OAuth scopes configuration in the WorkOS Dashboard](https://images.workoscdn.com/images/53f64aa3-fbd1-4371-9fba-2e2ff9eb0823.png?auto=format&fit=clip&q=50) Any scopes configured here will be included on every Google OAuth request. To specify additional scopes dynamically, use the `provider_scopes` query parameter on the [Get Authorization URL API endpoint](/reference/authkit/authentication/get-authorization-url). Any additional scopes that you plan to request must also be configured on your OAuth consent screen in the Google Cloud Platform Console. Google considers some scopes to be sensitive or restricted. If requesting any of these sensitive or restricted scopes, your application will need to be verified by Google. For more information, see Google's OAuth scopes [documentation](https://developers.google.com/identity/protocols/oauth2/scopes). ![A screenshot showing Google OAuth scopes configuration in the Google Cloud Console](https://images.workoscdn.com/images/c9f2cc5d-ca3c-466f-9db8-9138ad60cc43.png?auto=format&fit=clip&q=50) > IMPORTANT: Your users will see an "unverified app" screen from Google and may see errors during sign-in if the scopes included on an authorization request differ from the scopes configured on your OAuth consent screen, or if you request sensitive or restricted scopes without going through Google's app verification process. Changes to scopes should be tested in a staging environment before applying them to production. --- ## Frequently asked questions ### How is the WorkOS Google OAuth integration different from implementing regular Google OAuth flow? It's the same Google OAuth flow as you could build yourself, but it's encapsulated within WorkOS SSO. This means you don't need to build it yourself. In addition to Google OAuth, you can use WorkOS SSO to support other identity providers, all with a single integration. ### What is the provider query parameter and how is it used in the Google OAuth integration? You can use the `provider` query parameter in the [Get Authorization URL API endpoint](/reference/sso/get-authorization-url) to support global Google OAuth for any domain. The `provider` query parameter should be set to `GoogleOAuth`. ### Google Directory Sync Learn about syncing your user list with Google Workspace. ## Introduction This guide outlines how to synchronize your application’s Google Workspace directories. --- ## (1) Select environment Login to your WorkOS dashboard and ensure you have the desired environment selected. ![Select the desired WorkOS environment from the navigation.](https://images.workoscdn.com/images/8f30c9d7-8569-4cb2-8fbe-1d8fc46be717.png?auto=format&fit=clip&q=50) ## (2) Send an admin invite link Select “Organizations” in the navigation. Select the organization that'd like to enable a Google Directory Sync connection. On the Organization page, under “Invite an admin to set up this organization,” select “Invite Admin.” ![Select “Invite Admin” from the organization page.](https://images.workoscdn.com/images/f879b479-24e6-4c86-acb8-8abb05f2a2ff.png?auto=format&fit=clip&q=50) Select “Directory Sync” and any other features you'd like the organization to be able to onboard. ![Select “Directory Sync” and any other features you'd like the organization to be able to onboard.](https://images.workoscdn.com/images/2ff61c68-3709-4b35-ac0d-f2b5b6333d9b.png?auto=format&fit=clip&q=50) Enter the email address of the organization admin, or copy the setup link and send it to the organization admin. ![Enter the email address of the organization admin, or copy the setup link.](https://images.workoscdn.com/images/a3414089-79a1-4137-8687-3e803a6f364a.png?auto=format&fit=clip&q=50) --- ## (3) Authenticate with admin credentials Have the organization choose Google as a provider and follow the Google prompts to authenticate with admin credentials. ![A screenshot showing the requested permissions in the Google modal.](https://images.workoscdn.com/images/1809508c-e153-47f7-a9b7-5b243ff95c7c.png?auto=format&fit=clip&q=50) --- ## (4) Select which groups to sync to Your Application The organization admin can then select to filter which groups and memberships are synced to the directory. If groups are being filtered, then only users with a membership within one of the synced groups will be synced. ![A screenshot showing the setup screen with how to filter groups to sync.](https://images.workoscdn.com/images/43942f32-e228-4745-89a6-fa6ff3e6f4dc.png?auto=format&fit=clip&q=50) --- ## (5) Sync users and groups to Your Application Changes will appear live in the Directory Sync portal under the "Users" tab: ![A screenshot showing users in the "Users" tab of the WorkOS Dashboard.](https://images.workoscdn.com/images/268ff490-71bd-4aa4-9f7d-c01f3548b198.png?auto=format&fit=clip&q=50) A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) ## Frequently asked questions ### Can you selectively sync users and groups from Google Workspace? Yes, you can select to sync certain groups during setup within the Admin Portal as seen in [Step 4](/integrations/google-directory-sync/4-select-which-groups-to-sync-to-your-application). ### When do users get removed from a directory? There are 2 ways a user can be deleted from a Google Workspace directory. 1. The user is removed or archived on Google and no longer returned by their API. 2. When the directory is [filtering specific groups](/integrations/google-directory-sync/4-select-which-groups-to-sync-to-your-application), if a user is removed from all groups that are being filtered in, the user is removed from the directory as well. ### How often do Google Workspace directories perform a sync? Google Workspace directories are synced approximately every 30 minutes starting from the time of the initial sync ### Does Google Directory Sync support nested groups? Yes, nested groups (groups within groups) are supported in Google Directory Sync. This feature is currently available in a restricted preview. Contact [WorkOS support](mailto:support@workos.com) for additional details. ### What is the `idp_id` for directory groups from Google Workspace? Google Workspace provides a unique identifier for each group, which is persisted as the `idp_id` for [directory groups](/reference/directory-sync/directory-group) in WorkOS. ### GitLab OAuth Learn how to set up OAuth with GitLab ## Introduction The GitLab OAuth integration allows your users to authenticate using their GitLab credentials. The configuration process involves creating an OAuth application in GitLab and configuring the client credentials in your WorkOS Dashboard. --- ## What WorkOS provides When setting up GitLab OAuth, WorkOS provides one key piece of information that needs to be configured in your GitLab OAuth application: - [Redirect URI](/glossary/redirect-uri): The endpoint where GitLab will send authentication responses after successful login The Redirect URI is available in the [WorkOS Dashboard](https://dashboard.workos.com/). In the left navigation menu, select the **Authentication** tab and the **OAuth providers** sub-tab. Locate the **GitLab** section. ![The GitLab OAuth section in the WorkOS Dashboard](https://images.workoscdn.com/images/37e84a18-3d18-4fc9-a122-63589ab4ddf0.png?auto=format&fit=clip&q=50) Click **Enable**. The **GitLab OAuth** configuration dialog will open. Locate the **Redirect URI**. ![The GitLab OAuth configuration modal in the WorkOS Dashboard](https://images.workoscdn.com/images/3ec9c4c3-1fc1-4ef6-a2fb-eeca07701d33.png?auto=format&fit=clip&q=50) The **Redirect URI** serves as the destination for authentication responses and must be configured in your GitLab OAuth application as the redirect URI. --- ## What you'll need You will need to obtain two pieces of information from a GitLab OAuth application: - **GitLab Client ID**: Application identifier from GitLab (called Application ID in GitLab) - **GitLab Client Secret**: Authentication secret for the application (called Secret in GitLab) The following sections will guide you through creating an OAuth application in your GitLab account and generating these credentials. --- ## (1) Create the GitLab OAuth application Log in to your [GitLab account](https://gitlab.com) and navigate to your user settings. In the left navigation menu, select your avatar. Click **Edit profile**. Select **Applications**. Click **Add new application**. ![GitLab page to register a new OAuth application.](https://images.workoscdn.com/images/ad782ab8-74ad-4787-91fe-685e0f466509.png?auto=format&fit=clip&q=80) > You can also register a new application under a group, which may be more appropriate if it is maintained by a team of developers, or instance-wide if you have a dedicated GitLab instance. For more on this see the [GitLab docs](https://docs.gitlab.com/integration/oauth_provider/). --- ## (2) Configure the GitLab OAuth application Fill out the form with relevant details about your application, including the application name. For **Redirect URI**, enter the **Redirect URI** from the GitLab OAuth configuration in the WorkOS Dashboard. ![GitLab form to create a new OAuth application.](https://images.workoscdn.com/images/7c86fdf4-c635-46c5-977c-965b85a322fd.png?auto=format&fit=clip&q=80) The **Confidential** flag is enabled by default. It should be exclusively used by a trusted backend server that can securely store the client secret. For native-mobile, single-page, or other JavaScript applications, disable this flag. Select the **openid**, **profile**, and **email** scopes for this app to allow the application to read user profile information, then click **Save application**. --- ## (3) Generate client credentials On the next page, you will see the GitLab **Application ID** and **Secret** for your new OAuth application. ![OAuth client credentials in the GitLab application settings.](https://images.workoscdn.com/images/b7ce3a64-673a-476f-8a3c-cf63c76bf88e.png?auto=format&fit=clip&q=80) Note the **Application ID** and **Secret** values as you'll need them for the WorkOS configuration. --- ## (4) Configure GitLab credentials in WorkOS Now that you have the **GitLab Client ID** (Application ID) and **GitLab Client Secret** (Secret) from the previous step, return to the [WorkOS Dashboard](https://dashboard.workos.com). In the **GitLab OAuth** configuration dialog, enable the integration. Paste the credentials from GitLab into their respective fields in the WorkOS Dashboard. ![Where to enter GitLab client credentials in the WorkOS dashboard.](https://images.workoscdn.com/images/6e9b410d-33bf-485f-b1c4-6a16fbeaa946.png?auto=format&fit=clip&q=80) Click **Save** to complete the configuration. You are now ready to start authenticating with GitLab OAuth. You will use the `provider` query parameter in the Get Authorization URL API endpoint to support global GitLab OAuth for any domain. The `provider` query parameter should be set to `GitLabOAuth`. --- ## Configure Additional OAuth Scopes (Optional) WorkOS will request the OAuth scopes that are required for authentication by default. You can optionally configure your integration to request additional OAuth scopes as needed. When the **Return GitLab OAuth tokens** option is selected, the access token and refresh token from GitLab will be included in the response from the [Authenticate with code API](/reference/authkit/authentication/code). ![A screenshot showing GitLab OAuth scopes configuration in the WorkOS Dashboard](https://images.workoscdn.com/images/8d4803a8-f436-45cb-974e-eaa79522181e.png?auto=format&fit=clip&q=50) Any scopes configured here will be included on every GitLab OAuth request. To specify additional scopes dynamically, use the `provider_scopes` query parameter on the [Get Authorization URL API endpoint](/reference/authkit/authentication/get-authorization-url). Any additional scopes that you plan to request must also be configured on the Application settings page in GitLab. For more information, see GitLab's OAuth scopes [documentation](https://docs.gitlab.com/integration/oauth_provider). ![A screenshot showing GitLab OAuth scopes configuration in GitLab Application Settings](https://images.workoscdn.com/images/25d9971d-55b1-473b-9d7d-d8e42e893725.png?auto=format&fit=clip&q=50) > IMPORTANT: Your users will see an error during sign-in if the scopes included on an authorization request are not included in the scopes configured on the Application settings page in GitLab. Changes to scopes should be tested in a staging environment before applying them to production. --- ## Frequently asked questions ### How is the WorkOS GitLab OAuth integration different from implementing regular GitLab OAuth flow? It's the same GitLab OAuth flow as you could build yourself, but it's encapsulated within WorkOS SSO. This means you don't need to build it yourself. In addition to GitLab OAuth, you can use WorkOS SSO to support other identity providers, all with a single integration. ### What is the provider query parameter and how is it used in the GitLab OAuth integration? You can use the `provider` query parameter in the [Get Authorization URL API endpoint](/reference/sso/get-authorization-url) to support global GitLab OAuth for any domain. The `provider` query parameter should be set to `GitLabOAuth`. ### What scopes are required for GitLab OAuth? The **openid**, **profile**, and **email** scopes are required to allow the application to read user profile information necessary for authentication. This scope provides access to the user's basic profile data. ### Can I register the GitLab OAuth application under a group or organization? Yes, you can register a new application under a GitLab group, which may be more appropriate if it is maintained by a team of developers. You can also register it instance-wide if you have a dedicated GitLab instance. See the [GitLab documentation](https://docs.gitlab.com/integration/oauth_provider/) for more details. ### What is the difference between Confidential and non-Confidential applications in GitLab? The **Confidential** flag should be used for applications that can securely store the client secret, typically backend servers. For native mobile apps, single-page applications, or other JavaScript applications that cannot securely store secrets, you should disable this flag. ### GitHub OAuth Learn how to set up OAuth with GitHub ## Introduction The GitHub OAuth integration allows your users to authenticate using their GitHub credentials. The configuration process involves creating an OAuth application in GitHub and configuring the client credentials in the WorkOS Dashboard. --- ## Testing with default credentials in the staging environment WorkOS provides a default GitHub Client ID and Client Secret combination, which allows you to quickly enable and test GitHub OAuth. Use the [WorkOS API to initiate SSO](/sso/1-add-sso-to-your-app/add-an-endpoint-to-initiate-sso), setting the `provider` parameter to `GitHubOAuth`, and WorkOS will automatically use the default credentials until you add your own GitHub Client ID and Client Secret to the configuration in the WorkOS Dashboard. > The default credentials are only intended for testing and therefore only available in the Staging environment. For your production environment, please follow the steps below to create and specify your own GitHub Client ID and Client Secret. Please note that when you are using WorkOS default credentials, GitHub's authentication flow will display WorkOS' name, logo, and other information to users. Once you register your own application and use its GitHub Client ID and Client Secret for the OAuth flow, you will have the opportunity to customize the app, including its name, logo, contact email, etc. --- ## What WorkOS provides When setting up GitHub OAuth, WorkOS provides one key piece of information that needs to be configured in your GitHub OAuth application: - [Redirect URI](/glossary/redirect-uri): The endpoint where GitHub will send authentication responses after successful login The Redirect URI is available in the [WorkOS Dashboard](https://dashboard.workos.com/). In the left navigation menu, select the **Authentication** tab and the **OAuth providers** sub-tab. Locate the **GitHub** section. ![Open the GitHub configuration dialog](https://images.workoscdn.com/images/b4ddb4d0-39f2-4e58-bc15-f3857f63415b.png?auto=format&fit=clip&q=50) Click **Manage**. The **GitHub OAuth** configuration dialog will open. Locate the **Redirect URI**. ![GitHub OAuth Redirect URI in the WorkOS Dashboard](https://images.workoscdn.com/images/18629339-63d6-4b60-b5d5-7e75f7745de5.png?auto=format&fit=clip&q=50) The **Redirect URI** serves as the destination for authentication responses and must be configured in your GitHub OAuth application as the authorization callback URL. --- ## What you'll need You will need to obtain two pieces of information from a GitHub OAuth application: - **GitHub Client ID**: Application identifier from GitHub - **GitHub Client Secret**: Authentication secret for the application The following sections will guide you through creating an OAuth application in your GitHub account and generating these credentials. --- ## (1) Create the GitHub OAuth Application Sign in to GitHub and navigate to [**Developer settings**](https://github.com/settings/developers). Select **OAuth Apps**. Create a new OAuth app. ![The New OAuth App button in GitHub](https://images.workoscdn.com/images/d8991483-a60e-4bc6-985f-2053d8b3c2c9.png?auto=format&fit=clip&q=80) > You can also register a new application under a GitHub Organization, which may be more appropriate if it is maintained by a team of developers. You can also [transfer ownership](https://docs.github.com/en/apps/oauth-apps/maintaining-oauth-apps/transferring-ownership-of-an-oauth-app) of your GitHub OAuth application to a GitHub organization later. --- ## (2) Configure OAuth application Fill out the OAuth application form. For the **Authorization callback URL** input, enter the **Redirect URI** from the WorkOS Dashboard. Click **Register application**. ![The GitHub form to create a new OAuth application.](https://images.workoscdn.com/images/6282967b-eee8-4937-8ec8-a1f25d7ec873.png?auto=format&fit=clip&q=80) You'll be given a Client ID. Note this value as you'll need it for the WorkOS configuration. Click **Generate a new client secret** to generate a new GitHub Client Secret. Note that this value is only temporarily available, so make sure to save it before proceeding. ![The Client ID and Client Secret in GitHub](https://images.workoscdn.com/images/ba3c133b-3492-4b5b-b10c-69717ca3e50c.png?auto=format&fit=clip&q=80) --- ## (3) Configure GitHub credentials in WorkOS Now that you have the **GitHub Client ID** and **GitHub Client Secret** from the previous step return to the [WorkOS Dashboard](https://dashboard.workos.com/). In the **GitHub OAuth** configuration dialog, select **Your app's credentials**. Paste the credentials from GitHub into their respective fields in the WorkOS Dashboard. ![Where to enter the GitHub Client ID and GitHub Client Secret in the WorkOS Dashboard](https://images.workoscdn.com/images/01d06b09-d622-4815-8757-c3b6825b790b.png?auto=format&fit=clip&q=50) Click **Save** to complete the configuration. You're now able to authenticate users with GitHub OAuth. You will use the `provider` query parameter in the Get Authorization URL API endpoint to support global GitHub OAuth for any domain. The `provider` query parameter should be set to `GitHubOAuth`. --- ## Configure Additional OAuth Scopes (Optional) WorkOS will request the OAuth scopes that are required for authentication by default. You can optionally configure your integration to request additional OAuth scopes as needed. When the **Return GitHub OAuth tokens** option is selected, the access token from GitHub will be included in the response from the [Authenticate with code API](/reference/authkit/authentication/code). ![A screenshot showing GitHub OAuth scopes configuration in the WorkOS Dashboard](https://images.workoscdn.com/images/9cfbd37c-f1cc-436d-8e61-0ccce2612bc6.png?auto=format&fit=clip&q=50) Any scopes configured here will be included on every GitHub OAuth request. To specify additional scopes dynamically, use the `provider_scopes` query parameter on the [Get Authorization URL API endpoint](/reference/authkit/authentication/get-authorization-url). For more information, see GitHub's OAuth scopes [documentation](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps). --- ## Frequently asked questions ### How is the WorkOS GitHub OAuth integration different from implementing regular GitHub OAuth flow? It's the same GitHub OAuth flow as you could build yourself, but it's encapsulated within WorkOS SSO. This means you don't need to build it yourself. In addition to GitHub OAuth, you can use WorkOS SSO to support other identity providers, all with a single integration. ### What is the provider query parameter and how is it used in the GitHub OAuth integration? You can use the `provider` query parameter in the [Get Authorization URL API endpoint](/reference/sso/get-authorization-url) to support global GitHub OAuth for any domain. The `provider` query parameter should be set to `GitHubOAuth`. ### Fourth Learn about syncing your user list with Fourth. ## Introduction This guide outlines how to synchronize your application’s Fourth directories. To synchronize an organization’s users and groups provisioned for your application, you’ll need the following information from the organization: - Fourth Organization ID - Fourth username and password > Note: The Fourth integration isn't enabled by default in the WorkOS Dashboard or Admin Portal. Please reach out to [support@workos.com](mailto:support@workos.com) or via your team’s WorkOS Slack channel if you would like Fourth enabled. --- ## (1) Set up your directory sync integration Sign in into your WorkOS Dashboard and select “Organizations” from the left hand navigation bar. Select the organization you’ll be configuring a new Directory Sync connection with. Click “Manually Configure Directory”. ![A screenshot showing where to find "Manually Configure Directory" button for an organization in the WorkOS dashboard.](https://images.workoscdn.com/images/0a0fa511-08ae-4fd9-9cfc-0301b7041b3f.png?auto=format&fit=clip&q=50) Input the Name, and select "Fourth” as the directory type. Click the “Create Directory” button. ![A screenshot showing "Create Directory" details in the WorkOS dashboard.](https://images.workoscdn.com/images/ba13b740-7cbf-42e5-a511-b0c5a9f384e0.png?auto=format&fit=clip&q=50) You will now see your Fourth directory sync has been created successfully with an input for the Organization ID, username, and password. ## (2) Obtain and update directory details Retrieve the Fourth Organization ID from the organization's IT admin, as well as the username and password that will be used for authentication. Click “Update Directory” in the WorkOS Dashboard. ![A screenshot showing where to find the "Update Directory" button in the WorkOS dashboard.](https://images.workoscdn.com/images/9c641325-3703-4c17-955e-d6b0fc898996.png?auto=format&fit=clip&q=50) Enter the Organization ID, the username and the password. --- ## (3) View users and groups in your dashboard When the connection is successfully made, you will see the green “Linked” icon appear. Now, whenever the organization assigns users or groups to your application, you’ll receive Dashboard updates based on changes in their directory. Click on the “Users” tab in the Dashboard to view synced users. ![A screenshot showing where to find the "Users" tab in the WorkOS directory.](https://images.workoscdn.com/images/0784ded9-3fcd-45f1-87cc-44bb41e2031c.png?auto=format&fit=clip&q=50) --- ## Frequently asked questions ### How often do Fourth directories perform a sync? Fourth directories poll every 30 minutes starting from the time of the initial sync. ### Firebase Add Single Sign-On to your Firebase application with WorkOS. ## Introduction In this guide, you’ll learn how to use WorkOS to add Single Sign-On (SSO) to a Firebase application. This will allow users to sign in to an existing Firebase application using WorkOS SSO Connections. ## What WorkOS provides WorkOS will provide the following pieces of information: API key, Client ID, and the Issuer URL. - The API key can be found in your WorkOS dashboard under **API Keys**. - The Client ID can be found in your WorkOS dashboard under **Configuration**. - The Issuer URL is constructed with the Client ID. `https://auth.workos.com/sso/`. ## What you’ll need - An existing Firebase project --- ## (1) Configure Authentication for your Firebase project Log into Firebase and navigate to your project. Click on the Authentication tile to set up a new Authentication method for your project. ![A screenshot showing where to find the Authentication tile in Firebase.](https://images.workoscdn.com/images/612ce59a-a1c8-4eb9-a209-9d0f6b6c5086.png?auto=format&fit=clip&q=50) Next, click **Get started**. ![A screenshot showing where to find the Get started button in Firebase](https://images.workoscdn.com/images/bd877730-1e9a-487d-8938-10782c912d45.png?auto=format&fit=clip&q=50) Click on the Sign-in method tab and then select the OpenID Connect custom provider. ![A screenshot showing where to find the OpenID Connect custom provider in Firebase](https://images.workoscdn.com/images/ee3fbc76-d94b-491e-842a-5f74eb4a2d62.png?auto=format&fit=clip&q=50) Enter the configuration details for the connection between WorkOS and Firebase. You will need the following pieces of information: - **WorkOS Client ID**: Found on the **Configuration** tab of the WorkOS Dashboard - **WorkOS API Key**: Located on the **API Keys** tab of the WorkOS Dashboard - **Issuer (URL)**: This will be `https://auth.workos.com/sso/` appended with your client ID, ex: `https://auth.workos.com/sso/client_123` - **Provider ID**: This is found in Firebase under the Name of your OIDC provider. This will be important for a later step. ![A screenshot showing the authentication provider configuration details in Firebase](https://images.workoscdn.com/images/5eb66fe3-8cad-4555-9417-ab38924d1288.png?auto=format&fit=clip&q=50) --- ## (2) Configure the Redirect URI in WorkOS Click Next, then copy the **Callback URL** provided by Firebase. ![A screenshot showing where to obtain the Callback URL in Firebase.](https://images.workoscdn.com/images/a33d3b63-e6f9-4a43-8108-012f54d7c7db.png?auto=format&fit=clip&q=50) Paste the Callback URL in the list of Redirect URI’s in the configuration tab of your WorkOS dashboard. ![A screenshot showing where to enter the Redirect URI in WorkOS.](https://images.workoscdn.com/images/c2c6ef52-e61e-41af-9c37-1e2187bf1744.png?auto=format&fit=clip&q=50) --- ## (3) Create a Firebase web app and get configuration details On the Firebase Project Overview page, click the web icon above **Add an app to get started**, or navigate to your project settings page if your project is already set up. ![A screenshot showing where to create a web app in Firebase.](https://images.workoscdn.com/images/777e0c57-2c9d-4516-9e3e-985460ed38b6.png?auto=format&fit=clip&q=50) Choose a name for your application, and then take note of the firebaseConfig from the Add Firebase SDK step. ![A screenshot showing where to obtain the firebaseConfig details in Firebase.](https://images.workoscdn.com/images/64b62bc6-4891-4627-9a2a-9440e0d27aa7.png?auto=format&fit=clip&q=50) --- ## (4) Configure Firebase login in your application Your Firebase configuration and Provider ID can now be used along with any Organization ID from an Active WorkOS SSO connection to log users in to your Firebase app. Here is a basic example showing how this can be set up. Replace the `firebaseConfig` variable value with the config from your Firebase app, the `OAuthProvider` value with your Provider ID, and the organization under `provider.setCustomParameters` with the organization to target. This organization should have an active SSO connection already set up. > The `connection` parameter may be used in place of the `organization` parameter to target a connection. Finally, run the app and click the sign-in button. You will now see the user signed in on the Authentication section’s user tab in Firebase. You can also view the user information by decoding the access token which is logged to the console. ![A screenshot showing a successfully authenticated user in Firebase.](https://images.workoscdn.com/images/a4d521f9-3765-4d2d-909c-5340a462ba3e.png?auto=format&fit=clip&q=50) ### Entra ID SCIM (formerly Azure AD) Learn about syncing your user list with Entra ID SCIM. ## Introduction This guide outlines how to synchronize your application’s Entra ID directories using SCIM. To synchronize an organization’s users and groups provisioned for your application, you’ll need to provide the organization with two pieces of information: - An [Endpoint](/glossary/endpoint) that Entra ID will make requests to. - A [Bearer Token](/glossary/bearer-token) for Entra ID to authenticate its endpoint requests. Both of these are available in your Endpoint’s Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). > Steps 2, 3, and 4 below will need to be carried out by the organization admin when configuring your application in their Entra ID instance. --- ## (1) Set up your Directory Sync endpoint Sign in to your WorkOS Dashboard and select “Organizations” from the left hand navigation bar. Select the organization you’ll be configuring a new Directory Sync for. Click “Add Directory”. ![A screenshot showing where to add a new directory in the WorkOS dashboard.](https://images.workoscdn.com/images/cf3a5ae2-4add-47ca-887e-d4d78c33d786.png?auto=format&fit=clip&q=50) Select “Entra ID” from the dropdown, and enter the organization name. Then, click “Create Directory.” ![A screenshot showing the "Create Directory" menu in the WorkOS dashboard.](https://images.workoscdn.com/images/6244ecf4-65a0-4421-b984-d513704ef882.png?auto=format&fit=clip&q=50) > We have support for whitelabeled URLs for Directory Sync endpoints. [Contact us](mailto:support@workos.com) for more info! Your Entra ID directory sync has now been created successfully with an Endpoint and Bearer Token. ![A screenshot showing the Azure SCIM endpoint and bearer token in the WorkOS dashboard.](https://images.workoscdn.com/images/38a98a55-96fa-403d-86f8-cfb313cd51e5.png?auto=format&fit=clip&q=50) --- ## (2) Select or create your Azure application Sign in to the Entra ID Admin Center Dashboard. Select “Enterprise applications” from the list of Azure services. ![A screenshot showing where to select "Enterprise applications" in the Azure Active Directory Admin Center Dashboard](https://images.workoscdn.com/images/25d08d2e-48b8-49b0-b8e9-d57641606b57.png?auto=format&fit=clip&q=50) If your application is already created, select it from the list of applications and move to Step 3. ![A screenshot showing where to select the application of choice in the All Applications menu in Azure.](https://images.workoscdn.com/images/7430b6b1-2d16-4df1-b11a-a51d51bc4725.png?auto=format&fit=clip&q=50) If you haven’t created a SCIM application in Azure, select “New Application”. ![A screenshot showing where to select a new application in the All Applications menu in Azure.](https://images.workoscdn.com/images/8e9587aa-e259-4175-952c-bebe476457a2.png?auto=format&fit=clip&q=50) Select “Create your own application” and continue. ![A screenshot showing where to select "Create your own application" in the All Applications menu in Azure.](https://images.workoscdn.com/images/ef501e51-ca06-47ef-a731-f509960fbf70.png?auto=format&fit=clip&q=50) Give your application a descriptive name, and select the “Integrate any other application you don’t find in the gallery (Non-gallery)” option, then click “Create”. ![A screenshot showing where to configure the name of a new application in Azure.](https://images.workoscdn.com/images/cbd435b0-2313-4922-9fa3-87de57b39de8.png?auto=format&fit=clip&q=50) --- ## (3) Configure your integration Select “Provisioning” from the “Manage” section found in the navigation menu. ![A screenshot showing where to select "Provisioning" from the "Manage" section in Azure.](https://images.workoscdn.com/images/39c18ede-837f-4735-8fa7-6cc3eb855776.png?auto=format&fit=clip&q=50) Click the “Get Started” button. ![A screenshot showing where to select "Get Started" in the "Provisioning" menu in Azure.](https://images.workoscdn.com/images/e7d7e41f-1dec-4119-a3c4-fcc349a39eb5.png?auto=format&fit=clip&q=50) Select the “Automatic” Provisioning Mode from the dropdown menu. In the “Admin Credentials” section, copy and paste the Endpoint from your [WorkOS Dashboard](https://dashboard.workos.com/) in the “Tenant URL” field. Then, copy and paste the Bearer Token from your [WorkOS Dashboard](https://dashboard.workos.com/) into the Secret Token field. Click “Test Connection” to receive confirmation that your connection has been set up correctly. Then, select “Save” to persist the credentials. ![A screenshot showing where to configure the provisioning mode and credentials in Azure.](https://images.workoscdn.com/images/22d127dc-6834-4a84-b579-c7ae045cd339.png?auto=format&fit=clip&q=50) --- ## (4) Set and enable Attribute mappings Expand the “Mappings” section. ![A screenshot showing where to expand "Mappings" in Azure.](https://images.workoscdn.com/images/f78bb399-3ab3-4822-a6bf-e8e96db93cdd.png?auto=format&fit=clip&q=50) Make sure the group and user attribute mappings are enabled, and are mapping the correct fields. The default mapping should work, but your specific Azure setup may require you to add a custom mapping. ![A screenshot showing where to ensure User attribute mappings are enabled in Azure.](https://images.workoscdn.com/images/ab0daea3-dda3-4e3d-9199-9d30a710fdb2.png?auto=format&fit=clip&q=50) Make sure that you are mapping `objectId` to `externalId` within the Attribute Mapping section. ![A screenshot showing where to ensure object ID is mapped to external ID in the Attribute Mapping section in Azure.](https://images.workoscdn.com/images/389cb8cc-9bfd-4f0b-b623-1304cf863c64.png?auto=format&fit=clip&q=50) --- ## (5) Assign users and groups to your application In order for your users and groups to be synced, you will need to assign them to your Entra ID SCIM Application. Select “Users and groups” from the “Manage” section of the navigation menu. ![A screenshot showing where to navigate to "Users and groups" from the "Manage" section in Azure.](https://images.workoscdn.com/images/d4f01d7f-6dc4-46c6-a524-a6c5fe47cf7a.png?auto=format&fit=clip&q=50) Select “Add user/group” from the top menu. ![A screenshot showing where to select "Add user/group" in the Users and groups menu in Azure.](https://images.workoscdn.com/images/68717808-6ca4-47ff-8bc0-690f3bfffe0e.png?auto=format&fit=clip&q=50) Select “None selected” under the “Users and Groups”. In the menu, select the users and groups that you want to add to the SCIM application, and click “Select”. ![A screenshot showing where to select users for a SCIM application in Azure.](https://images.workoscdn.com/images/b6e2c4f6-ef9b-4881-8d9c-a23ae55a1490.png?auto=format&fit=clip&q=50) Select “Assign” to add the selected users and groups to your SCIM application. ![A screenshot showing where to assign the selected users for the SCIM application in Azure.](https://images.workoscdn.com/images/e2f7221f-9789-4288-bd66-5450d150db0b.png?auto=format&fit=clip&q=50) --- ## (6) Turn on provisioning for your SCIM application In the Provisioning menu, confirm the “Provisioning Status” is set to “On” and that the “Scope” is set to “Sync only assigned users and groups”. ![A screenshot showing where to ensure that the "Provisioning Status" is "On" and "Scope" is set to "Sync only assigned users and groups" in Azure.](https://images.workoscdn.com/images/67041f59-27dc-4026-b6a2-c43568c59dfd.png?auto=format&fit=clip&q=50) Begin provisioning users and groups and witness realtime changes in your [WorkOS Dashboard](https://dashboard.workos.com/). A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) --- ## Configuring user attribute mappings For any non-standard attributes used by the application, some configuration may be required in Microsoft Entra. Below is a guide on configuring user attribute mappings, so they propagate via SCIM. ### (1) Viewing application attributes From your Microsoft Entra SCIM application, navigate to the Manage → Provisioning page. Expand the Mappings section and click "Provision Microsoft Entra ID Users". ![Microsoft Entra enterprise application provisioning tab](https://images.workoscdn.com/images/cb7b0eb7-8ff7-452e-b3c5-14eede22c4da.png?auto=format&fit=clip&q=50) This will display a list of attribute mappings and settings: ![Microsoft Entra attribute mapping settings](https://images.workoscdn.com/images/472657ed-812c-4f3a-b57d-601e573adf48.png?auto=format&fit=clip&q=50) ### (2) Adding or editing an attribute To add a missing attribute, click the "Add New Mapping" button at the bottom left of the mappings list. To edit an existing attribute, click the "Edit" button next to the existing attribute you'd like to edit. ![Microsoft Entra add new mapping button](https://images.workoscdn.com/images/2319dab9-6392-4a7f-9988-fe8cf5260301.png?auto=format&fit=clip&q=50) To configure the mapping, select the source and target attribute from the dropdowns, and ensure "Apply this mapping" is set to "Always". For example, to map division, the source attribute has been selected as `employeeOrgData.division` and the target attribute has been selected as `urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:division`. ![Microsoft Entra configure mapping dialog](https://images.workoscdn.com/images/984c0ffe-0d18-4f04-a69b-d4e09b4a51d3.png?auto=format&fit=clip&q=50) These new attribute mappings will now propagate to your application when the next SCIM push occurs. --- ## Provisioning on demand By default, Entra ID SCIM 2.0 directories sync changes on a scheduled time interval, typically every 40 minutes. For use cases where more immediate provisioning or deprovisioning of users, groups, or group memberships is needed, Entra ID provides [provisioning on demand](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/provision-on-demand?pivots=app-provisioning). To provision on demand, from the enterprise application navigate to the "Provisioning" tab and click "Provision on demand". ![Entra ID provision on demand button](https://images.workoscdn.com/images/de50df7b-4088-4e95-a711-ad04e43474c5.png?auto=format&fit=clip&q=50) To provision a user, select the user from the dropdown and click "Provision". ![Entra ID provision user on demand](https://images.workoscdn.com/images/121aaa24-d160-40a4-824f-44cc2a5ff84d.png?auto=format&fit=clip&q=50) To provision a group or group membership, select the group from the dropdown, and select "View members only". Then select the group memberships to provision and click "Provision". ![Entra ID provision group memberships on demand](https://images.workoscdn.com/images/34167704-985a-4b0b-b110-89e19d618b37.png?auto=format&fit=clip&q=50) Upon clicking "Provision", SCIM requests will immediately be sent to the application. To deprovision a user, group, or group membership, remove it from the Entra application and follow the above provisioning on demand steps. --- ## Frequently asked questions ### No email addresses are coming through for users from Entra. How do I get emails for my Entra users? For cloud-managed users, Entra ID pulls the email from the `mail` attribute in Exchange. If your customer doesn’t have this set up, they will need to configure attribute mapping in their SCIM app in Entra in order to provision users with WorkOS. They can use [this tutorial from Microsoft](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/customize-application-attributes). They’ll want to map a known email attribute, such as UPN, to the `emails[type eq “work”].value` SCIM attribute. For directories with synchronized-users, they will need to map the `userPrincipalName` attribute into the `emails[type eq “work”].value` SCIM attribute. ### Sometimes, reactivating "suspended" users does not re-add them to their Entra groups. Why is that and how can I fix it? When a user is deleted from the entire directory, instead of only being deprovisioned from the SCIM app, the user may be soft-deleted (their state is set as "suspended"). Reactivating these suspended users will not send SCIM requests to re-add the user to the groups. To do so, the IT admin will need to select the "Restart Provisioning" button for the SCIM app in Azure. ![A screenshot showing where to restart provisioning in Entra.](https://images.workoscdn.com/images/757f8920-da4b-46ac-90b0-9780b150eb62.png?auto=format&fit=clip&q=50) ### Can profile images be accessed with Entra ID SCIM? Entra ID's SCIM provisioning does not support transmitting image. ### Why do I receive a `dsync.user.updated` event after `dsync.user.created`? Entra ID sends a newly provisioned user over to WorkOS in two separate actions. WorkOS will then send these actions as two individual events to your app. This is expected behavior. ### How often do Entra ID SCIM 2.0 directories perform a sync? By default, Entra ID SCIM 2.0 directories sync changes on a scheduled time interval, typically every 40 minutes. For more details, please refer to Entra ID's [official documentation](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/application-provisioning-when-will-provisioning-finish-specific-user#how-long-will-it-take-to-provision-users). [Provisioning on demand](/integrations/entra-id-scim/provisioning-on-demand) is also available, which can sync select users, groups, or group memberships in real-time. ### What is the `idp_id` for directory groups from Entra ID? Entra ID provides a unique object identifier for each group through the SCIM `externalId` field. This is persisted as the `idp_id` for [directory groups](/reference/directory-sync/directory-group) in WorkOS. ### Entra ID SAML (formerly Azure AD) Learn how to configure a connection to Entra ID via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). And often, the information required to create a Connection will differ by Identity Provider. To create an Entra ID SAML Connection, you’ll need the Identity Provider Metadata URL that is available from the organization's Entra ID instance. --- ## What WorkOS Provides WorkOS provides the [ACS URL](/glossary/acs-url) and [IdP URI (Entity ID)](/glossary/idp-uri-entity-id). It’s readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/get-started). ![A screenshot showing the ACS URL and Entity ID in the WorkOS dashboard.](https://images.workoscdn.com/images/736aee3b-9a67-4abd-9905-f091d20fe48e.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. In Entra ID’s case, it needs to be set by the organization when configuring your application in their Entra ID instance. Specifically, the ACS URL will need to be set as the “Reply URL (Assertion Consumer Service URL)” in the “Basic SAML Configuration” step of the Entra ID “Set up Single Sign-On with SAML” wizard: ![A screenshot showing the location to place the WorkOS ACS URL in the Azure Dashboard.](https://images.workoscdn.com/images/ea398d8e-71a8-4f54-9b85-3c092f325bf8.png?auto=format&fit=clip&q=50) The [Entity ID](/glossary/idp-uri-entity-id) is a URI used to identify the issuer of a SAML request, response, or assertion. In this case, the entity ID is used to communicate that WorkOS will be the party performing SAML requests to the organization's Entra ID instance. Specifically, the Entity ID will need to be set as the “Identifier (Entity ID)” in the “Basic SAML Configuration” step of the Entra ID “Set up Single Sign-On with SAML” wizard: ![A screenshot showing the location to place the WorkOS Entity ID in the Azure Dashboard.](https://images.workoscdn.com/images/55860959-b322-4098-b3d4-66d48ee73dd1.png?auto=format&fit=clip&q=50) --- ## What you’ll need In order to integrate you’ll need the Entra ID IdP Metadata URL. Normally, this information will come from the organization's IT Management team when they set up your application’s SAML 2.0 configuration in their Azure admin dashboard. Here’s how to obtain them: --- ## (1) Log in Log in to the [Entra ID Active Directory Admin dashboard](https://portal.azure.com/). Select “Enterprise Applications” from the list of Azure services. ![A screenshot showing where to select "Enterprise Applications" in the Azure dashboard.](https://images.workoscdn.com/images/37f3b3d2-fcdb-4a5f-8d93-970ec0239446.png?auto=format&fit=clip&q=50) --- ## (2) Select or create your application If your application is already created, select it from the list of Enterprise applications and move to Step 7. ![A screenshot showing where to select an existing application in the Azure dashboard.](https://images.workoscdn.com/images/a61ca1b9-4e06-4dc6-80de-eac3fea212cd.png?auto=format&fit=clip&q=50) If you haven’t created a SAML Application in Azure, select “New Application”. ![A screenshot showing where to select "New Application" in the Azure dashboard.](https://images.workoscdn.com/images/3c26fec7-f77a-4757-8a04-6998ff7beb26.png?auto=format&fit=clip&q=50) --- ## (3) Initial SAML Application Setup Select “Create your own application”, then enter a descriptive app name. Under “What are you looking to do with your application?”, select “Integrate any other application you don’t find in the gallery (Non-gallery)”, then select “Create”. ![A screenshot showing where to input the name of the new application in the Azure dashboard.](https://images.workoscdn.com/images/9f998b1b-87b4-4f1d-a50c-0a17f8bb3f98.png?auto=format&fit=clip&q=50) Select “Single Sign-On” from the “Manage” section in the left sidebar navigation menu, and then “SAML”. ![A screenshot showing how to select "SAML" as the Single Sign-On method of the Azure application in the Azure dashboard.](https://images.workoscdn.com/images/f90c0d1a-ed45-4bee-b77f-dcf37a63a6bd.png?auto=format&fit=clip&q=50) --- ## (4) Configure SAML Application Click the Edit icon in the top right corner of the first step "Basic SAML Configuration". ![A screenshot showing where to select "Edit" for the "Basic SAML Configuration" step in the Azure dashboard.](https://images.workoscdn.com/images/e7a4397c-8120-43c6-9b66-e6a2251cd5bd.png?auto=format&fit=clip&q=50) Input the IdP URI (Entity ID) from your WorkOS Dashboard as the “Identifier (Entity ID)”. Input the ACS URL from your WorkOS Dashboard as the “Reply URL (Assertion Consumer Service URL)”. ![A screenshot showing where to input the WorkOS ACS URL and WorkOS Entity ID in the Azure dashboard.](https://images.workoscdn.com/images/8bf326a6-f394-4894-9630-d86cdf9b574f.png?auto=format&fit=clip&q=50) --- ## (5) Configure User Attributes and Claims Click the Edit icon in the top right corner of the second step "Attributes & Claims". ![A screenshot showing where to select "Edit" for the "Attributes & Claims" step in the Azure dashboard.](https://images.workoscdn.com/images/6155597f-a4b8-4a3c-a7f3-a6e8d4e0865d.png?auto=format&fit=clip&q=50) Make sure the following attribute mapping is set: - `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` → `user.mail` - `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname` → `user.givenname` - `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name` → `user.userprincipalname` - `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname` → `user.surname` Below is an example of how to format your claim within the Azure claim editor. Make sure the 'Namespace' value ends in `/claims`. ![A screenshot showing the "Manage Claim" configuration in the Azure dashboard.](https://images.workoscdn.com/images/93ec5d1b-9ecd-49f5-8d2a-a718b5ea58b2.png?auto=format&fit=clip&q=50) ![A screenshot showing the "Attribute & Claims" configuration in the Azure dashboard.](https://images.workoscdn.com/images/f41b5a7c-1842-4567-9f46-85caa7309176.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, follow the guidance below. Select "Add a group claim" from the top menu. Next, select which groups you'd like to return in the Group Claims settings. For example, in Entra ID, you could select "Groups assigned to the application" to only send groups assigned to the SAML app. Finally, select "Save" once finished configuring the groups. ![A screenshot showing how to add a groups claim to your SAML app in the Azure dashboard.](https://images.workoscdn.com/images/4e33755c-945f-4164-873f-33482e3a2c43.png?auto=format&fit=clip&q=50) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (6) Add Users to SAML Application In order for your users or groups of users to be authenticated, you will need to assign them to your Entra ID SAML application. Select “Users and groups” from the “Manage” section of the navigation menu. ![A screenshot showing where to select "Users and groups" in the Azure dashboard.](https://images.workoscdn.com/images/7fe69c75-311e-409b-905a-dbd6b6087394.png?auto=format&fit=clip&q=50) Select “Add user/group” from the top menu. ![A screenshot showing where to select "Add user/group" in the Azure dashboard.](https://images.workoscdn.com/images/817e4d3d-7470-4e20-b9f1-af74ea8adc73.png?auto=format&fit=clip&q=50) Select “None selected” under the “Users and Groups”. In the menu, select the users and groups of users that you want to add to the SAML application, and click “Select”. ![A screenshot showing where to select "None Selected" under "Users and Groups" and add a user in the Azure dashboard.](https://images.workoscdn.com/images/85f005d7-3655-46ac-9554-77fda2c44747.png?auto=format&fit=clip&q=50) Select “Assign” to add the selected users and groups of users to your SAML application. ![A screenshot showing where to select "Assign" in the Azure dashboard.](https://images.workoscdn.com/images/5420b145-6086-4141-b096-9ae9f6ea8529.png?auto=format&fit=clip&q=50) --- ## (7) Obtain Identity Provider Details Select “Single Sign-On” from the “Manage” section in the left sidebar navigation menu. Navigate down to Section 3 of the “Single Sign-On” page, to “SAML Signing Certificate”. Copy the URL provided in “App Federation Metadata URL”. ![A screenshot showing where to select the "App Federation Metadata URL" in the Azure dashboard.](https://images.workoscdn.com/images/c4ee0b27-ddd7-4aab-96c0-ced1019b4cd7.png?auto=format&fit=clip&q=50) Next, within your connection settings under "Identity Provider Configuration", select "Edit Metadata Configuration" and enter the Azure metadata URL. ![A screenshot showing where to select "Edit Metadata Configuration" on the "SSO Connection" page in the WorkOS dashboard.](https://images.workoscdn.com/images/2ad55b55-e44f-48a6-93db-8699dcd98af6.png?auto=format&fit=clip&q=50) Your Connection will then be verified and good to go! ![A screenshot showing an active Azure SAML connection in the WorkOS dashboard.](https://images.workoscdn.com/images/2116ac59-3868-4c55-aa3d-43cdefd01f1f.png?auto=format&fit=clip&q=50) ### Entra ID OIDC (formerly Azure AD) Learn how to configure a connection to Entra ID via OIDC. ## Introduction Each SSO identity provider requires specific information to create and configure a new [SSO connection](/glossary/connection). Often, the information required to create an SSO connection will differ by identity provider. To create an Entra ID OIDC SSO connection, you'll need four pieces of information: a [redirect URI](/glossary/redirect-uri), [application (client) ID](/glossary/client-id), [client secret](/glossary/client-secret) and [discovery endpoint](/glossary/discovery-endpoint). Start by logging in to your WorkOS dashboard and navigate to the **Organizations** page from the left-hand navigation bar. Select the organization you'd like to configure an Entra ID OIDC SSO connection for, and select **Configure manually** under **Single Sign-On**. ![WorkOS Dashboard Organizations tab with "Configure manually" button highlighted](https://images.workoscdn.com/images/d577cfbe-028b-48cf-8cc0-4cd5d3adf853.png?auto=format&fit=clip&q=50) Select **Entra ID (Azure AD) OIDC** from the identity provider dropdown, enter a descriptive name for the connection, click **Create Connection**. ![Create Connection form with Entra ID (Azure AD) OIDC selected as Identity Provider](https://images.workoscdn.com/images/90fe747d-88e3-40da-a028-161132401a5c.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides WorkOS provides the Redirect URI, which can be found in the **Service Provider Details** section on the SSO connection page in the [WorkOS Dashboard](https://dashboard.workos.com/). - [Redirect URI](/glossary/redirect-uri): The endpoint where identity providers send authentication responses after successful login ![The Redirect URI of a OIDC connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/99a7c7d5-50a9-4bff-a3f3-22dc1cfeca58.png?auto=format&fit=clip&q=50) The Redirect URI is the location an identity provider redirects its authentication response to. In Entra ID’s case, it needs to be set during application registration when configuring your OIDC application, which is outlined in [step 1](/integrations/entra-id-oidc/1-register-an-application) below. --- ## What you’ll need You will need to obtain three pieces of information from the organization: - [Application (Client) ID](/glossary/client-id): Application identifier from the OIDC provider - [Client Secret](/glossary/client-secret): Authentication secret for the application - [Discovery endpoint](/glossary/discovery-endpoint): Configuration URL containing OIDC metadata Normally, this information will come from the organization’s IT Management team when they set up your application’s OIDC configuration in their Entra ID admin center. But, should that not be the case during your setup, the next steps will show you how to obtain it. --- ## (1) Register an application Sign in to the [Microsoft Entra admin center](https://entra.microsoft.com/). In the left navigation menu, expand the **Identity** section. Expand the **Applications** sub-section. Select the **App registrations** tab. Click **New registration**. ![Microsoft Entra admin center navigation showing Identity > Applications > App registrations](https://images.workoscdn.com/images/67c07f6f-f60d-48da-b950-eac73d094dfb.png?auto=format&fit=clip&q=50) Enter an appropriate app name, such as your organization or application name. Select one of these **Supported account types**: - Accounts in this organizational directory only (Default Directory only - Single tenant) (Default) - Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) In the **Redirect URI** field, select the **Web** option from the dropdown menu. Copy the [Redirect URI](/integrations/entra-id-oidc/what-workos-provides) from the SSO connection page in the WorkOS Dashboard and paste it into the input field. ![App registration form with name, supported account types, and redirect URI fields](https://images.workoscdn.com/images/d09699ac-00d4-4a8f-9ff7-9090c79d805b.png?auto=format&fit=clip&q=50) Click **Register**. --- ## (2) Obtain required configuration details Now you'll need to gather three pieces of information from your Entra ID application that will be configured in your WorkOS dashboard: the client ID, client secret, and discovery endpoint. Keep these values handy to input into the WorkOS Dashboard. ### Get the client ID From the application **Overview** page, copy the **Application (client) ID**. ![Entra ID application Overview page showing Application (client) ID field](https://images.workoscdn.com/images/70506649-66e4-490a-82b0-69175d0f3381.png?auto=format&fit=clip&q=50) ### Create and retrieve the client secret Navigate to the **Certificates & secrets** page. Click **New client secret**. ![Certificates & secrets page with "New client secret" button](https://images.workoscdn.com/images/28afb31c-3e94-4263-aedb-9924e0a4678d.png?auto=format&fit=clip&q=50) Enter an appropriate secret description and select an expiration period. Click **Add**. ![Add a client secret panel with the description, expires at fields highlighted](https://images.workoscdn.com/images/6d72665b-7ad0-4837-ac58-b9acbe2d7fee.png?auto=format&fit=clip&q=50) Copy the newly created client secret **Value** immediately as it will not be shown again after you navigate away from this page. ![Client secret creation form with description field and generated secret value](https://images.workoscdn.com/images/7e1604a5-1bdb-4a0c-80d5-8b4401c4269e.png?auto=format&fit=clip&q=50) ### Get the discovery endpoint From the application **Overview** page, click the **Endpoints** tab. ![Entra ID application Overview page with Endpoints tab highlighted](https://images.workoscdn.com/images/70fee14e-bb7d-43ab-8bb8-70150af299b6.png?auto=format&fit=clip&q=50) Scroll down to find and copy the **OpenID Connect metadata document** URL. This is your Discovery Endpoint. ![Endpoints list showing OpenID Connect metadata document URL](https://images.workoscdn.com/images/aca9c724-2a6f-4449-b435-f63bd538d60f.png?auto=format&fit=clip&q=50) ### Update the SSO connection settings Back in the WorkOS Dashboard on the SSO connection page, enter the client ID, client secret, and discovery endpoint you obtained from Entra ID into the respective fields in the **\{SSO connection name\} Settings** section. ![WorkOS Dashboard Identity Provider Configuration with Client ID, Client Secret, and Discovery Endpoint fields](https://images.workoscdn.com/images/714cb015-94db-4080-ad53-942da1804c01.png?auto=format&fit=clip&q=50) Click **Update connection** to save. --- ## (3) Configure token claims Navigate to the **Token configuration** page. Click **Add optional claim**. ![Token configuration page with "Add optional claim" button](https://images.workoscdn.com/images/c71dc730-995d-48d3-a5eb-3b28166fa6c0.png?auto=format&fit=clip&q=50) Select **ID** token type, and then select the following claims: - `email` - `family_name` - `given_name` ![Optional claims dialog with ID token type selected and email, family_name, given_name claims](https://images.workoscdn.com/images/0cfa531a-de60-4ead-9655-0a473dbd5658.png?auto=format&fit=clip&q=50) Click **Add**. In the pop-up, select **Turn on the Microsoft Graph email, profile permission**, then click **Add**. ![Add optional claim panel with turn on Microsoft Graph checkbox highlighted](https://images.workoscdn.com/images/644ac9db-6bb6-4ca5-bd65-af23ceec5b6a.png?auto=format&fit=clip&q=50) --- ## (4) Assign users and groups In the left navigation menu, expand the **Identity** section. Expand the **Applications** sub-section. Select the **Enterprise applications** tab. Search for your application by name and select it. ![Enterprise applications search interface with application list](https://images.workoscdn.com/images/7ca10480-3bc6-4d1e-99cd-7de8543e374d.png?auto=format&fit=clip&q=50) From the Enterprise application page, select the **Users and groups** tab. Click **Add user/group**. ![Enterprise application Users and groups tab with "Add user/group" button](https://images.workoscdn.com/images/15448828-6288-4350-9ac3-27c9997f04e4.png?auto=format&fit=clip&q=50) Select appropriate users and groups to add to the OIDC application. ![User and group assignment interface with selection options and Assign button](https://images.workoscdn.com/images/e3964bfc-92b2-497d-b291-098cbe1ee94f.png?auto=format&fit=clip&q=50) When finished, click **Assign** to add the selected users to your OIDC application. ![Add assignment page with Assign button highlighted](https://images.workoscdn.com/images/80e136c6-6e9f-41f4-aed9-85421746906b.png?auto=format&fit=clip&q=50) --- ## (5) Role assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. Users will automatically be granted the assigned roles within your application when they authenticate. To enable this functionality: ### Configure groups claim in Entra ID From the app registration, navigate to the **Token configuration** page. Click **Add groups claim**. ![Token configuration page with "Add groups claim" button](https://images.workoscdn.com/images/d6342c8f-1f32-43c3-a91e-16cacdd62b31.png?auto=format&fit=clip&q=50) In the **Group Claims** panel, select appropriate groups. For example, you could select **Groups assigned to the application** to only send groups assigned to the OIDC app in Entra ID. Click **Add**. ![Group Claims configuration panel with group selection options](https://images.workoscdn.com/images/5cf70ad4-6eb3-4f6e-87c6-16b15c1c781f.png?auto=format&fit=clip&q=50) ### Configure role assignment in WorkOS From the SSO connection page in the [WorkOS Dashboard](https://dashboard.workos.com/), scroll to the **Groups and role assignments** section. ![WorkOS dashboard highlighting create group button](https://images.workoscdn.com/images/c29ef1a7-d873-49f6-ad43-8c945245a033.png?auto=format&fit=clip&q=50) For each group you want to assign a role, click the **Create group** button and enter the following: 1. Copy the group id from Entra ID into the **IdP ID** field. 2. Optionally, enter a group name into the **Name** field. 3. Assign the appropriate role to the group. ![WorkOS dashboard with open create group dialog and idp_id, name, and role assignment inputs](https://images.workoscdn.com/images/d542c8c3-e032-41a6-ae72-c8dc586ec88d.png?auto=format&fit=clip&q=50) > Group members without an explicit role will receive the default role. --- ## Next steps Your Entra ID OIDC connection is now configured and ready to use. Users assigned to the application in Entra ID will be able to authenticate through WorkOS using their Microsoft credentials. To start using this connection in your application, refer to the [SSO guide](/sso) for implementation details. ### Duo Learn how to configure a connection to Duo via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a Duo SAML Connection, you’ll need three pieces of information: an [ACS URL](/glossary/acs-url) (provide by WorkOS), an [SP Entity ID](/glossary/sp-entity-id) (provided by WorkOS), and the [Metadata URL](/glossary/idp-metadata) (provided by Duo). Duo is also unique in that it requires a 3rd party IdP to federate the authentication. This means that along with the three pieces of information, you’ll also need to configure a Single Sign-On Authentication Source and a Cloud Application in your Duo Workspace. The high level overview of the authentication flow: Your App → WorkOS → Duo → Your SSO IdP → Duo → WorkOS → Your App ![A flowchart showing the authentication flow of Duo using WorkOS.](https://images.workoscdn.com/docs/integrations/sso/duo-saml/v1/duo-saml-1.png?auto=format&fit=clip&q=50) --- ## (1) Create a new Duo SAML Connection in WorkOS Navigate to the Organization in your WorkOS Dashboard under which you would like to set up this new SSO Connection. Click “Manually Configure Connection” and select Duo SAML from the list of SSO Identity Providers. You’ll want to select “Duo SAML” as the Identity Provider and give the Connection a descriptive name. Once this is filled out, click “Create Connection”. ![A screenshot showing how to create a Duo SAML connection in the WorkOS dashboard.](https://images.workoscdn.com/images/cfd42823-38c8-4994-b05c-b7c3609d1755.png?auto=format&fit=clip&q=50) Take note of the Connection Details as you’ll need to enter those in Duo later on. This page is also where you’ll enter the Metadata URL in a later step. ![A screenshot showing where to access Service Provider details in the connection settings.](https://images.workoscdn.com/images/98f72b30-9e6b-4e96-be86-176939471b6b.png?auto=format&fit=clip&q=50) --- ## (2) Select or create your application WorkOS will allow you to use any Duo supported IdP to handle the Federated authentication. Since each IdP will have different ways of setting up the SSO connection between Duo and the IdP, please refer to the [documentation that Duo provides to configure a Duo SSO Connection](https://duo.com/docs/sso#enable-duo-single-sign-on). --- ## (3) Create a Cloud Application in Duo After configuring the Duo SSO Connection with the IdP of your choice, the next step is to create a Cloud Application in Duo. This app will handle the connection between WorkOS and Duo. Navigate to the Duo Admin Panel and click on Applications on the left sidebar. Click “Protect an Application” and locate the entry for “Generic SAML Service Provider” with a protection type of “2FA with SSO hosted by Duo (Single Sign-On)” in the applications list. Click _Protect_ to the far-right to start configuring “Generic SAML Service Provider”. ![A screenshot showing how to create a Cloud App in Duo.](https://images.workoscdn.com/images/8404f0a8-a56f-4c58-b03e-d0ec48ef66b8.png?auto=format&fit=clip&q=50) Next, configure the Generic Service Provider settings. There are pieces of information on this page that need to come from WorkOS and your Duo SSO Connection, and also information to copy and enter in the WorkOS Connection. Start by gathering the Metadata URL to enter in the WorkOS Duo SAML Connection that you created in the prior step. ![A screenshot showing where to copy the IdP Metadata URL in Duo.](https://images.workoscdn.com/images/250ed44e-4044-441e-ab02-a045ed011cb2.png?auto=format&fit=clip&q=50) --- ## (4) Enter Duo SAML Settings in your WorkOS Dashboard Navigate to your WorkOS Duo SAML Connection and paste the Metadata URL in to the Metadata field. You won’t see the connection flip to Active yet as there is still some configuration to do on the Duo side. ![A screenshot showing how to add the IdP metadata in the WorkOS dashboard.](https://images.workoscdn.com/images/73a827e1-fa4f-4399-a1e6-3589abd0874a.png?auto=format&fit=clip&q=50) From the WorkOS Connection page you are currently on, copy the ACS URL value from the field just above the SAML Settings. ![A screenshot highlighting the ACS URL in the WorkOS dashboard.](https://images.workoscdn.com/images/45ce0799-449b-417e-8f2b-08cdaacdfea6.png?auto=format&fit=clip&q=50) Navigate to the Duo Applications Generic Service Provider configuration settings and paste the ACS URL in the Assertion Consumer Service (ACS) URL field under the Service Provider section. ![A screenshot showing where to input the ACS URL in Duo settings.](https://images.workoscdn.com/images/d7bff970-44e9-4320-b675-53d54d2ab4c9.png?auto=format&fit=clip&q=50) Next, copy the SP Entity ID value from the WorkOS Connection page. ![A screenshot highlighting the Entity ID in the WorkOS dashboard.](https://images.workoscdn.com/images/5dfd097f-1027-48af-9cdc-6ad2fd97f3d3.png?auto=format&fit=clip&q=50) Paste the SP Entity ID into the Entity ID field under the Service Provider section in the Duo Applications Generic Service Provider configuration. You may leave the Single Logout URL, Service Provider Login URL, and Default Relay State fields empty. ![A screenshot showing where to input the Entity ID in Duo settings.](https://images.workoscdn.com/images/5938b3ee-95a7-4dcf-aa2a-9e064d8c8311.png?auto=format&fit=clip&q=50) Scroll down on this page to the SAML Response section. Ensure that the NameID format has the id that you’d like to use for the unique identifier selected and matches the NameID attribute that you’d like to use as the value. If you’re using email as the unique ID, the options would look like the below. ![A screenshot showing how to configure SAML Response NameID in Duo.](https://images.workoscdn.com/images/e2ae9786-2a3f-4408-9c15-b33ba4c34f39.png?auto=format&fit=clip&q=50) Ensure the Signature algorithm is SHA256 and that the Signing options have both Sign response and Sign assertion selected. ![A screenshot showing where to configure the SAML Response Signing.](https://images.workoscdn.com/images/c491cab0-5abe-4b63-89cc-c5b8dbed9657.png?auto=format&fit=clip&q=50) Next make sure that you are mapping the attributes which WorkOS requires: `id`, `email`, `firstName`, and `lastName`. In the Map Attributes section enter these on the right side under SAML Response Attribute. on the left side, click the empty field box and select the pre-populated values that look like ``. Duo will automatically grab the corresponding fields and map them to the expected values. You can map any values you like, but WorkOS requires that these four values are included in SAML responses. If your users don’t have a last name value for instance, you could map Display Name or any other value to `lastName`, but `lastName` still needs to be included or WorkOS will reject the SAML Response. Here’s an example of the attribute mappings: ![A screenshot showing where to configure SAML Attribute Mapping in Duo.](https://images.workoscdn.com/images/dc4517d1-7f02-4199-a06e-e3d31ac56b76.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, follow the guidance below. In the "Role Attributes" section, enter `groups` as the "Attribute name". Then map the role names to their corresponding Duo groups. In the example below, the "Admins" role is mapped to the Admins group and the "Developers" role is mapped to the Developers group. ![A screenshot showing how to configure a groups attribute in Duo.](https://images.workoscdn.com/images/a13b9af3-65fc-4595-acd6-ecc3bc026fc3.png?auto=format&fit=clip&q=50) > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. ### Save your changes You may leave all of the other fields as their defaults. Scroll to the very bottom of the page and click the Save button. ![A screenshot highlighting the finished SAML Configuration in Duo.](https://images.workoscdn.com/images/dbe959a3-41eb-4dca-b1bd-69f1a389b10e.png?auto=format&fit=clip&q=50) --- ## (5) Verify Connection Status in WorkOS Navigate back to the WorkOS dashboard. After a minute or two you should see the Connection become Active as indicated by the green badge next to the connection name. ![A screenshot highlighting active status of the Duo connection.](https://images.workoscdn.com/images/9d79fcfe-386d-4bd7-a69d-e8e0578f0352.png?auto=format&fit=clip&q=50) ### CyberArk SCIM Learn about syncing your user list with CyberArk SCIM. ## Introduction This guide outlines how to synchronize your application’s CyberArk directories using SCIM. To synchronize an organization’s users and groups provisioned for your application, you’ll need to provide the organization with two pieces of information: - An [Endpoint](/glossary/endpoint) that CyberArk will make requests to. - A [Bearer Token](/glossary/bearer-token) for CyberArk to authenticate its endpoint requests. After completing step 1 below, both of these are available in your Endpoint’s Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). > The rest of the steps below will need to be carried out by the organization when configuring your application in their CyberArk instance. --- ## (1) Set up your directory in the WorkOS Dashboard In your WorkOS Dashboard, select or create an Organization. Then select “Manually Configure Directory”. ![A screenshot showing where to select "Manually Configure Directory" in the WorkOS dashboard.](https://images.workoscdn.com/images/2865e608-6524-4bd6-8f35-070de0d6cf2b.png?auto=format&fit=clip&q=50) Select “CyberArk” as the Directory Provider and add a descriptive name for the directory sync connection. ![A screenshot showing the proper configuration of the "Create Directory" modal in the WorkOS dashboard.](https://images.workoscdn.com/images/ea86a861-c18c-4d8b-ad92-5942f11a98c7.png?auto=format&fit=clip&q=50) On the Directory Sync connection settings page, save the Endpoint and the Bearer Token. You’ll input these in the CyberArk settings. ![A screenshot showing the Endpoint and Bearer Token in the WorkOS dashboard.](https://images.workoscdn.com/images/f77f41f5-8641-4452-b933-3a2d3f2351c5.png?auto=format&fit=clip&q=50) > We have support for whitelabeled URLs for Directory Sync endpoints. [Contact us](mailto:support@workos.com) for more info! --- ## (2) Select or create your CyberArk application CyberArk supports SCIM provisioning in the context of a SAML app. The usual set up is to enable SAML first, following [our docs here](/integrations/cyberark-saml). Log in to the CyberArk Admin Portal, and navigate to your SAML app. Open the “Provisioning” tab, and select the box to “Enable provisioning for this application”. ![A screenshot showing where to enable the "Enable provisioning for this application" setting in the CyberArk dashboard.](https://images.workoscdn.com/images/83b18d01-90d6-4cf2-8866-84c2046cd1f5.png?auto=format&fit=clip&q=50) Click “Yes” in the confirmation modal. ![A screenshot showing where to select "Yes" in the confirmation modal in the CyberArk dashboard.](https://images.workoscdn.com/images/38f35897-4fb6-47d0-9445-53b0405b8809.png) Enter the Endpoint from the WorkOS Dashboard into the "SCIM Service URL" field, and enter the Bearer Token from the WorkOS Dashboard into the corresponding field in the Provisioning tab. Select “Verify” to save these credentials. ![A screenshot showing where to input the WorkOS Endpoint as the "SCIM Service URL" and the Bearer Token in the CyberArk dashboard.](https://images.workoscdn.com/images/2bee64a8-cbb8-4d31-9f35-4f2bb3c237bd.png) Once the credentials have been verified, more options will be appear below. Deselect "Do not de-provision (deactivate or delete) users in target application" as seen below. ![A screenshot showing which checkboxes to disable in the CyberArk dashboard.](https://images.workoscdn.com/images/f8e6980a-76f7-4cf5-a5c5-958dae8268ba.png) --- ## (3) Configure your role mappings in CyberArk Users assigned to the SAML app will be synced, and roles mapped will be synced as groups. The roles are mapped on the Provisioning settings page, by selecting the “Add” button. ![A screenshot showing where to select “Add” in the CyberArk dashboard.](https://images.workoscdn.com/images/8a6039da-ccc0-493d-9888-40337e70da74.png) In the role mapping modal, select the role you’d like to map, and then create a destination group. The name will be what you see as the group name in directory sync. All users assigned to that role will be members of the mapped group. Select “Done”. ![A screenshot showing how to configure the "Role" and "Destination Group" settings in the "Role Mapping" modal of the CyberArk dashboard.](https://images.workoscdn.com/images/34f5f6cf-5011-4540-a911-d68d583e8411.png) After the role mapping is completed, click “Save”. The SCIM configuration part of the setup is complete. --- ## (4) Trigger the directory sync run in CyberArk In CyberArk, navigate to the Settings → Users → Outbound Provisioning page. Under Synchronizations, start the sync. You can also set up scheduled syncs here. ![A screenshot showing where to select "Start Sync" in the "Outbound Provisioning" settings in the CyberArk dashboard.](https://images.workoscdn.com/images/fe15e2da-4312-4b22-9750-6d9657d569f2.png) In the CyberArk SCIM directory in the WorkOS dashboard, select the "Users" tab and you will now see the users and groups synced over. ![A screenshot showing the populated "Users" tab in the CyberArk SCIM directory in the WorkOS dashboard.](https://images.workoscdn.com/images/fd7f1d1b-4390-44e5-9aa6-95308d911829.png) A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) ## Frequently asked questions ### When a group is removed, I don't see a `dsync.group.deleted` or `dsync.group.user_removed` events - is this expected? Instead of individually assigning users to a SCIM application, CyberArk SCIM requires that users are assigned to the application through group membership. It is a known issue with CyberArk SCIM that when a group is removed from the app, no indication is received that the group has changed. The users of the group must be cleaned up before the group itself is removed from the SCIM application. ### CyberArk SAML Learn how to configure a connection to CyberArk via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a CyberArk SAML Connection, you’ll need the Identity Provider metadata that is available from your CyberArk instance. --- ## What WorkOS provides The first thing you’ll need to do is create a new CyberArk SAML connection in your [WorkOS dashboard](https://dashboard.workos.com/). Start by logging in to your WorkOS dashboard and browse to the “Organizations” tab on the left hand navigation bar. Select the organization you’d like to configure a CyberArk SAML Connection for, and then click “Manually Configure Connection”. ![A screenshot showing where to select "Manually Configure Connection" in the WorkOS dashboard.](https://images.workoscdn.com/images/72c85573-ffe7-4be4-8fe1-2ea60db0c77a.png?auto=format&fit=clip&q=50) Select “CyberArk SAML” as the Identity Provider, give the Connection a descriptive name, and click “Create Connection”. ![A screenshot showing the "Create Connection" modal in the WorkOS dashboard.](https://images.workoscdn.com/images/d5ef1aab-8d6d-47ff-9af8-ae237ed31440.png?auto=format&fit=clip&q=50) WorkOS provides the [ACS URL](/glossary/acs-url) and [SP Entity ID](/glossary/sp-entity-id). They are readily available in your Connection Settings in the [WorkOS dashboard](https://dashboard.workos.com/). ![A screenshot showing where to locate the "ACS URL" and "SP Entity ID" in the WorkOS dashboard.](https://images.workoscdn.com/images/d443909c-712a-4084-9ac8-2b47f560a6fa.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. In CyberArk’s case, it needs to be set by the organization when configuring your application in their CyberArk instance. The SP Entity ID is a URI used to identify the issuer of a SAML request and the audience of a SAML response. In this case, the SP Entity ID is used to communicate that WorkOS will be the party performing SAML requests to the organization's CyberArk instance, and that WorkOS is the intended audience of the SAML responses from the CyberArk instance. Specifically, the ACS URL will need to be set as the “Assertion Consumer Service (ACS) URL”, and the SP Entity ID will need to be set as the “SP Entity Id / Issuer / Audience”, in the “Service Provider Configuration” section of the “Trust” tab in the SAML App. ![A screenshot showing where to input the WorkOS ACS URL and SP Entity ID in the “SP Entity ID” and "ACS URL" fields in the CyberArk dashboard.](https://images.workoscdn.com/images/bb1b0fe6-0e13-4c45-8bfd-fd0b4d9dc028.png?auto=format&fit=clip&q=50) --- ## What you’ll need Next, provide the Identity Provider metadata. Normally, this information will come from the organization's IT Management team when they set up your application’s SAML configuration in their CyberArk Identity Admin Portal. If that’s not the case during your setup, the following steps describe how to get the necessary information. --- ## (1) Log in Log in to the [CyberArk Identity Admin Portal](https://pod0.idaptive.app/my) and select “Web Apps” from the left-side navigation. ![A screenshot showing where to select 'Web Apps" in the CyberArk dashboard.](https://images.workoscdn.com/images/1e496ecf-4948-4161-8d0e-7dd085d1cc74.png?auto=format&fit=clip&q=50) --- ## (2) Select or create your application If your application is already created, select it from the list of applications and move to Step 4. If you haven’t created a SAML application in CyberArk, select “Add Web Apps”. ![A screenshot showing where to select "Add Web Apps" in the CyberArk dashboard.](https://images.workoscdn.com/images/034f7256-e5d1-40bf-a258-4532ba462966.png?auto=format&fit=clip&q=50) Select the “Custom” tab and then click to add “SAML”. ![A screenshot showing how to select the "SAML" web application type in the CyberArk dashboard.](https://images.workoscdn.com/images/48709bed-91f5-4549-8fec-3766ca10b5ee.png?auto=format&fit=clip&q=50) Select “Yes” to begin setting up the SAML App. ![A screenshot indicating to select "Yes" in the confirmation to add the new application in the CyberArk dashboard.](https://images.workoscdn.com/images/2877ea73-3e8b-4370-9dd2-b3a64ea8990a.png?auto=format&fit=clip&q=50) --- ## (3) Initial SAML Application Setup Enter a descriptive App Name and Description, then click “Save”. ![A screenshot showing how to populate the "Name" and "Description" fields in the CyberArk dashboard.](https://images.workoscdn.com/images/bb5bf913-edae-4286-9a72-20eaa12ca1e7.png?auto=format&fit=clip&q=50) Next, navigate to the “Trust” tab and enter the SP Entity ID from the Connection Settings into “SP Entity Id / Issuer / Audience” and the ACS URL from the Connection Settings into “Assertion Consumer Service (ACS) URL” in the “Service Provider Configuration” section of the “Trust” tab in the SAML App. > IMPORTANT: Be sure to check “Both” under “Sign Response or Assertion?”. ![A screenshot showing where to input the WorkOS ACS URL and SP Entity ID in the “SP Entity ID” and "ACS URL" fields in the CyberArk dashboard.](https://images.workoscdn.com/images/bb1b0fe6-0e13-4c45-8bfd-fd0b4d9dc028.png?auto=format&fit=clip&q=50) --- ## (4) Configure Attribute Mapping Select the “SAML Response” tab and use the “Add” button to add the following key-value pairs. Then, click “Save”. - `id` → `LoginUser.Uuid` - `email` → `LoginUser.Email` - `firstName` → `LoginUser.FirstName` - `lastName` → `LoginUser.LastName` ![A screenshot showing the "SAML Response" tab successfully configured in the CyberArk dashboard.](https://images.workoscdn.com/images/63c47f86-6205-4c23-b4b2-1c2950d94fe7.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, first add a new attribute in the "SAML Response" tab. In the "Attribute Name" column, input `groups`, and map it to the "Attribute Value" for a user’s group membership, such as `LoginUser.GroupNames`, as shown in the example below. ![A screenshot showing the groups attribute successfully configured in CyberArk.](https://images.workoscdn.com/images/e5b30513-3915-46a3-b876-650898f8f288.png?auto=format&fit=clip&q=50) Once your SAML app is configured to return groups, navigate to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (5) Add Users to SAML Application To give users permission to authenticate via this SAML app, you will need to assign individual users and/or groups of users to the CyberArk SAML app. Click on the “Permissions” tab, and select “Add”. ![A screenshot showing where to select "Add" in the "Permissions" tab of the application in the CyberArk dashboard.](https://images.workoscdn.com/images/473838e4-cf5f-4feb-a577-f167ac907f01.png?auto=format&fit=clip&q=50) Search for the individual user(s) and/or group(s) that you would like to assign to the app, and check the box next to them. Click “Add” when you are finished. Once users have been successfully added, you should also notice the “Status” of your CyberArk SAML app change to “Deployed”. ![A screenshot showing the selection of a user to add to the SAML application in the CyberArk dashboard.](https://images.workoscdn.com/images/a09d23b6-5eb7-4fdf-999b-fff77159d43c.png?auto=format&fit=clip&q=50) --- ## (6) Copy Metadata On the “Trust” tab of the SAML App, go to the “Service Provider Configuration Section” and select “Metadata”. Then click on “Copy URL” button to copy the Metadata URL. This URL will get entered in the WorkOS dashboard in the next step. ![A screenshot showing where to obtain the "Metadata URL" in the CyberArk dashboard.](https://images.workoscdn.com/images/5da3432f-1105-44f1-9433-d1002d1c832d.png?auto=format&fit=clip&q=50) --- ## (7) Provide Metadata Finally, select "Edit Metadata Configuration" and input the Metadata URL in your WorkOS Connection Settings. Your Connection will then be verified and good to go! ![A screenshot showing where to select "Edit Metadata Configuration" in the "Identity Provider Configuration" in the WorkOS dashboard.](https://images.workoscdn.com/images/bedce7fc-3dcd-468d-ab31-1e65f8f14cb9.png?auto=format&fit=clip&q=50) ### Cloudflare Learn how to configure a connection to Cloudflare via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a Cloudflare SAML Connection, you’ll need to manually enter the SSO URL, [IdP Entity ID](/glossary/idp-uri-entity-id), and X.509 Certificate obtained from your Cloudflare instance. Instructions on where to obtain these will be covered in this guide. --- ## What WorkOS provides The first thing you’ll need to do is create a new Cloudflare SAML connection in your [WorkOS Dashboard](https://dashboard.workos.com/). Start by logging in to your WorkOS dashboard and browse to the “Organizations” tab on the left hand navigation bar. Select the organization you’d like to configure a Cloudflare SAML Connection for, and from the dropdown menu select “Add Connection”. ![A screenshot showing how to add an SSO connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/685a5cfc-14f2-44b9-95de-3b6af1c1b4b1.png?auto=format&fit=clip&q=50) Select “Cloudflare SAML” as the Identity Provider and give the Connection a descriptive name. Once this is filled out, click “Create Connection”. ![A screenshot showing how to create a Cloudflare SAML Connection.](https://images.workoscdn.com/images/bb5d99c0-0f69-4ef6-b67d-654dd2311745.png?auto=format&fit=clip&q=50) WorkOS provides the [ACS URL](/glossary/acs-url) and the [SP Entity ID](/glossary/sp-entity-id). These are available in your Connection’s Settings in the Developer Dashboard. ![A screenshot showing where to find the Service Provider details in the WorkOS Dashboard.](https://images.workoscdn.com/images/bea6f73d-6dae-452b-be22-f22861c9497c.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. In Cloudflare’s case, it needs to be set by the organization when configuring the application in the Cloudflare instance. The SP Entity ID is a URI used to identify the issuer of a SAML request. In this case, the entity ID is used to communicate that WorkOS will be the party performing SAML requests to the organization's Cloudflare instance. --- ## What you’ll need Cloudflare SAML is a unique integration in that it sits between WorkOS and the Identity Provider. This allows for additional rules to be configured, but also means there are two connections that need to be made. The first necessary connection is between Cloudflare and the IdP, and the second connection is between WorkOS and Cloudflare. --- ## (1) Connect Cloudflare with your Identity Provider First, create the connection between Cloudflare and the Identity Provider. Cloudflare Access allows you to connect with any IdP that supports a SAML 2.0 connection. Follow the [documentation from Cloudflare](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/generic-saml) to configure a SAML application connection between Cloudflare and your IdP. The one deviation from the CloudFlare documentation is that the SAML attributes must include `email`, `firstName`, `lastName`, and `id`. Email is included by default as the “Email attribute name”, but you will need to add the other three as SAML attributes. When setting up the connection, be sure to enter `email`, `firstName`, `lastName`, and `id` as SAML attributes. ![A screenshot showing how to configure SAML attributes in Cloudflare Access.](https://images.workoscdn.com/images/57473539-2c40-4c16-b59b-471cbdce1764.png?auto=format&fit=clip&q=50) Save the connection and then click the “Test” button. When successful, you will see a success screen including your `saml_attributes` that have been added. ![A screenshot showing a successful test of Cloudflare Access.](https://images.workoscdn.com/images/bd575c26-8d01-4e12-8e7e-70198da3e33d.png?auto=format&fit=clip&q=50) --- ## (2) Add an Application in Cloudflare Access Next, create the connection between Cloudflare and WorkOS. From the Cloudflare Zero Trust dashboard Access menu, select “Applications”, then “Add an application”. ![A screenshot showing where to add an application in Cloudflare Access.](https://images.workoscdn.com/images/ae6525fa-194c-44f5-a20b-f6ea14667ec2.png?auto=format&fit=clip&q=50) Select “SaaS” for the type of application. ![A screenshot highlighting the SaaS application type in Cloudflare.](https://images.workoscdn.com/images/9202ac92-d1b7-4ad7-9c2d-486528e8edcb.png?auto=format&fit=clip&q=50) Copy the ACS URL and Entity ID from the Connection Settings in your WorkOS Dashboard. ![A screenshot showing where to find the Service Provider details in the WorkOS Dashboard.](https://images.workoscdn.com/images/bea6f73d-6dae-452b-be22-f22861c9497c.png?auto=format&fit=clip&q=50) Select the name of your application from the dropdown menu. If your application is not listed, type the name to save it. Paste the ACS URL and SP Entity ID to the corresponding fields in Cloudflare. Then select the Name ID Format that you would like to use for this application. For this example we’ll use Unique ID. ![A screenshot showing where to input Service Provider details into the Cloudflare application.](https://images.workoscdn.com/images/2417371c-2a7d-41e7-a98b-295461e1741f.png?auto=format&fit=clip&q=50) --- ## (3) Configure Attribute Mapping Now, Configure the attribute statements. WorkOS requires that `email`, `firstName`, `lastName`, and `id` be included. Cloudflare automatically sends `id` and `email`, so you only need to add `firstName` and `lastName`. These attributes were configured in Step 1, and the mapped values are the same here. Add `firstName` and `lastName` to both the right and left sides of the SAML attribute statements. ![A screenshot showing where to configure Cloudflare attribute mapping.](https://images.workoscdn.com/images/6d0a7e54-e912-4cb7-8688-427d595d30e6.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information, add a new attribute statement with `groups` as the "Name" and map it to the "IdP attribute" for `groups`, as shown in the example below. ![A screenshot showing how to configure a groups attribute in Cloudflare.](https://images.workoscdn.com/images/659df99d-79b9-4fd4-bcec-69b337504cfe.png?auto=format&fit=clip&q=50) #### Resolving groups attribute issues If you're having issues getting the `groups` attribute to come through, it's possible that Cloudflare is sending it as a nested structure, specifically an array of group objects rather than plain strings. WorkOS expects `groups` to be a top-level attribute where each value is a simple string, such as the group name or ID. To resolve this, go to the **Advanced Settings** section of your Cloudflare Access application and define a [JSONata transformation](https://developers.cloudflare.com/cloudflare-one/applications/configure-apps/saas-apps/generic-saml-saas/#jsonata-transforms) to map the structured `groups` attribute into the expected format. For example, to extract the `name` from each group object, use the following transformation: `$ ~> | $ | { "groups": groups.name } |` ![A screenshot showing JSONata transform applied to the groups attribute](https://images.workoscdn.com/images/3be403b4-26a1-40b6-a64e-3503f6f69a21.png?auto=format&fit=clip&q=50) This will transform an input like: ```json { "groups": [ { "name": "Engineering", "id": "abc123" }, { "name": "Finance", "id": "def456" } ] } ``` Into the expected format: ```json { "groups": ["Engineering", "Finance"] } ``` You may also use groups.id if you prefer to map group IDs instead. > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. --- ## (4) Finish SSO Application Configuration Select the Identity Provider that you are using from the list. In this example we are using an Okta SAML connection. ![A screenshot highlighting where to select the Identity Provider in the Cloudflare application.](https://images.workoscdn.com/images/0f4ea850-5111-4659-a67f-8887cde842dd.png?auto=format&fit=clip&q=50) Configure at least one policy and one rule, then click next. For this example the Policy sets the session length to 30 minutes for everyone. ![A screenshot showing where to configure policy and rules for the Cloudflare application.](https://images.workoscdn.com/images/c6141486-5b88-47e5-88d8-161294698ece.png?auto=format&fit=clip&q=50) --- ## (5) Copy Connection Credentials The SSO endpoint, Entity ID, and Public key (X.509 certificate) all will be entered in the Connection details in the [WorkOS Dashboard](https://dashboard.workos.com/). The SSO endpoint and Entity ID can be entered as-is, but the Public Key needs to be formatted as an X.509 certificate. ![A screenshot showing where to copy the connection credentials from the Cloudflare dashboard.](https://images.workoscdn.com/images/81f19129-0b22-4f78-b238-e9b087a3a52b.png?auto=format&fit=clip&q=50) To format the Public Key, copy the value to a text editor and add the following header and footer to the Public Key. Ensure there are no spaces above or below the Key value, then save with the file extension “.cert”. ```shell title="Certificate format" -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- ``` The format of the file should look like this when you’re finished. ```shell title="Completed Certificate Format" -----BEGIN CERTIFICATE----- MIIDUTCCAjmgAwIBAgIRAN557boQ2ZxW4Ww08cZYK2IwDQYJKoZIhvcNAQELBQAw YjELMAkGA1UEBhMCVVMxDjAMxxxxxAgTBVRleGFzMQ8wDQYDVQQHEwZBdXN0aW4x EzARBgNVBAoTCkNsb3VkZmxhcmUxHTAbBgNVBAMTFGNsb3VkZmxhcmVhY2Nlc3Mu Y29tMB4XDTxxxxxwMjE5MzMxM1oXDTMyMDIwMjE5MzMxM1owYjELMAkGA1UEBhMC VVMxDjAMBgNVBAgTBVRleGFzMQ8wDQYDVQQHEwZBdXN0aW4xEzARBgNVBAoTCkNs b3VkZmxhcmUxHTAbBgNVBAMTFGNsb3VkZmxxxxxhY2Nlc3MuY29tMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA49p6jXzk65DeG4DI2NgW0UOOJrd+9qYS OCuBYq/e4IqSeqchsm1JDY9MjB6xmiw+urC1qWuj0MS4dwAJQwiGFbCGDh5m4FAF mZm5VaMkW5Q+MG5zXRfeLmhvLuT0XVBcDlkwPC3k28/moKi1KlwPcujLF43+rf2d 8Rm6ZNCJgfVzRxxxxxPd5NGpNlEZ0ViPXM1gsO15/1Iginevv+xKqRTx0vMsNLWJ BwWLAAqm5b6U9XQefwy9lPqPywFwCuZEMXwI9Rpm0f2xmOK56EudtdSkQ1JtSgYX x9rf/97NfP8wI2x1IncQtwdWNdW5cvxMqYU/Za6WZvjNCnpFQGXLJQIDAQABowIw ADANBgkqhkiG9w0BAQsFAAOCAQEARZ0h2ZeNXSme0EbQeJfEFOX+mj9rPkHIJFfQ G7+dRG6DwDubxG56TsvUINcJX8O5C6oQ0T6dRutO/jG5LxJqmCz5wLUTA/6/YLDk 95gbYyJ/yfLm4sd6DEoXzWSld+EZ5b86pxFnvR/+cPY2tcSghQ+moZKR5THwHLsZ hie2Pr6UVvuS5D9BC4ijR+cPyB5r4qliI9C1p8phuZctoX9dPpFY+UwkWgUDx9sz UXFJsqueoibxfVqh4Jzdw+2XH6xN3WvTdJN4Sh1fqEpBeOxxxxxlRrCAJiMnLtG6 QgHF9ZnNRbIFcUHF/lyWY3oxcvgeUwEnE5QVVbdoMMGKKgffbQ== -----END CERTIFICATE----- ``` --- ## (6) Provide Connection Credentials Navigate to the Connection in your Developer Dashboard. Enter the SSO endpoint in the [IdP SSO URL](/glossary/idp-sso-url) field and enter the “Access Entity ID or Issuer” value into the “IdP URI (Entity ID)” field. Upload the file that you saved for the X.509 certificate to the “Add an X.509 Certificate” field. Click Save Configuration. ![A screenshot showing where upload the Metadata configuration details.](https://images.workoscdn.com/images/2d149107-fbc3-4e09-a644-b68dc5ff151b.png?auto=format&fit=clip&q=50) Your Connection will then be Active and good to go! ### Clever OIDC Learn how to configure a connection to Clever via OIDC. ## Introduction Each SSO identity provider requires specific information to create and configure a new [SSO connection](/glossary/connection). Often, the information required to create an SSO connection will differ by identity provider. To create a Clever OIDC SSO connection, you'll need three pieces of information: a [redirect URI](/glossary/redirect-uri), [client ID](/glossary/client-id), and [client secret](/glossary/client-secret). Start by logging into your WorkOS dashboard and navigate to the **Organizations** page from the left-hand navigation bar. Select the organization you'd like to configure a Clever OIDC SSO connection for, and select **Configure manually** under **Single Sign-On**. ![WorkOS Dashboard Organizations tab with "Configure manually" button highlighted](https://images.workoscdn.com/images/d577cfbe-028b-48cf-8cc0-4cd5d3adf853.png?auto=format&fit=clip&q=50) Select **Clever OIDC** from the identity provider dropdown. Click **Create Connection**. ![Create Connection form with Clever OIDC selected as Identity Provider](https://images.workoscdn.com/images/2a5545f1-70ea-4347-8d99-a39c5850085c.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides WorkOS provides the Redirect URI, which can be found in the **Service Provider Details** section on the SSO connection page in the [WorkOS Dashboard](https://dashboard.workos.com/). - [Redirect URI](/glossary/redirect-uri): The endpoint where identity providers send authentication responses after successful login ![The Redirect URI of a OIDC connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/062a78e9-1d87-4643-890f-ebd1221e645b.png?auto=format&fit=clip&q=50) The Redirect URI is the location an identity provider redirects its authentication response to. In Clever’s case, it needs to be added to the OAuth settings in the Clever admin as outlined in [step 1](/integrations/clever-oidc/1-configure-the-redirect-uri). --- ## What you'll need You will need to obtain two pieces of information from the organization: - [Client ID](/glossary/client-id): Application identifier from the OIDC provider - [Client secret](/glossary/client-secret): Authentication secret for the application Typically, this information comes from the organization's IT team when they set up your application's OIDC configuration in their Clever admin dashboard. However, if that’s not the case during your setup, the next steps will show you how to obtain it. --- ## (1) Configure the Redirect URI Sign in to [Clever](https://apps.clever.com/). In the left navigation bar, select the **Settings** tab. In the horizontal menu, select the **Integration** tab. Locate the **OAuth Settings** section and click **Edit**. ![Setting the redirect URI in the Clever admin dashboard](https://images.workoscdn.com/images/0f7a4169-8cf1-4239-9d03-9f2022fb6a88.png?auto=format&fit=clip&q=50) The **Update OAuth Settings** dialog will open. Copy the [Redirect URI](/integrations/clever-oidc/what-workos-provides) from the SSO connection page in the WorkOS Dashboard into the **REDIRECT URIS** field. Click **Save**. --- ## (2) Obtain configuration details While on the **Settings** tab in Clever, select the **General** tab in the horizontal menu. After creating an application, a client ID and client secret are provisioned. Locate the **CLIENT ID** and **CLIENT SECRET** fields and copy the values. ![Copying the client id and secret from the Clever admin dashboard](https://images.workoscdn.com/images/b4c527e1-0335-428e-a658-ef3ecfd820a3.png?auto=format&fit=clip&q=50) Back in the [WorkOS Dashboard](https://dashboard.workos.com/) on the SSO connection page, enter the client ID and client secret you obtained from Clever into the respective fields in the **Settings** section. ![WorkOS Dashboard Settings with Client ID and Client Secret fields](https://images.workoscdn.com/images/d7ebf399-4cc9-4588-9961-6160d6bbd9bf.png?auto=format&fit=clip&q=50) Click **Update connection** to save. --- ## (3) Test Single Sign-On Test signing in to verify that the single sign-on connection was configured correctly. From the SSO connection page in the WorkOS Dashboard, click **Test SSO** to initiate a test authentication flow. --- ## Next steps Your Clever OIDC connection is now configured and ready to use. Users assigned to the application in Clever will be able to authenticate through WorkOS using their Clever credentials. To start using this connection in your application, refer to the [SSO guide](/sso) for implementation details. ### ClassLink Learn how to configure a connection to ClassLink via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a ClassLink SAML Connection, you’ll need the Identity Provider Metadata URL that is available from the organization's ClassLink SAML instance. Start by logging in to your WorkOS dashboard and browse to the “Organizations” tab on the left hand navigation bar. Select the organization you’d like to configure a ClassLink SAML Connection for, and select “Manually Configure Connection” under “Identity Provider”. ![A screenshot showing the "Manual Configure Connection" option in the WorkOS Dashboard.](https://images.workoscdn.com/images/fe7f0470-1d95-4708-b364-6dfea9e94e59.png?auto=format&fit=clip&q=50) Select “ClassLink SAML” from the Identity Provider dropdown, enter a descriptive name for the connection, and then select the “Create Connection” button. ![A screenshot showing a ClassLink connection being created in the WorkOS Dashboard.](https://images.workoscdn.com/images/20fabb8d-91a2-4f7d-965f-837f886a8481.png?auto=format&fit=clip&q=50) --- ## What WorkOS provides WorkOS provides the [ACS URL](/glossary/acs-url), the [SP Metadata](/glossary/sp-metadata) link and the [SP Entity ID](/glossary/sp-entity-id). They are readily available in your Connection Settings in the [Developer Dashboard](https://dashboard.workos.com/). The SP Metadata link contains a metadata file that the organization can use to set up the SAML integration. ![A screenshot showing the Service Provider Details provided by WorkOS for a ClassLink connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/46a922ac-10d2-424a-9b10-762702f8fc05.png?auto=format&fit=clip&q=50) --- ## What you’ll need In order to integrate you’ll need the [IdP Metadata URL](/glossary/idp-metadata). Normally, this will come from the organization's IT Management team when they set up your application’s SAML 2.0 configuration in their ClassLink instance. Here’s how to obtain them: --- ## (1) Select or create your application Login to the ClassLink Management Console (CMC), click Single Sign-On and select SAML Console. Click ADD NEW or COPY EXISTING. Copy Existing contains pre-configured SAML apps which need to be updated to fit your unique settings. ![A screenshot showing where to select "Add Application" in the ClassLink console.](https://images.workoscdn.com/images/2adb6c82-eeb2-4fee-9eb1-cd1655d08e35.png?auto=format&fit=clip&q=50) --- ## (2) Initial SAML Application Setup Edit the new application by click the three dots menu icon, and then selecting Edit. ![A screenshot showing where to edit the ClassLink application.](https://images.workoscdn.com/images/70877547-fcac-40ec-a98f-87f5333ad59f.png?auto=format&fit=clip&q=50) Update the Metadata URL in the ClassLink application settings with the SP Metadata URL provided to you by WorkOS. ![A screenshot showing where to enter the SP Metadata URL in the ClassLink application settings.](https://images.workoscdn.com/images/d97393b1-5066-4f48-a6e4-bb5cf1a2c6c8.png?auto=format&fit=clip&q=50) --- ## (3) Configure SAML Application Under the “Attribute Mapping” section of the SAML app, map the following four attributes as shown below, and the select “Update”. - `id` → `Login id` - `email` → `Email` - `firstName` → `Given Name` - `lastName` → `Family Name` ![A screenshot showing how to input user attribute mapping in the ClassLink dashboard.](https://images.workoscdn.com/images/a6f3d9da-cb06-4eda-a243-f3fb84f9df76.png?auto=format&fit=clip&q=50) ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, map the groups in your identity provider to a SAML attribute named `groups`. > Finish role assignment set-up by navigating to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. ## (4) Upload Metadata URL Copy the IdP Metadata URL from your ClassLink SAML settings and upload it to your WorkOS Connection settings. ![A screenshot highlighting where the ClassLink Metadata URL is located in the ClassLink console.](https://images.workoscdn.com/images/a75ed9fa-3b21-469b-93e4-3b8483da3717.png?auto=format&fit=clip&q=50) In the Connection settings in the WorkOS Dashboard, click “Edit Metadata Configuration”. ![A screenshot highlighting the "Edit Metadata Configuration" button in a Connection details view in the WorkOS Dashboard.](https://images.workoscdn.com/images/c03dd1dc-84b3-4909-bee5-61249280e35f.png?auto=format&fit=clip&q=50) Paste the Metadata URL from ClassLink into the “Metadata URL” field and select “Save Metadata Configuration”. ![A screenshot showing how to input the Metadata URL into the Connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/88884c90-bb7d-4f18-9a7c-bb7c7ad1fee2.png?auto=format&fit=clip&q=50) Your Connection will then be linked and good to go! ### Cezanne HR Learn about syncing your user list with Cezanne HR. ## Introduction This guide outlines how to synchronize your application’s Cezanne HR directories. To synchronize an organization’s users and groups provisioned for your application, you’ll need the following information from the organization: - Cezanne HR Client ID - Cezanne HR Client Secret > Note: The Cezanne HR integration isn't enabled by default in the WorkOS Dashboard or Admin Portal. Please reach out to [support@workos.com](mailto:support@workos.com) or via your team’s WorkOS Slack channel if you would like Cezanne HR enabled. --- ## (1) Set up your Directory Sync Connection Login to your WorkOS Dashboard and select “Organizations” from the left hand navigation bar. Select the organization you’ll be configuring a new Directory Sync Connection with. Click “Manually Configure Connection”. ![A screenshot showing where to find "Manually Configure Directory" button for an organization in the WorkOS dashboard.](https://images.workoscdn.com/images/e65f54ae-6010-4492-a838-8583dc614e50.png?auto=format&fit=clip&q=50) Input the Name, and select “Cezanne HR” as the directory type. Click the “Create Directory” button. ![A screenshot showing "Create Directory" details in the WorkOS dashboard.](https://images.workoscdn.com/images/1217ac5a-6d04-4783-8ce5-b005c14aa005.png?auto=format&fit=clip&q=50) You will now see your Cezanne HR directory sync has created successfully with an input for the Client ID and Client Secret --- ## (2) Obtain a Cezanne HR Client ID and Client Secret To obtain these credentials, you will need to request a new API Application from the Cezanne HR Support Team. --- ## (3) Enter the details in the Directory’s detail page Click “Update Directory”. There are two fields to enter, the Client ID and Client Secret that Cezanne support provided for you. ![A screenshot showing where to find the "Update Directory" button in the WorkOS dashboard.](https://images.workoscdn.com/images/1b94ab4a-b001-47ea-a89f-548011881ff0.png?auto=format&fit=clip&q=50) --- ## (4) Sync Users and Groups to Your Application When the connection is successfully made, you will see the green “Linked” icon appear. Now, whenever the organization assigns users or groups to your application, you’ll receive Dashboard updates based on changes in their directory. Click on the “Users” tab in the Dashboard to view synced users. ![A screenshot showing where to find the "Users" tab in the WorkOS directory.](https://images.workoscdn.com/images/ed0393d9-84de-416b-8410-b5596e091d67.png?auto=format&fit=clip&q=50) A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) ## Frequently asked questions ### How often do Cezanne HR directories perform a sync? Cezanne HR directories poll every 30 minutes starting from the time of the initial sync. ### CAS SAML Learn how to configure a connection to CAS via SAML. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a CAS SAML Connection, you’ll need the Identity Provider Metadata URL that is available from your customer’s CAS SAML instance. --- ## What WorkOS provides WorkOS provides the [ACS URL](/glossary/acs-url), the [SP Metadata](/glossary/sp-metadata) link and the [SP Entity ID](/glossary/sp-entity-id). They are readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot highlighting the "Service Provider Details" of a CAS SAML connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/68f2825e-7787-4100-b7d5-8339ed75b6be.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. The SP Metadata link contains a metadata file that the organization can use to set up the SAML integration. The SP Entity ID is a URI used to identify the issuer of a SAML request, response, or assertion. --- ## What you’ll need In order to integrate you’ll need the [IdP Metadata URL](/glossary/idp-metadata). Normally, this will come from the organization’s IT Management team when they set up your application’s SAML 2.0 configuration in their CAS instance. But, should that not be the case during your setup, here’s how to obtain it. --- ## (1) Enter Service Provider Details Copy and paste the “ACS URL” and “SP Entity ID” into the corresponding fields for Service Provider details and configuration. For some setups, you can use the metadata found at the SP Metadata link to configure the SAML connection. --- ## (2) Obtain Identity Provider Metadata Copy the IdP Metadata URL from your CAS SAML settings and upload it to your WorkOS Connection settings. Your Connection will then be linked and good to go! ![A screenshot highlighting the "URL Metadata Configuration" input of a CAS SAML Connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/a32e166f-ab97-47f1-988d-6799b303160f.png?auto=format&fit=clip&q=50) Alternatively, you can manually configure the connection by providing the IdP URI (Entity ID), [IdP SSO URL](/glossary/idp-sso-url) and X.509 Certificate. ![A screenshot highlighting the "Switch to Manual Configuration" button on the URL Metadata Configuration modal of a CAS SAML connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/4b40807d-0f4c-4b0f-81a5-05f832b88b25.png?auto=format&fit=clip&q=50) ![A screenshot showing the input fields for manual configuration of a CAS SAML connection in the WorkOS Dashboard.](https://images.workoscdn.com/images/0eb372eb-551f-4ad8-8d89-9519ce10dfbe.png?auto=format&fit=clip&q=50) --- ## (3) Configure Attribute Mapping At minimum, the Attribute Statement in the SAML Response should include `id`, `email`, `firstName`, and `lastName` attributes. ### Role Assignment (optional) With [identity provider role assignment](/sso/identity-provider-role-assignment), users can receive roles within your application based on their group memberships. To return this information in the attribute statement, map the groups in your identity provider to a SAML attribute named `groups`. Once your SAML app is configured to return groups, navigate to the SSO connection page in the _Organization_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). Create SSO groups by referencing the group IdP ID. Then, assign roles to these SSO groups so group members are automatically granted roles within your application. ### Bubble Plugin Add WorkOS features to your Bubble application. ## Introduction The [Bubble plugin for WorkOS](https://bubble.io/plugin/workos-sso-1666727595127x530956156372516860) allows you to easily integrate [WorkOS API](/reference) endpoints in your application's workflows. This plugin includes actions for SSO, Directory Sync, Admin Portal, and webhook validation. --- ## Install the WorkOS SSO and API Plugins In the **Plugins** tab of your app editor in Bubble, click **Add Plugins**, then search for WorkOS. Install the plugins for both WorkOS SSO and WorkOS API and then click **Done**. ![A screenshot showing how to install the WorkOS SSO plugin in Bubble.](https://images.workoscdn.com/images/03cf97a8-e0e9-49bc-be67-e21501ff5ab4.png?auto=format&fit=clip&q=50) ![A screenshot showing how to install the WorkOS API plugin in Bubble.](https://images.workoscdn.com/images/165832c3-88d2-49e5-9153-8fd1009367aa.png?auto=format&fit=clip&q=50) The next step is to enter your secret keys/parameters on the **Plugins** settings page as seen below. The API key can be found in your WorkOS dashboard under **API Keys**. > In the WorkOS SSO plugin the API Key value can be entered directly. ![A screenshot showing where to enter environment variables in Bubble for the WorkOS SSO plugin.](https://images.workoscdn.com/images/40fd465f-b73c-4dd2-8478-375eb68757ae.png?auto=format&fit=clip&q=50) > In the WorkOS API plugin the API Key value needs to be preceded by **Bearer**. ![A screenshot showing where to enter environment variables in Bubble for the WorkOS API plugin.](https://images.workoscdn.com/images/4bd64da1-4212-4ef9-a1bc-8064d60eac64.png?auto=format&fit=clip&q=50) Now you’re set up to use the plugin directly in your workflows. --- ## Single Sign-On Whether you are implementing a Single Sign-On authorization flow for your application using a no-code platform or building your app from the ground up, the steps that you need to take on a high level are the same. You can find more information in our [SSO Quickstart Guide](/sso). ### Use SSO in a Workflow To configure SSO, you will need: - An active SSO connection, which can be configured manually or by using the [Admin Portal](/admin-portal). - A [connection](/reference/sso/connection) ID or [organization](/reference/organization) ID associated with the user logging in. If WorkOS does not handle user management on your application’s behalf, it is necessary to keep track of the association between your users and their WorkOS connection or organization IDs in your database. - [Redirect URI](glossary/redirect-uri), which is the URL to redirect the user to when they are authorized. This is provided by Bubble in the **Plugins** tab. Navigate to the **Workflow** page in your application and add a new event. Select the action that will trigger the workflow to start. In this case, the workflow is triggered when the submit button is clicked. Under the **Account** menu option, select **Signup/login with a social network**, then select **WorkOS SSO** from the **OAuth provider** dropdown menu. Enter either the connection ID, organization ID, or provider. > Select whether you will use connection, organization, or provider (OAuth connections only), and delete the other defaults. The value should be entered in the `organization=` format. ![A screenshot showing how to enter the parameter values in a Bubble workflow.](https://images.workoscdn.com/images/c39e8579-e064-4f79-b6ad-a3ec8d5c1118.png?auto=format&fit=clip&q=50) When a user launches this workflow, they will be prompted to log in through the associated WorkOS SSO connection. Upon a successful login, if the user does not exist in the application database, a new user will be created and logged in as the current user. If the user already exists, that user will be logged in as the current user. --- ## Directory Sync To start using [Directory Sync](/directory-sync), you will need to configure a new directory connection between your customer’s directory provider and WorkOS. This can be completed manually or by using the [Admin Portal](/admin-portal). Once a directory connection is activated in WorkOS, you can configure webhooks to send events to your Bubble application using the WorkOS plugin through a backend workflow. ### Enable backend workflows To enable backend workflows, navigate to the **Settings** page of your Bubble app under the **API** tab, and select **Enable Workflow API and backend workflows**. You are now able to configure backend workflows in the **Workflow** section. ![A screenshot showing how enable backend workflows in Bubble.](https://images.workoscdn.com/images/e3443ee9-38fb-4d1a-98d3-40d0af2bfa3d.png?auto=format&fit=clip&q=50) ### Create a new workflow to receive webhooks To create a new workflow that subscribes to WorkOS webhooks, navigate to the **Workflows** section of your app in Bubble and select **backend workflows** from the page selection dropdown. ![A screenshot showing how to navigate to and create a new backend workflow in Bubble.](https://images.workoscdn.com/images/ec2377c0-1d06-40a0-9608-710690f539b3.png?auto=format&fit=clip&q=50) Create a new API Workflow. In the **detected data option** ensure that **include headers** is selected before clicking **Detect data**. ![A screenshot showing how to configure a backend workflow to detect data in Bubble.](https://images.workoscdn.com/images/67a1be1b-7ec7-4f6a-8c30-d3804eca2aa7.png?auto=format&fit=clip&q=50) A pop-up window will show a test URL to validate the webhook body. ![A screenshot showing when a backend workflow is ready to detect data in Bubble.](https://images.workoscdn.com/images/070d64e5-899f-499c-9fca-74eb5cbc267a.png?auto=format&fit=clip&q=50) Navigate to the **Webhooks** tab in your WorkOS dashboard and enter this test URL as your webhook endpoint. ![A screenshot showing how to configure a webhook endpoint in the WorkOS dashboard.](https://images.workoscdn.com/images/85e7b624-c107-49d2-82af-9c7a026caeb9.png?auto=format&fit=clip&q=50) Then, click the **Send Test Event** button to send a test event. ![A screenshot showing where to send a test webhook event in the WorkOS dashboard.](https://images.workoscdn.com/images/87937fdf-a9e7-4804-a780-5e5d96b40a18.png?auto=format&fit=clip&q=50) Bubble will recognize the event and validate the endpoint. Click save to complete the subscription to WorkOS webhook events for this workflow. ![A screenshot showing a successfully detected webhook event in Bubble.](https://images.workoscdn.com/images/aa9531f1-7df5-4053-9021-e9cca649dbcc.png?auto=format&fit=clip&q=50) ### Implement the webhook validation action After the new workflow is set up to listen for new events, it is recommended that you use the webhook validation action to verify that the webhooks being received are from WorkOS. This action verifies the request is valid by using the webhook body, signature, and secret that you provide from your WorkOS dashboard. To properly define the webhook parameter, you should use the raw body text of the request data. Similarly, the `webhook_signature` should be defined using the `workos-signature` in the request data headers. ![A screenshot showing how to select the webhook validation action in Bubble.](https://images.workoscdn.com/images/e43720ac-5669-4a8d-8ac3-5a220ed2c730.png?auto=format&fit=clip&q=50) After the event is validated, you can use the data from the body to log the webhook and make changes to users. ### Reconcile the users The plugin also includes endpoints, documented under the directory sync section of the [API Reference](/reference), that can be used to reconcile users. Periodically calling the [List Directory Users](/reference/directory-sync/directory-user/list) endpoint and verifying that the returned date matches what you have stored in your user table helps ensure your application has up-to-date information about your users, so you can use it with confidence. --- ## Admin Portal The [Admin Portal](/admin-portal) provides an out-of-the-box UI for organization admins to configure SSO and Directory Sync connections. The WorkOS API plugin provides an API call that launches the Admin Portal if you would like to display it on the settings page of your application. You can also copy and paste these links directly from the WorkOS dashboard in the connection settings. Upon completing the setup flow with the Admin Portal, the organization admin will be able to test the new connection and validate that it has been configured correctly. ![A screenshot showing how to select the admin portal action in Bubble.](https://images.workoscdn.com/images/14cafa76-cb94-4880-800c-5b8b2aa93777.png?auto=format&fit=clip&q=50) ### Breathe HR Learn about syncing your user list with Breathe HR. ## Introduction This guide outlines how to synchronize your application’s Breathe HR directories. To synchronize an organization’s users and groups provisioned for your application, you’ll need the following information from the organization: - Breathe HR API key > Note: The Breathe HR integration isn't enabled by default in the WorkOS Dashboard or Admin Portal. Please reach out to [support@workos.com](mailto:support@workos.com) or via your team’s WorkOS Slack channel if you would like Breathe HR enabled. --- ## (1) Create an API Key The organization will need to create an API key for you. An API key can be generated from the Admin Settings menu. ![A screenshot showing where to select "Settings" in the Breathe HR dashboard.](https://images.workoscdn.com/images/3defb6ef-fe7d-458f-8639-d0410fc11f51.png) Under "Integrations", select "API Setup". ![A screenshot showing where to select "API Setup" in the Breathe HR dashboard settings.](https://images.workoscdn.com/images/d6c8d0e9-1d71-428e-b368-4bcd5240432c.png) Next, select "Enable API". ![A screenshot showing where to select "Enable API" on the "API Setup" page in the Breathe HR dashboard.](https://images.workoscdn.com/images/890c4a8e-4217-433f-b67f-037dda40a7c5.png) Verify that you’d like to enable the API to access user information. ![A screenshot showing to mark the checkbox denoting "I understand and want to continue" in the "Warning" modal in the Breathe HR dashboard.](https://images.workoscdn.com/images/e6623c61-c520-4636-a029-c91fb2b5a33f.png) Save the production API key – this will be used in the next step. ![A screenshot showing where to select the production API key in the "API Setup" section of the Breathe HR dashboard.](https://images.workoscdn.com/images/d66a8ba2-bcf6-44bf-a714-e08164cdf632.png) --- ## (2) Create your Directory Sync Connection Login to your WorkOS dashboard and select “Organizations” from the left hand Navigation bar Select the Organization you’d like to enable a Breathe HR Directory Sync connection for. On the Organization’s page click “Add Directory”. ![A screenshot showing where to select "Add Directory" in the WorkOS dashboard.](https://images.workoscdn.com/images/f6bdcf89-cfc4-46e6-a67c-d2f428e6052a.png) Select “Breathe HR” as the Directory Provider, and then provide a descriptive name for the connection. Select “Create Directory”. ![A screenshot showing the configuration of the "Create Directory" modal to create a Breathe HR Directory in the WorkOS dashboard.](https://images.workoscdn.com/images/32c361da-6bf7-428b-84c0-5b1f27db5c51.png) --- ## (3) Set up your Directory Sync Connection Click “Update Directory” on the Directory details page. ![A screenshot showing where to select "Update Directory" in the WorkOS dashboard.](https://images.workoscdn.com/images/d2f1bfb0-f119-4582-8c6c-83e11bbbbd87.png) Input the Breathe HR API key and click “Save Directory Details”. ![A screenshot showing the input of the Breathe HR API key into the "Directory Details" modal in the WorkOS dashboard.](https://images.workoscdn.com/images/12ede429-9f2b-4cff-8e30-00e2b3594a85.png) --- ## (4) Sync Users and Groups to Your Application Now, you should see users and groups synced over from Breathe HR. Departments from Breathe HR are synced as groups in WorkOS. All users are synced, but only those marked as “Current employee” or "Pending leaver" are active. ![A screenshot showing a successfully linked Breathe HR Directory in the WorkOS dashboard.](https://images.workoscdn.com/images/26b9a26a-1abc-4517-9251-104da59f7251.png) A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) ## Frequently asked questions ### How often do Breathe HR directories perform a sync? Breathe HR directories poll every 30 minutes starting from the time of the initial sync. ### BambooHR Learn about syncing your user list with BambooHR. ## Introduction This guide outlines how to synchronize your application’s BambooHR directories. To synchronize an organization’s users and groups provisioned for your application, you’ll need the following information from the organization: - The BambooHR subdomain. - A BambooHR API key to authenticate requests. > Note: The BambooHR integration isn't enabled by default in the WorkOS Dashboard or Admin Portal. Please reach out to [support@workos.com](mailto:support@workos.com) or via your team’s WorkOS Slack channel if you would like BambooHR enabled. --- ## (1) Create your Directory Sync Connection Login to your WorkOS Dashboard and select “Organizations” from the left hand navigation bar. Select the organization you’ll be configuring a new Directory Sync Connection with. Click “Manually Configure Connection”. ![A screenshot showing where to find “Manually Configure Connection” for an Organization in the WorkOS Dashboard.](https://images.workoscdn.com/images/60d14679-0ff2-4b7b-9e75-82ea0ae158f5.png?auto=format&fit=clip&q=50) Input the Name, and select “BambooHR” as the directory type. Click the “Create Directory” button. ![A screenshot showing "Create Directory" details in the WorkOS Dashboard.](https://images.workoscdn.com/images/e696881c-64b9-40c4-aa8e-593913179c92.png?auto=format&fit=clip&q=50) You will now see your BambooHR directory sync has created successfully with an [Endpoint](/glossary/endpoint), as well as fields to input your subdomain and API Key from BambooHR. --- ## (2) Retrieve the details from an organization IT admin To generate an API key, an IT admin should log into BambooHR and click their name in the upper right-hand corner of the BambooHR console. Select "API Keys" from the list. ![A screenshot showing where to find the "API Keys" option in the BambooHR Dashboard.](https://images.workoscdn.com/images/6165e109-527d-4960-adc2-b7882262e526.png?auto=format&fit=clip&q=80) Next, the IT admin should click “Add New Key”. ![A screenshot showing where to find the "Add New Key" in the BambooHR Dashboard.](https://images.workoscdn.com/images/eb6b50be-6a2c-478b-aa3f-0d7b69240ddd.png?auto=format&fit=clip&q=80) Give your key a descriptive name and select "Generate Key." ![A screenshot showing where to find "Generate Key" in the BambooHR Dashboard.](https://images.workoscdn.com/images/a176f1f3-10a0-4803-acd2-fbbe69fb9719.png?auto=format&fit=clip&q=80) Select "Copy Key" and save this API key, which you’ll upload in the next step. ![A screenshot showing where to find "Copy Key" in the BambooHR Dashboard.](https://images.workoscdn.com/images/69c5bff2-023f-4a1e-8cdf-48edc4609a29.png?auto=format&fit=clip&q=80) --- ## (3) Set up your Directory Sync Connection Click “Update Directory”. There are two fields to enter, one is the API key you created in step 2. The other is “Subdomain” which is the subdomain name of the Company’s BambooHR instance. ![A screenshot showing where to find the "Update Directory" button in the WorkOS Dashboard.](https://images.workoscdn.com/images/f562e95e-faf9-4658-ac27-1d1396abcccb.png?auto=format&fit=clip&q=50) --- ## (4) Sync Users and Groups to Your Application When the connection is successfully made, you will see the green “Linked” icon appear. Now, whenever your customer assigns users or groups to your application, you’ll receive Dashboard updates based on changes in their directory. A detailed guide to integrate the WorkOS API with your application can be found [here](/directory-sync) ## Frequently Asked Questions ### How do I add BambooHR's custom fields? For BambooHR's custom fields, please contact [support@workos.com](mailto:support@workos.com) with your directory ID and a list of the custom fields you would like to be added. ### How often do BambooHR directories perform a sync? BambooHR directories poll every 30 minutes starting from the time of the initial sync. ### AWS Cognito Learn how to use WorkOS with your existing AWS Cognito applications. ## Introduction This guide outlines the steps to make WorkOS SSO Connections available to AWS Cognito applications without requiring changes to your existing application code. The integration works by configuring WorkOS connections as third-party [Identity Providers](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-identity-federation.html) inside a Cognito User Pool which enables users to sign in to a Cognito application leveraging all SSO integrations supported by WorkOS. > The AWS Cognito integration is in feature preview. Reach out to [WorkOS support](mailto:support@workos.com?subject=AWS%20Cognito%20Integration) if you want early access. --- ## (1) Configure AWS IAM role WorkOS manages the configuration of the Cognito Identity Providers by leveraging AWS role delegation. You will need to create an IAM role in your AWS account that grants permissions to the WorkOS AWS account. This is can be easily accomplished through the AWS Console. ![Create AWS IAM role](https://images.workoscdn.com/images/0a36c5ff-505e-46ba-805a-66d13c9150ed.png?auto=format&fit=clip&q=50) The external ID will be provided by the WorkOS support team upon request. The AWS account ID should be `611361754156` which is the ID of a dedicated WorkOS AWS account used for Cognito integrations. You will need to attach the following policy to the role so that the Identity Providers can be managed when the role is assumed by WorkOS. ```json language="json" title="IAM Policy" { "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor", "Effect": "Allow", "Action": ["cognito-idp:*"], "Resource": "*" } ] } ``` Complete the creation of the role and take note of the name you provide as it will be used in the following step. ## (2) Provide AWS details to WorkOS Once the role has been configured you will need to provide the following details from your AWS account to the WorkOS support team. - Account ID - Role name - User pool ID Once the WorkOS support team has configured your AWS details, you should see Identity Providers configured in the specified User Pool for every connection configured in WorkOS. Newly added WorkOS connections will automatically be created in the specified User Pool. ## (3) Enable Identity Providers for App Client Now that the Identity Providers have been configured, they will need to be enabled for the App Client you wish to use the WorkOS Connections with. From the user pool navigate to **App integration** → **_Your App Client_** → **Edit hosted UI settings** and select the newly created Identity Providers. ![App Client Identity Provider settings](https://images.workoscdn.com/images/e0f4a7c1-4131-4110-a6a3-9f5466110745.png?auto=format&fit=clip&q=50) > If you do not complete this step you will receive a **Login option is not available** error from Cognito upon sign in. ## (4) Configure redirect URI Locate the domain of the Cognito User Pool and configure the following redirect URI in the WorkOS Dashboard under **Configuration** → **Settings** → **Redirect URIs**. ```plain title="Cognito callback URI" https:///oauth2/idpresponse ``` ## (5) Sign in with WorkOS connection Once an Identity Provider has been created in the Cognito User Pool, you may initiate authentication by passing the `idp_identifier` query parameter to the [OAuth2 Authorize endpoint](https://docs.aws.amazon.com/cognito/latest/developerguide/authorization-endpoint.html) provided by Cognito using the details from the App Client that was previously configured with the Identity Providers. You may pass either a WorkOS [Organization](/reference/organization) or [Connection](/reference/sso/connection) ID as the `idp_identifier`. Passing this query parameter will result in Cognito bypassing it’s standard sign-in page and immediately redirecting the user to the appropriate sign-in page of the upstream identity provider configured in the WorkOS Connection. Once the user is authenticated they will be redirected to your Cognito App Client redirect URL with the Cognito `code` query parameter. ### Auth0 Learn how to configure a connection to Auth0 via SAML. > Looking to migrate from Auth0 to WorkOS? Check out the [full migration guide](/migrate/auth0). ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a Connection will differ by Identity Provider. To create a Auth0 SAML Connection, you’ll need the Identity Provider metadata that is available from the organization's Auth0 instance. Start by logging in to your WorkOS dashboard and browse to the “Organizations” tab on the left hand navigation bar. Select the organization you’d like to configure an Auth0 SAML Connection for, and select “Manually Configure Connection” under “Identity Provider”. ![A screenshot showing where to find "Manually Configure Connection" in the WorkOS Dashboard.](https://images.workoscdn.com/images/2c3eff01-e84c-4e65-9739-ae72facb9eaa.png?auto=format&fit=clip&q=50) Select "Auth0 SAML” from the Identity Provider dropdown, enter a descriptive name for the connection, and then select the “Create Connection” button. ![A screenshot showing "Create Connection" details in the WorkOS Dashboard.](https://images.workoscdn.com/images/6e0f49c0-06fb-4a18-b805-31e3a10b27bb.png?auto=format&fit=clip&q=50) --- ## What WorkOS Provides WorkOS provides the [ACS URL](/glossary/acs-url) and [SP Entity ID](/glossary/sp-entity-id), which are readily available in your Connection Settings in the [WorkOS Dashboard](https://dashboard.workos.com/). ![A screenshot showing where to find the ACS URL and SP Entity ID in the WorkOS Dashboard.](https://images.workoscdn.com/images/ec8cb8f8-b440-47d5-9a80-7b51ca9950bd.png?auto=format&fit=clip&q=50) The ACS URL is the location an Identity Provider redirects its authentication response to. In Auth0’s case, the ACS URL needs to be set by the organization when configuring your application in their Auth0 instance. The SP Entity ID is a URI used to identify the issuer of a SAML request and the audience of a SAML response. In this case, the SP Entity ID is used to communicate that WorkOS will be the party performing SAML requests to the organization's Auth0 instance, and that WorkOS is the intended audience of the SAML responses from the Auth0 instance. Specifically, the ACS URL will need to be set as the “Application Callback URL” on the SAML2 Web App Settings page found under the “Addons” tab in an Auth0 application. You will need to toggle on the SAML2 Web App for the settings modal to appear where you can add the ACS URL under the Application Callback URL input. ![A screenshot showing a toggle to turn on the SAML2 web app addon for Auth0 applications.](https://images.workoscdn.com/images/63ffadf6-ed3b-429d-a4a7-a5294b1a3a0d.png?auto=format&fit=clip&q=50) ![A screenshot showing where to set the ACS URL in the SAML2 web app settings for Auth0 applications.](https://images.workoscdn.com/images/294645cc-18d2-4969-a9ed-6ec69f2bca3d.png?auto=format&fit=clip&q=50) The SP Entity ID will need to be set as the "audience" value in the Settings JSON object on the SAML2 Web App Settings page. After the Application Callback URL and Audience have been added, scroll to the bottom and click "Enable". ![A screenshot showing where to set the SP Entity ID in the SAML2 web app settings for Auth0 applications.](https://images.workoscdn.com/images/4fd65ff7-6296-43d8-8e65-0bd528028f70.png?auto=format&fit=clip&q=50) --- ## What you’ll need In order to integrate you’ll need the Auth0 IdP Metadata URL. Normally, this information will come from the organization's IT Management team when they set up your application’s SAML 2.0 configuration in their Auth0 admin dashboard. Here’s how to obtain them: --- ## (1) Log In and Select Your Application Log in to [Auth0](https://auth0.com/auth/login), go to the admin dashboard, select “Applications” in the sidebar, and then select the “Applications” menu option. Next, select your application from the list of applications. ![A screenshot showing where to find the web application in Auth0 Dashboard.](https://images.workoscdn.com/images/e4bb38d9-fa10-4caa-b097-05a8d83a4e2b.png?auto=format&fit=clip&q=50) --- ## (2) Obtain Identity Provider Metadata On the application’s Settings page, scroll down to the bottom and expand the “Advanced Settings” section. Select the “Endpoints” tab and copy the SAML Metadata URL. You’ll need this in the next step. ![A screenshot of the IdP Metadata XML URL in the Auth0 Dashboard.](https://images.workoscdn.com/images/6288c6a6-ab57-4608-8a1e-872bbd7eb2bd.png?auto=format&fit=clip&q=50) --- ## (3) Upload Metadata URL Finally, upload the SAML Metadata URL you saved earlier in your WorkOS Connection settings. Your Connection will then be linked and good to go! ![A screenshot showing where to place the Auth0 IdP Metadata URL in the WorkOS Dashboard.](https://images.workoscdn.com/images/f1cb1c5c-8554-48a5-89a1-31a42d356690.png?auto=format&fit=clip&q=50) ### Auth0 Enterprise Connection Learn how to use WorkOS with your existing Auth0 applications. > Looking to migrate from Auth0 to WorkOS? Check out the [full migration guide](/migrate/auth0). ## Introduction This guide outlines the steps to make WorkOS SSO connections available to Auth0 applications without requiring changes to your existing Auth0 application code. > The Auth0 Enterprise Connection integration is in feature preview. Reach out to [WorkOS support](mailto:support@workos.com?subject=WorkOS%20Support) if you want early access. --- ## (1) Configure Auth0 API Access WorkOS uses Auth0 credentials you provide to manage the Auth0 Enterprise Connection automatically. The first step is authorizing an application in Auth0 to access the Management API. In the Auth0 dashboard, navigate to **Applications** → **APIs** → **Auth0 Management API**: ![A screenshot showing the "Auth0 Management API" entry on the Auth0 APIs page.](https://images.workoscdn.com/images/e2baba2e-a442-4449-90db-d1be8db41ef2.png?auto=format&fit=clip&q=50) Click on the **Machine To Machine Applications** tab and expand the section for your Auth0 application. Then, toggle the **Authorized** switch to enable the API. Under **Permissions**, ensure the following scopes are granted to the application: - `create:connections` - `read:connections` - `update:connections` Your permissions configuration should match the following screenshot: ![A screenshot a correctly configured API application in the Auth0 dashboard.](https://images.workoscdn.com/images/13b5acb2-b5c6-4cd5-a032-0dd7afedc81a.png?auto=format&fit=clip&q=50) Next, navigate to **Applications** → **_Your App_** → **Settings**. You should see three fields under **Basic Information**: "Domain", "Client ID", and "Client Secret". ![A screenshot showing application credentials in the Auth0 dashboard.](https://images.workoscdn.com/images/c8303868-de12-40e5-a0cc-27bec508131c.png?auto=format&fit=clip&q=50) Record this information in a safe place, as you will provide it to the WorkOS dashboard in the next step. --- ## (2) Connect WorkOS to Auth0 In the WorkOS dashboard, navigate to **Configuration** → **Settings** and scroll to the **Auth0 Credentials** section. Click **Set Auth0 Credentials**: ![A screenshot showing the "Auth0 Credentials" section in the WorkOS dashboard.](https://images.workoscdn.com/images/16b3ea51-8564-4ced-86fb-f3ab9fad8d28.png?auto=format&fit=clip&q=50) In the modal, enter the credentials you obtained in the previous step: "API Domain", "Client ID", and "Client Secret". ![A screenshot showing the "Auth0 Credentials" form in the WorkOS dashboard.](https://images.workoscdn.com/images/3e915c68-97c0-4d1e-88e9-cda8bff7fd31.png?auto=format&fit=clip&q=50) Click **Save**. In the final step, you will head back to the Auth0 dashboard one last time to complete the configuration. --- ## (3) Enable the Enterprise Connection After saving your credentials, WorkOS will create an Enterprise Connection in your Auth0 environment. This connection is the entry point into WorkOS SSO from Auth0. The next step is to enable the connection for your Auth0 application. In the Auth0 dashboard, navigate to **Applications** → **_Your App_** → **Connections**. You should see a connection with a `workos-sso-` prefix in its name. Enable it for your application. ![A screenshot showing enabled connections for an application in the Auth0 dashboard.](https://images.workoscdn.com/images/4cd3dbec-7ccc-462a-a101-5f8fc29aa332.png?auto=format&fit=clip&q=50) --- ## (4) Enable "Identifier First" Login Flow In the Auth0 dashboard, navigate to **Authentication** → **Authentication Profile**. You should see three options for configuring login flow. Select **Identifier First**. ![A screenshot showing "Identifier First" selected in the Auth0 dashboard.](https://images.workoscdn.com/images/b30e3808-b978-4f86-9443-8e2e7d588a90.png?auto=format&fit=clip&q=80) This configures the Auth0 Universal Login page to begin by prompting the user for their email address. This is necessary as it allows Auth0 to select the WorkOS SSO Enterprise Connection if the user’s email domain matches one of your WorkOS organizations. Non-enterprise users will still be prompted for their password. > [IdP-initiated SSO](/sso/login-flows/idp-initiated-sso) is currently not supported when using the Auth0 Enterprise Connection integration. --- ## Summary Your WorkOS SSO connections are now available to your Auth0 application! You are ready to use WorkOS features like [Admin Portal](admin-portal), allowing IT admins to configure their SSO setup for your application directly. As you create [organizations](/reference/organization), WorkOS will keep the Auth0 Enterprise Connection's [Home Realm Discovery](https://auth0.com/docs/authenticate/login/auth0-universal-login/identifier-first#define-home-realm-discovery-identity-providers) list updated with the organization's domains – ensuring correct routing of enterprise users to WorkOS for authentication. When users enter their email address into the Auth0 Universal Login, which matches a domain associated with a WorkOS organization, Auth0 redirects users to their WorkOS-enabled IdP sign-in page for their organization. Once the authentication process is complete with the IdP, WorkOS redirects to your Auth0 app callback URL. > Since email domains are used to route users to the correct IdP when using Auth0, WorkOS will enforce that [organization domains](/reference/organization-domain) are unique, and therefore a domain cannot be assigned to more than one organization. ### Auth0 Directory Sync Learn how to use Directory Sync with your Auth0 applications. > Looking to migrate from Auth0 to WorkOS? Check out the [full migration guide](/migrate/auth0). ## Introduction This guide will walk you through the steps to enable WorkOS Directory Sync for your Auth0 applications. If you are new to automated user provisioning and deprovisioning, the [Directory Sync](/directory-sync) introduction is a good place to learn the basics. > The Auth0 Directory Sync integration is in feature preview. Reach out to [WorkOS support](mailto:support@workos.com?subject=Auth0%20Directory%20Sync%20Integration) if you want early access. ## (1) Configure Auth0 API access WorkOS uses Auth0 credentials you provide to automatically create and manage an Auth0 database connection. The first step is to authorize an application in Auth0 to access the Management API. In the Auth0 dashboard, navigate to **Applications** → **APIs** → **Auth0 Management API**: ![A screenshot showing the “Auth0 Management API” entry on the Auth0 APIs page.](https://images.workoscdn.com/images/e2baba2e-a442-4449-90db-d1be8db41ef2.png?auto=format&fit=clip&q=50) Click on the **Machine To Machine Applications** tab and expand the section for your Auth0 application. Then, toggle the **Authorized** switch to enable the API. Under **Permissions**, ensure the following scopes are granted to the application: - `create:connections` - `create:users` - `read:connections` - `read:users` - `update:connections` - `update:users` Your permissions configuration should match the following screenshot: ![A screenshot a correctly configured API application in the Auth0 dashboard.](https://images.workoscdn.com/images/13b5acb2-b5c6-4cd5-a032-0dd7afedc81a.png?auto=format&fit=clip&q=50) Next, navigate to **Applications** → **_Your App_** → **Settings**. You should see three fields under **Basic Information**: “Domain”, “Client ID”, and “Client Secret”. ![A screenshot showing application credentials in the Auth0 dashboard.](https://images.workoscdn.com/images/c8303868-de12-40e5-a0cc-27bec508131c.png?auto=format&fit=clip&q=50) Record this information in a safe place, as you will provide it to the WorkOS dashboard in the next step. --- ## (2) Connect WorkOS to Auth0 In the WorkOS dashboard, navigate to **Configuration** → **Settings** and scroll to the **Auth0 Credentials** section. Click **Set Auth0 Credentials**: ![A screenshot showing the “Auth0 Credentials” section in the WorkOS dashboard.](https://images.workoscdn.com/images/16b3ea51-8564-4ced-86fb-f3ab9fad8d28.png?auto=format&fit=clip&q=50) In the modal, enter the credentials you obtained in the previous step: “API Domain”, “Client ID”, and “Client Secret”. ![A screenshot showing the “Auth0 Credentials” form in the WorkOS dashboard.](https://images.workoscdn.com/images/3e915c68-97c0-4d1e-88e9-cda8bff7fd31.png?auto=format&fit=clip&q=50) Click **Save**. In the final step, you will head back to the Auth0 dashboard one last time to complete the configuration. --- ## (3) Enable the database connection After saving your credentials, WorkOS will create a database connection in your Auth0 environment. This connection will contain the users from directories in your WorkOS organizations. The next step is to enable the connection for your Auth0 application. In the Auth0 dashboard, navigate to **Applications** → **_Your App_** → **Connections**. You should see a connection with a `workos-dsync-` prefix in its name. Enable it for your application. ![A screenshot showing enabled connections for an application in the Auth0 dashboard.](https://images.workoscdn.com/images/73b12882-d286-49cd-ba58-a0527eab7f4f.png?auto=format&fit=clip&q=50) --- ## Summary Your WorkOS directories will now be synchronized with your new Auth0 database connection! You are ready to use WorkOS features like [Admin Portal](/admin-portal), allowing IT admins to configure their directory provider for your application directly. New users provisioned into Auth0 are given a randomly generated password. They will need to reset their password before they can sign in. You can also use [WorkOS directory sync webhooks](/events/data-syncing/webhooks) to be notified when new users are provisioned, allowing you to tailor the onboarding experience for these new users, like sending a welcome email. Deprovisioned users will be deleted from the Auth0 database connection. If you need to perform additional cleanup in your application, you can receive WorkOS directory sync webhooks for delete events as well. ### Apple Learn how to set up “Sign in with Apple” ## Introduction The “Sign in with Apple” integration allows your users to authenticate using their Apple ID credentials. The configuration process involves obtaining credentials from your Apple Developer account and configuring them in the WorkOS Dashboard. You may also set up Private Email Relay for users who choose to hide their email addresses. --- ## Testing with default credentials in the staging environment WorkOS provides a default set of Apple credentials, which allow you to quickly enable and test Sign in with Apple. WorkOS will automatically use the default credentials until you add your own Apple Team ID, Apple Service ID, and Apple Private Key to the configuration in the [WorkOS dashboard](https://dashboard.workos.com). > The default credentials are only intended for testing and therefore only available in the Staging environment. For your production environment, please follow the steps below to create and specify your own Apple Team ID, Apple Service ID, and Apple Private Key. Please note that when you are using WorkOS default credentials, Apple's authentication flow will display the WorkOS name, logo, and other information to users. Once you register your own application and use its credentials for the authentication flow, you will have the opportunity to customize the app. --- ## What WorkOS provides When setting up “Sign in with Apple”, WorkOS provides two key pieces of information that need to be configured in your Apple Developer account: - [Redirect URI](/glossary/redirect-uri): The endpoint where Apple will send authentication responses after successful login - **Outbound Email Domains**: Registered domains for Apple's Private Relay email service These are available in the [WorkOS Dashboard](https://dashboard.workos.com/). In the left navigation menu, select the **Authentication** tab and the **OAuth providers** sub-tab. Locate the **Sign in with Apple** section. ![Open the Sign in with Apple configuration dialog](https://images.workoscdn.com/images/b9abf389-f950-49b2-8cf3-2c47e9b810bf.png?auto=format&fit=clip&q=50) Click **Enable**. The **Sign in with Apple** configuration dialog will open. Locate the **Redirect URI** and **Outbound email domains**. ![Sign in with Apple Redirect URI in the WorkOS dashboard.](https://images.workoscdn.com/images/54680256-09bc-478f-ab0f-5889c1d846be.png?auto=format&fit=clip&q=50) The **Redirect URI** serves as the destination for authentication responses and must be configured in your Apple Developer account. **Outbound email domains** are registered with Apple's Private Relay email service to deliver email to users who choose to hide their email addresses. --- ## What you'll need You will need to obtain four pieces of information from your Apple Developer account: - **Apple Team ID**: Your organization's unique identifier in the Apple Developer program - **Apple Service ID**: Application identifier for “Sign in with Apple” - **Apple Private Key**: Authentication key file for secure communication - **Private Key ID**: Identifier for the private key The following sections will guide you through generating these credentials in your Apple Developer account. --- ## (1) Retrieve your Apple Team ID Sign in to the [certificates, identifiers, and profiles](https://developer.apple.com/account/resources/certificates/list) section of your Apple Developer account. The landing page will display your name, company name, and Team ID. Note the Team ID value as you'll need it later. ![Team ID in the Apple Developer dashboard.](https://images.workoscdn.com/images/2edd45b9-7e84-45fa-8da2-3c6dcd5607a1.png?auto=format&fit=clip&q=80) > The Team ID is sensitive and will only be used by the server to communicate with Apple. It should not be shared with the client. --- ## (2) Register an App ID > Skip this step if you already have an App ID. Click on **Identifiers** in the sidebar, then click the + button to create a new identifier. ![Identifiers page in the Apple Developer dashboard with Create Identifier plus button highlighted.](https://images.workoscdn.com/images/54be9c35-f7c9-4119-9765-64299d42ff23.png?auto=format&fit=clip&q=80) On the next page, select **App IDs** and click **Continue**. ![First step in the Identifier creation wizard with App IDs selected.](https://images.workoscdn.com/images/a028e2b5-9443-4208-aa0c-175056ac55b5.png?auto=format&fit=clip&q=80) Next, select **App** and click **Continue**. ![Second step in the Identifier creation wizard with App selected.](https://images.workoscdn.com/images/baff59f5-f060-4faf-9761-678321cc496a.png?auto=format&fit=clip&q=80) On the next page, fill in a description and a bundle ID. The bundle ID should be unique and in reverse domain notation, e.g., `com.example.myapp`. Also check the **Sign in with Apple** box in the Capabilities section. There is no need to update anything in the **Edit** modal. ![Third step in the Identifier creation wizard with placeholder Description and Bundle ID entered.](https://images.workoscdn.com/images/ef85061d-ff63-4d5a-8fad-a9cbefeb6786.png?auto=format&fit=clip&q=80) ![Third step in the Identifier creation wizard with Sign in with Apple checkbox checked.](https://images.workoscdn.com/images/9f184ccb-40d8-4410-9250-b8ab56600452.png?auto=format&fit=clip&q=80) Then click **Continue**. Review your selections and click **Register**. --- ## (3) Register a Service ID Next you need to create a linked Service ID. Click on **Identifiers** in the sidebar, then click the + button. ![Identifiers page in the Apple Developer dashboard with Create Identifier plus button highlighted.](https://images.workoscdn.com/images/4a129d31-33c8-4976-8340-d59fc6618b67.png?auto=format&fit=clip&q=80) On the next page, select **Services IDs** and click **Continue**. ![First step in the Identifier creation wizard with Services IDs selected.](https://images.workoscdn.com/images/2496cf53-f593-4eda-a2f9-14d6728b0c5d.png?auto=format&fit=clip&q=80) Enter a description and a Service ID. The Service ID should be unique and in reverse domain notation, e.g. `com.example.myapp`. ![Second step in the Identifier creation wizard with placeholder Description and Service ID entered.](https://images.workoscdn.com/images/dbf69235-951c-4f1d-97b2-3a1c6854c758.png?auto=format&fit=clip&q=80) Click **Continue**. Note the Service ID as you'll need it later, then click **Register** to create the service. Now you'll configure your new service for “Sign in with Apple”. First select the new service from the list of Service IDs. ![Identifiers page in the Apple Developer dashboard with the newly created Service ID highlighted.](https://images.workoscdn.com/images/478f799f-298e-4dee-9b6d-ff75d02fd9f5.png?auto=format&fit=clip&q=80) Check the **Sign in with Apple** box and click **Configure**. ![Service ID Edit page with Sign in with Apple checkbox checked.](https://images.workoscdn.com/images/8c3e92fe-f5fc-403e-b7ee-fa215ad61ccf.png?auto=format&fit=clip&q=80) Ensure the App ID you created earlier is selected in the dropdown. Then enter `api.workos.com` in the **Domains and Subdomains** field and paste the **Redirect URI** from the WorkOS Dashboard in the **Return URLs** field. ![Service ID Sign in with Apple edit modal with placeholder values in the inputs.](https://images.workoscdn.com/images/574617e5-4e3c-41a9-8704-dfa47bf504e2.png?auto=format&fit=clip&q=80) Click **Done** and then **Continue**. Review your changes and click **Save**. --- ## (4) Register a private key Click on **Keys** in the sidebar, then click the + button to create a new key. ![Keys page in the Apple Developer dashboard with Create Key plus button highlighted.](https://images.workoscdn.com/images/ebeffde4-091d-4b2c-a9f9-fede59d6674a.png?auto=format&fit=clip&q=80) On the next page, enter a human-readable **Key Name**. Then check the **Sign in with Apple** box and click **Configure**. ![First step in the Key creation wizard.](https://images.workoscdn.com/images/264d1e39-ccae-4d32-80da-af2d5813723c.png?auto=format&fit=clip&q=80) In the **Configure** dialog, select the App ID you created earlier and click **Save**. ![Key Configure dialog with App ID from the previous step selected.](https://images.workoscdn.com/images/d1442a7c-47a3-412c-956b-415a11acda9b.png?auto=format&fit=clip&q=80) Click **Continue**. Review your changes and click **Register** to create your key. ![Download Your Key page.](https://images.workoscdn.com/images/eb032a3d-4d2a-44be-a2f5-292e901fae16.png?auto=format&fit=clip&q=80) Make sure to download your new private key and note the Key ID as you'll need both later. --- ## (5) Configure Apple credentials in WorkOS Now you have all the required credentials: - Apple Team ID - Apple Service ID - Private Key ID - The downloaded private key file Return to the [WorkOS Dashboard](https://dashboard.workos.com). In the **Sign in with Apple** configuration dialog, toggle **Enable** on. Select **Your app's credentials**. Paste the credentials from Apple that you generated in the previous steps into their respective fields. ![Sign in with Apple configuration modal in the WorkOS dashboard filled out with information from earlier steps.](https://images.workoscdn.com/images/cfedc298-8666-4f38-ab71-f6ed777b44c1.png?auto=format&fit=clip&q=80) --- ## (6) Set up Private Email Relay Sign in with Apple users can opt to hide their email address when signing in. In order for emails to be sent to those users, you need to configure Private Email Relay. Copy the **Outbound Email Domains** from the **Sign in with Apple** configuration modal in the WorkOS Dashboard. ![Sign in with Apple configuration modal in the WorkOS dashboard with outbound email domains control highlighted.](https://images.workoscdn.com/images/8c4ae9a5-1b27-49c7-90f7-31a3010ee2b5.png?auto=format&fit=clip&q=80) Open your Apple Developer account and click on **Services** in the sidebar. Then click on **Configure** under **Sign in with Apple for Email Communication**. ![Services page in the Apple Developer dashboard with Sign in with Apple Configure button highlighted.](https://images.workoscdn.com/images/cc81ae18-450d-417f-9e22-6392b335e437.png?auto=format&fit=clip&q=80) Click the + button next to **Email Sources** and enter the outbound email domains from the WorkOS Dashboard in the **Domains and Subdomains** text box. Then click **Next** and **Register**. ![Modal to register Email Sources with domains from the WorkOS dashboard in the Domains and Subdomains text box.](https://images.workoscdn.com/images/021882c4-e299-44b8-9a44-fcf22f3be150.png?auto=format&fit=clip&q=80) ![New domains with green check marks next to them.](https://images.workoscdn.com/images/fa3e78e6-688d-46a8-b4e7-1f6c788da4f6.png?auto=format&fit=clip&q=80) You are now ready to start authenticating with “Sign in with Apple”. Your users will see the option to “Sign in with Apple” when visiting your [AuthKit](/authkit) domain. Alternatively if you're using the [standalone SSO API](/reference/sso/get-authorization-url), you can initiate “Sign in with Apple” by passing `AppleOAuth` as the `provider`. --- ## Frequently asked questions ### How is the WorkOS “Sign in with Apple” integration different from implementing regular Apple OAuth flow? It's the same Apple OAuth flow as you could build yourself, but it's encapsulated within WorkOS SSO. This means you don't need to build it yourself. In addition to “Sign in with Apple”, you can use WorkOS SSO to support other identity providers, all with a single integration. ### What is the provider query parameter and how is it used in the Apple OAuth integration? You can use the `provider` query parameter in the [Get Authorization URL API endpoint](/reference/sso/get-authorization-url) to support global Apple OAuth for any domain. The `provider` query parameter should be set to `AppleOAuth`. ### Why do I need to configure Private Email Relay? “Sign in with Apple” allows users to hide their real email address from your app. When a user chooses this option, Apple generates a unique, random email address that forwards to their real email. To send emails to these users, you need to register your sending domains with Apple's Private Email Relay service. ### What happens if I don't set up Private Email Relay? If you don't configure Private Email Relay, you won't be able to send emails to users who choose to hide their email address. Those users will still be able to sign in, but any emails you attempt to send to their relay address will not be delivered. ### Can I use the same App ID for multiple services? Yes, you can use the same App ID for multiple Services IDs. This is useful if you have multiple applications or environments that need to use “Sign in with Apple”. ### ADP OpenID Connect Learn how to configure a connection to ADP via OIDC. ## Introduction Each SSO Identity Provider requires specific information to create and configure a new [Connection](/glossary/connection). Often, the information required to create a connection will differ by Identity Provider. ADP is unique in that it authenticates using the Open ID Connect (OIDC) protocol instead of [SAML](/glossary/saml). This means that instead of providing an [ACS URL](/glossary/acs-url) and [SP Entity ID](/glossary/sp-entity-id) into the IdP, The IdP will provide a client ID and secret. ADP also provides an SSL Certificate and Private RSA Key file to authenticate. These four pieces of information will all need to be uploaded into the WorkOS dashboard in the steps below. --- ## (1) Create a New ADP OIDC Connection in WorkOS Navigate to the Organization in your WorkOS Dashboard under which you would like to set up this new SSO connection. Click on the "Manually Configure Connection" button. ![A screenshot showing where to find "Manually Configure Connection" in the WorkOS Dashboard.](https://images.workoscdn.com/images/b7370939-c547-4ad1-9b2d-cc8ed150b90b.png?auto=format&fit=clip&q=50) Select ADP OIDC as the Identity Provider and select “Create Connection”. ![A screenshot showing "Create Connection" details in the WorkOS Dashboard.](https://images.workoscdn.com/images/e20c45f0-2842-45e0-9364-7878f493f0a4.png?auto=format&fit=clip&q=50) --- ## (2) Select or Create a Project in ADP Login to the [ADP Partner Self Service Portal](https://adpapps.adp.com/self-service/projects). From this page there are two environments to select from, Development and Production. Please use the environment that best suits your use-case for this SSO connection. In the selected environment select “Create New Project”. ![A screenshot showing the Projects Overview page in the ADP Partner Self Service Portal.](https://images.workoscdn.com/images/39422d34-f4b8-42c2-af5a-b7c8b26dfe1f.png?auto=format&fit=clip&q=50&w=2048) Give the project a meaningful name to designate the SSO connection, there is no need to add a description. ![A screenshot showing the Create New Project details in the ADP Partner Self Service Portal.](https://images.workoscdn.com/images/614daf3e-afa8-4007-9aec-f087fb60a394.png?auto=format&fit=clip&q=50&w=2048) Make the selections “US Marketplace” and “ADP Workforce Now” respectively for the next selections and then click “Next”. ![A screenshot showing selection options for the ADP Marketplace in the ADP Partner Self Service Portal.](https://images.workoscdn.com/images/e38e06a8-7c82-44d3-bb58-cc7cc875b8cc.png?auto=format&fit=clip&q=50&w=2048) Finally, select “Other” for the use case that best describes your application and click “Submit”. ![A screenshot showing app description selection options in the ADP Partner Self Service Portal.](https://images.workoscdn.com/images/8de31a18-444c-4a48-b41a-fd3be86b4933.png?auto=format&fit=clip&q=50) --- ## (3) Upload the WorkOS Redirect URI in ADP After configuring the ADP project, the next step is to provide ADP with the redirect URI generated by WorkOS. ![A screenshot showing where to find the ACS URL and SP Entity ID in the WorkOS Dashboard.](https://images.workoscdn.com/images/5bc6cf1c-c327-4e81-9588-442fc61bf55d.png?auto=format&fit=clip&q=50) Now that a new project has been created browse to the “Development API Credentials” Tab within the project. Click on the “End-User/SSO sub-tab” from this view. Paste the [Redirect URI](/glossary/redirect-uri) into the App redirect URI field and click “Update Redirect”. ![A screenshot showing where to place the WorkOS Single Sign-On URL and SP Entity ID in the ADP Partner Self Service Portal.](https://images.workoscdn.com/images/5ae15d57-82d5-4591-bc86-f6637a1588f7.png?auto=format&fit=clip&q=50) --- ## (4) Enter ADP OIDC Client Settings in your WorkOS Dashboard Now that the redirect URI has been provided, the next step is to gather the [Client ID](/glossary/client-id) and [Client Secret](/glossary/client-secret) from ADP and add it into the WorkOS Dashboard. Under the same tab used in the previous step, you’ll provide the Client ID and Client Secret from ADP. Click to reveal the secret and copy and paste both the client ID and client secret into the WorkOS dashboard. ![A screenshot showing where to find the ADP Client Credentials in the ADP Partner Self Service Portal.](https://images.workoscdn.com/images/2c8b784a-88e5-4d63-9853-3f8eb6acd304.png?auto=format&fit=clip&q=50) ![A screenshot showing where to enter the ADP Client Credentials WorkOS Dashboard.](https://images.workoscdn.com/images/fc0444d4-9864-4c19-ab4a-327ab914417f.png?auto=format&fit=clip&q=50) --- ## (5) Upload the ADP SSL Cert and Private Key in your WorkOS Dashboard Now that the Client ID and Secret have been provided, the next step is to gather the SSL Certificate and Private Key from ADP and add it into the WorkOS Dashboard. ADP uses a two fold certificate method with an SSL certificate and an SSL Private Key. The SSL Private Key is only displayed one time when the certificate is generated. If the certificate has already been generated, the IT Administrator who generated it should have also received the Private Key otherwise a new certificate and key can be generated by browsing to the certificates tab on the left hand navigation. The SSL Certificate can be found in ADP by browsing to “Certificate” on the left hand nav bar. You can also create a new SSL Certificate and Private Key pair if necessary. ![A screenshot showing where to download the ADP SSL Certificate and Private Key in the ADP Partner Self Service Portal.](https://images.workoscdn.com/images/31e16dbd-3f08-41b4-9478-5a02b0c3a9f5.png?auto=format&fit=clip&q=50) Upload the two files into your WorkOS dashboard in their respective portals on the connection page and click “Update Connection”. ![A screenshot showing where to upload the ADP SSL Certificate and Private Key in the WorkOS Dashboard](https://images.workoscdn.com/images/783a81be-f5c4-43ba-b2f2-25a9f1c18a8f.png?auto=format&fit=clip&q=50) --- ## (6) Verify Connection Status in WorkOS Navigate back to the connection in your WorkOS dashboard. After a minute or two you should see the connection become Active as indicated by the green badge next to the connection name. All that’s left to do now is test out the connection. You can use your own application if it’s connected to WorkOS already, or feel free to use one of our example applications like this [Python Flask SSO app](https://github.com/workos/python-flask-example-applications/tree/main/python-flask-sso-example) to get up and running with a PoC quickly ### Access People HR Learn about syncing your user list with Access People HR. ## Introduction This guide outlines how to synchronize your application’s Access People HR directories. To synchronize an organization’s users and groups provisioned for your application, you’ll need the following information from the organization: - Access People HR API key > Note: The Access People HR integration isn't enabled by default in the WorkOS Dashboard or Admin Portal. Please reach out to [support@workos.com](mailto:support@workos.com) or via your team’s WorkOS Slack channel if you would like Access People HR enabled. --- ## (1) Create an API Key The organization will need to create an API key for you. First, they’ll need to log in to their Access People HR admin dashboard and select to the “Settings” page from the side bar menu. Then, select “API” from the Settings side bar menu. On the API Key Management page, select the plus sign to add a new API Key. ![A screenshot showing where to find the plus sign in the Access People HR Dashboard.](https://images.workoscdn.com/images/9cbff13f-9ea3-442a-90ae-7c135e14e07b.png?auto=format&fit=clip&q=50) In the API Key Generator, give the API Key a descriptive name. Under “Application”, select “Employee”. ![A screenshot showing where the "Employee" option is location in the Access People HR Dashboard.](https://images.workoscdn.com/images/02f54969-422c-4f17-9c34-559bd419cf3e.png?auto=format&fit=clip&q=50) On the Select Permissions page, check only “Get All Employee Detail” and then select “Save”. ![A screenshot showing where to select the "Get All Employee Detail" permission is located in the Access People HR Dashboard.](https://images.workoscdn.com/images/7387653b-7d30-4733-96e4-033004396449.png?auto=format&fit=clip&q=50) On the API Key Generator page, select “Save”. ![A screenshot showing the API Key Generator page in the Access People HR Dashboard.](https://images.workoscdn.com/images/c58ba765-8015-4776-8fe0-6260de530d52.png?auto=format&fit=clip&q=50) Copy and save the API key – this will be used in Step 3. ![A screenshot showing the copy icon in the Access People HR Dashboard.](https://images.workoscdn.com/images/a8248b85-173a-4f6b-812f-f58b9abfc9f1.png?auto=format&fit=clip&q=50) --- ## (2) Create your Directory Sync Connection Login to your WorkOS dashboard and select “Organizations” from the left hand Navigation bar Select the Organization you’d like to enable an Access People HR Directory Sync connection for. On the Organization’s page click “Manually Configure Directory”. ![A screenshot showing where to find “Manually Configure Directory” for an Organization in the WorkOS Dashboard.](https://images.workoscdn.com/images/ed383bc9-e626-4d2c-bbfd-78dbe8bbc5d4.png?auto=format&fit=clip&q=50) Select “Access People HR” as the Directory Provider, and then provide a descriptive name for the connection. Select “Create Directory”. ![A screenshot showing Create Directory details in the WorkOS Dashboard.](https://images.workoscdn.com/images/cc5dde6b-4eda-4af7-bcb9-3ec958e6bc79.png?auto=format&fit=clip&q=50) --- ## (3) Setup your Directory Sync Connection In the directory details section, select “Update Directory”. ![A screenshot showing where to find "Update Directory" in the WorkOS Dashboard.](https://images.workoscdn.com/images/b0b0e10f-59ab-43da-b348-52b5d53bd299.png?auto=format&fit=clip&q=50) Enter your API Key from Step 1, and select “Save Directory Details”. ![A screenshot showing where to enter your API Key in the WorkOS Dashboard.](https://images.workoscdn.com/images/31881779-5153-4193-a5bd-316b9684650b.png?auto=format&fit=clip&q=50) --- ## (4) Sync Users and Groups to Your Application Now, you should see users and groups synced over from Access People HR. Departments from Access People HR are synced as groups in WorkOS. All users are synced, but only those marked as “ACTIVE” or “LEAVER_MARKED” have a state of active. --- ## Frequently asked questions ### How often do Access People HR directories perform a sync? Access People HR directories poll every 30 minutes starting from the time of the initial sync. ## FGA {#fga} ### Warrants Warrants specify relationships between resources in your application. **Warrants** are access rules that specify relationships between the resources in your application (e.g. `[store:A] is [parent] of [item:123]`). WorkOS FGA uses the set warrants and resource types for an application to answer access checks and queries. Individual warrants define explicit relations between resources while resource types define rules (policies) by which some relationships can exist implicitly. ## Overview ```shell tenant:stark-industries # admin @ user:tony-stark | | | Resource Relation Subject ``` Each warrant is composed of three core attributes and an optional _policy_ (more on this later): - **Resource** - This is the resource the warrant specifies a relationship on. The resource is broken down into a `resource_type` and a `resource_id`. The `resource_type` must refer to a valid [resource type](/fga/schema/schema-syntax/resource-types) defined for the application. The `resource_id` must be a unique identifier used by the application to identify the resource. - **Relation** - This is the relationship the warrant specifies between the resource and the subject. The relation must be one of the defined [relations](/fga/schema/schema-syntax/relations) on the referenced `resource_type`. It is often used to specify an action the warrant will grant the subject the ability to perform on the resource (e.g. `editor`, `viewer`, etc.). - **Subject** - This is the resource being granted the specified relation. Like the resource, the subject is broken down into a `resource_type`, and a `resource_id`, and optionally a `relation` (to specify a group of subjects). A subject's `resource_type` must refer to a valid resource type defined for the application, and its `resource_id` must be a unique identifier used by the application to identify the resource. While the subject will often times be an individual user or resource, the subject can also specify a _group_ of resources (e.g. in [group warrants](#group-warrants)). - **Policy** (optional) - The policy specifies an additional boolean expression to be evaluated _at the time of each check/query request_. The provided expression can reference arbitrary variables which can be provided in check or query requests as _context_. Given some context at check/query time, a warrant's policy must evaluate to `true` in order for the warrant to be considered a match for the check/query. If a warrant's resource, relation, and subject attributes do not match the requested check/query **or** the policy expression evaluates to `false`, the warrant will not be matched during evaluation of the check/query. The policy attribute can be used to implement a form of attribute-based access control (ABAC). Here is an example warrant specifying that the subject `user:ABC` has the relation `editor` on resource `item:123`: ```json { "resource_type": "item", "resource_id": "123", "relation": "editor", "subject": { "resource_type": "user", "resource_id": "ABC" } } ``` ## Direct Warrants A direct warrant represents a relationship between a resource and a _specific_ subject. For example, we can define a warrant specifying that `[user:1] is a [member] of [role:admin]`: ```json { "resource_type": "role", "resource_id": "admin", "relation": "member", "subject": { "resource_type": "user", "resource_id": "1" } } ``` ## Group Warrants In some cases, we might need to specify a relationship between a resource and a _group_ of subjects (e.g. `[member]s of [role:admin]`, `[manager]s of [tenant:acme]`, etc). Group warrants are warrants that include the optional `relation` attribute on the `subject`. They specify that _all_ resources matching the subject's `resource_type`, `resource_id`, and `relation` will have the specified `relation` on the resource. For example, we can define a group warrant specifying that `[member]s of [role:admin] are [editor]s of [report:1]`: ```json { "resource_type": "report", "resource_id": "1", "relation": "editor", "subject": { "resource_type": "role", "resource_id": "admin", "relation": "member" } } ``` It's important to note that resource inheritance rules achieve the same thing as group warrants, but group warrants are a data-first approach. Group warrants are typically used as an exception for certain resources that might have different sets of requirements than the schema. We typically recommend using resource inheritance rules over group warrants because it is easier to manage a single schema than a set of group warrants defined on several different resources. ## Wildcard Warrants While FGA is designed to model fine-grained authorization, some use-cases call for more coarse-grained access to individual resources. For example, publicly sharing read privileges on a particular document with all users. Scenarios like this can be modeled using wildcard warrants. A wildcard warrant is a warrant that specifies a wildcard (`*`) for the `subject_id` attribute. This means the warrant applies to _all_ subjects of the specified `subject_type`. Note that group warrants cannot specify a wildcard as the `subject_id`. Here is an example of a wildcard warrant that grants _all users_ `viewer` access to `document:doc_123`: ```json { "resource_type": "document", "resource_id": "doc_123", "relation": "viewer", "subject": { "resource_type": "user", "resource_id": "*" } } ``` ## Creating and Managing Warrants Warrants can be created directly in the [FGA dashboard](https://fga.workos.com) or programmatically via API. Refer to the [Warrants API Reference](/reference/fga/warrant/list) to learn more about managing Warrants via API. ### Warrant Tokens Configure whether you favor performance or consistency on a per request basis depending on your application's consistency requirements. ## Overview FGA is a distributed service deployed to multiple cloud regions. All traffic to the FGA API flows through a single endpoint (`api.workos.com/fga`). To ensure reliability, data is replicated to multiple regions behind the scenes. To maximize performance, FGA is an _eventually consistent_ service by default. In order to balance performance and consistency, FGA supports a _bounded staleness protocol_ similar to Google Zanzibar's _Zookie_ protocol. This allows client applications to specify when they prefer the fastest results (to minimize latency added by authorization checks) and when they prefer immediately consistent results (to ensure recent changes to permissions are reflected for a particular check or query). FGA generates an opaque token (known as a _Warrant Token_) for all warrant _write_ operations (i.e. creating or deleting warrants). Each Warrant Token uniquely identifies a warrant write operation. All warrant write operations return a Warrant Token in the response body. ```shell { "warrant_token": "MjM0fDM0MzQyM3wyMTM0MzM0MzY0NQ==" } ``` ## `Warrant-Token` Header Unlike traditional eventually-consistent distributed systems, FGA allows clients to specify their desired consistency level via Warrant Tokens. Clients can pass a previously generated Warrant Token via the `Warrant-Token` header on check, query, and list warrants requests to instruct the server to process the request using data _no older_ than the write operation identified by the specified Warrant Token. This allows clients to ensure that a particular check, query, or list warrants request has the data necessary to give the most up-to-date result as dictated by the application's authorization requirements. ### `latest` In some cases, a client may need an up-to-date result but may not have an accompanying Warrant Token to use for the request. In this scenario, the client can pass the special value `latest` in the `Warrant-Token` header to instruct FGA to use the most up-to-date data: ```shell 'Warrant-Token: latest' ``` Note that using the `latest` token effectively instructs FGA to bypass all caches in favor of hitting the database for the most up-to-date result. Therefore, it can incur additional performance overhead, so it's recommended to only use `latest` sparingly. Instead, opt to use server-provided Warrant Tokens or no token at all (the default consistency) to maximize performance in most cases. ## Storing Warrant Tokens In practice, clients can store Warrant Tokens in their system on a _per-subject_ basis, passing in the stored token to each read request for that subject to achieve optimal performance. For example, if creating a new warrant (e.g. `user:x is an editor of report:y`) generates a Warrant Token with value `45f87sdf=`, the client can store that token their db along for subject `user:x`. Subsequent checks or queries for `user:x` can then include that stored Warrant Token for the optimal balance of performance and consistency. ## Default consistency Passing a Warrant Token on check, query, and list warrants requests is optional. If a Warrant Token is not provided, FGA uses a default staleness window to fulfill check and query requests. This window is cache-optimized and is the recommended approach for the 90-95% of read requests that can tolerate short periods (on the order of seconds) of inconsistent results. ### Schema Define authorization logic independently from application code using a domain-specific language (DSL). ## Overview A schema is the core structure of an authorization model in FGA. It defines the types of resources, the relations between them, and the policies that govern access. A schema can be represented in two formats: - **JSON** – Accepted by [Schema API](/reference/fga/schema) endpoints when using `Content-Type: application/json`. - **FGA Schema Language** – A more developer-friendly domain-specific language (DSL) that is applied via the `apply` command with the CLI or on the [FGA Dashboard](https://fga.workos.com/schema). Schemas allow you to manage authorization logic independently from application logic. They can be versioned, stored in Git, and applied via the CLI: ```shell workos fga schema apply ./schema.txt ``` Once applied, changes take effect immediately, meaning any updates to authorization logic will instantly reflect in subsequent permission checks and queries. FGA Schema Language transpiles into JSON format so that you can write your authorization model in a more readable and maintainable way, but still use JSON for API calls if you prefer. ## JSON vs Schema Language The JSON representation of a schema is the raw format that FGA uses to define resource types, relations, and inheritance rules. However, it can be verbose and difficult to read - especially for complex authorization models. Consider the following examples: ### JSON Representation ```json { "resource_types": [ { "type": "user", "relations": { "manager": { "allowed_types": ["user"] } } }, { "type": "store", "relations": { "owner": { "allowed_types": ["user"] }, "editor": { "allowed_types": ["user"], "inherit_if": "owner" }, "viewer": { "allowed_types": ["user"], "inherit_if": "editor" } } }, { "type": "item", "relations": { "owner": { "allowed_types": ["user"] "inherit_if": "owner", "of_type": "store", "with_relation": "parent" }, "editor": { "allowed_types": ["user"], "inherit_if": "any_of", "rules": [ { "inherit_if": "owner" }, { "inherit_if": "editor", "of_type": "store", "with_relation": "parent" }, { "inherit_if": "manager", "of_type": "user", "with_relation": "owner" } ] }, "viewer": { "allowed_types": ["user"], "inherit_if": "editor" }, "parent": { "allowed_types": ["store"] } } } ] } ``` ### Schema Language Representation ```fga version 0.3 type user relation manager [user] type store relation owner [user] relation viewer [user] inherit viewer if relation editor // editors are also viewers relation editor [user] inherit editor if relation owner type item // An item can have a parent store relation parent [store] relation owner [user] inherit owner if relation owner on parent [store] relation editor [user] inherit editor if any_of relation owner relation editor on parent [store] relation manager on owner [user] relation viewer [user] inherit viewer if relation editor ``` The FGA schema language representation is more concise, easier to read, and supports comments. These features make it simpler to define and manage complex authorization models in a more developer-friendly format. ## Schema Syntax ### Version Each schema must start with a `version` declaration. This version declaration dictates the version of the schema language the transpiler will use to convert the schema into its JSON representation. As we add support for new features and functionality to the schema language, we will release new versions of it. Versioning the language in this way allows us to ensure backwards compatibility as we roll out these enhancements. See a full changelog of schema versions [here](/fga/schema/schema-changelog). ### Comments Comments are prefixed with `//`. Comments are ignored by the transpiler. ### Resource Types Resource types are the basic building blocks of an authorization model in FGA. Each resource type defines a set of relationships that can exist on a specific type of resource (e.g. store, item, etc). These relationships can be assigned to other resources (e.g. user) known as subjects. Resource types are an incredibly flexible way to define authorization models, allowing you to express complex hierarchical and inherited relationships. They can be created directly in the [FGA dashboard](https://fga.workos.com/schema), via the [Resource Types API](/reference/fga/resource-type/create) or by applying the schema with the CLI. Let's explore the various attributes of resource types by creating a schema-based authorization model for a simple e-commerce application that has three resource types: users, stores, and items. First, define a resource type using the `type` keyword. Each resource type must have a unique string as its type. Let's start defining the resource types for our e-commerce application: ### Relations With the basic definitions above, we've started building an authorization model for our application that will allow us to create fine grained access control rules for stores, items, and users, helping us answer questions like: ```shell Does [user:1] have the ability to [edit] [item:x]? is [user:1] the [owner] of [store:3]? ``` In order to create access rules using our resource types, we first need to define the relationships available on a resource of that type. For example, if we want to specify that `[user:A] is an [owner] of [store:S]`, we must add an `owner` relation to the `store` resource type. By default, a subject can only have a relation on a resource explicitly. This means the relation must be _explicitly_ granted via a [warrant](/fga/warrants). Let's add some relations to our resource types. In our application, a store can have `owners`, `editors`, and `viewers`. `owners` and `editors` have more privileged access (like being able to modify details about a store) than `viewers` (who have read-only access). An item can have the same three relations as a store _plus_ a fourth relation called `parent`. This is because a store can be the `parent` of an item, meaning the item belongs to that store. We'll use this relation later to implement inherited relations on items. Lastly, our `user` resource type is relatively simple and has one relation: `manager`. This is because a user can be the `manager` of another user. We'll use this relation later to enable inherited relations based on user hierarchies. Let's add these relations to our resource types: With these resource types, we can now create authorization rules that specify exactly which users are `owners`, `editors`, and `viewers` of each store or item. We can also assign stores as `parents` of items, and users as `managers` of other users. Use brackets [] in the schema language after defining a relation to enforce which type(s) of subjects can be assigned the relation. Use empty type restrictions to define computed relationships with no direct subjects. This is useful for defining a relation that cannot be assigned directly to a subject but is used to make an authorization check from your application. > Version `0.1` of the schema language does not support type safety on relations. ### Inheritance Rules While only using explicitly assigned relations to build your authorization model can be powerful, creating warrants for each and every relationship in an application can become tedious or infeasible for larger, more complex use cases. That's why relations can define rules under which they can be inherited (e.g. `a user is an editor of a store if they're an owner of that store`). There are two ways in which relations can be inherited: - Relation Inheritance - Resource Inheritance #### Relation Inheritance In practice, it's common for relations to have overlap (e.g. an `owner` has the same privileges as an `editor` + additional privileges). For example, in many applications a user with write privileges inherits read privileges too. In our example application, an `owner` will inherit both the `editor` and the `viewer` relations, and an `editor` will inherit the `viewer` relation. Instead of having to explicitly assign each of the `owner`, `editor`, and `viewer` relations to a user who is an `owner`, resource types allow you to specify an inheritance hierarchy (e.g. the `editor` relation is inherited if the user is an `owner`) using the `inherit_if` property. Let's add `inherit if` rules to our `store` and `item` resource types specifying that: - `owners` are also `editors` - `editors` are also `viewers` With our `inherit if` rules in place, we can simply grant a user the `editor` relation and they will implicitly inherit the `viewer` relation. `inherit` rules also work recursively on other inherited relations, so assigning a user the `owner` relation will implicitly grant that user _both_ the `editor` and `viewer` relations. This is because `owner` will inherit `editor` and `editor` will in turn inherit `viewer`. This will simplify our access checks and cut down on the number of warrants we need to create for each user. #### Resource Inheritance In many applications, resources themselves have a hierarchy (e.g. a document belongs to a folder, a user belongs to a team, a team belongs to an organization, etc.) and the access rules for these resources follow that hierarchy (e.g. the owner of a folder is the owner of any document in that folder). Using the following two rules: ```txt inherit if ``` ```txt relation on [] ``` We can specify that a relation can be inherited when a user has a particular relation (``) on another resource (``) that has a particular relation (``) on the resource we are checking access to. For example, a user is an `editor` of a document if they are an `editor` of a `folder` that is the document's `parent`. In our example app, let's define the following three resource inheritance rules: 1. A user is an `owner` of an item if that user is an `owner` of a `store` that is the item's `parent`. 2. A user is an `editor` of an item if that user is an `editor` of a `store` that is the item's `parent`. 3. A user is an `editor` of an item if that user is the `manager` of the `user` that is the item's `owner`. > **NOTE:** Some of the relations below will be [composing multiple inheritance rules together using logical operators](/fga/schema/schema-syntax/logical-operators). We'll cover this in detail later. These rules make it easy to define inheritance rules for complex relationships between resources so we don't have to create a large number of explicit warrants. Without them, we'd need to create a warrant for every item ↔ store ↔ user relationship in our application. This could easily be thousands, if not hundreds of thousands of rules. ### Logical Operators With both the two types of relation inheritance rules in our toolkit, we can create authorization models for a majority of use cases, but there are still some scenarios that require a combination of these inheritance rules (e.g. a user is an `editor` of an item if they are an `owner` of that item **OR** they are the `manager` of another user who is an `editor` of that item). To design authorization models that cover such scenarios, relations can compose multiple inheritance rules using _logical operators_ to form more complex conditions. The three supported logical operations are `any_of`, `all_of`, and `none_of`. #### any_of The `any_of` operation allows you to specify that a relation be inherited if _at least one of_ the rules in the set is satisfied. In other words, it works like the logical _OR_ operation. The following resource type specifies an `editor-or-viewer` relation that is inherited if the user is an `editor` **OR** if the user is a `viewer`: #### all_of The `all_of` rule type allows you to specify that a relation be inherited if _all of_ the rules in the set are satisfied. In other words, it works like the logical _AND_ operation. The following resource type specifies an `editor-and-viewer` relation that is implicitly granted if the user is an `editor` **AND** the user is a `viewer`: #### none_of The `none_of` rule type allows you to specify that a relation be inherited if _none of_ the rules in the set are satisfied. In other words, it works like the logical _NOR_ operation. The following resource type specifies a `not-editor-and-not-viewer` relation that is implicitly granted if the user is _not_ an `editor` **AND** the user is _not_ a `viewer`: ### Policies Policies are a way to define custom logic that can be used in your schema. They allow you to create complex rules that go beyond simple relation inheritance. Policies can be defined using the `policy` keyword and can include parameters, expressions, and logical conditions. Read more about policies in the [Policies documentation](/fga/policies). ### Group Warrants Define type restrictions on [group warrants](/fga/warrants/group-warrants) by joining the type and expected relation with a `#`. For example, `relation editor [group#member]` means that the `editor` relation can be assigned to warrants where `group` is the subject type and `member` is the subject relation. Group warrants are a special type of warrant that allow you to define exceptions to schema relationships at runtime. See the [Group Warrant documentation](/fga/warrants/group-warrants) for more details. If your relation type defines a resource type and no group warrant types, it will default to allow all group warrants. For example: ```js // Allows subject_type == "group" and subject_relation == null | relation editor [group] // Allows subject_type == "group" and subject_relation == "member" relation editor [group#member] // Allows subject_type == "group" and subject_relation == "member" | "owner" relation editor [group#member, group#ownwer] // Allows subject_type == "group" and subject_relation == null | "member" relation editor [group, group#member] ``` ## Converting Schema Language to JSON You can convert the FGA schema language to JSON using the `workos fga schema convert` command. This command transpiles the schema language into its JSON representation, which can then be used with the FGA API. ```shell workos fga schema convert schema.txt --to json --output raw > schema.json ``` ## Schema Changelog ### v0.3 - Add support for policy in the schema ```fga version 0.3 type user type group relation member [user] type asset relation access_diagnostics [] relation service_manager [group] inherit access_diagnostics if all_of relation member on service_manager [group] policy is_in_geo_fence policy is_in_geo_fence(user_location map, geofence map) { user_location.lat >= geofence.min_lat && user_location.lat <= geofence.max_lat && user_location.lon >= geofence.min_lon && user_location.lon <= geofence.max_lon } ``` ### v0.2 - Add support for resource-type relation type safety - Add support for group warrant types ```fga version 0.2 type report relation parent [organization, organization#member] relation owner [user] relation editor [user] ``` ### v0.1 - Initial implementation of the schema language - Supported features: - Transpiler version - Resource types - Relations - Inheritance rules - Resource inheritance - Logical operators ### Schema Management Learn how to test, debug, and safely apply changes to your authorization schema and setup a GitOps workflow to automatically validate and apply changes to production. ## Overview Designing a schema that meets your requirements and using it in production for the first time is only the beginning of your fine-grained authorization journey. As your product's authorization requirements change, you will need to evolve your schema to meet those requirements. To do this safely, you need a process in place to test, debug, and safely apply changes to your schema in production. In case of bugs, you also need the ability to roll back to a previous (working) schema if needed. This guide will explain how to use the [FGA Dashboard](https://fga.workos.com) and [WorkOS CLI](https://github.com/workos/workos-cli) to test and debug your schema. We will use the CLI and the [CLI GitHub Action](https://github.com/workos/cli-action) to setup a GitOps workflow that automatically tests and applies changes to your schema as part of your software development life cycle (SDLC). ## Before getting started To get the most out of this guide, you'll need: - A [WorkOS account](https://dashboard.workos.com/) - Your WorkOS [API Key](/glossary/api-key) - The [WorkOS CLI](/fga/quick-start/1-install-the-workos-cli) --- ## Test Your Schema Let's create a shell script that uses the WorkOS CLI to test the example schema below. > Note: we've decided to prefix permissions in our authorization model with `can_` (`can_invite_users`) to imply an action. This is not a required convention, so feel free to use relation names that suit your application. ```fga title="schema.txt" version 0.3 type user type organization relation role_admin [user] relation role_member [user] relation can_invite_users [] relation can_remove_users [] relation can_view_users [] inherit role_member if relation role_admin inherit can_invite_users if relation role_admin inherit can_remove_users if relation role_admin inherit can_view_users if relation role_member ``` First, apply the schema ```shell title="Apply the example schema" workos fga schema apply schema.txt ``` Next, use the `fga warrant create` command to setup some warrants. ```shell title="Setup test data" workos fga warrant create user:acme_admin role_admin organization:org_acme workos fga warrant create user:acme_member role_member organization:org_acme ``` Then use the `fga check` command with the `--assert` flag to assert that a permission check returns the expected result. ```shell title="Make assertions" workos fga check user:acme_admin can_invite_users organization:org_acme --assert true workos fga check user:acme_admin can_remove_users organization:org_acme --assert true workos fga check user:acme_admin can_view_users organization:org_acme --assert true workos fga check user:acme_member can_invite_users organization:org_acme --assert false workos fga check user:acme_member can_remove_users organization:org_acme --assert false workos fga check user:acme_member can_view_users organization:org_acme --assert true ``` Finally, use the `fga resource delete` command to clean up the test data. This makes it easy to re-run tests with a clean environment in the future. ```shell title="Clean up test data" workos fga resource delete user:acme_admin workos fga resource delete user:acme_member workos fga resource delete organization:org_acme ``` --- ## Debug Your Schema The simplest way to understand (debug) why your schema is (or is not) answering a permission check as you expect it to is via the [Check page](https://fga.workos.com/check) or using the `--debug` flag via the CLI. ### Using the FGA Dashboard To debug a permission check from the FGA dashboard, navigate to the [Check page](https://fga.workos.com/check). Enter valid arguments for the permission check you want to debug and click `Check Access`. The page will display the result of the permission check and a tree visualizing all of the paths in the authorization graph that were explored to reach the result. ### Using the CLI To debug a permission check using the CLI, use the `fga check` command with the `--debug` flag: ```shell title="Debug a permission check" workos fga check user:james can_approve_purchase purchase:pur_123 --debug ``` Permission checks that use the `--debug` flag will output the check result and a tree visualizing all of the paths in the authorization graph that were explored to reach the result. > Note: running the `fga check` command with the `--debug` flag will execute the check without any caching enabled. #### Tests The CLI provides a streamlined way to run multiple tests against your schema using a single `workos fga test command`. The `test` command will set up warrants, perform checks, and handle teardown. It also supports running multiple test files from a directory, allowing you to organize tests in a structure that fits your application. ```yaml title="org-roles.test.yaml" setup: warrants: - subject: user:acme_admin relation: role_admin resource: organization:org_acme - subject: user:acme_member relation: role_member resource: organization:org_acme tests: - name: acme_admin can invite users check: subject: user:acme_admin relation: can_invite_users resource: organization:org_acme expect: true - name: acme_admin can remove users check: subject: user:acme_admin relation: can_remove_users resource: organization:org_acme expect: true - name: acme_admin can view users check: subject: user:acme_admin relation: can_view_users resource: organization:org_acme expect: true - name: acme_member cannot invite users check: subject: user:acme_member relation: can_invite_users resource: organization:org_acme expect: false - name: acme_member cannot remove users check: subject: user:acme_member relation: can_remove_users resource: organization:org_acme expect: false - name: acme_member can view users check: subject: user:acme_member relation: can_view_users resource: organization:org_acme expect: true teardown: resources: - user:acme_admin - user:acme_member - organization:org_acme ``` To run the tests defined in the `schema.test.yaml` file, use the following command: ```shell title="Run tests" workos fga test org-roles.test.yaml ``` > The teardown section is optional and used for cleaning up specific data (resources or warrants). If you want to automatically cleanup **all resources and warrants** created during the test, you can also use the `--cleanup` flag when running the `workos fga test` command. --- ## GitOps Workflow Now that we have a script to test that our schema works as we expect, let's setup a GitHub Action to automatically test changes to the schema and apply the schema if all of the tests pass. ```yaml title=".github/workflows/fga.yaml" name: Test FGA Schema on: push: branches: [main] jobs: ci: runs-on: ubuntu-latest steps: - name: Install WorkOS CLI uses: workos/cli-action@v1 with: version: latest - name: Test Schema run: | workos fga schema apply schema.txt workos fga test tests/org-roles.test.yaml env: WORKOS_ACTIVE_ENVIRONMENT: staging WORKOS_ENVIRONMENTS_HEADLESS_API_KEY: - name: Apply Schema to Production if: github.ref == 'main' && github.event_name == 'push' run: | workos fga schema apply schema.txt env: WORKOS_ACTIVE_ENVIRONMENT: production WORKOS_ENVIRONMENTS_HEADLESS_API_KEY: ``` ### Resources Resources are FGA's references to your application's access controlled resources. FGA stores a set of warrants representing relationships between _resources_ in an application. These resources are typically application-specific objects persisted in the application's datastore (e.g. MySQL, PostgreSQL, MongoDB, etc). In FGA, they are referred to as _resources_. ## Overview ```shell report : balance-sheet | | Resource Type Resource ID ``` Resources consist of three attributes: - **Resource Type** - Specifies what _type_ of entity a particular resource is (e.g. a user, a tenant, a report, etc). - **Resource ID** - Specifies a unique identifier for the resource (typically the same unique identifier used in your application to identify the resource). - **Meta** (optional) - A JSON object containing additional data related to the resource that it would be helpful for FGA to know about (e.g. a user's email address, a tenant's display name, a description of the privileges a role grants, etc). Resources make it easier to manage the warrants associated with each resource, providing a way for applications to persist authorization-specific data outside of (or often, in lieu of) their primary datastore. ## Creating and Managing Resources FGA automatically creates the resources that are referenced by warrants when they are created. This means developers using FGA don't need to worry about manually creating resources. For example, given the following warrant: ```json title="report:balance-sheet#editor@user:john-doe" { "resource_type": "report", "resource_id": "balance-sheet", "relation": "editor", "subject": { "resource_type": "user", "resource_id": "john-doe" } } ``` FGA will automatically create two resources upon creation of the warrant: ```json title="report:balance-sheet" { "resource_type": "report", "resource_id": "balance-sheet" } ``` ```json title="user:john-doe" { "resource_type": "user", "resource_id": "john-doe" } ``` Resources can be managed from the [FGA Dashboard](https://fga.workos.com) and/or via API. Refer to the [Resources API Reference](/reference/fga/resource/create) to learn more about managing resources via API. > When a resource is deleted, any warrants associated with the resource will automatically be deleted. This makes it easier for applications to remove all warrants associated with a resource when the resource is deleted from the application itself. ## Metadata Resources can be augmented with additional authorization-specific metadata (e.g. the display name for a role or permission, the description of a particular feature, etc). Metadata is especially useful when implementing permission-specific user interfaces. For example, when building a customer-facing page for managing team-level roles and permissions, metadata can provide user-friendly names and descriptions of what actions/resources each role or permission will grant to a user. ```json title="user:john-doe w/ metadata" { "resource_type": "user", "resource_id": "john-doe", "meta": { "email": "john-doe@acme-corp.com", "isActivated": true } } ``` ```json title="role:accountant w/ metadata" { "resource_type": "role", "resource_id": "accountant", "meta": { "name": "Accountant", "description": "Allows a user to view the financial reporting pages and edit charges." } } ``` > There is a 50kb limit on the size of the metadata object. ### Quick Start Set up resource types and warrants that model your authorization requirements. Then use the SDK to make access checks from your application. ## Before getting started To get the most out of this guide, you should have: - A [WorkOS account](https://dashboard.workos.com/) - Your WorkOS [API Key](/glossary/api-key) - A basic understanding of [resource types](/fga/schema/schema-syntax/resource-types) ## What you'll build In this guide, we'll implement fine-grained authorization for a simple B2B SaaS application that gives users the ability to build and share reports generated using company data. We will: 1. Design a resource type schema that models the application's authorization requirements. 2. Create warrants to define relationships between the application's resources. 3. Make access checks that determine whether or not a user should have access to a resource. ## API resource definitions [Schema](/fga/schema) : A schema defining the different types of relationships available on your application's resources and how those relationships can be inherited [Warrant](/fga/warrants) : A rule assigning a relationship between two resources in your application ## (1) Install the WorkOS CLI Install the WorkOS CLI using [Homebrew](https://brew.sh/). ```shell brew install workos/tap/workos-cli ``` To initialize the CLI, use the command below. Follow the prompts to complete setup. ```shell workos init ``` --- ## (2) Define a resource type schema Our application has three types of resources: reports, teams, and users. Our authorization model should meet the following requirements: - Every report belongs to a team. - Every user belongs to a team. - Users who create a report are considered the owner of the report. - The owner of a report can also edit the report. - The owner of a report can add other users as editors. - An editor of a report can also view the report. - Users can view any report belonging to their team. We'll define the following resource type schema to fulfill these requirements: ```fga title="schema.txt" version 0.3 type user type team relation member [user] type report relation parent [team] relation owner [user] relation editor [user] relation viewer [user] inherit editor if relation owner inherit viewer if any_of relation editor relation member on parent [team] ``` ### (A) Using the CLI Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to update your schema in WorkOS FGA. ```shell workos fga schema apply schema.txt ``` ### (B) Using the FGA Dashboard Define a resource type schema from the FGA dashboard using the schema editor available on the [Schema](https://fga.workos.com/schema) page. --- ## (3) Create warrants Warrants are rules that assign relationships between the resources in an application. These relationships are then used to figure out whether or not a user should have access to a resource. For example, let's create two warrants: - One specifying that `[user:d6ed6474-784e-407e-a1ea-42a91d4c52b9] is a [member] of [team:stark]` - One specifying that `[team:stark] is [parent] of [report:7]` ### (A) Using the CLI Create warrants using the CLI. ```shell workos fga warrant create user:d6ed6474-784e-407e-a1ea-42a91d4c52b9 member team:stark workos fga warrant create team:stark parent report:7 ``` ### (B) Using the SDK Create warrants programmatically from your application using the SDK. --- ## (4) Check and query access Now that we have our resource types and some warrants set up, we can check and query access. Since we assigned `[team:stark]` as the `parent` team of `[report:7]` and `[user:d6ed6474-784e-407e-a1ea-42a91d4c52b9]` as a `member` of `[team:stark]`, they should automatically be a `viewer` of `[report:7]`. Let's do a check to make sure. ### (A) Using the CLI Check if a subject has a given relation on a resource. ```shell title="Check if user is viewer of report:7" workos fga check user:d6ed6474-784e-407e-a1ea-42a91d4c52b9 viewer report:7 ``` Query which resources a user has a given relation on. ```shell title="List reports where user is a viewer" workos fga query 'select report where user:d6ed6474-784e-407e-a1ea-42a91d4c52b9 is viewer' ``` ### (B) Using the SDK Check if a subject has a given relation on a resource. Query which resources a user has a given relation on. --- ## Summary That's it! We've now setup a powerful authorization system for our application that features a hierarchy of privileges (owner → editor → viewer) and inheritance of privileges based on team membership. ### Query Language Query which resources users have access to in your application. The Query Language is a declarative, SQL-like language used to [query](/reference/fga/query) WorkOS FGA for (1) the set of resources a particular subject has access to or (2) the set of subjects who have access to a particular resource. Examples of queries that can be specified with the query language include: 1. List all documents `user:A` is a `viewer` on. 2. List all users who are `editor`s of `document:finance-report`. 3. List all resources `user:malicious` has access to. 4. List all users who have the permission `view-financial-reporting`. 5. and many more ## Overview A query is composed of a `select` clause and either a `for` clause (if querying for subjects) or a `where` clause (if querying for resources): ```sql select permission where user:tony-stark is member ``` ## Select Clause The **select clause** specifies whether a query should return resources a subject has access to or return subjects that have access to a resource. ### Select Resources Return resources a subject has access to ```sql select ``` > `` can be a comma separated list of one or more resource types that results of the query will be filtered to. To select resources matching _any_ resource type, pass a wildcard (`*`) instead. ### Select Subjects Return subjects that have access to a resource. ```sql select of type ``` > `` and `` can be comma separated lists of one or more relations or one or more resource types respectively, that results of the query will be filtered to. To match _any_ relation or _any_ subject type, pass a wildcard (`*`) for the `` or `` properties respectively. ## Where Clause When selecting resources (e.g. `select tenant`), provide a `where` clause to specify a subject and one or more relations that subject must have on any resources returned in the query result. ```sql select where is ``` > `` must be a resource in the format `:`. `` can be a comma separated list of one or more relations. To match _any_ relation, pass a wildcard (`*`) instead. ## For Clause When selecting subjects (e.g. `select member of type user`), provide a `for` clause to specify a resource and one or more relations subjects must have on the specified resource to be returned in the query result. ```sql select of type for ``` > `` and `` can be comma separated lists of one or more relations or one or more resource types respectively. To match _any_ relation or _any_ resource type respectively, pass a wildcard (`*`) instead. ### Implicit vs. Explicit Results A query can optionally include the `explicit` keyword immediately following the `select` keyword to indicate that the query should _only_ return results that _explicitly_ match the provided relations. Explicit results are results for which a warrant matching one or more of the relations specified in the query explicitly exists. Implicit results are results which may implicitly match the relations specified in the query through [inheritance rules](/fga/schema/schema-syntax/inheritance-rules). Without the `explicit` keyword specified, a query will return both explicit and implicit results. ```sql title="Example: Get all users who explicitly have the viewer relation on document:doc1" select explicit viewer of type user for document:doc1 ``` ```sql title="Example: Get all users who have the viewer relation on document:doc1 explicitly OR implicitly" select viewer of type user for document:doc1 ``` ## Limitations ### Schema policies Schema policies are **not supported** in the current Query implementation. Any access results that are granted only by schema policies (as determined via the [check endpoint](/reference/fga/check)) will be excluded from query responses. This limitation exists because schema policies are fundamentally more complex than warrant policies. While warrant policies apply to specific relationships (e.g., user:1 is viewer of document:doc1), schema policies define rules that apply across all resources of a certain type and relation — for example, every viewer of every document. This generalization introduces two core issues: 1. **Scalable Evaluation**: The query engine would have to evaluate every resource of type B for every relation A, leading to major performance bottlenecks at scale. 2. **Security and UX Risks**: Alternatively, returning wildcard-based access (e.g., “user has access to resource type B:\*”) increases the risk of unintended data exposure and shifts the burden of filtering valid results to the application layer. Given these challenges, schema policies should be evaluated like traditional policy engines — by explicitly checking access between individual subjects and resources. This is what the check endpoint is for. > Warrant policies are supported in query, since they conditionally create specific relationship edges rather than applying general rules. To check access to a list of resources when using schema policies, you have two options: 1. Convert schema policies into equivalent warrant policies where feasible. 2. Use the batch check endpoint to validate access for many resources individually. ### No Joins The query engine does not support join semantics across relationships. For example, a query like: ```sql title="Invalid query" select viewer of type user for document:doc1 where group is viewer ``` …is not supported directly. To achieve a similar behavior, you could do one of the following: #### 1. (Recommended) Define a new relation in your schema that does the join via [inheritance rules](/fga/schema/schema-syntax/inheritance-rules) ```fga title="Example: Define a new relation in schema to join viewer and group" type user type group relation member [user] type document relation viewer [user, group] relation group_viewer [] // Query for documents where a user is a viewer through their group membership inherit group_viewer if relation member on viewer [group] inherit viewer if relation member on viewer [group] ``` Then you can query for the new relation: ```sql title="Example: Get all users who are viewers of document:doc1 through their group membership" select group_viewer of type user for document:doc1 ``` If you want to intersect results of two queries, you can use an `all_of` rule in your schema to define a new relation that combines the results of two existing relations. For example: ```fga title="Example: Define an all_of rule to combine viewer and group membership" type document relation subscriber [user] relation owner [group] inherit subscriber_and_owner if all_of relation owner relation subscriber inherit owner if relation member on owner [group] ``` Then you can query for the new relation: ```sql title="Example: Get all users who are both subscribers and owners (through a group membership) of document:doc1" select subscriber_and_owner of type user for document:doc1 ``` #### 2. Chain queries and combine results in application logic ```sql title="Example: Get all users who are viewers of document:doc1 and user:1 is a viewer" select viewer of type group for document:doc1 select member of type user for group:xyz // using groups from prior query ``` #### 3. Use a [batch check](/reference/fga/batch-check) to check access on multiple resources returned by a query ```sql title="Example: Batch check access for multiple resources returned by a query" select viewer of type group for document:doc1 ``` Then you can batch check `user:xyz` on all `viewer groups` for `document:doc1`. ## Examples ```sql title="Get all documents on which user:1 is a viewer (either explicitly or implicitly)" select document where user:1 is viewer ``` ```sql title="Get all documents on which user:1 is explicitly a viewer" select explicit document where user:1 is viewer ``` ```sql title="Get all documents on which user:1 has any relation (either explicitly or implicitly)" select document where user:1 is * ``` ```sql title="Get all resources of any type on which user:1 has any relation (either explicitly or implicitly)" select * where user:1 is * ``` ```sql title="Get all users who are viewers of document:doc1 (either explicitly or implicitly)" select viewer of type user for document:doc1 ``` ```sql title="Get all users who are explicitly viewers of document:doc1" select explicit viewer of type user for document:doc1 ``` ```sql title="Get all users who have any relation on document:doc1 (either explicitly or implicitly)" select * of type user for document:doc1 ``` ```sql title="Get all subjects of any type who have any relation on document:doc1 (either explicitly or implicitly)" select * of type * for document:doc1 ``` ### Policies Use policies to implement advanced attribute based access control with FGA, providing relevant data from your application at access control check time. WorkOS FGA allows you to define custom logic that is executed when evaluating access checks. A **policy** is a [boolean expression](https://en.wikipedia.org/wiki/Boolean_expression) that specifies additional conditions to be satisfied in order for an access check to be authorized. Use policies to enforce complex rules and conditions that go beyond simple role-based access control (RBAC) or attribute-based access control (ABAC). Policies can be defined on warrants or as part of your schema. > FGA currently supports defining policy expressions using [expr](https://expr-lang.org/docs/language-definition). Support for more policy languages will be coming soon. ## Warrant Policies You can optionally include a policy in a warrant. For a warrant to match a check/query, its policy must evaluate to true. The system evaluates policies after matching the warrant based on its resource, relation, and subject attributes. It evaluates the policy in the context of the check/query request, using any dynamic values provided via the context attribute (see [context](fga/policies/warrant-policies/context) below) to process the expression. For example, the following warrant states that `[role:accountant] is a [member] of [permission:view-profits-and-losses]` _only when_ `companyId == 'wayne-enterprises'`: ```json { "resource_type": "permission", "resource_id": "view-profits-and-losses", "relation": "member", "subject": { "resource_type": "role", "resource_id": "accountant" }, "policy": "companyId == 'wayne-enterprises'" } ``` Policies can reference dynamic variables. You must provide values for these variables in check or query requests via the context attribute (e.g., role, tenant, or geographic location). Before evaluating a policy, the system substitutes the provided values into the expression. Policy expressions undergo static type checking, so type mismatches prevent evaluation from returning true. Policies with missing values or evaluation errors also do not return true. The system compiles and statically checks policies for errors upon creation. Policies have numerous uses but are most commonly used to implement forms of attribute-based access control (ABAC). For example, create a warrant that only matches users visiting from a specific IP address: ```json { "resource_type": "database", "resource_id": "prod", "relation": "admin", "subject": { "resource_type": "user", "resource_id": "ops-user" }, "policy": "user.client_ip == '192.168.1.1'" } ``` Combine policies with role-based access control (RBAC) to support different role/permission mappings per customer or tenant. For example, define a warrant stating that `[role:accountant]` grants `[permission:view-balance-sheet]` only when `companyId == 'wayne-enterprises'`: ```json { "resource_type": "permission", "resource_id": "view-balance-sheet", "relation": "member", "subject": { "resource_type": "role", "resource_id": "accountant" }, "policy": "companyId == 'wayne-enterprises'" } ``` Create another warrant specifying that `[role:accountant]` grants users `[permission:view-profits-and-losses]` only when `companyId == 'daily-planet'`: ```json { "resource_type": "permission", "resource_id": "view-profits-and-losses", "relation": "member", "subject": { "resource_type": "role", "resource_id": "accountant" }, "policy": "companyId == 'daily-planet'" } ``` ### Context [Make access checks](/reference/fga/check), passing in different `companyId` values via the `context` based on the company a user belongs to: ```json { "checks": [ { "resource_type": "permission", "resource_id": "view-profits-and-losses", "relation": "member", "subject": { "resource_type": "role", "resource_id": "accountant" }, "context": { "companyId": "wayne-enterprises" } } ] } ``` This access check returns `false` because `[role:accountant]` only grants `[permission:view-profits-and-losses]` within the context of company `daily-planet`. ## Schema Policies You can reference policies in your schema, allowing you to define and reuse complex rules across different relations and inheritance rules. Use policies in the inherit clause of your schema definition. For example, consider the following schema: ```fga version 0.3 type user type organization relation viewer [user] relation view [] inherit view if all_of policy ip_allowed relation viewer policy ip_allowed(clientIp string) { clientIp matches "192\\.168\\..*\\..*" } ``` Here, the `view` relation is inherited based on the ip_allowed policy and the viewer relation. This means that users must meet the conditions of the `ip_allowed` policy and also be in the `viewer` relation to access the `view` permission. `view` has no allowed types, so it cannot be assigned a warrant directly. Instead, it inherits from the `viewer` relation and the `ip_allowed` policy so that we can check if a user is in the `viewer` relation and also meets the conditions of the `ip_allowed` policy. > Make sure schema version is set to `0.3` or higher to use policies in your schema. ### Defining and Using Policies Policies can be defined in the Schema Editor of the WorkOS FGA Dashboard or via the API. Each policy consists of the following fields: - **name** - a unique identifier for the policy - **language** - currently only `expr` is supported - **parameters** - define which values the policy accepts - **expression** - the boolean expression that defines the policy #### Policy Syntax `Expr` policies are defined directly in your FGA schema, making it easy to view policies alongside your inheritance rules. More languages will be supported in the future and managed through a different user interface. ```txt policy ( , ...) { } ``` > View `expr` language [documentation](https://expr-lang.org/docs/language-definition). Policies are referenced in inheritance rules using their name. ```txt inherit if policy ``` ### Attribute-Based Access Control (ABAC) You can use policies to implement pure attribute-based access control (ABAC) without any inheritance rules or warrant data. This allows you to define access control based solely on user attributes or other context values as you would with a policy engine. For example: ```fga version 0.3 type user type organization relation view_internal_settings [] inherit view_internal_settings if policy staff_user policy staff_user(user map) { user.email endsWith "@internal-domain.com" && user.role == "staff" } ``` In this example, the `view_internal_settings` relation inherits from the `staff_user` policy. This means only users with a staff role and an email ending in `@internal-domain.com` can access `view_internal_settings`. Since this policy is the sole inheritance rule for `view_internal_settings`, FGA does not check for warrants when evaluating access. This allows you to use FGA purely as an attribute-based access control (ABAC) system if desired. ### Combining Policies with ReBAC Policies can also be combined with ReBAC inheritance rules to create more complex access control models. Consider the following example: ```fga version 0.3 type user type organization relation admin [user] relation configure_payments [user] inherit configure_payments if all_of relation admin policy has_strong_auth policy has_strong_auth(user_attributes map) { user_attributes.mfa_enabled == true && user_attributes.account_age_days > 30 } ``` In this example, the `configure_payments` relation inherits from both the `admin` relation and the `has_strong_auth` policy. This means that users must be an admin and meet the strong authentication requirements to access the `configure_payments` relation. ## Managing Policies via API WorkOS FGA provides API endpoints if you prefer managing policies programmatically and separately from the schema. For more details, see the [Policies API documentation](/reference/fga/policy). ## Making Checks When making an FGA check, pass the required context values as you would with warrant policies. FGA evaluates warrant and schema policies together during access checks. ```json { "checks": [ { "resource_type": "organization", "resource_id": "acme-corp", "relation": "configure_payments", "subject": { "resource_type": "user", "resource_id": "123" }, "context": { "user_attributes": { "mfa_enabled": true, "account_age_days": 45 } } } ] } ``` ## Policies in Schema JSON Policies can also be defined in the schema JSON format. Here’s an example of how to define a policy in JSON: ```json { "version": "0.3", "resource_types": { "user": {}, "organization": { "relations": { "view": { "policy": "ip_allowed" } } } }, "policies": { "ip_allowed": { "name": "ip_allowed", "language": "expr", "parameters": [ { "name": "clientIp", "type": "string" } ], "expression": "clientIp matches \"192\\\\.168\\\\..*\\\\..*\"" } } } ``` > At runtime, if a policy fails to evaluate due to an invalid or missing context parameter, the system will return a 400 Bad Request in response to the check or query. ## Advanced Usage ### Injected Context Policies can reference dynamic variables that are injected by the FGA system **at runtime**. When a policy is evaluated, the system substitutes the provided values into the expression. This allows you to create policies that depend on runtime context, such as warrant data that the policy is stored with or check arguments. #### `check_ctx` A map containing the subject, resource, and relation of the check (or sub-check) executing the policy. This context variable is only available when the policy is evaluated in the context of a check (otherwise it is an empty map). ```json title="check_ctx" { "subject_type": "user", "subject_id": "123", "relation": "view_feature_1", "resource_type": "organization", "resource_id": "acme-corp" } ``` ```fga policy is_user_in_org(user_attributes map) { check_ctx.resource_type == "organization" && user_attributes.organization_id == check_ctx.resource_id } ``` Use `check_ctx` in a policy when: - **You want to avoid duplicating check arguments in context**\ Instead of manually passing `subject_id`, `resource_type`, or `relation` as context values in every access check, reference them directly via `check_ctx` to reduce redundancy and simplify your check requests. - **Your policy logic needs to vary based on the check's subject or resource**\ For example, use `check_ctx` when applying different rules depending on whether the subject is a `user` or `service`, or if the resource type is `document` versus `organization`. - **You're leveraging [policy helper functions](/fga/policies/advanced-usage/helper-functions)**\ Pass resource ids from `check_ctx` into helper functions. #### `warrant_ctx` A map containing the subject, resource, and relation of the warrant that the policy was stored on. This context variable is only available when the policy is stored on a warrant (otherwise it is an empty map). ```json title="warrant_ctx" { "subject_type": "user", "subject_id": "123", "relation": "editor", "resource_type": "organization", "resource_id": "acme-corp", "created_at": "2023-10-01T00:00:00Z" } ``` ```fga policy warrant_not_expired() { let expiration = duration("1h"); date(warrant_ctx.created_at) > now() + expiration } ``` Use `warrant_ctx` in a policy when: - **You need time-based or expiring access control**\ Reference `warrant_ctx.created_at` to enforce temporal constraints like short-lived or trial permissions. - **Your policy behavior depends on the warrant’s subject, resource, or relation**\ For example, restrict logic to apply only if the warrant’s `relation` is `"editor"` or `resource_type` is `"project"`. - **You need to evaluate policies only within warrant-based contexts**\ Helps enforce logic that should not apply in schema-only (inheritance) scenarios. - **You're using [policy helper functions](/fga/policies/advanced-usage/helper-functions)**\ Pass resource ids from `warrant_ctx` into helper functions. > Context variables can be empty if the policy is not evaluated in the context of a check or warrant. Make sure to check for empty values in your policy expressions to avoid errors. ### Helper Functions In addition to all of the built-in functions available in the [expr language](https://expr-lang.org/docs/language-definition), FGA provides the following helper functions for use in policies: #### `get_metadata` Fetches metadata for a given resource type and id when a policy is evaluated. This allows you to access metadata attributes stored on the resource in FGA without having to pass them in as context. This is especially useful when you don't want to update your check requests to include additional context values after schema changes. ```fga policy user_in_org() { let subject_metadata = get_metadata(check_ctx.subject_type, check_ctx.subject_id); subject_metadata.organization_id == check_ctx.resource_id && check_ctx.subject_type == "user" && check_ctx.resource_type == "organization" } ``` > Make sure to check for empty values in your policy expressions to avoid errors. It is best practice to avoid nested keys or use [optional chaining](https://expr-lang.org/docs/language-definition#optional-chaining) to prevent errors when accessing metadata attributes. #### `jwt_claim` Retrieves a specific claim from the JWT used to authenticate an access check. This is useful for policy logic that depends on user attributes embedded in the JWT, without needing to explicitly pass them through the context. This helper returns `nil` if a different authentication method (i.e. not a JWT) was used or the claim does not exist. This also works directly with Custom Attributes from AuthKit [JWT templates](/authkit/jwt-templates), allowing you to access user attributes directly in your policies. > Ensure your JWKS (JSON Web Key Set) is [properly configured](/fga/identity-provider-sessions) to validate JWT signatures and authorize requests. ```fga policy user_is_workos_admin() { let role = jwt_claim("role"); let email = jwt_claim("email"); role == "admin" && check_ctx.subject_type == "user" && email endsWith "@workos.com" } ``` ### Combine with Inheritance Rules Combine policies with inheritance rules to create complex access control models. For example, define a policy that checks specific conditions and apply it across multiple relations or inheritance rules: ```fga version 0.3 type user type staff_group relation member [user] type org_role relation member [user] type organization relation internal_admin [staff_group] relation viewer [user, org_role] relation view_feature_1 [] inherit view_feature_1 if any_of relation member on internal_admin [staff_group] all_of any_of relation viewer relation member on viewer [org_role] policy valid_enterprise_plan policy valid_enterprise_plan(payment_plan map) { payment_plan.is_active == true && payment_plan.tier == "enterprise" } ``` In this example: - `view_feature_1` access can be inherited based on multiple conditions. - Internal admins (`staff_group` members) can access `view_feature_1`. - Users in `viewer` or an `org_role` can also access it if they meet the `valid_payment_plan` policy requirements. ## Passing Context vs. Injecting Context When using policies, you can provide context in two ways: by passing values directly in the check request, or by injecting them into the policy using `get_metadata`. The right approach depends on where your data lives, how often it changes, and how you want to manage changes to your schema or policies. **Pass context**: Use this method when you want to provide specific values for the policy to evaluate. This is useful for dynamic values that may change frequently or are specific to the check being made. Passing context also does not require syncing data between your application and FGA, as the context is provided at check time. The major drawback is that it can lead to large check requests if you have many attributes to pass in. This can also make it difficult to manage and maintain the context values over time since changes to your schema or policies may require updates to the context values in your check requests. **Inject context**: Use this method when you want to fetch metadata or other attributes from the resource itself. This is useful for static values that are stored in FGA and do not change frequently or when you want to avoid passing large amounts of context data in the check request. Schema or policy changes do not require updates to the context values in your check requests, as the metadata is fetched at runtime. The major drawback is that it requires syncing data between your application and FGA. See the [Policy Context](/fga/modeling/policy-context) modeling guide for more details on how to use context in your policies. ## Common Use Cases Using policies and inheritance rules together provides a powerful way to model permissions for: - **Entitlements** (e.g., feature access based on plan level) - **Feature flags** (e.g., enabling experimental features for specific groups) - **Domain-specific logic** (e.g., enforcing security constraints specific data attributes) - **Temporal data** (e.g., granting temporary access based on time-based or location-based policies) ## Next Steps To start using policies in your schema, ensure the following: 1. Create policies in the schema or with the Policy API 2. Reference policies in your schema 3. Pass the correct context values when making access checks 4. Test your schema logic using the FGA dashboard and API ### Playground Use the FGA Playground to explore the capabilities of WorkOS Fine-Grained Authorization. The [FGA Playground](https://explore.fga.workos.com/playground) runs in the browser and allows you to interact with the schema, warrants, and queries in real-time before implementing them in your application. ![A screenshot of the FGA Playground](https://images.workoscdn.com/images/d2e7e812-17d0-4607-a0c5-db78a4b86207.png?auto=format&fit=clip&q=50) ### Operations & Usage Understand the operations_consumed metric and how it can help you optimize your FGA usage. WorkOS Fine-Grained Authorization (FGA) empowers developers to design custom authorization models tailored to their specific needs using Access Control Lists (ACLs). In FGA, ACLs can inherit from one another through explicit connections or custom inheritance rules (see [inheritance rules documentation](/fga/schema/schema-syntax/inheritance-rules)). However, the flexibility of these models can complicate capacity planning for FGA quota. FGA includes the `operations_consumed` metric in select API responses to provide visibility into quota consumption. This metric measures the computational cost of access checks, queries, and warrant transactions, offering developers valuable insights into how their authorization models affect quota usage. Complex models with deeply nested data or intricate inheritance rules can significantly increase the computational cost of FGA transactions, making it critical to design models thoughtfully. By understanding the impact of these factors, developers can make informed decisions to balance functionality and efficiency. This article breaks down the purpose of the `operations_consumed` metric, how it works, and strategies for optimizing FGA usage to better manage quota consumption. ## What is `operations_consumed`? operations_consumed is a metric that quantifies the number of computational operations performed during an ACL check or query in FGA. These operations include sub-tree checks and partial queries that are required to return the response. By tracking this value, FGA provides visibility into quota consumption, enabling developers to: - Understand the cost of their authorization checks. - Optimize their schema for better performance. - Ensure efficient usage within the provided quota. ```json title="POST /v1/check" { "result": "authorized", "is_implicit": true, "operations_consumed": { "total": 5 } } ``` ## How Does It Work? FGA performs access checks by traversing the ACL graph. The ACL graph is defined by warrant connections that are bridged by the inheritance rules defined in your schema. These operations include: 1. **Edge Traversals:** Verifying ACL connectivity through adjacent resources using warrant relations. 2. **Inheritance Rules:** Evaluating relationships based on inherited connections in your schema. 3. **Consistency Operations:** Determining whether fully consistent or eventually consistent results are required. In addition to schema complexity, the number of operations required to evaluate an access check also depends on sub-tree caching. Fully consistent checks inherently rely less on caching than eventually consistent checks. Eventually consistent checks have less strict cache policies, reducing the number of required sub-tree evaluations. However, requests for eventual consistency are not guaranteed to be served from cache. As a result, _`operations_consumed` may vary slightly across requests, with the worst-case scenario involving no caching._ FGA handles cached operations as follows: - A single access check on cached data always counts as **one operation**. - Multiple checks on the same cached result within a single transaction each count as **one operation**. - Accessing cached sub-trees avoids evaluating the sub-tree, significantly optimizing query execution. To optimize both performance and cost, it’s essential to use Warrant Tokens (see [Warrant Token documentation](/fga/warrant-tokens)) effectively and align your schema design with your consistency requirements. ## Implications of Graph Structure The structure of your ACL graph significantly impacts the operations_consumed metric. Here’s why: - **Nested Graphs:** While some nesting is acceptable, deeply nested relationships can significantly increase the complexity of access checks. Each additional layer in the graph requires more operations to resolve access, potentially impacting performance and query efficiency. ![FGA diagram showing an ACL graph with nested connections](https://images.workoscdn.com/images/9e3a627d-448a-4769-87e5-1de0ee4b5e10.png?auto=format&fit=clip&q=50) - **Wide Graphs:** Graphs with many/all resources converging on a single node demand more operations per check to resolve access. As your application grows in size and complexity, more connections may focus on a single node. Performance may degrade and usage could increase. ![FGA diagram showing a wide ACL tree](https://images.workoscdn.com/images/bb30073a-aa9a-41aa-a22a-1c5766d610a0.png?auto=format&fit=clip&q=50) - **Sparse or Disjoint Graphs:** Sparse graphs, where resources and subjects are minimally connected, consume fewer operations. Disjoint sub-graphs, typically separated by tenant or user, are particularly efficient. Both reduce the traversal scope. ![FGA diagram showing disjoint graphs separated by company identifier](https://images.workoscdn.com/images/2d4610e1-8e4c-44e8-bbfd-fe9f66c49731.png?auto=format&fit=clip&q=50) ## Optimizing operations_consumed Usage To preserve operations and stay within quota limits, developers can utilize the following strategies: ### Sub-graph Separation Divide ACLs into smaller, independent sub-graphs. This approach reduces the traversal depth and isolates computational effort to specific areas of the graph. For example, building disjoint sub-graphs for different tenants that use your application. ### Favor Eventual Consistency Use fully consistent checks only when necessary. Opt for eventually consistent checks to increase the likelihood of cache hits. In practice, developers can avoid fully consistent checks by using Warrant Tokens in API requests. ### Cache Warrant Tokens Store API-generated Warrant Tokens with atomic writes to reuse them for future access checks, minimizing redundant computations. Cached warrant tokens reduce the need to use fully consistent checks. ### Simplify Relationships Avoid building a model with unnecessary nesting, complicated inheritance rules, or wide connections. Streamlining relationships minimizes the number of operations required to resolve an access check. ## Why `operations_consumed` Matters FGA charges based on `operations_consumed` usage, encouraging efficient graph design while providing the flexibility to build robust, scalable access control systems. Key benefits include: - **Lower Costs:** Reduce quota consumption with optimized graph structures. - **Better Performance:** Deliver faster response times for access checks and queries. - **Scalability:** Handle larger datasets efficiently without increased resource demands. By optimizing `operations_consumed`, developers can create cost-effective, high-performing access control models that scale with their applications. ## Testing and Local Development WorkOS offers an isolated FGA Docker image designed for testing and development. This image utilizes SQLite and in-memory caching and is not intended for production use. It should be used only in a local environment or for running test suites in your CI/CD pipeline. The fga-dev image is available on our [public ECR repository](https://gallery.ecr.aws/workos/fga-dev). View the `Usage` section for more information about how to use it. ### Local Development Learn how to setup your local development environment with FGA using the FGA Dev Docker image for isolated testing and schema development. ## Overview When developing with FGA, you can either connect to a managed WorkOS FGA instance or run a local FGA instance using the [`fga-dev` Docker image](https://gallery.ecr.aws/workos/fga-dev). Each option has its own advantages depending on your workflow. This guide will help you choose the best approach and walk you through setting up a local instance if that fits your needs. ### Managed FGA Instance Best for testing against production-like infrastructure and when you need persistent, shared data. | Pros | Cons | | -------------------------------------------------------------- | ------------------------------------------------------------------- | | Data persists and is accessible by multiple clients | Data is shared (multiple consumers can overwrite each other's data) | | Uses production infrastructure for performance and reliability | Consumes operation credits | ### Local FGA Instance Best for isolated development and testing especially when you want to avoid using operation credits or need a clean environment for each run (such as in CI). | Pros | Cons | | ------------------------------ | ------------------------------------------ | | Isolated test environment | You must manage setup and teardown of data | | Does not use operation credits | Uses local resources and is not scalable | The `fga-dev` Docker image provides a fully self-contained FGA environment using SQLite and local caching. This setup is **not intended for production** but is fine for local development, CI, and integration testing. It is less scalable than the managed instance because it cannot handle high concurrency, complex models, or large datasets. This guide will show you how to use the [`fga-dev` Docker image](https://gallery.ecr.aws/workos/fga-dev) to spin up an isolated FGA instance on your machine. --- ## Prerequisites To start this guide, you'll need: - [Docker](https://www.docker.com/get-started) installed on your machine - A [WorkOS account](https://dashboard.workos.com/) (for API keys) - Your WorkOS [API Key](/glossary/api-key) --- ## Running fga-dev Locally ### Option 1: Using Docker Compose (Recommended) Create a `docker-compose.yaml`: ```yaml title="docker-compose.yaml" version: '3.8' services: fga-dev: image: public.ecr.aws/workos/fga-dev:latest-arm64 user: root # Run as root to avoid permission issues with mounted volumes (non-production only) volumes: - fga-dev-volume:/data:rw,cached # Persist data between runs ports: - '8001:8001' environment: FGA_DEV_PORT: 8001 FGA_DEV_AUTH_API_KEY: # Your staging WorkOS API key to authenticate the dev image FGA_DEV_TEST_API_KEY: test_key # A mock API key to authenticate FGA requests from your application volumes: fga-dev-volume: ``` #### Usage 1. **Start the server:** ```shell docker compose up -d ``` 2. **Configure your app:** - Point your application's WorkOS SDK or CLI to the proper host. - Use `test_key` as the API key for FGA requests from your app. | Environment | API Host | | --------------------------- | -------------------------------- | | Local machine | http://localhost:8001 | | Separate Docker container | http://host.docker.internal:8001 | | Same Docker Compose network | http://fga-dev:8001 | > If you’re using the WorkOS SDK, you can set the API Hostname option to point to your local FGA instance. Since each SDK instance supports only one API Host, you may need to create a separate SDK instance specifically for FGA when testing against the local service. 3. **Develop:** Apply schemas, create warrants, and test locally. All data persists in the Docker volume. See [Schema Management](/fga/schema-management) for how to apply a schema to your local instance and test authorization checks. 4. **Shut down:** ```shell docker compose down ``` 5. **Clear all data (optional):** ```shell docker volume rm fga-dev-volume ``` > Tip: Add a secondary Docker Compose service to seed your local instance with test data on startup. --- ### Option 2: Running a Docker Container You can also run the `fga-dev` image directly using `docker run` if you prefer not to use Docker Compose. ```shell docker run -d \ --name fga-dev \ -p 8001:8001 \ -e FGA_DEV_PORT=8001 \ -e FGA_DEV_AUTH_API_KEY= \ -e FGA_DEV_TEST_API_KEY=test_key \ -v fga-dev-volume:/data:rw \ --user root \ public.ecr.aws/workos/fga-dev:latest-arm64 ``` To stop and remove the container: ```shell docker stop fga-dev && docker rm fga-dev ``` To remove the volume and reset all data: ```shell docker volume rm fga-dev-volume ``` --- ## Best Practices Consider the following best practices to ensure a smooth local development experience with FGA: - **Isolate test data**: Use unique resource IDs to avoid collisions which is especially critical when working with shared or managed instances. - **Automate environment setup**: Script the schema and warrant creation on first startup. This makes your development and CI pipelines more reliable and repeatable. - **Clean up regularly**: Tear down and reset your environment when needed to avoid stale data and hidden state, which can lead to confusing behavior. - **Choose the right environment**: Use a managed instance for shared, persistent testing; use the local fga-dev container for isolated development or CI. --- ### Fine-Grained Authorization (FGA) Scalable, centralized, fine grained authorization for your application. ## Introduction WorkOS Fine-Grained Authorization (FGA) is a centralized authorization service for customer applications. Teams can use FGA to implement a custom authorization model tailor-made for their application(s), with the ability to integrate elements of role-based access control (RBAC), relationship-based access control (ReBAC), and attribute-based access control (ABAC) as needed. ## Key features - Fully managed, centralized authorization service (inspired by Google Zanzibar) for managing and enforcing application authorization - [Check API](/reference/fga/check) to perform fast access checks from your application (i.e. `Is user:A an editor of document:X?`) - [Query API](/reference/fga/query) to quickly lookup which resources users have access to from your application (i.e. `Which documents can user:A edit?`) - Central log of all authorization events & operations to make auditing and debugging of your application(s) easy - Pre-built templates for common access control patterns like RBAC, multi-tenancy, pricing tiers & feature entitlements, and more ## Common Use Cases ### Role-based access control (RBAC) One of the most common forms of access control, role-based access control involves 3 main entities: roles, permissions and users. Permissions define _behaviors_ that are grouped together into roles (e.g. admin, owner). Roles are then assigned to users to grant them the ability to perform a group of behaviors. RBAC is common within B2B software and SaaS applications used by enterprises, often being necessary to meet regulatory, compliance, and/or enterprise contract requirements. ### Custom roles Most applications start by implementing RBAC with a static set of roles. This works well for simple applications used by one customer (single-tenant). However, this model often breaks down in multi-tenant applications (apps used by multiple customers). Different customers might require a different set of roles or a different mapping of roles to permissions. This requirement introduces a new dimension (tenant) on top of existing roles, permissions, and users, requiring a flexible access model to prevent a problem known as _role explosion_. ### Fine-grained access control (FGAC) Fine-grained access control is a more granular form of access control that is becoming popular in applications today. As opposed to the coarse-grained access control provided by RBAC, which grants access to behaviors across _all resources_, FGAC allows applications to grant users certain behaviors _per resource_. For example, while a RBAC rule might specify that `[admins] can [edit] [reports]`, a fine grained rule can specify that `[user:1] can [edit] [report:xsd34]`. ### Resource-level RBAC FGAC can also be used in conjunction with RBAC to enable what we call 'fine-grained RBAC'. This is especially common in SaaS apps and developer tools. For example, let's take a cloud infrastructure multi-tenant SaaS that defines a resource called `customer-application`. A 'customer-application' can have `owners`, `editors` and `viewers`. Now let's say that the users within this SaaS can have multiple 'roles' within their 'tenant' based on their access level. In order to specify an access rule like `all [admins] of [tenant:x] can [edit] [all applications] that belong to [tenant:x]`, we need 'fine-grained RBAC', or the ability to specify resource-level rules by role. ### Collaboration & document sharing One of the most common use cases for FGAC is to enable access control on user-generated content, similar to Google Docs or Box. With FGAC, you can easily define `owners`, `editors` and `viewers` of your own resources and objects (ex. documents, reports). ### Organization hierarchies Another common use case for FGAC is to model complex organization hierarchies, often those found within most mid-large scale enterprises. For example, let's say that we'd like to specify a rule within an organization which states that `all [members] of [team:x] can access [report:y87dXfd]`. Furthermore, let's say that membership in `team:x` is driven by org hierarchy and whether a specific person reports to a given manager. Using a FGA system, we can model the exact org hierarchy as well as easily define rules such as `all [direct reports] of [manager:y] are [members] of [team:x]` and `all [members] of [team:x] can access [report:y87dXfd]` in order to process queries such as `can [user:1] access [report:y87dXfd]` in realtime. ### Regional access control Similar to enterprise org hierarchies, apps with complex regional hierarchies are a good use case for FGAC. For example, let's say we're building a supply-chain or operations-focused SaaS app where data and functionality is separated by region. We may have `region:east` and `region:west` to distinguish the two core regions with teams and users defined within each region. Using a FGA system, we can accurately model the regions and easily make queries against it at runtime to ensure that the right users have access to the right data and functionality. ### Pricing tiers & feature entitlements Although not directly related to security, a common form of access control often used within SaaS is what we call 'pricing tiers & feature entitlements'. Pricing tiers are groups of features within an app, typically assigned based on the end customer's payment tier. Mature SaaS apps often build out their own management and enforcement layer for pricing tiers, in order to support everything from feature overrides and metering to integrations with payment systems. With a FGAC system, pricing tiers and feature entitlements can be expressed as rules like `[company:x] is on [tier:enterprise]` and `[feature:dashboard] is part of [tier:enterprise]` in order to easily support runtime queries like `can [user:y] which is a member of [company:x] access [feature:dashboard]?` ### Fine-Grained Authorization (FGA) Scalable fine-grained authorization built for B2B SaaS. ## Introduction > Coming Q1 2026 - The endpoints and features described on this page are not yet available. > The previous version of WorkOS Fine-Grained Authorization (FGA) was officially deprecated on November 15, 2025. A fully re-architected FGA is now in development and will be released soon. Please read our [blog post](https://workos.com/blog/fga-how-workos-is-rethinking-authorization-for-the-next-generation-of-saas) for details. Fine-Grained Authorization (FGA) extends the existing WorkOS RBAC system to handle the complex, fast-changing authorization needs of modern B2B SaaS products. Most products start with simple, org-level roles like Admin and Member. As adoption grows, the model is forced to account for workspaces, projects, apps, pipelines, nested tenants, custom roles, group-based collaboration, and enterprise exceptions. What used to evolve over a decade can now change in 12–18 months. Teams patch RBAC with special cases, multiply role variants, and eventually face full rewrites. FGA is designed as the next step in that evolution: - It keeps the **mental model of RBAC**: roles, permissions, assignments. - It adds **hierarchical, resource-scoped access control**. - It integrates **natively with existing WorkOS products**, including RBAC, SSO, Directory Sync/SCIM, AuthKit, and IdP role mapping. - It can be **adopted incrementally** with no data migration or confusing schema DSL. The goal is to give SaaS teams a single authorization foundation that adapts as the product and customer requirements change, without introducing a parallel system or forcing conceptual rewrites. --- ## Core concepts FGA formalizes three building blocks: - **Subjects** – Users, groups, devices, or agents that can be granted access. - **Resources** – Business entities in your product (organizations, workspaces, projects, apps, etc.) arranged in a hierarchy. - **Privileges** – Roles and the permissions contained within them. The key shift from traditional, org-only RBAC is that **resources and their hierarchy are first-class**. Roles and permissions are scoped to specific resource types and may be assigned at any level of that hierarchy. --- ## Resource model FGA’s resource model captures how entities in your application relate to one another. It is: - **Hierarchical** – Up to five layers deep. - **Typed** – Each layer can define multiple resource types. - **Single-parent** – Each resource instance has exactly one parent (organization or another resource). > Note: Resource types and resource instances are distinct. Resource types define the schema of the hierarchy and may specify multiple valid parent types. Resource instances are the actual objects created at runtime, and each instance always has exactly one parent, ensuring predictable inheritance and traversal. Typical hierarchies: ```text organization └─ workspace └─ project └─ app organization └─ account └─ dashboard organization └─ team ├─ repository └─ pipeline ``` Resource types and their allowed parent/child relationships are defined in the WorkOS Dashboard. Examples: - `Organizations` - `Workspaces` - `Accounts` - `Projects` - `Applications` - `Pipelines` - `Spaces` - `Repositories` - `Dashboards` ### Resource instances At runtime, your application registers resource instances as users create them: ```text Org:acme └─ Workspace:finance └─ Project:quarterly-plan └─ App:forecasting ``` Each instance has: - A **type** - what kind of resource it is (`workspace`, `project`, …). - An **id** - a unique identifier for that specific resource instance. - A **parent** - the organization or resource it belongs under. This structure drives: - Where roles can be assigned. - How permissions inherit down the tree. - How cascaded cleanup works when a resource is deleted. The model is optimized for low-cardinality entities like workspaces, accounts, and apps. High-volume application objects—documents, messages, tasks, rows, and similar—should remain in your application’s own source of truth rather than being modeled as FGA resource instances. Syncing these objects into an external authorization store introduces latency, reconciliation issues, and operational overhead. Some systems attempt to avoid this by querying your database during authorization (“local evaluation”), but this shifts the problem: authorization performance becomes tied to your production database, rule logic becomes tightly coupled to your schema, and developers must maintain custom query filters that scale poorly in multi-tenant environments. Modeling inheritance or hierarchy must also be done manually, which becomes brittle as products evolve. FGA avoids both patterns. High-cardinality objects remain in your database, but can still participate in authorization by storing a reference to their nearest FGA-managed parent resource. Your application passes that parent during checks, allowing permissions to be evaluated through the hierarchy without syncing every object or embedding authorization logic in database queries. This keeps authorization fast, predictable, and decoupled from your data model—without the trade-offs required by other approaches. --- ## Roles and permissions Roles and permissions in FGA are always defined relative to a resource type. This means a role created for a workspace applies only to workspace resources, a project role applies only to projects, and so on. Existing organization-level RBAC roles continue to function exactly as they do today and are automatically scoped to the organization. A role describes what a subject can do within the scope of a particular resource type. Each role contains one or more permissions, and those permissions may apply either to: - the same resource type as the role (for example, workspace:view), or - a child resource type (for example, project:edit), enabling permission inheritance down the hierarchy. ## How scoping works If a role is scoped to a workspace type, it can grant permissions such as viewing or editing that workspace. If it includes child-type permissions (like project-level actions) those permissions automatically apply to all child resources under that workspace. This prevents role explosion and allows a single workspace-level role to control access across the entire sub-tree beneath it. Example: - An `Organization Member` role grants organization-level permissions such as viewing the org or accessing its workspaces. - A `Workspace Admin` role grants full access to a specific workspace and all projects within it. - A `Project Editor` role grants edit rights only to a particular project and its apps, without affecting sibling projects. Through this model, FGA ensures permissions are predictable, type-safe, and aligned with the structure of your application’s resource hierarchy—while preserving all existing RBAC behavior. ### Assignment and inheritance An assignment binds: - An [Organization Membership](/authkit/users-organizations/organizations/organization-memberships) (user) - A [role](/rbac/configuration/configure-roles) - An [Organization](/authkit/users-organizations/organizations) or resource instance When a role includes child-type permissions, FGA automatically **propagates** those permissions down to children under that parent resource. Consider the following hierarchy: ```text Org └─ Project └─ App ``` We can configure roles at each level to define the following access patterns: - A user is `Member` of `Org:1` with `org:view`, `project:view`, and `app:view` permissions. They can view the organization, all of its projects, and all apps under those projects. - The same user is `Project Editor` for `Project:B` and can edit that project and all of its apps. - A user is `App Editor` for `App:Finance` and can edit only that app instance. - Another user is `Project Read-Only` on `Project:A` and can view only that project, not its apps. ![Example resource hierarchy with roles](https://images.workoscdn.com/images/74c1fad7-abe9-4c21-a244-8c2563f1313c.png?auto=format&fit=clip&q=50) --- ## Access evaluation [AuthKit](/authkit) continues to embed organization-level [roles and permissions in access tokens](/authkit/roles-and-permissions/role-aware-sessions). These roles come from the existing RBAC product and may also include any resource-scoped permissions defined within those org-level roles. They remain the best mechanism for coarse-grained checks—for example, determining whether a user can access an organization at all or perform billing-related actions. To evaluate access on a specific resource instance, your application calls the Authorization API: ```json POST /authorization/check ``` The check engine considers: - Direct assignments on a resource (`project:proj_123`). - Assignments on parent resources (a project permission inheriting from role assignment on the workspace it belongs to). - Organization-level roles from the session token that contain permissions for the relevant resource type. --- ## Authorization API (Not yet available - coming Q1 2026) FGA is exposed through a set of Authorization API endpoints grouped into three concerns: **resources**, **assignments**, and **access checks**. ### Resource instance management - `GET /authorization/resources/` - `POST /authorization/resources` - `PATCH /authorization/resources/` - `DELETE /authorization/resources/` ### Resource Management using external IDs - `GET /authorization/organizations//resources//` > Note: Resource types are defined in the WorkOS Dashboard and are not managed via the API. ### Role assignments - `POST/DELETE /authorization/assignments` ### Access checks and resource discovery - `POST /authorization/check` - `GET /authorization/resources/{resource_id}/organization_memberships` - `GET /authorization/organization_memberships/{membership_id}/resources` - `GET /authorization/organization_memberships/{membership_id}/roles` With resource discovery endpoints, you can implement queries that align with common product features, such as: - “List members with access to this workspace” - “All projects under a parent workspace this user can edit” - “List all assigned roles for a user” --- ## Enterprise identity integration FGA integrates directly with [SSO](/sso), [Directory Sync](/directory-sync), and IdP [role/attribute mapping](/directory-sync/identity-provider-role-assignment). Organizations can: - Map IdP groups to resource-level roles, so teams inherit the correct workspace or project access automatically. - Use IdP attributes to drive assignments, ensuring roles reflect organizational metadata such as department or job function. - Align internal team structures with FGA resource types, allowing identity changes in the IdP to cascade cleanly across the application’s authorization model. **Coordinating identity information with a hierarchical authorization system is one of the hardest challenges in modern SaaS architecture—and FGA provides a unified solution that no other provider offers today.** --- ## Performance and scalability FGA is designed for real-time authorization and heavily optimized. It uses the resource hierarchy to efficiently evaluate permissions, ensuring accurate and fast access decisions. Key performance characteristics: - Sub-50 ms p95 access checks. - Strong consistency. - High availability. - Warmed caches. - Edge caches for low-latency global access (scheduled for a future release). --- ## Adoption and integration with existing products FGA works **alongside** the existing RBAC product: - No migrations are required. - Existing RBAC roles and organization memberships continue working. - You can adopt FGA incrementally. A typical rollout: 1. Use current RBAC for org-level access. 2. Define resource types to mirror your product structure. 3. Begin registering resource instances. 4. Introduce scoped roles like `workspace_admin` or `project_editor`. 5. Replace custom logic with Authorization API checks. 6. Map IdP groups and attributes to resource-scoped roles. --- ## Handling high-cardinality resources High cardinality resource types introduce a subtle but serious anti-pattern in Zanzibar inspired systems: syncing millions of rapidly changing resource instances to an external authorization system. As cardinality increases, so does the likelihood of data inconsistencies and update failures, especially when resources sit in the application's hot path. Pushing resource updates over the network to a third-party system adds latency and instability in the application's critical path. WorkOS FGA takes a different approach. Instead of treating every individual resource as an external entity that must be synced, applications store high-cardinality resource types locally and register only the stable parent resource types inside WorkOS. This keeps authorization fast, consistent, and close to the application's core workflows while offloading complex hierarchy management to WorkOS. The result is an expressive model that avoids remote bottlenecks and an architecture that stays performant, resilient, and easy to evolve as the product grows. --- ## Release Timeline | Phase | Features | Target Date | | -------------------- | -------------------------------------------------------- | ----------------------- | | Restricted Preview | Core Authorization API and dashboard modeling | January – February 2026 | | General Availability | Refinements based on early customer feedback | February – March 2026 | | Enhancements | User groups, advanced IdP mapping, widgets, custom roles | Q2 2026 | | Global Access | Edge caching and streaming for low-latency checks | Q4 2026 | If you are interested in participating in the restricted preview, please reach out to WorkOS support. ### Identity Provider Sessions Learn how to configure FGA to use your identity provider's ID tokens. ## Overview Fine-Grained Authorization (FGA) is commonly used to enforce detailed authorization on your application's backend. However, it can also be utilized on the frontend to perform access checks directly within your client application. FGA supports the use of ID tokens issued by identity providers, allowing you to make user-specific authorization decisions on the frontend. This not only improves the security of your application but also enables you to present a customized user interface and experience based on the access levels of different users. ## Before getting started To get the most out of this guide, you’ll need: - A [WorkOS account](https://dashboard.workos.com/) - Your WorkOS [Client ID](/glossary/client-id) - The JSON Web Key Set (JWKS) endpoint of your identity provider. ([AuthKit](/reference/authkit/session-tokens/jwks)) - A schema set up in a FGA environment. If you haven't done so, check out our [Quick Start](/fga/quick-start) to create one. --- ## (1) Configure your JWKS URL A JWKS URL is an endpoint that contains the set of public keys used to verify any JSON Web Tokens (JWTs) issued by your provider. Currently, FGA only supports JWTs that are signed using the **RS256** signing algorithm. Common identity provider JWKS URLs: - **WorkOS AuthKit**: `https://api.workos.com/sso/jwks/{clientId}` - **Auth0**: `https://{yourDomain}/.well-known/jwks.json` - **Google/Firebase**: `https://www.googleapis.com/oauth2/v3/certs` You can set your JWKS URL in the _Configuration_ section of the [FGA Dashboard](https://fga.workos.com/configuration). ![FGA JWKS Configuration](https://images.workoscdn.com/images/35f59a84-d1ad-4c78-8be4-210678a6c161.png?auto=format&fit=clip&q=50) ## (2) Create a context for FGA Next, let's create a [context](https://react.dev/learn/passing-data-deeply-with-context) for FGA that will allow us to make checks from anywhere in our application. The FGA context will set and track the user's session token and expose a `check` method that we can access anywhere in our application where we need to make an access check before displaying a UI element or performing an action. ## (3) Set the session token when a user logs in Before we begin making access checks in our application, we need to provide a server-generated session token and set it in our FGA context. ## (4) Make check requests from your app Now that we've created our FGA context and set the session token, we can start making check requests from our client application. The main difference here from regular check requests is that we don't need to provide a subject in our checks because all checks will be scoped to the user specified by the user ID in the session token. Let's make a check to see if the user has the `viewer` relation on `report:7` before displaying the report's data. --- ## Summary In this guide, we demonstrated how to perform authorization checks directly in a client application using ID tokens from our identity provider. We created a context to manage the user's session token upon login, which is then used for subsequent access checks. This approach allows us to deliver a secure and personalized experience to users within our application, leveraging FGA for fine-grained access control. ### User Groups Learn how to make user group abstractions to manage permissions at scale. > Explore the example from this guide [in the FGA Playground](https://explore.fga.workos.com/playground?example=user_groups), where you can interact with the schema, warrants, and access checks in real-time! User groups in Fine-Grained Authorization (FGA) allow you to manage permissions at scale by grouping users and granting access to those groups. This is particularly useful in large organizations where managing individual user permissions can become cumbersome. ## When to Use It? You should consider using user groups in the following scenarios: - **Large Organizations**: When you have a large number of users and resources, managing permissions individually can be inefficient. - **Dynamic User Base**: If your user base changes frequently (e.g., employees joining or leaving), management groups can simplify the process of updating permissions. - **Hierarchical Structures**: When your organization has a hierarchical structure (e.g., departments, teams), management groups can help you define permissions at different levels of the hierarchy without duplicating effort. ## Example Applications Management groups can be applied in various scenarios, including: - **Enterprise Applications**: In large enterprises, you can create groups for different departments (e.g., Sales, Engineering) and assign permissions to these groups rather than individual users. - **Multi-Tenant SaaS Applications**: For SaaS applications serving multiple organizations, you can create groups for each tenant and manage permissions for users within those tenants. ## Schema ```fga version 0.3 type user type organization relation admin [user] relation document_viewer [user] relation document_manager [user] inherit document_manager if relation admin // admins are also document managers inherit document_viewer if relation document_manager // document managers are also viewers type document // A document has a parent organization relation parent [organization] relation edit [user] relation view [user] // Allow users to edit the document if they // are in the document manager group on the organization that owns it inherit edit if relation document_manager on parent [organization] // Allow users to view the document if they // are in the document viewer group on the organization that owns it inherit view if relation document_viewer on parent [organization] ``` ## Example ### (1) Apply the schema Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment. > Note: make sure to select the correct environment with the [CLI](https://github.com/workos/workos-cli?tab=readme-ov-file#usage) ```shell workos fga schema apply schema.txt ``` --- ### (2) Create warrants Create warrants that associate organizations and documents. Add a users to a `document_viewer` / `document_manager` groups. --- ### (3) Check access With our environment setup, we can check the user's permission to view items. --- ### Superusers Learn how to use policies to create superuser overrides. > Explore the example from this guide [in the FGA Playground](https://explore.fga.workos.com/playground?example=superusers), where you can interact with the schema, warrants, and access checks in real-time! Superuser policies allow specific users to override inheritance rules to grant broad access to many resources. This is useful for granting elevated privileges to trusted users, such as administrators, support engineers, or internal employees. ## When to Use It? Use superuser policies when you need to: - Provide emergency access to a resource without modifying existing permissions. - Allow internal employees to manage resources without explicitly assigning them to each one. - Implement organization-wide administrative roles that apply across multiple resources. ## Example Applications Many applications implement superuser policies, including: - **E-commerce platforms**: Store administrators or support agents need access to all stores for troubleshooting. - **Multi-tenant SaaS applications**: Internal employees may need to access any tenant's data for support purposes. - **Content management systems**: Superusers may need the ability to edit or review content across multiple projects. ## Schema ```fga version 0.3 type user type store relation editor [user] relation viewer [user] // Editors of a store are either // Assigned directly as an editor of the store // Or superusers who can edit any store (via is_superuser policy) inherit editor if policy is_superuser // Any editor can also view the store inherit viewer if relation editor policy is_superuser(user_attributes map) { user_attributes.superuser == true && user_attributes.email endsWith "@internal-domain.com" } ``` ## Example ### (1) Apply the schema Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment. > Note: make sure to select the correct environment with the [CLI](https://github.com/workos/workos-cli?tab=readme-ov-file#usage) ```shell workos fga schema apply schema.txt ``` --- ### (2) Check access With our environment setup, we can check the user's permission to view a document. --- ### Google Docs Build a Google Docs-like authorization model in which users have varying levels of access to documents they can collaborate on with each other. > Explore the example from this guide [in the FGA Playground](https://explore.fga.workos.com/playground?example=google_docs), where you can interact with the schema, warrants, and access checks in real-time! Implement an authorization model similar to Google Docs document sharing. Allow users to grant read and/or write access to other users on individual documents and folders containing other nested documents and/or folders. ## When to Use it Consider this authorization model for: - **User Generated Content**: Your application supports user-generated content (e.g. documents, notes, images, etc.) and users can share access to this content with each other - **Collaboration**: You want to allow users to collaborate on content or resources together ## Schema ```fga title="schema.txt" version 0.3 type user type document // Note: folders are modeled as documents. // They can be parents of other documents. relation parent [document] relation role_owner [user] relation role_editor [user] relation role_viewer [user] relation can_write_users [] relation can_read_users [] relation can_write_content [] relation can_read_content [] inherit role_owner if relation role_owner on parent [document] inherit role_editor if any_of relation role_owner relation role_editor on parent [document] inherit role_viewer if any_of relation role_editor relation role_viewer on parent [document] inherit can_write_users if relation role_owner inherit can_read_users if any_of relation role_viewer relation can_write_users inherit can_write_content if relation role_editor inherit can_read_content if any_of relation role_viewer relation can_write_content ``` ## Example ### (1) Apply the schema Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment. > Note: make sure to select the correct environment with the [CLI](https://github.com/workos/workos-cli?tab=readme-ov-file#usage) ```shell workos fga schema apply schema.txt ``` --- ### (2) Create warrants Create warrants that associate users and documents. The example schema defines the following relationships: - documents with other documents (i.e. folders) - users with documents (using one of the defined roles: `owner`, `editor`, or `viewer`) Let's create a few warrants between documents `doc-1`, `doc-2`, `doc-3`, `folder-1`, `folder-f2`, and user `user_2oDscjroNWtzxzYEnEzT9P7VYEe`: --- ### (3) Check access With our environment setup, we can check whether the user can read a document's contents. --- ### Public Access Model public document access using FGA policies. > Explore the example from this guide [in the FGA Playground](https://explore.fga.workos.com/playground?example=public_access), where you can interact with the schema, warrants, and access checks in real-time! Public access allows users to view resources without requiring a direct relationship or explicit grant. This is useful for cases where content is meant to be openly accessible but still requires a basic set of conditions, such as being published or flagged as public. ## Example Applications - **Document Management**: Public reports or documents. - **Education Platforms**: Make certain course materials or syllabus open access. - **Media & Publishing**: Allow public access to some articles while gating premium ones. - **E-Commerce**: Public product listings with private admin dashboards or private draft listings. ## Schema ```fga version 0.3 type user type document relation viewer [user] inherit viewer if policy is_public_document policy is_public_document(document_attributes map) { document_attributes.public == true && document_attributes.status == "published" } ``` > Note: Public access can also be modeled with [wildcard warrants](/fga/warrants/wildcard-warrants). This example focuses on using policies for more control over access conditions. ## Example ### (1) Apply the schema Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment. > Note: make sure to select the correct environment with the [CLI](https://github.com/workos/workos-cli?tab=readme-ov-file#usage) ```shell workos fga schema apply schema.txt ``` --- ### (2) Check access With our environment setup, we can check the user's permission to view a document. --- ### Policy Context Learn how to pass context to policies in FGA. Policies in FGA allow you to define complex access control rules based on the context of the request. This context can include resource attributes, location and temporal data, or any other relevant information that can help determine access to a specific resource. This guide will walk you through the process of creating a policy that pulls context in two different ways: check context and injected context. ## When to Use it Use policy context when: - **Dynamic Access**: You need to make access decisions based on runtime attributes such as location, time of day, IP address, device type, or authentication method. - **Resource Attribute-Based Access**: You want to enforce permissions based on properties of the resource itself such as a course’s level, a document’s classification, or user data. - **Complex Policies**: You need to evaluate multiple attributes or conditions together to enforce advanced access rules. ## Check Context In this approach, you pass context directly in the check request. These values are made available to the policy as named parameters and must be explicitly defined in the policy function signature within your schema. ```fga version 0.3 type user type course relation editor [user] relation viewer [user] relation instructor [user] relation edit [] relation view_materials [] relation moderate_discussion [] inherit edit if all_of relation editor policy can_edit_course policy has_security_compliance inherit view_materials if any_of all_of relation viewer policy can_access_materials relation edit inherit moderate_discussion if all_of relation instructor policy can_moderate_discussion policy can_edit_course(check_data map, user_attr map) { check_data.resource_type == "course" && check_data.resource_id in user_attr.assigned_course_ids && user_attr.role == "instructor" } policy can_access_materials(user_attr map, course_attr map) { user_attr.is_enrolled == true && user_attr.org_id == course_attr.org_id } policy can_moderate_discussion(user_attr map, course_attr map) { user_attr.verified == true && course_attr.discussion_enabled == true && course_attr.course_level == "advanced" } policy has_security_compliance(security_info map) { security_info.mfa_enabled == true && date(security_info.last_password_change) > now() - duration("90d") } ``` ### (1) Apply the schema Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment. ```shell workos fga schema apply schema.txt ``` --- ### (2) Create warrants Create warrants that associate users with courses. We'll make a user an editor of a course: --- ### (3) Check access With our environment setup, we can check the user's permission to `view_materials` on a course. In this example, the check context includes `check_data`, `user_attr`, `course_attr`, and `security_info`. The policy will evaluate these attributes to determine if the user has access to view materials for the course. > A drawback with this approach is the size of the context in the check request. This method of passing context requires no state in FGA (other than warrant data), but it starts to break down with complex schemas that require large sets of context data. Consider using injected context for more complex schemas. ## Injected Context In this method, you can use context injected by the FGA service. Use injected context to fetch resource metadata in your policy so that you don't have to pass it in the check request. This is useful when your schema requires large context objects, when the context is not known at the time of the check, or when you want to change schemas without updating context in the check request. Read more about injected context and helper functions in the [policy documentation](/fga/policies/advanced-usage). ```fga version 0.3 type user type course relation editor [user] relation viewer [user] relation instructor [user] relation edit [] relation view_materials [] relation moderate_discussion [] inherit edit if all_of relation editor policy can_edit_course policy has_security_compliance inherit view_materials if any_of all_of relation viewer policy can_access_materials relation edit inherit moderate_discussion if all_of relation instructor policy can_moderate_discussion policy can_edit_course() { let user_metadata = get_metadata(check_ctx.subject_type, check_ctx.subject_id); let is_user = check_ctx.subject_type == "user"; let is_course = check_ctx.resource_type == "course"; let is_assigned = check_ctx.resource_id in user_metadata.assigned_course_ids; let is_instructor = user_metadata.role == "instructor"; is_user && is_course && is_assigned && is_instructor } policy can_access_materials() { let user_metadata = get_metadata(check_ctx.subject_type, check_ctx.subject_id); let course_metadata = get_metadata(check_ctx.resource_type, check_ctx.resource_id); let is_user = check_ctx.subject_type == "user"; let is_enrolled = user_metadata.is_enrolled == true; let same_org = user_metadata.org_id == course_metadata.org_id; is_user && is_enrolled && same_org } policy can_moderate_discussion() { let user_metadata = get_metadata(check_ctx.subject_type, check_ctx.subject_id); let course_metadata = get_metadata(check_ctx.resource_type, check_ctx.resource_id); let is_user = check_ctx.subject_type == "user"; let is_verified = user_metadata.verified == true; let discussion_enabled = course_metadata.discussion_enabled == true; let is_advanced = course_metadata.course_level == "advanced"; is_user && is_verified && discussion_enabled && is_advanced } policy has_security_compliance() { let user_metadata = get_metadata(check_ctx.subject_type, check_ctx.subject_id); let is_user = check_ctx.subject_type == "user"; let mfa_enabled = user_metadata.mfa_enabled == true; let recent_password = date(user_metadata.last_password_change) > now() - duration("90d"); is_user && mfa_enabled && recent_password } ``` ### (1) Apply the schema Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment. ```shell workos fga schema apply schema.txt ``` --- ### (2) Create warrants Create warrants that associate users with courses. We'll make a user an editor of a course: --- ### (3) Update app code to sync resource metadata In order to pull resource metadata from our policies, we need to update our app code to sync resource metadata with the FGA service. This is done by calling the [update resource](/reference/fga/resource/update) endpoint in the FGA API. --- ### (4) Check access With our environment setup, we can check the user's permission to `view_materials` on a course. ### Org Roles & Permissions Create org-scoped roles based on common user personas and map them to a static set of permissions that grant capabilities in your application. > Explore the example from this guide [in the FGA Playground](https://explore.fga.workos.com/playground?example=org_roles_permissions), where you can interact with the schema, warrants, and access checks in real-time! Build a role-based access control (RBAC) that scopes each user's role and permission assignments to a specific organization. ## When to Use it Implement org roles and permissions when: - **Role-based access control**: Your application's requirements call for role-based access control (RBAC) - **Org-specific roles**: Your customers want to grant their users privileges based on their role within a specific organization. ## Schema ```fga title="schema.txt" version 0.3 type user type organization relation role_admin [user] relation role_read_only [user] inherit role_read_only if relation role_admin relation can_read_company_info [role] relation can_write_company_info [role] relation can_read_reports [role] relation can_write_reports [role] inherit can_read_company_info if any_of relation can_write_company_info relation role_read_only inherit can_write_company_info if relation role_admin inherit can_read_reports if any_of relation can_write_reports relation role_read_only inherit can_write_reports if relation role_admin ``` ## Example ### (1) Apply the schema Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment. > Note: make sure to select the correct environment with the [CLI](https://github.com/workos/workos-cli?tab=readme-ov-file#usage) ```shell workos fga schema apply schema.txt ``` --- ### (2) Create warrants Create warrants that associate organizations, roles, and users. The example schema defines the following relationships: - users with organizations - users with custom roles (e.g. `org:acme:read-only`) Let's create a few warrants between organization `acme`, role `org:acme:read-only`, and user `user_2oDscjroNWtzxzYEnEzT9P7VYEe`: --- ### (3) Check access With our environment setup, we can check the user's permission to read company info. --- ### Managed Service Provider Model a managed service provider (MSP) that provides services to clients and manages projects, tasks, and assets. > Explore the example from this guide [in the FGA Playground](https://explore.fga.workos.com/playground?example=managed_service_provider), where you can interact with the schema, warrants, and access checks in real-time! In a managed service provider (MSP) scenario, a client organization grants access to an external provider to perform services or manage resources on its behalf, while retaining control over access by assigning roles to the provider and its personnel. ## When to Use It? This model is ideal when you need to grant limited access to external service providers without compromising internal access controls. It’s particularly useful in scenarios where external teams (like IT consultants, marketing agencies, or law firms) are brought in to manage specific projects or assets. - **IT services**: Clients delegate infrastructure or helpdesk support to an MSP. - **Marketing agencies**: Agencies manage campaigns and related assets for clients. - **Law firms**: External legal teams manage cases and documents for clients. - **Project management**: Providers handle maintenance tasks and asset management for clients. - **Warehousing**: Providers manage inventory and logistics for clients. ## Schema ```fga title="schema.txt" version 0.3 type user // A client is a customer of the provider type client relation admin [user] // A provider is a service provider managed by the client type provider relation admin [user] relation technician [user] inherit technician if relation admin // A project is a project managed by the client and assigned a provider type project relation client [client] relation provider [provider] relation editor [user] relation viewer [user] inherit editor if any_of relation admin on client [client] relation admin on provider [provider] relation technician on provider [provider] inherit viewer if any_of relation editor type task relation assignee [user] relation project [project] relation edit [] relation view [] inherit edit if any_of relation assignee relation editor on project [project] inherit view if any_of relation edit relation viewer on project [project] type asset relation manager [user] relation project [project] relation edit [] relation view [] inherit edit if any_of relation manager relation editor on project [project] inherit view if any_of relation edit relation viewer on project [project] ``` ## Example ### (1) Apply the schema Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment. > Note: make sure to select the correct environment with the [CLI](https://github.com/workos/workos-cli?tab=readme-ov-file#usage) ```shell workos fga schema apply schema.txt ``` --- ### (2) Create warrants Create warrants that associate users, clients, providers, and projects. The example schema defines the following relationships: - clients and providers with projects - tasks and assets as children of projects - users with clients or providers (using one of the defined roles: `admin` or `technician`) Let's create a few warrants between client `client-1`, provider `provider-1`, project `project-1`, and users: --- ### (3) Check access With our environment setup, we can check whether the user can view an asset. --- ### Feature Entitlements Restrict access to features in your SaaS application based on subscription tier using FGA policies and relation-based access control. > Explore the example from this guide [in the FGA Playground](https://explore.fga.workos.com/playground?example=entitlements), where you can interact with the schema, warrants, and access checks in real-time! In SaaS applications, it's common to control access to product features based on a subscription tier. This approach allows product teams to define distinct experiences for different customer segments—like offering basic tools to free users/organizations and premium features to paying ones. For example, a design tool might offer a `Free` tier with limited capabilities and a `Pro` tier that unlocks collaboration and team-based workflows. ## When to Use It? Use feature entitlements when: - Your product has multiple pricing tiers with different access levels. - You want to gate advanced features behind specific subscription plans. - Fine-grained resource access is controlled by subscription level. Use this approach when you need dynamic, policy-driven access control for features across different plans or user types. It’s especially helpful in multi-tenant SaaS apps where access logic needs to scale cleanly and stay centralized. ## Example Applications - **B2B SaaS Platforms**: Unlock additional collaboration tools for premium customers. - **Design Tools**: Offer project and team management to higher-tier subscribers. - **Analytics Services**: Gate advanced reporting or integrations behind Enterprise plans. - **Productivity Software**: Provide shared team workspaces for Pro users. ## Schema ```fga version 0.3 type user type organization relation admin [user] relation member [user] inherit member if relation admin // Tiers are defined by subscription attributes relation pro_subscriber [] inherit pro_subscriber if all_of relation admin // In this example, you must be an admin on the org to get access to pro features policy is_pro_subscriber relation free_subscriber [] inherit free_subscriber if any_of policy is_free_subscriber policy is_pro_subscriber // Pro subscribers can also access free features // Feature access based on subscription tier relation feature_projects [] inherit feature_projects if all_of relation member relation free_subscriber relation feature_teams [] inherit feature_teams if relation pro_subscriber // Teams and Projects demonstrate how you can utilize ReBAC permissions // to control access to features based on org subscription tiers type team relation owner [organization] relation view [] inherit view if relation feature_teams on owner [organization] type project relation owner [organization] relation view [] inherit view if relation feature_projects on owner [organization] // Policies check subscription attributes passed from a third party integration policy is_pro_subscriber(subscription_attrs map) { subscription_attrs.subscription_tier == "pro" } policy is_free_subscriber(subscription_attrs map) { subscription_attrs.subscription_tier == "free" } ``` > Note: Feature access is determined entirely by an organization’s subscription attributes, which are evaluated by policy. This approach enables dynamic, attribute-based access control without manually managing feature grants. --- ## Example ### (1) Apply the schema Create a file called `schema.txt` with the schema above, and apply it to your FGA environment using the CLI. ```shell workos fga schema apply schema.txt ``` --- ### (2) Add warrants Create warrants that associate users to organizations and add teams / projects. ### (3) Check access Once everything is set up, check if a user can access specific features. --- ### Custom Roles Allow B2B customers to create org-scoped custom roles and map them to a static set of permissions that grant capabilities in your application. > Explore the example from this guide [in the FGA Playground](https://explore.fga.workos.com/playground?example=custom_roles), where you can interact with the schema, warrants, and access checks in real-time! Customizable, role-based access control gives customers the freedom to define their own custom roles and map each one to a subset of the permissions offered by your application. ## When to Use it Implement custom roles when: - **Role-based access control**: Your application's requirements call for role-based access control (RBAC). - **Custom roles**: Your customers need the ability to define custom roles that are scoped to their organization and map them to a static set of permissions in your application. ## Schema ```fga title="schema.txt" version 0.3 type user type role relation member [user] type organization relation can_read_company_info [role] relation can_write_company_info [role] relation can_read_reports [role] relation can_write_reports [role] inherit can_read_company_info if any_of relation can_write_company_info relation member on can_read_company_info [role] inherit can_write_company_info if relation member on can_write_company_info [role] inherit can_read_reports if any_of relation can_write_reports relation member on can_read_reports [role] inherit can_write_reports if relation member on can_write_reports [role] ``` ## Example ### (1) Apply the schema Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment. > Note: make sure to select the correct environment with the [CLI](https://github.com/workos/workos-cli?tab=readme-ov-file#usage) ```shell workos fga schema apply schema.txt ``` --- ### (2) Create warrants Create warrants that associate organizations, roles, and users. The example schema defines the following relationships: - users with organizations - users with custom roles (e.g. `org:acme:read-only`) Let's create a few warrants between organization `acme`, role `org:acme:read-only`, and user `user_2oDscjroNWtzxzYEnEzT9P7VYEe`: --- ### (3) Check access With our environment setup, we can check the user's permission to read company info. --- ### Conditional Roles Combine relationship-based access control (ReBAC) with attribute-based access control (ABAC) to create conditional roles. > Explore the example from this guide [in the FGA Playground](https://explore.fga.workos.com/playground?example=conditional_roles), where you can interact with the schema, warrants, and access checks in real-time! Use FGA to combine **Relationship-Based Access Control (ReBAC)** and **Attribute-Based Access Control (ABAC)**. Define roles that are bound to specific resources and change based on specific conditions. This allows for more granular control over who can do what, when, and under which circumstances. ## When to Use It Use conditional roles when you cannot determine access by relationships alone. For example, a team member may be allowed to approve some expenses, but only if they are below a certain amount or belong to specific cost centers. As systems grow in complexity, pure ReBAC or ABAC models may become limiting. Conditional roles help bridge that gap with clear, composable rules. ## Example Applications - **Expense Management**: Finance managers can approve expense reports only if the amount is below a defined threshold and aligned with their assigned cost centers. - **Procurement**: Department heads may approve purchase orders only after completing mandatory compliance or budget authorization training. - **Healthcare Systems**: Authorized clinicians can access sensitive health records only if the individual is assigned to their care team and the access occurs during regulated working hours. ## Schema ```fga version 0.3 type user type team relation finance_admin [user] relation finance_manager [user] inherit finance_manager if relation finance_admin type expense relation approval_team [team] relation submitter [user] relation approve [] inherit approve if any_of all_of relation finance_manager on approval_team [team] policy can_approve_amount all_of relation finance_admin on approval_team [team] policy is_high_value_expense policy can_approve_amount(expense_attributes map, user_attributes map) { let can_approve_cost_center = expense_attributes.cost_center in user_attributes.approved_cost_centers; let can_approve_amount = expense_attributes.amount <= 1000; can_approve_cost_center && can_approve_amount } policy is_high_value_expense(expense_attributes map) { expense_attributes.amount > 1000 } ``` ## Example ### (1) Apply the schema Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment. > Note: make sure to select the correct environment with the [CLI](https://github.com/workos/workos-cli?tab=readme-ov-file#usage) ```shell workos fga schema apply schema.txt ``` --- ### (2) Create warrants Create warrants that associate users, teams, and expenses. The example schema defines the following relationships: - users with teams (using the `finance_admin` or `finance_manager` roles) - teams with expenses (using the `approval_team` relation) Let's create a few warrants between team `finance-1`, expense `expense-1`, and user `user_2oDscjroNWtzxzYEnEzT9P7VYEe`: --- ### (3) Check access With our environment setup, we can check the user's permission to approve expenses. --- ### Blocklists Blocklist users from accessing certain resources based on specific attributes or warrants > Explore the example from this guide [in the FGA Playground](https://explore.fga.workos.com/playground?example=blocklist), where you can interact with the schema, warrants, and access checks in real-time! A blocklist allows systems to deny access to specific users or sessions based on contextual data or warrants. ## When to Use It? - A user IP address is associated with suspicious behavior - A user is flagged for abuse - A user is subject to temporary access restrictions (e.g., after multiple failed login attempts) This approach combines relationship-based access control (ReBAC) with attribute-based access control (ABAC), giving you fine-grained control without complicating your core permissions model. ## Example Applications - **Content Moderation**: Block users from viewing or interacting with content based on their IP address. - **E-commerce Systems**: Block users from purchasing or viewing products based on behavior patterns. - **Banking and Finance**: Deny access based on fraud scores or geolocation mismatches. ## Schema ```fga version 0.3 type user type store relation member [user] type item relation owner [store] relation blocked [user] relation view [] inherit view if all_of relation member on owner [store] // Users are blocked either explicitly or with the ip_not_allowed policy none_of relation blocked policy ip_not_allowed policy ip_not_allowed(ip_risk_score integer) { ip_risk_score > 75 } ``` ## Example ### (1) Apply the schema Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment. > Note: make sure to select the correct environment with the [CLI](https://github.com/workos/workos-cli?tab=readme-ov-file#usage) ```shell workos fga schema apply schema.txt ``` --- ### (2) Create warrants Create warrants that associate users, stores, and items. Add a blocked user to an item. --- ### (3) Check access With our environment setup, we can check the user's permission to view items. --- ### Attribute-Based Access Control (ABAC) Learn how to use policies to implement a pure attribute-based access control (ABAC) model in Fine-Grained Authorization (FGA). > Explore the example from this guide [in the FGA Playground](https://explore.fga.workos.com/playground?example=abac), where you can interact with the schema, warrants, and access checks in real-time! Attribute-Based Access Control (ABAC) is an authorization model that grants access based on attributes of users, resources, environments, and other contextual factors. FGA allows you to implement a pure ABAC model, where permissions rely solely on attributes without requiring warrant data. By centralizing authorization policies, FGA eliminates hardcoded access logic, making your system more scalable and maintainable. > **Note**: Starting with a pure ABAC model can be an effective way to remove hardcoded authorization logic while keeping policies flexible. As your needs evolve, you can seamlessly integrate Relationship-Based Access Control (ReBAC) to support permissions based on user-resource relationships, such as team memberships, delegated roles, or hierarchical access. ## When to Use Pure ABAC? ABAC is ideal when access rules are complex and depend on multiple dynamic factors such as: - **Entitlements**: feature access based on plan level. - **Feature flags**: enabling experimental features for specific groups. - **Domain-specific data**: security constraints based on specific resource data attributes. - **Role membership**: access based on user roles or attributes that are not strictly hierarchical. - **Temporal data**: granting temporary access based on time-based or location-based policies. ## Schema ```fga version 0.3 type user type organization relation view_financial_records [] inherit view_financial_records if // Policies can be combined with inheritance rules all_of policy user_in_organization policy is_finance_manager relation view_research_data [] inherit view_research_data if all_of policy user_in_organization policy is_assigned_researcher policy is_within_working_hours type document relation edit [] inherit edit if policy edit_document policy user_in_organization(user_attributes map, organization_id string) { user_attributes.organization_id == organization_id } policy is_finance_manager(user_attributes map) { user_attributes.department == "finance" && "manager" in user_attributes.roles } policy is_assigned_researcher(user_attributes map, project_id string) { user_attributes.role == "manager" && project_id in user_attributes.assigned_projects } policy is_within_working_hours(access_time_epoch_seconds integer) { let second_since_midnight = access_time_epoch_seconds % 86400; // 9 AM (32400s) to 5 PM (61200s) second_since_midnight >= 32400 && second_since_midnight <= 61200 } policy edit_document(user_attributes map, document_attributes map) { let user_is_document_editor = "document_editor" in user_attributes.roles; let draft_status = document_attributes.status == "draft"; let user_can_access_document = document_attributes.organization_id == user_attributes.organization_id; user_is_document_editor && draft_status && user_can_access_document } ``` ## Example ### (1) Apply the schema Create a file called `schema.txt` containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment. > Note: make sure to select the correct environment with the [CLI](https://github.com/workos/workos-cli?tab=readme-ov-file#usage) ```shell workos fga schema apply schema.txt ``` --- ### (2) Check access With our environment setup, we can check the user's permissions. --- ## Feature Flags {#feature-flags} ### Slack Notifications Get notifications about feature flag changes in your Slack workspace. ## Introduction Feature flags give teams precise control over feature releases. The WorkOS app for Slack sends real-time notifications throughout your feature flags' lifecycle, from creation and enabling to deletion. This keeps all stakeholders informed about critical changes, such as when a feature flag is enabled for specific customers or organizations. --- ## Configure your Slack connection To set up Slack notifications, navigate to [_Feature Flags_](https://dashboard.workos.com/environment/flags) and click _Enable Slack notifications_. ![A screenshot showing the WorkOS Dashboard Feature Flags page](https://images.workoscdn.com/images/840a7450-12bf-4d8d-ba12-b30da70912d7.png?auto=format&fit=clip&q=50) Next, click _Connect to Slack_ to go to the Slack Installation page. ![A screenshot showing the WorkOS Dashboard Slack notifications dialog when no connection exists](https://images.workoscdn.com/images/7b873377-4847-43ae-a7ba-bf50b25d9f5e.png?auto=format&fit=clip&q=50) Finally, select the channel that you'd like to get your notifications in. By default, notifications are sent for all production environments in your WorkOS account. ![A screenshot showing the Slack installation page](https://images.workoscdn.com/images/83ed7c7f-1e27-4b52-b20e-6439cec854a9.png?auto=format&fit=clip&q=50) --- ## Slack notifications Once your Slack notifications are enabled, you'll start to receive messages in the configured channel for all feature flag events. ### Flag lifecycle events - A flag is created - A flag's details are updated (name, description, tags) - A flag is deleted ![Sample message of a flag created event](https://images.workoscdn.com/images/1bc973f6-f879-4c71-8f0a-fd3eece4f252.png?auto=format&fit=clip&q=50) ### Rule updates and targeting changes - A flag is enabled or disabled - Targeting is changed between All, Some, or None - Specific users or organizations are added or removed ![Sample message of a flag enabled for some event](https://images.workoscdn.com/images/9613033e-f313-449d-bbd3-9bcff85af2c2.png?auto=format&fit=clip&q=50) --- ## Disconnect an existing connection To disable notifications or to change your configured Slack channel, you must disconnect the existing connection. To start, navigate to [_Feature Flags_](https://dashboard.workos.com/environment/flags) and click _Connected to Slack_. ![A screenshot showing the WorkOS Dashboard Slack notifications dialog for an existing connection](https://images.workoscdn.com/images/1c2e2fad-af7a-48a4-8b93-75b93653ed2b.png?auto=format&fit=clip&q=50) Next, click _Disconnect_ and confirm to disable Slack notifications to the listed channel. ### Feature Flags Manage rollout of new features for specific users and organizations with Feature Flags. ## Overview Feature flags are a tool that allows teams to control the rollout of features in real time. They enable businesses to separate feature delivery from code deployment, creating a more agile and risk-managed approach to launching and managing product experiences. WorkOS Feature Flags provides a developer-friendly solution that integrates seamlessly with your existing authentication flow. Create and manage flags through the dashboard then access them through a user's access token. Feature flags can target organizations or individual users. This approach lets you safely roll out new functionality, enable beta programs for select customers, and manage premium feature access without deploying code changes. ## Use cases - **Targeted rollouts:** Enable features for specific organizations before a general release - **Beta programs:** Allow early access to new features for select customers - **Premium features:** Restrict advanced functionality to organizations on higher-tier plans ## Before getting started To get the most out of these guides, you’ll need: - A [WorkOS account](https://dashboard.workos.com/) - An existing organization in your WorkOS Dashboard ![WorkOS Dashboard UI showing organization creation](https://images.workoscdn.com/images/1c69fd98-01be-491d-9255-58363bc6a983.png?auto=format&fit=clip&q=50) ## API object definitions [Organization](/reference/organization) : Describes an organization whose users sign in with a SSO Connection, or whose users are synced with a Directory Sync Connection. [User](/reference/authkit/user) : Describes a user who can be targeted with feature flags. ## (1) Create a feature flag from the WorkOS dashboard - Sign in to your [WorkOS dashboard](https://dashboard.workos.com/) account and navigate to the Feature Flags page. - Click the `Create feature flag` button and enter a name, slug, and description. ![A screenshot showing the WorkOS dashboard feature flags page.](https://images.workoscdn.com/images/9be5d8f6-8956-47fc-aca6-66478bb37881.png?auto=format&fit=clip&q=80) Feature flags are created across all environments, allowing you to test your feature flag in a sandbox environment before enabling it in production. --- ## (2) Set the users and organizations that should have access To edit which set of users and organizations should have the feature flag enabled, click `Edit` on the rule for the environment you want to edit. Next, select your desired rule setting between `None`, `Some`, and `All`. Selecting `Some` will allow you select specific users and organizations. To edit a feature flag's rules in other environments, click the `Edit in X` button which will update your active dashboard environment to the selected environment, allowing you to update rules in the chosen environment. ![A screenshot showing the configuration of a feature flag organization rule.](https://images.workoscdn.com/images/bf958da9-1288-464c-b087-b54f60f03171.png?auto=format&fit=clip&q=80) ![A screenshot showing the configuration of a feature flag user rule.](https://images.workoscdn.com/images/32f8b6da-d357-4ac7-b9b3-96c9cf3ef60f.png?auto=format&fit=clip&q=80) --- ## (3) Enable the feature flag Once you're ready to enable the feature for the configured set of organizations and users, toggle the flag on to start including it in a user's access token when they authenticate for a configured organization or when the user is individually targeted. ![A screenshot showing the enabling of a feature flag.](https://images.workoscdn.com/images/f526ab53-0ec5-4261-abe5-24f05e92cdd8.png?auto=format&fit=clip&q=80) --- ## (4) Use the feature flags in your application The access token includes the `feature_flags` claim, containing the user’s entitlements. You can use this information to gate access to features in your application. Feature flags will show up in the access token the next time the user logs in or the session is refreshed. You can manually [refresh the session](reference/authkit/authentication/refresh-token) after granting the organization access in the dashboard. ## Events {#events} ### Events Respond to activity that occurs within WorkOS and third-party providers. Events represent activity that has occurred within WorkOS or within third-party identity and directory providers. Your app can [sync the data](/events/data-syncing) via either the events API or webhooks. #### Event object All event objects share a similar structure. | Attribute | Description | | ------------ | -------------------------------------------------------------------------- | | `event` | A string that distinguishes the event type. | | `id` | Unique identifier for the event. | | `data` | Event payload. Payloads match the corresponding [API objects](/reference). | | `created_at` | Timestamp of when the event occurred. | | `context` | An optional object of extra information relevant to the event. | ## API key events {{ "url": "api-key" }} Events emitted when [API keys](/authkit/api-keys) are created or revoked. Triggered when an API key is created. Triggered when an API key is revoked. ## Authentication events {{ "url": "authentication" }} Each step in the [authentication](/reference/authkit/authentication) flow emits an authentication event. Authentication success events are emitted even when additional steps, such as MFA, are required to complete the process. Triggered when a user fails to verify their email. Triggered when a user successfully verifies their email. Triggered when a user fails to authenticate via Magic Auth. Triggered when a user successfully authenticates via Magic Auth. Triggered when a user fails to authenticate with a multi-factor authentication code. Triggered when a user successfully authenticates with a multi-factor authentication code. Triggered when a user fails to authenticate via OAuth. Triggered when a user successfully authenticates via OAuth. Triggered when a user fails to authenticate with password credentials. Triggered when a user successfully authenticates with password credentials. Triggered when a user fails to authenticate with a passkey. Triggered when a user successfully authenticates with a passkey. Triggered when a user fails to authenticate with Single Sign-On. Triggered when a user successfully authenticates with Single Sign-On. Triggered when an authentication succeeds but is flagged by Radar. For example, the authentication may have succeeded at passing a Radar challenge. ## Connection events {{ "url": "connection" }} Events emitted when Single Sign-On connections are activated, deactivated, or deleted. Also emitted when a SAML certificate is renewed for the connection. Payload `data` corresponds to the [Connection](/reference/sso/connection) object. Triggered when a connection is activated. Payload `data` corresponds to the [Connection](/reference/sso/connection) object. Triggered when a connection is deactivated. Payload `data` corresponds to the [Connection](/reference/sso/connection) object. Triggered when a connection is deleted. The `state` attribute indicates connection state before deletion. The `certificate_type` can be one of `ResponseSigning`, `RequestSigning`, or `ResponseEncryption`. Triggered when a SAML certificate is renewed either in the Dashboard or Admin Portal. The `certificate_type` can be one of `ResponseSigning`, `RequestSigning`, or `ResponseEncryption`. Triggered when a SAML certificate is expiring (multiple events are sent out as it approaches expiry), or expired (once every 7 days after expiry). ## Directory Sync events {{ "url": "directory-sync" }} Events emitted when directory-related resources are changed. To learn what exactly each of these events represents, see the [in-depth Directory Sync events guide](/directory-sync/understanding-events). Payload `data` is based on the [Directory](/reference/directory-sync/directory) object, but the `domain` property is replaced with a `domains` array of [Organization Domain](reference/organization-domain). Triggered when a [directory is activated](/directory-sync/understanding-events/directory-events/dsync-activated). Payload `data` is based on the [Directory](/reference/directory-sync/directory) object, except the `domain` property is omitted. Triggered when a [directory is deleted](/directory-sync/understanding-events/directory-events/dsync-deleted). The `state` attribute indicates directory state before deletion. Payload `data` corresponds to the [Directory Group](/reference/directory-sync/directory-group) object. Triggered when a [directory group is created](/directory-sync/understanding-events/directory-group-events/dsync-group-created). Payload `data` corresponds to the [Directory Group](/reference/directory-sync/directory-group) object. Triggered when a [directory group is deleted](/directory-sync/understanding-events/directory-group-events/dsync-group-deleted). Payload `data` corresponds to the [Directory Group](/reference/directory-sync/directory-group) object. Triggered when a [directory group is updated](/directory-sync/understanding-events/directory-group-events/dsync-group-updated). Payload `data` contains a `user` which corresponds to the [Directory User](/reference/directory-sync/directory-user) object and a `group` which corresponds to the [Directory Group](/reference/directory-sync/directory-group) object. The `groups` field is omitted from the `user` object to avoid performance issues in large directories. Triggered when a [directory group user is added](/directory-sync/understanding-events/directory-group-events/dsync-group-user-added). Payload `data` contains a `user` which corresponds to the [Directory User](/reference/directory-sync/directory-user) object and a `group` which corresponds to the [Directory Group](/reference/directory-sync/directory-group) object. The `groups` field is omitted from the `user` object to avoid performance issues in large directories. Triggered when a [directory group user is removed](/directory-sync/understanding-events/directory-group-events/dsync-group-user-removed). Payload `data` corresponds to the [Directory User](/reference/directory-sync/directory-user) object. The `groups` field is omitted to avoid performance issues in large directories. Triggered when a [directory user is created](/directory-sync/understanding-events/directory-user-events/dsync-user-created). Payload `data` corresponds to the [Directory User](/reference/directory-sync/directory-user) object. The `groups` field is omitted to avoid performance issues in large directories. Triggered when a [directory user is deleted](/directory-sync/understanding-events/directory-user-events/dsync-user-deleted). The `state` attribute indicates directory user state at time of deletion. Payload `data` corresponds to the [Directory User](/reference/directory-sync/directory-user) object. The `groups` field is omitted to avoid performance issues in large directories. Triggered when a [directory user is updated](/directory-sync/understanding-events/directory-user-events/dsync-user-updated). ## Email verification events {{ "url": "email-verification" }} Events emitted when a user is required to verify their email. Payload `data` corresponds to the [Email verification](/authkit/email-verification) object with the `code` omitted. Triggered when a user is required to verify their email and a code is created. ## Feature flag events {{ "url": "feature-flags" }} Events emitted when WorkOS feature flags are created, updated, deleted, or their rules are updated. Payload `data` corresponds to the [Feature Flag](/reference/feature-flags) object. Triggered when a feature flag is created. Payload `data` corresponds to the [Feature Flag](/reference/feature-flags) object. Triggered when a feature flag is updated. Payload `data` corresponds to the [Feature Flag](/reference/feature-flags) object. Triggered when a feature flag is deleted. Payload `data` corresponds to the [Feature Flag](/reference/feature-flags) object. Triggered when a feature flag's rules are modified. ## Invitation events {{ "url": "invitation" }} Events emitted when an [AuthKit user](/reference/authkit/user) is invited to join an organization. Payload `data` corresponds to the [Invitation](/reference/authkit/invitation) object with the `token` and `accept_invitation_url` omitted. Triggered when a user accepts an invitation. Payload `data` corresponds to the [Invitation](/reference/authkit/invitation) object with the `token` and `accept_invitation_url` omitted. Triggered when a user is invited to sign up or to join an organization. Payload `data` corresponds to the [Invitation](/reference/authkit/invitation) object with the `token` and `accept_invitation_url` omitted. Triggered when an invitation is resent. Payload `data` corresponds to the [Invitation](/reference/authkit/invitation) object with the `token` and `accept_invitation_url` omitted. Triggered when an invitation is revoked. ## Magic Auth events {{ "url": "magic-auth" }} Events emitted when a user requests a Magic Auth code. Payload `data` corresponds to the [Magic Auth](/reference/authkit/magic-auth) object with the `code` omitted. Triggered when a user initiates Magic Auth and an authentication code is created. ## Organization events {{ "url": "organization" }} Events emitted when WorkOS organizations are created, updated, or deleted. Payload `data` corresponds to the [Organization](/reference/organization) object. Triggered when an organization is created. Payload `data` corresponds to the [Organization](/reference/organization) object. Triggered when an organization is updated. Payload `data` corresponds to the [Organization](/reference/organization) object. Triggered when an organization is deleted ## Organization domain events {{ "url": "organization-domain" }} Events emitted when organization domains are created, updated, deleted, or their verification status changes. Payload `data` corresponds to the [Organization Domain](/reference/domain-verification) object. Triggered when an organization domain is created. Payload `data` corresponds to the [Organization Domain](/reference/domain-verification) object. Triggered when an organization domain is updated. Payload `data` corresponds to the [Organization Domain](/reference/domain-verification) object. Triggered when an organization domain is deleted. Payload `data` corresponds to the [Organization Domain](/reference/domain-verification) object. Triggered when an organization domain is verified. Payload `data` contains a `reason` and an `organization_domain` which corresponds to the [Organization Domain](/reference/domain-verification) object. Triggered when an organization domain verification fails. ## Organization membership events {{ "url": "organization-membership" }} Events emitted when an [AuthKit user](/reference/authkit/user) joins or leaves an organization. Payload `data` corresponds to the [Organization Membership](/reference/authkit/organization-membership) object. Triggered when an organization membership is created. Payload `data` corresponds to the [Organization Membership](/reference/authkit/organization-membership) object. Triggered when an organization membership is deleted. Payload `data` corresponds to the [Organization Membership](/reference/authkit/organization-membership) object. Triggered when an organization membership is updated. ## Password reset events {{ "url": "password-reset" }} Events emitted when a user requests to reset their password. Payload `data` corresponds to the [Organization Membership](/reference/authkit/password-reset) object with the `token` omitted. Triggered when a user requests to reset their password. Payload `data` corresponds to the [Password Reset](/reference/authkit/password-reset) object with the `token` omitted. Triggered when a user successfully resets their password. ## Role events {{ "url": "role" }} Events emitted when roles are created or deleted in the WorkOS dashboard. Triggered when a role is created. Triggered when a role is deleted. Triggered when a role's permissions are updated. ## Session events {{ "url": "session" }} Events emitted when AuthKit sessions are created. Triggered when a session is created. Sessions started using [impersonation](/authkit/impersonation) will include an additional `impersonator` field with data about the impersonator. Triggered when an issued session is revoked for a user. ## User events {{ "url": "user" }} Events emitted when [AuthKit users](/reference/authkit/user) are created, updated, or deleted. Payload `data` corresponds to the [User](/reference/authkit/user) object. Triggered when a user is created. Payload `data` corresponds to the [User](/reference/authkit/user) object. Triggered when a user is deleted. Payload `data` corresponds to the [User](/reference/authkit/user) object. Triggered when a user is updated. ### Stream events to Datadog Stream and analyze WorkOS activity in Datadog. ![WorkOS Datadog dashboard showing various metrics and graphs describing authentication events and user activity](https://images.workoscdn.com/images/9ec8c9ce-e087-4967-8b66-9311aaf13902.png?auto=format&fit=clip&q=50) WorkOS supports real-time streaming of events to Datadog. By analyzing WorkOS activity directly in Datadog, you are able to: - View trends in user sign-ins, user growth, new SSO connections and more. - Debug customer issues related to sign-in, email verification, password resets and more. - Generate reports of user activity per customer organization. - Set alerts for unexpected activity, such as sudden spike in failed password attempts. See all of the WorkOS events that stream to Datadog in the [event types](/events) documentation. --- ## Introduction Setting up real-time streaming of WorkOS events to Datadog only takes a few minutes and can be done in three simple steps. --- ## (1) Create a Datadog API key First, create a new Datadog API key to give WorkOS permission to send event activity as logs to your Datadog account. While you can use an existing API key, WorkOS recommends creating a new key that will only be used for WorkOS event streaming. 1. Sign in to your [Datadog account](https://app.datadoghq.com/). 2. Navigate to the [Organization Settings → API Keys](https://app.datadoghq.com/organization-settings/api-keys) page. 3. Choose the **New Key** button 4. Enter a name for your new API key. 5. Choose the **Create Key** button. ![A screenshot showing how to create an API key in the Datadog dashboard.](https://images.workoscdn.com/images/d69f49e9-6e8b-444a-8736-0cc2db98cf72.png?auto=format&fit=clip&q=50) --- ## (2) Configure event streaming in WorkOS The next step is to configure event streaming in the [WorkOS Dashboard](https://dashboard.workos.com/) using the Datadog API key that was created in the previous step. 1. Sign in to the [WorkOS Dashboard](https://dashboard.workos.com/). 2. Navigate to the **Events** page. 3. Choose the **Stream to Datadog** button. ![A screenshot showing how setup streaming events to Datadog in the WorkOS Dashboard.](https://images.workoscdn.com/images/0259f8e3-6fb2-4b3a-819a-f98d128c1c79.png?auto=format&fit=clip&q=50) 4. Enter the Datadog API key. 5. Select your Datadog region. 6. Choose the **Save Log Stream Details** button. ![A screenshot showing how to enter a Datadog API key in WorkOS Dashboard.](https://images.workoscdn.com/images/e1d4d7bb-e076-492f-971f-e116ffe2de0e.png?auto=format&fit=clip&q=50) With event streaming configured, when new events occur, WorkOS will send the events to Datadog with the source `workos`. --- ## (3) Add the WorkOS Datadog dashboard The final step is to add the WorkOS Datadog dashboard to your Datadog account. 1. Sign in to your [Datadog account](https://app.datadoghq.com/). 2. Navigate to the [Dashboard List](https://app.datadoghq.com/dashboard/lists) page. 3. Choose the **+ New Dashboard** button. ![A screenshot showing how to create a new dashboard in Datadog.](https://images.workoscdn.com/images/feee6689-2477-4711-bf0e-10c917cc02f7.png?auto=format&fit=clip&q=50) 4. Enter a dashboard name. 5. Choose the **New Dashboard** button. 6. In the new dashboard, choose the **Configure** button. 7. Download the [WorkOS Datadog dashboard JSON file](/docs/assets/workos-datadog-dashboard.json) 8. Scroll down in the context menu and choose **Import dashboard JSON**. 9. Upload the WorkOS Datadog dashboard JSON file downloaded in the previous step. ![A screenshot showing how to import a JSON definition of a Dashboard into Datadog.](https://images.workoscdn.com/images/3dc7f949-67ff-470e-84f1-8a5a8880114d.png?auto=format&fit=clip&q=50) ### Sync data with webhooks A step-by-step guide on how to start syncing data using webhooks. ## What you’ll build In this guide, we will walk you through what you will need to set up webhooks: - Create your endpoint to receive webhook events - Register your endpoint with WorkOS - Process the events received from WorkOS - Test your endpoint --- ## (1) Set up your webhook endpoint Create a public endpoint that WorkOS can send events to. This endpoint should use HTTPS and should accept POST requests with the `workos-signature` header. > WorkOS sends the header as `WorkOS-Signature`, but many web servers normalize HTTP request headers to their lowercase variants. --- ## (2) Register your endpoint Set and save the webhook URL in the [WorkOS Dashboard](https://dashboard.workos.com/), so WorkOS knows where to deliver the events. Your webhook endpoints should only be configured to receive the ones required by your integration. Receiving all event types can put undue strain on your servers and is not recommended. ![WorkOS Dashboard Webhooks UI](https://images.workoscdn.com/images/a6bebfe6-d5db-475c-bf34-a5bdf35433e0.png?auto=format&fit=clip&q=90) --- ## (3) Process the events In order to avoid unnecessary retry requests hitting your webhook handler, we recommend using two concurrent processes for handling events: one for receiving the event, and the other for processing it. ### Respond with HTTP 200 OK On receiving an event, you should respond with an `HTTP 200 OK` to signal to WorkOS that the event was successfully delivered. Otherwise, WorkOS will consider the event delivery a failure and retry up to 6 times, with exponential backoff over 3 days. You do not need to signal to WorkOS whether or not the event was processed successfully. ### (A) Validate the requests using the SDK Before processing the request payload, verify the request was sent by WorkOS and not an unknown party. WorkOS includes a unique signature in each webhook request that it sends, allowing you to verify the authenticity of the request. In order to verify this signature, you must obtain the secret that is generated for you when you set up your webhook endpoint in the WorkOS dashboard. Ensure that this secret is stored securely on your webhook endpoint server as an environment variable. The SDKs provide a method to validate the timestamp and signature of a webhook. Examples using these methods are included below. The parameters are the payload (raw request body), the request header, and the webhook secret. There is an optional parameter, tolerance, that sets the time validation for the webhook in seconds. The SDK methods have default values for tolerance, usually 3–5 minutes. ### (B) Validate the requests manually If implementing webhook validation yourself, you’ll need to use the following steps: First, extract the timestamp and signature from the header. There are two values to parse from the `WorkOS-Signature` header, delimited by a `,` character. | Key | Value | | ------------------ | ----------------------------------------------------------------------------------------------- | | `issued_timestamp` | The number of milliseconds since the epoch time at which the event was issued, prefixed by `t=` | | `signature_hash` | The HMAC SHA256 hashed signature for the request, prefixed by `v1=` | To avoid replay attacks, we suggest validating that the `issued_timestamp` does not differ too much from the current time. Next, construct the expected signature. The expected signature is computed from the concatenation of: 1. `issued_timestamp` 2. The `.` character 3. The request’s body as a utf-8 decoded string Hash the string using HMAC SHA256, using the webhook secret as the key. The expected signature will be the hex digest of the hash. Finally, compare signatures to make sure the webhook request is valid. Once you’ve determined the event request is validly signed, it’s safe to use the event payload in your application’s business logic. ### Create an IP allowlist WorkOS sends webhooks from a fixed set of IP addresses. It’s recommended to restrict access to your webhook endpoint to only these IP addresses: ```plain title="WorkOS IP addresses" 3.217.146.166 23.21.184.92 34.204.154.149 44.213.245.178 44.215.236.82 50.16.203.9 52.1.251.34 52.21.49.187 174.129.36.47 ``` --- ## (4) Test your endpoint From the dashboard, you can send test webhook events after configuring an endpoint. Go to the webhook endpoint detail page and click the **Send test event** button. The types of events that you have configured for your endpoint are available for you to send sample payloads. ![A screenshot showing how to send a test webhook in the WorkOS dashboard.](https://images.workoscdn.com/images/bda8fdc7-becb-494e-a9b6-f8295e5998a4.png?auto=format&fit=clip&q=90) If you would like to test against your local development environment, we recommend using a tool like [ngrok](https://ngrok.com) to create a secure tunnel to your local machine, and sending test webhooks to the public endpoint generated with ngrok. See our [blog post](https://workos.com/blog/test-workos-webhooks-locally-ngrok) to get more details on how you may want to test webhooks locally with ngrok. --- ## Best practices ### Respond to events immediately To avoid webhook requests potentially stressing your system, WorkOS strongly recommends that you respond to a webhook request with a 200 OK response as quickly as possible once received. If you process the event before responding, your system may not be able to handle a spike of requests. This may cause requests to timeout and result in missing important updates. A common pattern is to store the request payload on a message queue, respond with a 200 OK response, and use a background worker to process the messages in the queue. ### Recover from failed events If your endpoint fails to respond to a webhook request with a `2xx` response, WorkOS will automatically retry the event with exponential back-off for up to 3 days in production environments. If for some reason your endpoint is still unable to respond successfully to events during that period, the event will be considered failed, and we will no longer retry sending it. You can reconcile your data using our [Directory Sync endpoints](/reference/directory-sync) to update your data. > In staging environments, WorkOS only retries failed webhooks for several minutes before giving up. You can, however, manually retry webhooks using the WorkOS Dashboard for these environments. ### Handle out-of-sequence events WorkOS does not guarantee that events are delivered in the same sequence that they are generated. For example, when syncing a directory you may receive: - `dsync.group.created` - `dsync.user.created` - `dsync.group.user_added` Your endpoint should handle cases when these events are delivered out of order. Each event includes the full payload of the objects involved, so you can perform an upsert using the payload data. It is also possible that event data can be stale due to a retry of an older event being delivered after a newer event for the same object. Therefore, we recommend checking the timestamp of the incoming webhook data against the timestamp of the data in your system to ensure you do not overwrite your data with stale data. Each object in the payload includes a `created_at` field and an `updated_at` field. ### Ignore duplicate events It is possible to receive the same event more than once. WorkOS recommends that you handle webhook events using idempotent operations. One way of doing this is logging the ID of webhook events that you have processed and ignoring subsequent requests with the same ID. ### Obfuscate your endpoint URL A small security measure you can incorporate is to make your webhook endpoint difficult to guess. Including a token comprised of series of random numbers and letters to your endpoint URL can prevent malicious actors from easily guessing your endpoint. For example: `https://api.example.com/webhooks/n0dbga5x…` is much more difficult to guess than `https://api.example.com/webhooks` ### Data syncing Keep your app in sync with WorkOS. ## Introduction Syncing your app data with WorkOS is done using events. Events represent activity that has occurred within WorkOS or within third-party identity and directory providers that interact with WorkOS. When important activity occurs, we record an event. For example, a new SSO connection being activated is an event. A user being created, assigned membership to an organization, or successfully signing in are all events as well. Events are activity that your application might be interested in for the purposes of syncing data or extending your application's business logic. Your app can consume events from WorkOS via either the events API or webhooks. ```json language="json" title="A sample event" { "object": "event", "id": "event_07FKJ843CVE8F7BXQSPFH0M53V", "event": "dsync.user.updated", "data": { "id": "directory_user_01E1X1B89NH8Z3SDFJR4H7RGX7", "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "idp_id": "8931", "first_name": "Lela", "last_name": "Block", "email": "lela.block@example.com", "state": "active", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "custom_attributes": { "department": "Engineering", "job_title": "Software Engineer" }, "role": { "slug": "member" }, "raw_attributes": {} }, "created_at": "2023-04-28 20:05:31.093" } ``` --- ## Sync using the events API With the events API, your application retrieves events from WorkOS. The events API offers a more robust data synchronization solution compared to webhooks, ensuring seamless synchronization of your system state with WorkOS. To sync data using the events API, continue to the [events API guide](/events/data-syncing/events-api). --- ## Sync using webhooks With webhooks, WorkOS automatically notifies your app when an event occurs by invoking an endpoint hosted within your application. To sync data using webhooks, continue to the [webhooks guide](/events/data-syncing/webhooks). --- ## API vs. webhooks We recommend using the Events API instead of webhooks to keep your data in sync—especially for [user](/events/user) and [directory](/events/directory-sync) events. With the Events API, you control how often and how much data you ingest. Webhooks, on the other hand, require your endpoint to handle unpredictable spikes in event volume, which can make them harder to manage at scale. That said, webhooks may still be the better fit depending on your use case. Here’s how the two compare: | Aspect | Events API | Webhooks | | -------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | Timing | Controlled by your app. Your server can process events at its own pace. | Real-time. Webhooks trigger as soon as an event occurs. | | Order | A consistent order is guaranteed. | No guarantee of order on receipt. Events contain timestamps to determine order. | | Reconciliation | Replayable. Can go back to a specific point in time and reprocess events. | Failed requests are retried with exponential back-off for up to 3 days. | | Security | Authentication, confidentiality, and integrity protection by default. | You must expose a public endpoint and validate webhook signatures. | ### Sync data using the events API A step-by-step guide on how to start syncing data using the API. ## What you’ll build In this guide, we will walk you through what you will need to integrate with the [events API](/reference/events): - Create a _cursor_ for use with the events API - Update your cursor - Choose a cursor if you lose yours - Handle event replay in your app ## Before getting started To get the most out of this guide, you’ll need: - A [WorkOS account](https://dashboard.workos.com/) - An [SSO](/sso/1-add-sso-to-your-app) or [directory](/directory-sync/quick-start/1-create-a-new-directory-connection) connection configured in order to generate events --- ## (1) Integrate the events API SDK WorkOS offers native SDKs in several popular programming languages. Choose a language below to see instructions in your app’s language. ### Set secrets To make calls to WorkOS, provide the API key and, in some cases, the client ID. Store these values as managed secrets, such as `WORKOS_API_KEY` and `WORKOS_CLIENT_ID`, and pass them to the SDKs either as environment variables or directly in your app's configuration based on your preferences. ```plain title="Environment variables" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' ``` > The code examples use your staging API keys when [signed in](https://dashboard.workos.com) --- ## (2) Start consuming events Your app can start consuming events once it integrates the WorkOS SDK. The first thing to do is to pick a starting place in the data set. ### Keep a cursor A _cursor_ is a bookmark to track your app’s position in the events list. The very first call to the events API won’t have a cursor. Subsequent requests to WorkOS should include the updated cursor using the `after` parameter. You will need to update and store your cursor after processing an event. ### Avoid overwriting newer data To avoid repeating an update, store the `updated_at` timestamp provided by WorkOS for each object. Extract this tag from the data object in the event. If the `updated_at` timestamp in the event is newer, update the local state with the latest event data. Otherwise, you can skip processing that event. --- ## (3) Select event types Determine the [event types](/events) you want to consume. Choose the relevant event types that align with your app’s functionality and integration with WorkOS. Retrieve events from the API using cursor pagination. To fetch the next set of events, provide the ID of the latest processed event in the `after` parameter. --- ## (4) Handle event replay In some cases, it may be necessary to go back in time and “replay” the events. When designing your app logic to handle events replay it is important to design your event handling logic in a way that can safely accommodate it without undesired effects. To achieve this, focus on separating your app’s data handlers from transactional business logic like sending emails, communicating to 3rd party APIs, etc. By implementing separate data handling, you can replay events without side effects. WorkOS recommends processing events synchronously, handling them in the order they occurred. > The events API returns events up to 90 days old. You can query for up to 30 days of events per request. ### If your app stops processing events When resuming event processing, you have two options to pick up where you left off: - **Using the latest known cursor:** Retrieve the most recent cursor that was successfully processed and use it as the starting point for event resumption. - **Using a timestamp:** Alternatively, you can make an API call with the `range_start` parameter and then use the cursor. Utilize the `updated_at` timestamp to prevent overwrites. --- ## Scaling recommendations ### Single consumer WorkOS recommends that your app starts with a single worker. Process events in a separate thread or process from your app’s main execution thread. Deploying a single worker responsible for handling events simplifies and streamlines event consumption. This approach ensures serial event processing. After completing the processing of events on the current page, request the next page of events to maintain progress. ### Parallel processing For onboarding large organizations, divide events into independent queues for parallel processing when calling the events API from a single worker. Concurrently processing events from different organizations is safe, but for consistency and integrity, it is recommended to sequentially process events within a single organization. --- ## Migrating from webhooks You can migrate to the events API if you already use webhooks. To migrate, start querying the events API using the `range_start` parameter that corresponds to the time you’d want to start syncing from. The event IDs passed in webhook bodies are the same as those returned by the events API. ### Data reconciliation Keep your app in sync with WorkOS. ## Introduction While the events API makes it easier to keep your app in sync with WorkOS, there may still be cases where your app gets out of sync. For example, your app may have a bug in its event processing logic or in rarer cases, may experience some data loss. Data reconciliation refers to the process of comparing and aligning the state of objects between WorkOS and your app to ensure consistency. Depending on the scope of the issue, you can reconcile your app state by either replaying events from the [events API](/reference/events) or by using the WorkOS [state API](/reference). ## Definitions **Data reconciliation** : Refers to the process of comparing and aligning data from different sources or systems to ensure consistency and accuracy. The goal of data reconciliation is to ensure that all relevant data sources are synchronized and reflect the same information. **Event replay** : Is the act of reprocessing recorded events in an app. It is used to recreate past event sequences for debugging, testing, auditing, or ensuring data consistency. **Side effects** : These are secondary consequences that arise from data modifications in an app. They can alter related data, trigger additional processes, update external systems, or affect the app’s overall state. e.g., Sending an email on a user’s profile change. **Periodic reconciliation** : Is the regular process of comparing and synchronizing data between systems to ensure accuracy and consistency. It involves scheduled checks to identify and resolve discrepancies in data integrity. ## Reconciling via the events API In general, reconciling state changes between WorkOS and your app using the events API is simplest. Pick your cursor, which is usually the last known cursor you have processed, and paginate through events using the `after` parameter. For special cases such as webhook migration or event replay, you can specify a starting time for event consumption using the `range_start` parameter. ### Handling side effects in the case of event replay Side effects, such as sending emails, updating 3rd party APIs, or performing other actions specific to your app, present challenges during event replay. Separating data handling from business logic allows you to exercise control over what actions you want your app to make. This allows your app to replay events to sync data but bypass transactional logic e.g., not sending out the same email twice. ## Reconciling via the WorkOS state API Your app may perform data reconciliation by syncing state via the WorkOS [state APIs](/reference) e.g., in disaster recovery scenarios. Data reconciliation using state APIs requires performing diffs to identify deletions to ensure the correct state is maintained. This introduces additional complexity, making it essential to carefully design and test the reconciliation process. The general approach for reconciling data via the state API is as follows: 1. Pull state from WorkOS API for the objects your app is interested in. 2. Update based on `updated_at`. If the timestamp is out of date, update the object. 3. Identify deactivated objects or deletions and sync that state. If you need to force all objects to update state, perform a complete resynchronization of the affected data instead of relying solely on the `updated_at` timestamp. Update all objects regardless of the individual `updated_at` timestamp. ### Considerations for periodic reconciliation In some cases, you may want to run periodic reconciliation jobs to proactively check and reconcile the state between WorkOS and your app. When implementing such jobs, it is important to account for potential race conditions for concurrent updates. Additionally, consider the specific characteristics of your app to determine the frequency and scope of periodic reconciliation. ## Domain Verification {#domain-verification} ### Domain Verification Self-serve domain verification --- # Introduction Domain Verification allows your customers to claim ownership of a domain. Once they have claimed ownership, features that require a higher level of trust and security can be activated. WorkOS Domain Verification provides a self-serve flow through the Admin Portal in which IT admins can prove ownership through the creation of DNS TXT records. ## Before getting started You’ll need a [WorkOS account](https://dashboard.workos.com/). ### API object definitions [Organization](/reference/organization) : Describes an organization whose users sign in with a SSO Connection, or whose users are synced with a Directory Sync Connection. [Organization Domain](/reference/organization-domain) : Describes a domain associated to an organization, verified or unverified. [Portal Link](/reference/admin-portal/portal-link) : A temporary link to initiate an Admin Portal session. Valid for 5 minutes. All domains belong to an [Organization](/reference/organization). In order to create and verify a domain through the Admin Portal, an Organization must first be [created](/reference/organization/create). ## (A) Setup link from the WorkOS dashboard - Sign in to your [WorksOS dashboard](https://dashboard.workos.com/) account and create or locate an Organization. - Click the “Invite Admin” button, select **Domain Verification** then click “Next." Enter the email of the IT admin for the organization to automatically send them a setup link, or click "Copy setup link". If you chose to copy the setup link you can share it over email, Slack or direct message. We also recommend including details on what the link does and how long the link is active. ![A screenshot showing the workOS dashboard admin invite.](https://images.workoscdn.com/images/c9196bbf-3860-4a9a-be8c-83b503ae4e3d.png?auto=format&fit=clip&q=80) ## (B) Integrate with your app Admin Portal links can also be programmatically generated for the domain verification flow. This can be used to provide a link to the Admin Portal flow directly in your application. You’ll have to generate the link with the `domain_verification` intent: Please refer to the [Admin Portal Integration Guide](/admin-portal/b-integrate-with-your-app) for additional integration details. --- ## Admin Portal domain verification After receiving the invitation and clicking on the setup link, the organization's admin is prompted to enter the domain they wish to verify. ![A screenshot show the Admin portal domain entry form.](https://images.workoscdn.com/images/e7e719d6-579b-4567-8c80-772bc2f77563.png?auto=format&fit=clip&q=80) If the domain is valid, we identify the DNS service provider and offer custom setup instructions. The admin will find instruction to add a DNS TXT record with a token generated by our system. ![A screenshot showing the Admin Portal domain DNS instructions.](https://images.workoscdn.com/images/9ab7e2a4-8b11-4a03-8203-d95d1c1abb07.png?auto=format&fit=clip&q=80) When we detect and verify the DNS record, we will mark the domain as `verified` and dispatch a [domain verification event](/events) to inform your application. ### API Programmatic domain verification Instead of leveraging the Admin Portal, the Domain Verification API can be used to verify domains programmatically. Integrating with the API goes as follows: 1. Create an organization domain for an organization 2. Share the token and setup instructions with the organization owner (IT admin) 3. Wait for the verification to complete ## Create a new organization domain All domains belong to an [organization](/reference/organization). In order to create and verify a domain, an organization must first be [created](/reference/organization/create). The `verification_token` returned can then be set as the value of a TXT record that WorkOS will periodically check until the record is found. The TXT record for the above response example would be: - Name: `domain-to-verify.com` - Value: `verification_token=3CVZxo4HgvSiYRKlV4RdOWwWl` ## Get a domain Fetch an existing domain and it’s current verification status. This endpoint can be polled once verification has been initiated to determine if verification has been successful. Possible `state` values: - `pending`: domain verification has been initiated and not yet completed - `verified`: domain has been verified - `failed`: domain was not able to be verified Possible `verification_strategy` values: - `dns`: domain is verified with the DNS flow - `developer`: domain is verified by a person or a system, without running the DNS flow ## Initiate verification for existing domain If a domain has not successfully verified within thirty days and moves to the `failed` state, verification can be restarted manually. ## Directory Sync {#directory-sync} ### Understanding the Events Lifecycle Understand the lifecycle of the events that occur in Directory Sync. ## Introduction Directory Sync events represent actions performed within directory providers. For example, an action could mean an IT admin assigning a user to your app or modifying a user group assigned to your app. These actions form the basis of user lifecycle management (ULM). WorkOS provides information about these actions through a set of structured events. This reference guide will cover the events Directory Sync produces and what they mean. To learn about how to handle these events on your side, see the [data syncing guide](/events/data-syncing). --- ## Directory events ### `dsync.activated` This event occurs when you or your customer have successfully created a connection between WorkOS and your customer’s directory provider. - | Lifecycle - | Payload `dsync.activated` is triggered if you manually create the directory connection in the [Developer Dashboard](https://dashboard.workos.com/), or your customer sets the connection up using the [Admin Portal](/admin-portal). The directory ID identifies a connection with the directory of a particular customer. Your app should save it and associate the directory ID with the corresponding organization ID. ### `dsync.deleted` This event occurs when a Directory Sync connection is deleted in WorkOS, thus tearing down the link between your customer’s directory provider and your app. - | Lifecycle - | Payload A connection can be deleted through the [Admin Portal](/admin-portal), [Developer Dashboard](https://dashboard.workos.com), or [WorkOS API](/reference/directory-sync/directory/delete). At this point your app should remove the association between the corresponding organization and its directory, as it no longer exists. Directories, users, and groups are typically deleted if your app offboards a customer altogether. When receiving a `dsync.deleted` event, you can ignore the connection’s `state` attribute, since it indicates the state before the deletion occurs. When a directory is deleted in WorkOS, a sole `dsync.deleted` event is sent. When a `dsync.deleted` event is received, it indicates that the users and groups in that directory have been deleted in WorkOS. You can process the `dsync.deleted` event accordingly in your application, removing the organization’s groups and its users from your application or marking them as deleted. `dsync.user.deleted` and `dsync.group.deleted` events will not be sent for the deleted directory. --- ## Directory user events ### `dsync.user.created` This event occurs when an IT admin creates a user using their directory provider. It is standard to create and provision the user in your app when you receive this event. - | Lifecycle - | Payload You can add this user to your users table in your app and associate them with the directory ID and organization ID. You can begin to engage with the user at this point, e.g., send the user a “Getting Started” email. During the initial sync of any directory, you will receive a `dsync.user.created` event for each existing user in the directory. ### `dsync.user.updated` This event occurs when users’ attributes change. These attributes may be [standard attributes](/directory-sync/attributes/standard-attributes), [auto-mapped attributes](/directory-sync/attributes/custom-attributes/auto-mapped-attributes), or [custom-mapped attributes](/directory-sync/attributes/custom-attributes/custom-mapped-attributes). - | Lifecycle - | Payload The payload for `dsync.user.updated` event shows changes between directory group snapshots in the `previous_attributes` property. The changes in the object are shallow differences for root properties, `raw_attributes`, and `custom_attributes`. If the current snapshot has a new attribute that did not exist previously, then the value for the attribute will be indicated as `null`. ### `dsync.user.deleted` This event occurs when a user is hard-deleted from a directory. Typically, you would remove the user from your app in this case. - | Lifecycle - | Payload When users are removed from a directory, most providers will use a form of soft user deletion. In these cases, rather than receiving a `dsync.user.deleted` event, you will receive a `dsync.user.updated` event with the user’s `state` marked as `inactive`. > After Oct. 19, 2023, all new environments will delete Directory Users that get moved to the "inactive" state. If you would like to retain these users, please reach out to support. You can find [more details here](/directory-sync/handle-inactive-users). --- ## Directory group events ### `dsync.group.created` This event occurs when creating a directory group in the directory provider. WorkOS also sends this event when a directory connection is established. - | Lifecycle - | Payload When WorkOS ingests this event, it first processes the users in the group. So, in most cases, you would receive `dsync.user.created`, then `dsync.group.created`, and finally, `dsync.group.user_added`. For more information on best practices for out-of-sequence events, see the [data syncing guide](/events/data-syncing). ### `dsync.group.updated` This event is sent when an attribute of a directory group has changed. - | Lifecycle - | Payload The payload for `dsync.group.updated` events shows changes between directory group snapshots in the `previous_attributes` property. The changes in the object are shallow differences for root properties, `raw_attributes`, and `custom_attributes`. If the current snapshot has a new attribute that did not exist previously, then the value for the attribute will be indicated as `null`. ### `dsync.group.deleted` This event occurs when deleting a directory group in the directory provider. When a `dsync.group.deleted` event is received, it indicates that the members in that group have been deleted in WorkOS. You can process the `dsync.group.deleted` event accordingly in your application, removing the group's members from your application or marking them as deleted. `dsync.group.user_removed` events will not be sent for the members in the deleted group. - | Lifecycle - | Payload If your app relies on groups to sync users or map roles, you should remove access for the users who belonged to the deleted group. ### `dsync.group.user_added` This event occurs when adding a directory user to a directory group. - | Lifecycle - | Payload If you map roles using groups, you should assign the group’s role to the newly added user. ### `dsync.group.user_removed` This event occurs when removing a directory user from a directory group. - | Lifecycle - | Payload If you map roles using groups, you should remove the group’s role from the user who belonged to the group. --- ## Data reconciliation techniques ### With the WorkOS state API The WorkOS API allows for data reconciliation for your app. You can use the WorkOS API to pull the latest data to reconcile any data discrepancies between WorkOS and your app. A standard method apps use for data reconciliation is to set up a cron job that pulls from the WorkOS API on a consistent interval, e.g., every 1 to 6 hours, depending on your app’s user provisioning volume. > **Known issue:** Keeping track of WorkOS updated timestamps is of limited use right now because group membership changes for users do not alter the WorkOS `updated_at` timestamp. We're actively working on this issue. The general approach for performing a full sync of Directory Sync objects goes as follows: 1. Traverse all directory groups and update all local objects. 2. Traverse all directory users and update all local objects. 3. Extract group membership information from each user. Compare with local membership state. Add and remove memberships accordingly. 4. Compare the list of local users to all users seen in WorkOS traversal. Deactivate any users that exist locally but not on WorkOS. 5. Compare the list of local groups to all groups seen on WorkOS traversal. Deactivate any groups that exist locally but not on WorkOS. ### With the events API You can also reconcile directory data using the events API. See our [data syncing guide](/events/data-syncing/data-reconciliation) to learn more. ### Quick Start Set up a directory, install the SDK, and integrate Directory Sync. ## What you’ll build In this guide, we’ll take you from learning about Directory Sync and POC-ing all the way through to building production-ready features fully integrated with the WorkOS Directory Sync API. This guide will show you how to: 1. Create a new directory in the WorkOS Dashboard 2. Add Directory Sync to your app and fetch directory resources 3. Use events to keep your app in sync with the directory changes ## Before getting started To get the most out of this guide, you’ll need: - A [WorkOS account](https://dashboard.workos.com/) - A directory from a directory provider that WorkOS supports ## API object definitions [Directory](/reference/directory-sync/directory) : Stores info about an organization’s user management system (i.e. directory provider). [Directory user](/reference/directory-sync/directory-user) : Represents an organization user that is active in an organization’s directory provider. [Directory group](/reference/directory-sync/directory-group) : A collection of organization users within a directory, e.g. IT, database admins, HR. > The WorkOS Directory Sync API exclusively uses read-only operations. We never mutate end-user directories. --- ## (1) Create a new directory connection The first step to connecting with a directory is creating an organization in the [WorkOS Dashboard](https://dashboard.workos.com/). You will then be able to create a new [connection](/glossary/connection) to the organization’s directory. Let’s start by creating one for development in your sandbox environment Get provider-specific instructions by selecting the directory provider you want to test: > You can view and copy the unique identifier for the directory connection on the directory page, once it has been set up. The id takes the form `directory_*`. --- ## (2) Add Directory Sync to your app Let’s integrate the Directory Sync API into your app to enable fetching directory resources programmatically. ### Install the WorkOS SDK WorkOS offers native SDKs in several popular programming languages. Choose a language below to see instructions in your application’s language. ### Set secrets To make calls to WorkOS, provide the API key and, in some cases, the client ID. Store these values as managed secrets, such as `WORKOS_API_KEY` and `WORKOS_CLIENT_ID`, and pass them to the SDKs either as environment variables or directly in your app's configuration based on your preferences. ```plain title="Environment variables" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' ``` > The code examples use your staging API keys when [signed in](https://dashboard.workos.com). ### Fetch directory resources Get the details of an existing directory user. Example use case: pre-populate user attributes for new user accounts. #### List directory users Get directory users for a given directory or directory group. Example use case: Build an onboarding experience that allows an admin to select who to invite and create accounts for. > Use the optional `limit`, `before`, and `after` parameters to paginate through results. See the [API Reference](/reference/pagination) for details. #### Get directory group Get the details of an existing directory group. Example use case: Pre-populate team attributes for new organizations. #### List directory groups Get directory groups for a given directory or directory user. Example use case: Build an onboarding experience that allows an admin to select which groups of employees to invite and create accounts for. > Use the optional `limit`, `before`, and `after` parameters to paginate through results. See the [API Reference](/reference/pagination) for details. --- ## (3) Handle directory events Actions performed in a WorkOS environment are represented by events. These can occur as a result of user-related actions, manually via the WorkOS dashboard, or via API calls. To keep your app in sync with the latest directory data, follow the corresponding guides: - We recommend using our [events API](/events/data-syncing/events-api) to sync data to your application. To learn more about other ways to sync data, see the [data syncing guide](/events/data-syncing). - Learn about the different types of events that you can receive. See [event types](/events). - Understand how directory events work. See the [understanding events guide](/directory-sync/understanding-events). - Optionally, stream events to Datadog. See the [observability guide](/events/observability/datadog). ### Directory Sync Build frictionless onboarding for organizations with real‑time user provisioning and deprovisioning. ## Introduction Organizations use company directories and HRIS systems to manage users and enforce their access to organization resources. Directories enable IT admins to activate and deactivate accounts, create groups that inform access rules, accelerate adoption of new tools, and more. ## Definitions **ULM** : User Lifecycle Management (or ULM) is the process of managing a user’s access to an app. This occurs from app onboarding until they are removed from an app. ULM is also commonly referred to as identity provisioning. **SCIM** : System for Cross-domain Identity Management (or SCIM) is an open standard for managing automated user and group provisioning. It’s a standard that many directory providers interface with. **HRIS** : A Human Resources Information System (or HRIS) is software designed to maintain, manage, and process detailed employee information and human resources-related policies. Examples include: Workday, HiBob, BambooHR, etc. **User Provisioning** : Provisioning is the process of creating a user and setting attributes for them – inside of an app. **User Deprovisioning** : Deprovisioning is the process of removing a user from an app. ## What is Directory Sync? Directory Sync is a set of developer-friendly APIs and IT admin tools that allows you to implement enterprise-grade User Lifecycle Management (ULM) into your existing app. ULM allows IT admins to centrally provision and deprovision users from their directory provider. A directory provider is the source of truth for your enterprise customer’s user and group lists. Directory Sync sends automatic updates to your app for changes to directories, groups, users, or access rules. Common directory providers include: [Microsoft Active Directory](/integrations/microsoft-ad-fs-saml), [Okta](/integrations/okta-scim), [Workday](/integrations/workday), and [Google Workspace](/integrations/google-directory-sync). See the full list of supported directory providers on the [integrations](/integrations) page. ## Why use Directory Sync? ULM increases the security of your app and makes it easier for your customers to use your app. ULM is most often implemented using [SCIM](/glossary/scim). SCIM requests are sent between directory providers and your app to inform you of changes to a user’s identity. Changes can include: - Provisioning an identity for a user (account creation) - When a user’s attribute has changed (account update) - Deprovisioning a user from your app (account deletion) Each directory provider implements SCIM differently. Implementing SCIM is often a challenging process and can introduce security vulnerabilities into your app. Directory Sync hides this complexity, so you can focus on building core product features in your app. ## What your customer experiences Let’s take a look at two different user provisioning scenarios. ### (N) Your app doesn’t use Directory Sync Without ULM, your customers have to manually add, update, and remove users from your app. Imagine a scenario where your customer has purchased your software and onboards a new employee to your app. Your customer would have to do the following: 1. The IT admin provisions the employee in their directory provider (_if they use one_) and manually in your app. 2. All employee information has to be set manually in both the directory provider and your app. 3. The IT admin has to manually provision a login method for the employee; through either SSO (_if they use an identity provider_) or a self-registration page. 4. The IT admin sends the invite link to their employee. Often initiating a back and forth via either email, messaging app, or IT helpdesk ticket. 5. The employee has to proceed with the registration method and can then use your app. All future changes to this employee’s data and access are manually entered by the IT admin. This is error prone and can lead to security vulnerabilities where users get unauthorized access to resources. As your customers adopt more cloud software, these manual processes do not scale well. Manual input error can lead to the source of truth (directory) drifting from your app’s state. As a result, ULM has become a table stakes product requirement for enterprises. ### (Y) Your app uses Directory Sync If your app supports ULM via Directory Sync, the IT admin can provision this employee from one place: 1. Add the employee to their directory provider. 2. Assign the employee to your app with the appropriate role once; via the directory provider admin page. 3. **Optional.** Have the employee go through a password setup if they are not using an identity provider (SSO). Directory Sync makes this integration easy by providing APIs your app interfaces with. All updates for this directory will automatically be sent to your app from WorkOS. --- ## API overview [Directory](/reference/directory-sync/directory), [directory group](/reference/directory-sync/directory-group), and [directory user](/reference/directory-sync/directory-user) are the main components your app interfaces with. ### Directory A directory is the source of truth for your customer’s user and group lists. WorkOS supports dozens of integrations including SCIM. Directory updates are delivered to you via webhooks. Your app stores a mapping between your customer and their directory. This allows you to maintain your app in sync with the directory provider used by your customer. You can enable self-service Directory Sync setup for your customers using the [Admin Portal](/admin-portal). ### Directory group A directory group is a collection of users within an organization who have been provisioned with access to your app. Directory groups are mapped from directory provider groups. Directory groups are most often used to categorize a collection of users based on shared traits. i.e. Grouping software developers at a company under an “Engineering” group. ### Directory user A directory user is a person or entity within an organization who has been provisioned with access to your app. Users can belong to multiple directory groups. Users have [attributes](/directory-sync/attributes) associated with them. These attributes can be configured for your app’s needs. ### Identity Provider Role Assignment Learn how to map role data from identity providers to roles in your app with Directory Sync. ## Introduction A role represents a logical grouping of permissions, defining access control levels for users within your application. Roles are identified by a unique, immutable slug and are assigned to Directory Sync [users](/directory-sync/api-overview/directory-user) through their group memberships. These role assignments can be configured on the WorkOS dashboard. To utilize Identity Provider (IdP) role assignment, you must first [configure roles](/rbac/configuration). ## Directory group role assignment Users are assigned to groups via the identity provider. Groups usually correspond to roles in your app. Therefore, IT admins will often map a group one-to-one to a role. This can be defined within the WorkOS dashboard or Admin Portal for your application to receive automatic role updates. > Only supported in directories using SCIM-based or Google Workspace providers. ### Sample scenario Consider the fictional SaaS company _HireOS_. _HireOS_ has integrated Directory Sync and supports group-based role assignment. For example, a _HireOS_ customer would like to assign their engineering team to it. The customer’s IT admin would take the following steps: 1. Create a group “Engineering” using their identity provider. 2. Push the group to _HireOS_ via the identity provider. This is configured in the identity provider admin console. The developer on the WorkOS dashboard can then assign users of that group to the role "Developer". 1. Navigate to the directory page on the WorkOS dashboard. ![The directory page on the WorkOS dashboard](https://images.workoscdn.com/images/88d4701b-7e6d-4655-ad74-48bc7c14959f.png?auto=format&fit=clip&q=50) 2. Create an assignment for “Engineering" to the "Developer" role. ![The role assignment dialog on the WorkOS dashboard](https://images.workoscdn.com/images/bdd4cc91-11cb-49b1-858b-f2509ce3675e.png?auto=format&fit=clip&q=50) From this point on, all new users added to “Engineering" will be given "Developer” role from the WorkOS API. The role will be in the [directory user response](/reference/directory-sync/directory-user). ![Screenshot of directory user page](https://images.workoscdn.com/images/18f584f6-d758-4f11-bfc8-e93c16452580.png?auto=format&fit=clip&q=50) ### Multiple roles When [multiple roles is enabled](/rbac/configuration/configure-roles/multiple-roles) in your environment, directory users can be assigned multiple roles from their identity provider group memberships. If a user belongs to multiple mapped groups, they will receive all corresponding roles. For example, if a user is a member of both "Engineering" and "Design" groups, and both groups are mapped to roles, the directory user will receive both the "Developer" and "Designer" roles. If a user is not a member of any groups with explicit mappings, they will receive the [default role](/rbac/configuration). When using [AuthKit with Directory Provisioning](/authkit/directory-provisioning), these multiple roles are automatically applied to the user's [organization membership](/reference/authkit/organization-membership) and reflected in their [session token](/authkit/sessions/integrating-sessions/access-token). #### Use cases By default, multiple roles is disabled and users can only have a single role per entity. It's recommended to start with a single-role setup for simplicity, where it's easier to maintain consistent and correct access patterns. You might want to enable multiple roles when you need: - **Cross-department collaboration**: e.g., designers who need some engineering permissions. - **Additive, disjoint permissions**: independent permission sets that should stack. - **Temporary access**: grant time-bound extra capabilities without creating hybrid roles. ### Role assignment in Admin Portal Once [roles](/rbac/configuration) are configured for your application, enable directory group role assignment in [Admin Portal](/admin-portal) to allow IT admins to assign roles to groups during directory setup. ![Enable directory group role assignment dashboard setting](https://images.workoscdn.com/images/fe19e3ac-6370-404e-9590-cdb06b3de127.png?auto=format&fit=clip&q=50) This is an environment-level setting, but can be configured per organization via the _Roles_ tab under an organization in the WorkOS Dashboard. If your application is integrated with Directory Sync, it is recommended to use directory group role assignment as the environment default. ![Screenshot of admin portal with role assignment step](https://images.workoscdn.com/images/74d09b62-b2b2-4aba-9803-3ec6305897e0.png?auto=format&fit=clip&q=50) If enabled, all Admin Portal sessions for SCIM-based or Google Workspace directories will have the ability to see and assign roles to identity provider groups. ## Other forms of role assignment Your customers will store role information in different forms, depending on their preferred provisioning workflow. WorkOS allows for flexibility in how you source role data, though these formats are not automated today and not available on the role property on the [directory user response](/reference/directory-sync/directory-user). You can fetch role data via two distinct mechanisms: - A custom-mapped role attribute from the directory user profile. - A groups attribute in the SSO user profile. The type of mechanism needed will depend on the level of support for roles in your app, your app’s architecture, and your customer’s workflows: | Approach | Your app | Your customer | | ------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------ | | SSO group role assignment | Receives role data each time a user logs in | Uses identity provider groups to assign roles in your app | | Attribute-based role assignment | Sets roles based on a per-user custom-mapped attribute | Assigns roles using attributes on users in their identity provider | ### SSO group role assignment [SSO group role assignment](/sso/identity-provider-role-assignment/sso-group-role-assignment) involves mapping identity provider (IdP) groups to roles within your application during [Single Sign-On](/sso) and [JIT Provisioning](/sso/jit-provisioning). In this method, SSO groups corresponding to IdP groups are defined in the WorkOS Dashboard, and roles are assigned based on these group memberships. The user’s role is then included in the [SSO profile](/reference/sso/profile) returned from WorkOS. [Read more](/sso/identity-provider-role-assignment/considerations/drawbacks) on this approach, including [drawbacks](/sso/identity-provider-role-assignment/considerations/drawbacks) to consider. ### Attribute-based role You can use [custom-mapped attributes](/directory-sync/attributes/custom-attributes/custom-attributes) if your customers do not use groups to establish and manage user roles. You can create a custom-mapped attribute role (e.g., `myRole`) in the [WorkOS Dashboard](https://dashboard.workos.com/) under Configuration → Directory Sync. You can set the status of a role attribute to “Required” or “Optional”. ```json language="json" title="Directory user with a custom-mapped attribute" { "id": "directory_user_01E1X7B89OH8Z3SXFJR4H7RGX7", "idp_id": "821991", "first_name": "Jane", "last_name": "Doe", "email": "jane@example.com", "state": "active", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "object": "directory_user", "directory_id": "directory_01E1X194NTJ3PXMAY79DYV0F0P", "organization_id": "org_01EHWNCE74X7JSDV0X3SZ3PJNY", "custom_attributes": { "myRole": "admin" }, "raw_attributes": {} } ``` The newly created attribute will appear as a field in the [Admin Portal](/admin-portal). When setting up Directory Sync with their identity provider in Admin Portal, your customers can map this role field to a field in their identity provider. You’ll have to communicate with your customer what value(s) you expect in the custom-mapped attribute. An example being that `myRole` should be one of `"admin"`, `"viewer"`, or `"editor"`. This allows your app to parse the `myRole` field value correctly. ## Common edge cases ### A user is part of multiple groups Having a user who belongs to multiple groups is a common scenario. For example, there might be a case where an employee _Jane_ is an _Engineering Manager_ and belongs to an “Engineering”, “Manager”, and “Admin” group. With group-based role assignment, the user will be assigned the role that has the [highest priority defined](/rbac/configuration/configure-roles/priority-order). ### Role assignment availability on Directory Sync Identity provider role assignment through groups is only available through SCIM compliant and Google Workspace directories. ### Handle Inactive Users Learn why inactive users are deleted from directories by default and how to configure this behavior. ## Introduction Traditionally, user provisioning involves the ingestion of user information from various providers (either through SCIM or non-SCIM integrations). This process typically includes categorizing users into states such as `active`, or `inactive` as provided by the IdP data source. However, the challenge arises when businesses need to handle these `inactive` users differently based on their unique operational and security requirements. Some developers may prefer a security-first approach, automatically deleting these users to enhance data security, while others may opt to retain this information for reactivation processes or comprehensive directory management. --- ## Configuration To provide improved security and customizability, you can choose how `inactive` users are handled during the provisioning process. Here is an overview of the two options available: ### Secure flow (default) By selecting this option, customers can opt for a security-focused workflow. Any user marked as `inactive` will be automatically deleted from the directory, resulting in cleaner and potentially more secure data. This approach reduces the data footprint and minimizes potential security risks associated with unused accounts. ### Custom management flow Alternatively, customers can choose to maintain the existing flow, keeping the `inactive` users in the directory. This approach supports reactivation processes and ensures a comprehensive view of the directory, allowing for easier reintegration of users when needed. > Contact [customer support](mailto:support@workos.com) to enable custom management flow for your environment. ![A breakdown of the different events for each configuration path on handling inactive users.](https://images.workoscdn.com/images/2304739c-17e9-4521-96d2-81fa3fa83110.png?auto=format&fit=clip&q=80) ## Weighing the tradeoffs Both options offer distinct advantages, and the right choice depends on your organization's unique needs and security posture: ### Security vs. flexibility The automatic deletion option prioritizes data security by minimizing the data footprint, while the customized management option provides flexibility for reactivation flows and comprehensive directory oversight. ### Compliance and regulations Depending on industry regulations and compliance requirements, one option may align better with your organization's obligations. ### Operational efficiency Consider how each option impacts operational efficiency using WorkOS to handle a set of the computation for you. ### Reactivation If a user is temporarily removed, does the same user information need to be retained when they return? A new directory user will be created by default on return, whereas using the `inactive` user will retain the same information on reactivation. ### Example Apps View sample Directory Sync apps for each SDK. You can view minimal example apps that demonstrate how to use the WorkOS SDKs to power Directory Sync: ### User Attributes Configure how attributes map from directory providers to Directory Users. ## Introduction WorkOS can automatically find and normalize most common attributes from directory providers into the [Directory User](/reference/directory-sync/directory-user) object, which represents an enterprise user. More unique cases can be mapped by your customers admins. - ### Directory User object Here is an example Directory User. The data stored varies per directory provider and may include attributes such as photo URLs, pay groups, supervisors, etc. ```json language="json" title="Directory User" { "id": "directory_user_01E1X7B89OH8Z3SXFJR4H7RGX7", "idp_id": "821991", "first_name": "Jane", "last_name": "Doe", "email": "jane@example.com", "state": "active", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "object": "directory_user", "directory_id": "directory_01E1X194NTJ3PXMAY79DYV0F0P", "organization_id": "org_01EHWNCE74X7JSDV0X3SZ3PJNY", "custom_attributes": { "emails": [ { "type": "work", "value": "jane@example.com", "primary": true } ], "employee_type": "Full Time", "employment_start_date": "2021-06-27T12:00:00.000Z", "department_name": "Engineering", "manager_email": "john@example.com", "division_name": "Analytics", "cost_center_name": "IT", "job_title": "Software Engineer", "addresses": [ { "type": "work", "street_address": "101 123rd Ave", "locality": "Brooklyn", "region": "New York", "postal_code": "12345", "country": "USA", "raw_address": "101 123rd Ave, Brooklyn, New York, 12345, USA", "primary": true }, { "type": "home", "street_address": "102 W 321st St", "locality": "Brooklyn", "region": "New York", "postal_code": "54321", "country": "USA", "raw_address": "102 W 321st St, Brooklyn, New York, 54321, USA", "primary": false } ], "username": "jane@example.com", "my_new_key": "" }, "raw_attributes": { "name": { "givenName": "Jane", "familyName": "Doe" }, "active": true, "emails": [ { "type": "work", "value": "jane@example.com", "primary": true } ], "groups": [], "locale": "en_US", "schemas": ["urn:directory:schemas:core:1.0"], "password": "redacted", "userName": "jane@example.com", "externalId": "821991", "displayName": "Jane Doe" } } ``` In this guide, we’ll explain how to map data from directory providers to the Directory Users. ## Definitions **Standard attributes** : The most common user information, normalized across providers. **Predefined attributes** : Detailed user attributes for specific use cases, normalized across providers. You can opt-in to each attribute you'd like auto-mapped. **Custom attributes** : For unique cases, you can create custom attributes your customers can map when setting up a directory. ## Standard attributes Every Directory User comes with the following standard attributes. These are the core set of attributes that are common across all identity providers. These are structured fields with a guaranteed schema in the top-level Directory User payload. | Attribute | Type and description | Status | | ------------ | ------------------------------------------------------------------------------------------------------------------------ | -------- | | `idp_id` | The user’s unique identifier, assigned by the directory provider. Different directory providers use different ID formats | Required | | `first_name` | The user’s first name | Optional | | `last_name` | The user’s last name | Optional | | `email` | The user’s email | Optional | | `state` | The user’s state. May be `active`, or `inactive` | Required | > `emails`, `job_title`, and `username` were previously considered standard attributes, but have been deprecated in favor of equivalent [auto-mapped custom attributes](/directory-sync/attributes/custom-attributes/predefined-attributes). --- ## Custom attributes For more detailed user information, you can opt-in to additional predefined attributes and define your own custom attributes. These attributes will appear in the custom attributes field on [Directory User](/reference/directory-sync/directory-user) objects and can be configured in the [WorkOS Dashboard](https://dashboard.workos.com/). > Custom attributes are configured at the environment level. To configure attributes for a specific organization, please [contact our support team](mailto:support@workos.com). ### Predefined attributes When enabled, the values will be mapped without additional setup. Not every directory provider has data for every field, so they are always optional if enabled. These fields are named and schematized by WorkOS – they cannot be renamed. | Attribute | Type and description | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | `addresses` | The user’s list of address objects (`street_address`, `locality`, `region`, `postal_code`, `country`, `primary`, `raw_address`) | | `cost_center_name` | The user’s cost center name | | `department_name` | The user’s department name | | `division_name` | The user’s division name | | `emails` | The user’s list of email objects (`type`, `value`, `primary`) | | `employee_type` | The user’s employment type | | `employment_start_date` | The user’s start date | | `job_title` | The user’s job title | | `manager_email` | The email address for the user’s manager | | `username` | The user’s username | #### Enable or disable a predefined attribute Predefined attributes can be enabled or disabled in the [WorkOS Dashboard](https://dashboard.workos.com/) on the Identity Provider Attributes page. ![WorkOS Dashboard UI showing editing predefined attributes](https://images.workoscdn.com/images/73b775ed-c3ef-4c81-bb56-7b040d3d073a.png?auto=format&fit=clip&q=50) > Updates to these settings may take up to an hour to reflect in your Directory User API response. A [dsync.user.updated](/events/directory-sync) event is emitted for each Directory User changed by toggling auto-mapped attributes. ### Support per directory provider The following support table outlines the attribute availability across directory providers. ### Custom attributes Custom attributes can be utilized to enrich [Directory User](/reference/directory-sync/directory-user) objects with additional data from the identity provider. You can create attributes that appear as fields in the [Admin Portal](https://workos.com/admin-portal). Your customers can map these fields to the correct values in their system when setting up Directory Sync with their identity provider. #### Create a custom attribute Custom attributes can be created in the [WorkOS Dashboard](https://dashboard.workos.com/) on the Identity Provider Attributes page. ![WorkOS Dashboard UI showing custom attribute creation](https://images.workoscdn.com/images/c1d00c4c-4dea-415e-a8f8-c870317410df.png?auto=format&fit=clip&q=50) #### Delete a custom attribute When a custom attribute is deleted, the attribute will be deleted from all [Directory User](/reference/directory-sync/directory-user) objects. > Updates to custom attributes may take up to an hour to reflect in your Directory User API response. A [dsync.user.updated](/events/directory-sync) event is emitted for each Directory User changed. #### Nested attributes Custom attributes support nested attribute mapping. Different directory providers structure their data differently, and nested attribute support allows you or your customer to map values regardless of where they appear in the directory structure. Nested attributes from the directory can be mapped to custom attributes using the WorkOS [Dashboard](https://dashboard.workos.com/) or [Admin Portal](/admin-portal) by selecting attributes from an interactive schema viewer. The schema viewer displays the structure of user data from their directory, allowing them to browse and select any nested field. This ensures accurate mapping without manual configuration. ##### Example: Different structures across providers The same logical attribute (like "license") may appear at different nesting levels depending on the provider: ```json language="json" title="Provider A - Nested under URN" { "userName": "jdoe@example.com", "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": { "license_tier": "silver" } } ``` ```json language="json" title="Provider B - Under custom schemas" { "userName": "jdoe@example.com", "customSchemas": { "license_tier": "silver" } } ``` With nested attribute support, you can create a single custom attribute called `license_tier`, and IT admins can map it to the correct location in their specific directory provider's structure using the schema viewer. --- ## Raw attributes [**Deprecated**] These are unfiltered and unstructured attributes that are unique to each directory provider. These attributes are included as fields in the `raw_attributes` object that is included in the [Directory User](/reference/directory-sync/directory-user). The `raw_attributes` property will be phased out soon. [IdP role assignment](/directory-sync/identity-provider-role-assignment) or [custom attributes](/directory-sync/attributes/custom-attributes) should be used instead. Contact support [via email](mailto:support@workos.com) or slack if you need help with the migration. ### Migration from raw_attributes to custom attributes If you currently access nested fields from `raw_attributes` in your application code, you should migrate to using custom attributes with nested attribute mapping. This provides a consistent, structured API while giving your customers' IT admins the flexibility to map any field from their directory provider. **Before (deprecated):** ```javascript const license_tier = user.raw_attributes[ 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' ]?.license_tier; const employeeId = user.raw_attributes.customSchemas?.Company?.employeeId; ``` **After (recommended):** ```javascript const license_tier = user.custom_attributes.license_tier; const employeeId = user.custom_attributes.employee_id; ``` **How to migrate:** 1. **Identify nested fields** you currently access from `raw_attributes` 2. **Create custom attributes** in the [WorkOS Dashboard](https://dashboard.workos.com/) for each field 3. **Instruct your customers' IT admins** to map these attributes using the schema viewer during directory setup 4. **Update your application code** to read from `custom_attributes` instead of `raw_attributes` 5. **Test with a pilot directory** before migrating all directories The nested attribute mapping feature ensures IT admins can map any field from their identity provider, regardless of structure, while your application receives a consistent, predictable schema. --- ## Frequently asked questions ### Are existing directories required to update the attribute mapping when new required custom attributes are added? No, when you add a new required custom attribute to your settings, this won’t be retroactively required for directories that have already been set up and configured. However, in the WorkOS dashboard, you will be able to navigate directly to the existing directory and fill in details for those attributes manually. ### Can our customers add their own custom attributes outside of what is defined in the WorkOS dashboard? We do not currently support this functionality, as you have to define any custom attributes in the dashboard first. Please reach out to [support](mailto:support@workos.com) if you have a specific use case that you would like to discuss. ### What happens if an attribute cannot be mapped from the IdP? Attributes that cannot be mapped for a particular [Directory User](/reference/directory-sync/directory-user) will result in a `null` value for the attribute. [dsync.user.updated](/events/directory-sync) events are not emitted when an attribute changes from `null` to `undefined` or vice versa. ### How do IT admins map nested attributes? IT admins can map nested attributes using the schema viewer in the WorkOS [Admin Portal](/admin-portal) when configuring their directory. The schema viewer displays the actual structure of user data from their directory provider, showing how attributes are organized. To map a nested attribute: 1. IT admins navigate to the attribute mapping step during directory configuration 2. They view a visual representation of their directory's user data structure 3. They select any field, regardless of nesting level, from the schema viewer 4. The mapping is automatically configured for that nested attribute This approach works consistently across all directory providers, even though each provider may structure their data differently. The schema viewer adapts to show the specific structure of the IT admin's directory provider, ensuring accurate mapping without requiring technical knowledge of the underlying data format. ## Docs {#demo} ### Tabs Test page for the tabs component - | Directory User Whether to parse strikethrough with a single tilde (boolean, default: true). - | List Directory Get the details of an existing Directory User. - | Get Directory Group ### Table Demo example of a table. ## Default table | First Header | Second Header | | ------------ | ------------- | | Content Cell | Content Cell | | Content Cell | Content Cell | ## Formatting with `inline code blocks`, `links`, and `text styles` | Command | Description | | ------------ | ------------------------------------------------------------------------ | | `git status` | List all _new or modified_ files | | `git diff` | Show [file](https://workos.com) differences that **haven’t been** staged | ## Text alignment | Left-aligned | Center-aligned | Right-aligned | | ------------ | -------------: | ------------: | | git status | git status | git status | | git diff | git diff | git diff | ### Code Block Replacements Test page for the code block replacements ```js 'foo@foo-corp.com foo-corp.com foo@foo-corp.com'; ``` ```js 'foo-corp.com'; ``` ```js 'afoo-corp.com'; ``` ```js 'foo-corp.com foo-corp.com'; ``` ```js const api_key = 'sk_example_123456789'; const client_id = 'client_123456789'; ``` ### Punctionation This will be SEO description. The punctuation should use proper typographic symbols, like dashes and curly quotes via [SmartyPants](https://daringfireball.net/projects/smartypants/). ## Apostrophe and smart quotes "It'll be great" they said. Here's a sentence. "Great", he said. They said it'll be great. "We'll do that" they said. "You'll do that" he said. _They_ can't do that. `don't replace the apostrophe here`. `"string"` ```plaintext Don't replace the "apostrophe" and "quotes" here too. ``` ## Dashes One - a hyphen. Two – an en-dash. Three—an em dash. All should be transformed into en-dashes. Code should not be transformed: ```plaintext One - a hyphen. Two – an en-dash. Three—an em dash. ``` `One - a hyphen. Two – an en-dash. Three—an em dash.` ## Ellipsis Counting... ### Demo page This will be SEO description. These pages are for demo purposes only. They are not meant to be used in production. ### Definition List Demo example of a definition list. Not a definition item. Term 1 : Definition 1 Not a definition item. Term 2 : Definition 2 **Term 3** : _Definition_ 3 **Term 4** : Definition 4 Term 5 : `Definition 5` Term 6 : Definition `6` Term `7` : Definition 7 : Not a definition item. Not a term : ### Code Block Test page for the code block component ## From file ## Without title ```js console.log(); ``` ## Empty code block ```plain ``` ## With tabs across all languages Input: ```html ``` Output: ## One language with tabs Only Java should have tabs here. Input: ```html ``` Output: ### Checklist Test page for the checklist component ## Checklist syntax stress test Adjacent lists shouldn’t be mangled. - [ ] One two. - [x] Three four. - [ ] Five six. - [ ] Seven eight. - Nine - Ten - Eleven - Twelve - [ ] 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, GitHub OAuth, Sign in with Apple, or Magic Link connections 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 - one - two - three - four ### Accordion Test page for the accordion component ## Accordion syntax stress test Adjacent lists shouldn’t be mangled. - ### One? Two. - ### Three? Four. - ### Five? Six. - ### Seven? Eight. - Nine - Ten - Eleven - Twelve - ### `dsync.deactivated` Accordion content goes here. - ### `dsync.activated` Accordion content goes here. - ### `dsync.deactivated` Accordion content goes here. - ### `dsync.deleted` Accordion content goes here. - One - Two - Four - Three ## Custom Domains {#custom-domains} ### Custom Domains Configure your integration to match your brand identity. ## Overview By default, a WorkOS domain will be used for services such as sending email and hosting AuthKit. In the staging environment these will always use a WorkOS domain, however in production you have the option to provide your own custom domain. This is a paid service, for which you can find additional details on our [pricing page](https://workos.com/pricing). Custom domains can be set for: - [Email](/custom-domains/email) - [AuthKit](/custom-domains/authkit) - [Admin Portal](/custom-domains/admin-portal) - [Authentication API](/custom-domains/auth-api) ### Email Domain Guidance on configuring a custom domain for emails. ## Configuring a domain Several AuthKit features require sending emails: - Magic Auth - Email verification - Password resets - Invitations While developing with WorkOS in a staging environment, WorkOS will send AuthKit emails from `workos.dev`. In production environments, emails are sent from a custom domain when configured or from `workos-mail.com` by default. ### (1) Navigate to Domains configuration With the production environment selected, navigate to the _Domains_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). ![Dashboard displaying domain configuration settings](https://images.workoscdn.com/images/1b02397b-89b0-451d-9d6d-d222db5635b9.png?auto=format&fit=clip&q=80) ### (2) Add an email domain Click the _Add Domain_ button and enter the domain you would like to use for sending emails. ![Dashboard displaying a domain entry input](https://images.workoscdn.com/images/2e7840fb-1a05-444c-a68f-52f3ac3eceb5.png?auto=format&fit=clip&q=80) ### (3) Create CNAME records You will be prompted to create 3 CNAME records with your DNS provider. After creating these DNS records, click _Verify now_. ![Dashboard displaying CNAME entries](https://images.workoscdn.com/images/0d85fad9-2af7-425d-8b4b-55c407a0db83.png?auto=format&fit=clip&q=80) > It can take some time for DNS changes to take effect. If the initial verification attempt is not successful, WorkOS will continue trying to verify your domain for 72 hours. Once your domain is successfully verified, authentication emails and Admin Portal invites will be sent from `no-reply@your-domain.com`. It’s important to keep the CNAME records in place to ensure that WorkOS can deliver mail on your behalf. ### AuthKit Domain Guidance on configuring a custom domain for AuthKit. ## Configuring a domain The domain for AuthKit will consist of a randomly generated phrase plus the domain `authkit.app`, for instance `youthful-ginger-43.authkit.app`. This is the default in the staging environment, in Production environments a custom domain can be configured via the dashboard. ### (1) Navigate to Domains configuration With the production environment selected, navigate to the _Domains_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). ![Dashboard displaying domain configuration settings](https://images.workoscdn.com/images/f04be28f-4af8-4a2e-a812-815d1a441674.png?auto=format&fit=clip&q=80) ### (2) Add an AuthKit domain Click the _Configure AuthKit domain_ button and enter the domain you would like to use. ![Dashboard displaying a domain entry input](https://images.workoscdn.com/images/b7e45bfe-2948-4d5e-a7ee-be3eb223d710.png?auto=format&fit=clip&q=80) ### (3) Create CNAME records You will be prompted to add a CNAME record to your DNS provider. If your DNS provider is Cloudflare, ensure the CNAME record is configured as DNS-only and is not proxied. To manage custom domains, WorkOS uses Cloudflare, who prohibit domains from being proxied across accounts. ![Dashboard displaying CNAME entries](https://images.workoscdn.com/images/68d96188-8d68-4a89-8843-5d21d9b739c5.png?auto=format&fit=clip&q=80) > It can take some time for DNS changes to take effect. If the initial verification attempt is not successful, WorkOS will continue trying to verify your domain for 72 hours. Once your domain is successfully verified, users signing in via AuthKit will be redirected to your custom domain. ### Authentication API Domain Guidance on configuring a custom domain for the Authentication API. ## Configuring a domain WorkOS authentication requests are done via the Authentication API, which defaults to `api.workos.com`. This can be configured to a custom domain if you prefer to use your own branding instead of the default. While developing with WorkOS in a Sandbox environment, requests are made to the `api.workos.com` domain. In production environments, requests are made to `api.workos.com` by default or a custom domain if configured. For instance, if you were retrieving a user via the API and you had a custom Authentication API domain `api.example.com` set up, you'd make requests to: `https://api.example.com/user_management/users/:id` Instead of the default: `https://api.workos.com/user_management/users/:id` > When a custom domain is configured, requests to the API should be routed through that domain. Continuing to make requests to `api.workos.com` after a custom domain is configured for the Authentication API can result in issues with your integration. ### Custom domains for SCIM endpoints Custom Authentication API domains are also used for SCIM endpoints when using [Directory Sync](/directory-sync). For example, if you had a custom domain `api.example.com` set up, your customer's identity provider would make requests to `https://api.example.com/scim/v2.0/:id`. The custom domain is reflected in the Admin Portal setup steps for a directory. Adding a custom domain does not affect existing directory integrations pointing to `api.workos.com`. ### Using custom domains in SDKs When using the WorkOS SDKs, a custom API hostname can be configured: ### (1) Navigate to Domains configuration With the production environment selected, navigate to the _Domains_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). ![Dashboard displaying domain configuration settings](https://images.workoscdn.com/images/28d1072b-1bc7-42af-8d7d-fb8da0363413.png?auto=format&fit=clip&q=80) ### (2) Add an email domain Click the _Configure authentication API domain_ button and enter the domain you would like to use. ![Dashboard displaying a domain entry input](https://images.workoscdn.com/images/cc648df5-603a-4001-bfc0-cea2bfca02e5.png?auto=format&fit=clip&q=80) ### (3) Create CNAME records You will be prompted to add a CNAME record to your DNS provider. If your DNS provider is Cloudflare, ensure the CNAME record is configured as DNS-only and is not proxied. To manage custom domains, WorkOS uses Cloudflare, who prohibit domains from being proxied across accounts. ![Dashboard displaying CNAME entries](https://images.workoscdn.com/images/e920f0c9-4bd5-4f11-a2e3-9d709b483ed1.png?auto=format&fit=clip&q=80) > It can take some time for DNS changes to take effect. If the initial verification attempt is not successful, WorkOS will continue trying to verify your domain for 72 hours. Once your domain is successfully verified, your custom domain will act as the [ACS URL](/glossary/acs-url) for authentication. ### Admin Portal Domain Guidance on configuring a custom domains for the Admin Portal. ## Configuring a domain When your customer's organization admins use the Admin Portal self-serve onboarding experience, they'll be directed to a `setup.workos.com` domain. While developing with WorkOS in a staging environment, users will see the `setup.workos.com` domain. In production environments, users will see `setup.workos.com` by default or a custom domain if configured. ### (1) Navigate to Domains configuration With the production environment selected, navigate to the _Domains_ section of the [WorkOS Dashboard](https://dashboard.workos.com/). ![Dashboard displaying domain configuration settings](https://images.workoscdn.com/images/b6afe130-219c-4e0e-8209-49b1a0fb6098.png?auto=format&fit=clip&q=80) ### (2) Add an Admin Portal domain Click the _Configure Admin Portal domain_ button and enter the domain you would like to use. ![Dashboard displaying a domain entry input](https://images.workoscdn.com/images/6dc8c261-3f1a-4d7a-b9ea-e7541d5e1361.png?auto=format&fit=clip&q=80) ### (3) Create CNAME records You will be prompted to add a CNAME record to your DNS provider. If your DNS provider is Cloudflare, ensure the CNAME record is configured as DNS-only and is not proxied. To manage custom domains, WorkOS uses Cloudflare, who prohibit domains from being proxied across accounts. ![Dashboard displaying CNAME entries](https://images.workoscdn.com/images/467edbdc-ba6d-42be-809e-7b0b1e560385.png?auto=format&fit=clip&q=80) > It can take some time for DNS changes to take effect. If the initial verification attempt is not successful, WorkOS will continue trying to verify your domain for 72 hours. Once your domain is successfully verified, admins using the self-serve Admin Portal will be redirected to your custom domain. ## AuthKit {#authkit} ### Users and Organizations Flexible application modeling with user and membership features. ## Users The [User object](/reference/authkit/user) represents an identity that has access or owns artifacts in your application. A User object may not uniquely identify an individual person, since a person may present themselves as having multiple identities in the same system. What uniquely identifies a user is their **email address**, since having access to that email inbox ultimately gives access to all accounts based on that address. ### Authentication methods There may be multiple authentication methods on a single user object, such as [Email + Password](/authkit/email-password) or [OAuth](/authkit/social-login). A user can sign in with any of the authentication methods associated with them, as long as you have enabled those authentication methods in the WorkOS Dashboard. ### Identity linking Because a user is uniquely identified by their email address, you won’t have users with duplicate email addresses. WorkOS handles [identity linking](/authkit/identity-linking) automatically. ### Email verification All users will go through an initial [email verification process](/authkit/email-verification) by default. This applies to all authentication methods, including OAuth and SSO. This unifying interface simplifies how your application considers the authenticity of your users. ### Domain verification If a user’s email domain matches a verified organization domain when signing in with SSO, they will [automatically be considered verified](/authkit/domain-verification) and will not need to go through the email verification flow. --- ## Organizations Organizations represent both a collection of users that your customer’s IT admin has control over and a workspace within which members collaborate. Organizations are a first-class concept in WorkOS and support a suite of features around organizational management. There is no limit to the number of organizations you can create in WorkOS. ### Organization memberships An organization contains users as members. Organization membership allows you to model organizations as "workspaces" and user’s access to them with memberships. WorkOS organization memberships are designed to be flexible, and support any B2B app model. For example: - **Multiple Workspaces:** A self-serve productivity app, like Figma, where each user can be in any number of organizations, can create their own workspace and join any number of other workspaces. - **Single Workspace:** An app that has no collaboration outside a customer’s company, like an employee survey tool, where each user is in exactly one organization. While these are two distinct models, your choice may depend on your go-to-market strategy, which may change over time. **WorkOS AuthKit supports both**. ### Organization access It’s common for users to create resources in B2B applications. You can use the organization as a container for these resources, so that access is dependent on a user’s access to the organization. This means when a user leaves an organization and is no longer a member, the data remains with the organization and not the user. Organizations provide the level of data ownership that B2B applications structure around. While organization membership conveys the most basic form of access, you can attach more granular role information per member within your own application’s database. ### Organization roles In addition to the [environment-level roles](/authkit/roles-and-permissions/configure-roles-and-permissions), organizations can define their own custom roles, which are assignable only within the context of the organization. Refer to the [organization roles documentation](/authkit/roles-and-permissions/organization-roles) for more details. ### Membership management If your application uses a soft-delete model, you can utilize the extended organization membership lifecycle. Organization memberships have three possible statuses: - `pending`, when a user is invited to an organization - `active`, when a user is added as an organization member or accepts an invitation - `inactive`, when an organization membership is deactivated For soft-delete use cases, we also provide deactivation and reactivation APIs: - [Deactivating an organization membership](/reference/authkit/organization-membership/deactivate) sets its status to `inactive` and revokes all active [sessions](/authkit/sessions). Note `pending` memberships cannot be deactivated and should be deleted using the [deleting membership API](/reference/authkit/organization-membership/delete) instead. - [Reactivating an organization membership](/reference/authkit/organization-membership/reactivate) sets its status to `active` and retains the role attached to the organization membership prior to deactivation. This role can be updated using the [update organization membership API](/reference/authkit/organization-membership/update). Note `pending` memberships cannot be reactivated. For this the user should go through the [invitation acceptance flow](/authkit/invitations) instead. If invitations are not needed, the organization membership can be [created as active directly](/reference/authkit/organization-membership/create). If your application uses a hard-delete model, you may use organization memberships without deactivation/reactivation by [deleting memberships](/reference/authkit/organization-membership/delete) for users who should no longer have access to an organization. ### When to use deletion vs. deactivation Hard deletion is preferred if the app has no need to "remember" the membership. For example, when members operate solely on customer data and have no data of their own. When a member of the organization is gone, there's no need to keep around their membership data. An app in this case may even want to entirely [delete the User](/reference/authkit/user/delete) once the membership is deleted. Deactivation may be preferred in cases where a member retains some data after leaving the organization, for example: messages, documents, or other data which reference that member. It also allows for building a user interface to list former members, perhaps with the option to reactivate them. ### Automated memberships Beyond manually adding or removing users to and from organizations as members, users can be automatically [Just-in-Time (JIT) provisioned](/authkit/jit-provisioning) into an organization if their email address matches one of the organization's [verified domains](/authkit/domain-verification). This allows customers to quickly onboard teammates. Users can also [invite individuals to organizations](/authkit/invitations), regardless of their email domain. This is handy for contractors within a company, or a collection of people without a shared domain. ### Creating organizations for new users In some applications, all activity should happen within the context of an organization. This pattern is common in B2B applications where: - All features and data are scoped to an organization - Users need to be associated with an organization to use the application For these applications, when new users don't already belong to an organization via [Just-in-Time provisioning](/authkit/jit-provisioning) or an [invitation](/authkit/invitations), you'll want to create an organization for them. To ensure all users have at least one organization: 1. **Check the access token**: When AuthKit redirects a user to your application after sign up or sign in, check whether the [access token](/authkit/sessions/integrating-sessions/access-token) contains an `org_id` 2. **Present organization creation form**: If no organization is present, show the user a form with a name field to create a new organization 3. **Create the organization**: On form submission, use the [create organization API](/reference/organization/create) to create the organization 4. **Create organization membership**: Use the [create organization membership API](/reference/authkit/organization-membership/create) to add the user as a member of the new organization 5. **Refresh the token**: Call the [authenticate with refresh token API](/reference/authkit/authentication/refresh-token) with the new organization ID to receive a new access token that includes the organization ### Single Sign-On Facilitate greater security, easier account management, and accelerated application onboarding and adoption. ## Introduction Single Sign-On is the most frequently asked for requirement by organizations looking to adopt new SaaS applications. SSO enables authentication via an organization’s [identity provider (IdP)](/glossary/idp). This service is compatible with any IdP and supports both the [SAML](/glossary/saml) and [OIDC](/glossary/oidc) protocols. It’s modeled to meet the [OAuth 2.0](/glossary/oauth-2-0) framework specification, abstracting away the underlying authentication handshakes between different IdPs. ## Getting started AuthKit greatly simplifies the process of integrating SSO into your application. AuthKit will make the necessary API calls automatically and handle the routing of SSO users when their account is associated with an existing SSO connection. ## (1) Enable SSO Navigate to the _Authentication_ settings section in the [WorkOS Dashboard](https://dashboard.workos.com/) and enable Single Sign-On. ![Dashboard demonstrating how to enable Single Sign-On](https://images.workoscdn.com/images/09c9b3c5-833e-4fe0-985b-f5b1934e4284.png?auto=format&fit=clip&q=80) AuthKit will now automatically detect when a user is attempting to sign in via SSO and redirect them to the appropriate IdP. ## (2) Test with the Test Identity Provider To confirm your Single Sign-On integration works correctly you can use the Test Identity Provider to simulate login flows end-to-end. Your staging environment includes a default Test Organization and active SSO connection configured with the Test Identity Provider. ![WorkOS Test Identity Provider](https://images.workoscdn.com/images/7b7407d7-dcc7-4fd4-859f-4ee4214d69c2.png?auto=format&fit=clip&q=80) ### Getting started Log into the [WorkOS Dashboard](https://dashboard.workos.com/) and navigate to the _Test SSO_ page to get started with the Test IdP. This page outlines a number of different SSO scenarios you can follow and provides all the necessary information to complete the tests. ![Test SSO WorkOs Dashboard](https://images.workoscdn.com/images/7b7407d7-dcc7-4fd4-859f-4ee4214d69c2.png?auto=format&fit=clip&q=80) ### Service provider-initiated SSO This case is likely the first [login flow](/sso/login-flows/sp-initiated-sso) you would test when implementing SSO in your app. The test simulates users initiating authentication from your sign-in page. In this scenario, the user enters their email in your app, gets redirected to the identity provider, and then is redirected back to your application. ### Identity provider-initiated SSO This test simulates users initiating authentication from their identity provider. It is a common [login flow](/sso/login-flows/idp-initiated-sso) that developers forget to consider. In the scenario, users log in to the identity provider directly, select your application from their list of SSO-enabled apps, and are redirected to your application upon successful authentication. ### Guest email domain This test simulates users authenticating with an email domain different from the verified domain of the test organization, `example.com`. A relevant scenario is authenticating freelance users, whose email domain is not owned by the company. ### Error response This test simulates a generic [error response](/reference/sso/get-authorization-url/error-codes) from the user’s identity provider. In this scenario, SSO authentication has failed for the user. Below is an example of the error-related parameters passed to the [redirect URI](/sso/redirect-uris) in your application. --- ## (3) Test with other identity providers Test Identity Provider saves time by providing an out of the box experience compared to the configuration process that someone using a real identity provider would have to go through to enable Single Sign-On for your app. If your integration works with the Test Identity Provider, you can be sure it will work with other identity providers. However, it may be helpful to also learn about the setup process that your customers will go through on their side, which varies depending on a specific identity provider. ### Create an organization To get started, you will need to [create an organization](https://dashboard.workos.com/organizations) in the WorkOS Dashboard. Organizations in WorkOS represent your customer, so by creating an organization, you can test your SSO connection the way your customers will experience it. ![Create an organization dialog](https://images.workoscdn.com/images/2ef3565c-526a-42e6-9830-622e83b67ee5.png?auto=format&fit=clip&q=80) ### Create a connection Go to the organization you created and click _Invite admin_. Select _Single Sign-On_ from the list of features. In the next step, enter an email address to send the setup link to, or click _Copy setup link_. The setup link goes to Admin Portal, where your customers get the exact instructions for every step they need to take to enable Single Sign-On with your app. > You can also integrate [Admin Portal](/admin-portal) directly into your app to enable self-serve setup of Single Sign-On and other enterprise features for your users. ![Invite an admin dialog](https://images.workoscdn.com/images/b9ab80fc-606a-417c-bade-3483ef48c2ae.png?auto=format&fit=clip&q=80) ### Follow the Admin Portal instructions To complete the integration, you’ll have to also create an account with the identity provider you want to test with. After you have signed up with an identity provider of your choice, follow the corresponding Admin Portal instructions from the setup link. Once done, you can start testing your SSO integration with that identity provider. ![Admin Portal setup instructions](https://images.workoscdn.com/images/0ee15c3d-5356-4f41-a26a-440f95355b28.png?auto=format&fit=clip&q=80) The setup instructions you’ve seen in the Admin Portal are also available directly in the docs if you want to create a connection manually: --- ## Integrating via the API If you'd prefer to build and manage your own authentication UI, you can do so via the AuthKit [Authentication API](/reference/authkit/authentication). Examples of building custom UI are also [available on GitHub](https://github.com/workos/authkit). ### SSO with contractors Enforcing organization SSO access with external contractors. ## Introduction In this scenario, we outline the considerations, concepts, and best practices for configuring and enforcing SSO sign-in for all members of an organization, we'll also cover how to enforce these same constraints on external contractors who may need access to company resources but are not permanent members. ## Goals & requirements The application should be available to logged in users only. Each user is typically assigned to a single organization and will be able to collaborate with other users within that organization. - The majority of users collaborate within the same organization. - Permanent members of the organization use an email address that matches the organization's domain. - Organization members are required to authenticate using SSO. - External contractors and collaborators are also required to authenticate using SSO. ![Diagram of AnalyticsOS auth flow for users and contractors](https://images.workoscdn.com/images/b9752155-4f5d-4702-890d-c64caa54005e.png?auto=format&fit=clip&q=80)[border=false] ## Integrating SSO Adding SSO to your application is a straightforward process when using AuthKit, and can mostly be done via the WorkOS dashboard. Steps include: (1) Add a new SSO connection to an organization in the dashboard (2) Configure a callback endpoint in your application (3) Add your endpoint URL as a redirect URI in the WorkOS dashboard (4) Handle the user session and grant access to the application ### Enforcing SSO authentication With an active SSO connection established, it's now possible to enable it as an authentication method in the WorkOS Dashboard. This can be achieved by visiting the authentication settings view for the environment and enabling Single Sign-On. ![Enable SSO in the WorkOS dashboard](https://images.workoscdn.com/images/feb25320-d75c-47bf-ae63-ae7a99a84afb.png?auto=format&fit=clip&q=80)[border=false] This will allow users to sign-in with AuthKit using SSO, but will not enforce it as a requirement. In order to do so, we'll need to configure an authentication policy for the organization. ### SSO authentication flow When the user logs in, they will move through the following flow: (1) User clicks “Sign in” button (2) User is redirected to AuthKit, where they sign via SSO (3) User is redirected from AuthKit to the redirect URI configured in the WorkOS dashboard (4) User is authenticated via code presented in the `redirect_uri` (5) Access is provisioned by the application More in-depth information on configuration can be found in the [Single Sign-On section](/authkit/sso), with AuthKit implementation guidance available in the [Quick Start guide](/authkit). ## Understanding authentication policies An authentication policy is a way to enforce specific authentication methods during sign-in. They typically apply to all users attempting to access the organization. There are several approaches to enforcing SSO within an organization, including domain verification and enforcing specific policies on those inside and outside of the organization based on their attached email domain, but for the purposes of simplicity we will simply cover a blanket authentication policy which applies to all users attempting to sign-in, regardless of verified domain existence. An authentication policy allows the organization to: - Enforce SSO be used by all users accessing the organization - Enforce an MFA requirement for all users accessing the organization ## Adding an authentication policy Authentication policies can be applied in the organization settings view of the WorkOS Dashboard. ![Applying authentication policy in the WorkOS dashboard](https://images.workoscdn.com/images/22fc71c4-1565-45e4-a148-d96de148cdd4.png?auto=format&fit=clip&q=80)[border=false] After adding SSO enforcement to the policy, all users will be required to sign-in using SSO. This will apply to all users, including external contractors. For this to function with external contractors, they will need to be added to the organization's IdP. For cases where external contractors can not be added to the organization's IdP, an MFA requirement can be set as an enforcement fallback. This is sometimes a reasonable compromise if many contractors rotate in out of the organization. ## Summary The organization should now be set up and to both accept SSO connections and enforce their use for all users, including external contractors. In the contractor case they will require adding to the organizations IdP or otherwise fallback to using MFA. This scenario did not cover the full range of access constraints that can be applied to an organization following domain verification, for more information on this topic see the Access Constraints section of the documentation. ### Social Login Quickly and easily integrate with social OAuth providers. ## Introduction Social Login allows users to sign in or sign up using their existing credentials with OAuth providers such as Google, Microsoft, GitHub, and Apple. ## Getting started AuthKit will make the necessary API calls and route users through OAuth providers automatically during the authentication flow, though the relevant providers must first be configured and enabled. ### (1) Configure OAuth providers Configuration can be supplied via the _Authentication_ section of the [WorkOS Dashboard](https://dashboard.workos.com). WorkOS provides integration guides for common providers such as [Google](/integrations/google-oauth), [Microsoft](/integrations/microsoft-oauth), [GitHub](/integrations/github-oauth), [Apple](/integrations/apple), [GitLab](/integrations/gitlab-oauth), [LinkedIn](/integrations/linkedin-oauth), and [Slack](/integrations/slack-oauth). ![Dashboard configure OAuth settings](https://images.workoscdn.com/images/037ede88-0b7a-4e26-9ede-441a25ce584c.png?auto=format&fit=clip&q=80) ### (2) Enable OAuth providers After a provider has been configured and enabled, it will appear as a sign in option on the AuthKit authentication page. ![AuthKit sign in page with social providers highlighted](https://images.workoscdn.com/images/f743cf4f-a32c-464b-94a4-db9f5c146773.png?auto=format&fit=clip&q=80) ## Custom OAuth scopes AuthKit offers support for custom OAuth scopes for Google, Microsoft, GitHub, GitLab, and Xero integrations. This allows you to request specific permissions when accessing user profile data from these providers. For instance, requesting access to read Google Calendar events or retrieve emails from a Microsoft account. See the relevant provider section for more information: - [Google](/integrations/google-oauth/configure-additional-oauth-scopes-optional) - [Microsoft](/integrations/microsoft-oauth/configure-additional-oauth-scopes-optional) - [GitHub](/integrations/github-oauth/configure-additional-oauth-scopes-optional) - [GitLab](/integrations/gitlab-oauth/configure-additional-oauth-scopes-optional) - [Xero](/integrations/xero-oauth/configure-additional-oauth-scopes-optional) ## Provider-driven user profile updates When a user logs in with a social provider, the user profile information may be updated. The user's profile picture and name will always be updated to match the information supplied by the social provider. If the email address at the provider has changed and the user is only linked to a single provider, the email will also be updated to match (If the new email is already in use, no change will take place). --- ## Integrating via the API If you'd prefer to build and manage your own authentication UI, you can do so via the AuthKit [Authentication API](/reference/authkit/authentication). Examples of building custom UI are also [available on GitHub](https://github.com/workos/authkit). ### Sessions Learn more about integrating sessions. ## Introduction When a user signs in to your app, a user session is created. Along with the [User object](reference/authkit/user), a successful authentication response will include an access token and refresh token. Your application can use these tokens to ensure that the user’s session is still active. Each user session can be viewed from within the WorkOS dashboard: ![Sessions Detail UI](https://images.workoscdn.com/images/295ded3e-7e8f-4322-bcc0-95db1cfc255b.png?auto=format&fit=clip&q=80) Navigate to _Users_ and select a user. Then, switch to _Sessions_ tab and click on a user session to get more information. ## Integrating Sessions Successful authentication responses will include both an access token and a refresh token. The access token should be stored as a secure cookie in the user’s browser and should be validated by the backend on each request. The refresh token should either be stored in a secure cookie or persisted on your backend. Once the access token has expired, a new one can be obtained using the refresh token. ![Sessions Diagram](https://images.workoscdn.com/images/aa420ffa-3b8c-462c-992b-b53e458dd916.png?auto=format&fit=clip&q=80)[border=false] ### Access Token If you’re using our [Next SDK](https://www.npmjs.com/package/@workos-inc/authkit-nextjs) or [Remix SDK](https://github.com/workos/authkit-remix), all the work of validating access tokens and refreshing expired tokens is handled for you (more framework support coming soon). Read on for details about how token handling works. The access token is a JSON Web Token (JWT), which should be validated on each request using a library like jose. The [signing JWKS](/reference/authkit/session-tokens/jwks) can be found at `http://api.workos.com/sso/jwks/`. The JWT includes the following claims: - `sub`: the WorkOS user id - `sid`: the session ID (used for signing out) - `iss`: `https://api.workos.com/` (will be your custom auth domain if configured) - `org_id`: the organization that was selected at sign-in time (if applicable) - `role`: the role of the selected organization membership (only applicable if an organization is selected) - `permissions`: the permissions assigned to the role (if applicable) - `exp`: the standard `expires_at` claim (the token should not be trusted after this time) - `iat`: the standard `issued_at` claim ### Refresh Token Refresh tokens should be persisted on the backend in, for instance, a database, cache, or secure http-only cookie. A new access token can be obtained by using the [authenticate with refresh token](/reference/authkit/authentication/refresh-token) endpoint. If the session is still active, a new access token and refresh token will be returned. Refresh tokens may be rotated after use, so be sure to replace the old refresh token with the newly returned one. ### Switching Organizations Refresh tokens can be used to obtain a new access token for a different organization by passing the `organization_id` parameter to the [authenticate with refresh token](/reference/authkit/authentication/refresh-token) endpoint. If the session for the refresh token is authorized to access the organization, then the `org_id` will be set to the given organization, along with the `role` and `permissions` claims matching the user's membership in that organization. If the user is not authorized for the organization, then an appropriate [authentication error](/reference/authkit/authentication-errors) will be returned and the user will need to authenticate. Applications can use the [Get Authorization URL](/reference/authkit/authentication/get-authorization-url) and the `organization_id` parameter to initiate the authentication flow specifically for the organization. ### Signing Out When a user signs out of your app, the following steps should occur: - Get the session id (`sid` claim) out of the access token. - Delete the user’s app session. - Redirect the user’s browser to [logout endpoint](/reference/authkit/logout) endpoint (this will ensure the user’s session ends at WorkOS). - The user will be redirected back to the URL configured as your _App homepage URL_ #### Example ```javascript // extract sessionId from access token const sessionId = jose.decodeJwt(session.accessToken).sid; // delete app session cookie cookies().delete('my-app-session'); // redirect to logout endpoint // (the user will be redirected to your app homepage url // after the logout completes) redirect(workos.userManagement.getLogoutUrl({ sessionId })); ``` ## Configuring Sessions Using the WorkOS dashboard you can configure how Sessions work in your integration. You’ll find the settings in the _Authentication_ section. ![Session Configuration UI](https://images.workoscdn.com/images/158987a3-127c-4bcd-a3ac-53b1be0abd8a.png?auto=format&fit=clip&q=50) - **Maximum session length:** The session will expire after this length of time. Once expired the user will need to sign in again. - **Access token duration:** Your backend can verify the access token on each request (see the [Integrating Sessions](authkit/sessions/integrating-sessions) section above). It’s recommended to keep the access token duration short so that changes in the session are quickly reflected in your app. - **Inactivity timeout:** The session ends if a refresh has not occurred in this length of time. The user will need to sign in again. Additionally, make sure to review your settings in the _Redirect_ section: ### Sign-out redirect ![Sign-out redirect settings](https://images.workoscdn.com/images/4a90f418-8ce0-44f2-a34c-c8336a317277.png?auto=format&fit=clip&q=50) Make sure to set a default Sign-out redirect, which will be the location users will be redirected to after their session has been ended. Non-default Sign-out redirects can be used as values to the `return_to` parameter of the [Logout API](/reference/authkit/logout/get-logout-url) in order to dynamically choose the final logout redirect location. #### Wildcards The `*` symbol can be used as a wildcard for subdomains; however, it must be used in accordance with the following rules in order to properly function. - The wildcard **must** be located in a subdomain within the hostname component. For example, `http://*.com` will not work. - The wildcard **must** be located in the subdomain which is furthest from the root domain. For example, `https://sub.*.example.com` will not work. - The URL **must not** contain more than one wildcard. For example, `https://*.*.example.com` will not work. - A wildcard character **may** be prefixed and/or suffixed with additional valid hostname characters. For example, `https://prefix-*-suffix.example.com` will work. - A URL with a valid wildcard **will not** match a URL more than one subdomain level in place of the wildcard. For example, `https://*.example.com` will not work with `https://sub1.sub2.example.com`. - In production environments, wildcards cannot be used with [public suffix domains](https://publicsuffix.org). For example, `https://*.ngrok-free.app` will not work. - The wildcard will match a sequence of letters (`A` – `Z`, `a` – `z` ); digits (`0` – `9`), hyphens (`-`), and underscores (`_`). - A URL with a wildcard cannot be set as the default redirect URI. ### Roles and Permissions Manage and assign roles and permissions to users. ## Introduction A role represents a logical grouping of permissions, defining access control levels for users within your application. Roles are identified by unique, immutable slugs and are assigned to users through [organization memberships](/authkit/users-organizations/organizations). Permissions grant users privileged access to resources and actions in your application and are referenced in your code by unique, immutable slugs. A permission can be assigned to any number of roles. ### Standalone roles Roles alone can be sufficient when your application only requires very coarse-grained access control. This is suitable if users only need to be separated into broad categories and there is minimal overlap between roles. Simple roles can be easier to manage, but are less flexible for complex access control scenarios. ### Utilizing permissions with roles Permissions allow for more detailed and flexible management of access. They are particularly useful when: - You anticipate the need to frequently modify access rights or introduce new roles. - There is significant overlap in access rights between different roles, but with some variations. - You want to minimize code changes when modifying access rights. By abstracting access control checks to permissions, you can add or modify roles and their access rights without changing the application code. ## Configure roles and permissions Roles and permissions are managed in their own section of the [WorkOS Dashboard](https://dashboard.workos.com/environment/roles-and-permissions/). ![Roles section WorkOS Dashboard](https://images.workoscdn.com/images/09c8fb23-5748-4236-914e-79849ac03a9a.png?auto=format&fit=clip&q=50) ### Create permissions When configuring permissions, we recommend: - Defining a common naming scheme to use across all permissions for your application. Consider separating the resource and action with a delimiter, such as `users:view`. The following delimiters are permitted: `-.:_*`. - Keep permission slugs clear and concise. When assigned to roles, these slugs will be included in session cookies in the [session JWT claims](/authkit/sessions/integrating-sessions/access-token), which is limited to a maximum size of 4KB in many modern web browsers. ### Assign permissions to roles Permissions can be assigned when creating a new role or when editing an existing role. ![Assign permissions to a role](https://images.workoscdn.com/images/f6fd6d9a-a7b0-4df7-908b-b657e669a3dc.png?auto=format&fit=clip&q=50) ### Default role Role configuration occurs at the environment level. Each environment is seeded with a default `member` role, which is automatically assigned to every organization member. This default role cannot be deleted, but any role can be set as the default. If you need to set default roles or other role configurations at the organization level, refer to the [Organization roles](/authkit/roles-and-permissions/organization-roles) section. ### Assign roles By default, organization memberships require exactly one role. Every user with an organization membership is automatically assigned the default role when added to an organization. This role can be edited. When [multiple roles is enabled](/authkit/roles-and-permissions/multiple-roles), you can assign several roles to an organization membership. The user gets all permissions from each role. You can retrieve the role information from the user's [organization membership object](/reference/authkit/organization-membership) to determine their access level and capabilities within your application. Role changes are tracked and logged via the [`organization_membership.updated` event](/events/organization-membership). To view these changes, go to the [events page](https://dashboard.workos.com/environment/events) and filter by `organization_membership.updated`. ### Delete roles When roles are deleted: - **Single role mode**: All organization memberships with the deleted role are reassigned to the default role. - **Multiple roles mode**: The deleted role is removed from all organization memberships that have it assigned, while other roles on the organization membership remain intact. If the deleted role was the only role assigned to the membership, it will be reassigned the default role. Role deletion happens asynchronously, so there may be a slight delay between deleting a role and updating all affected organization memberships. > To migrate from one default role to another, set the new default role and delete the old one. All users will then be reassigned to the new default role. ### Priority order If a user is provisioned from multiple sources with conflicting roles, the role with the highest priority will be assigned. This is applicable for a single role architecture utilizing [role assignment](/authkit/roles-and-permissions/role-assignment). Priority order also determines which role will be assigned to users when migrating from a multiple roles to single role configuration in the environment. ## Multiple roles When [enabled](/rbac/configuration/configure-roles/multiple-roles), AuthKit supports multiple roles per organization membership. A user receives the **union of permissions** across all assigned roles. For example, a user with the _Designer_ and _Engineer_ roles gets both sets of permissions in their session. This prevents role explosion by avoiding redundant hybrid roles, like "designer-engineer". Each organization membership must have **at least one** role, they will always receive the default role if no other role(s) are set. ### Use cases By default, multiple roles is disabled and users can only have a single role per entity. You might want to enable multiple roles when you need: - **Cross-department collaboration**: e.g., designers who need some engineering permissions. - **Additive, disjoint permissions**: independent permission sets that should stack. - **Temporary access**: grant time-bound extra capabilities without creating hybrid roles. For most apps, start with **single-role relationships** for simplicity and predictability, and adopt multiple roles only when overlapping permission sets become common. | Mode | Access calculation | Pros | Considerations | | -------------- | ------------------------------------------ | -------------------------------------------- | --------------------------------------------------- | | Single role | One role's permissions per membership | Simple model; predictable audits; small JWTs | May require hybrid roles for cross-functional users | | Multiple roles | Union of permissions across assigned roles | Flexible; avoids role sprawl | Larger JWTs; more governance | ### Manually assign roles to a user Roles can be assigned manually following the steps below, or via identity provider roles assignment outlined in the next section. 1. From the WorkOS Dashboard, open [Users](https://dashboard.workos.com/environment/users). 2. Select a user and go to **Organization memberships** 3. Click **Edit roles** and add all relevant roles 4. Or assign roles [via the API](/reference/authkit/organization-membership/update) Each organization membership must have **at least one** role. ## Role assignment You can map identity provider groups to roles to automatically assign roles to users. AuthKit supports two methods for role assignment: ### SCIM (Directory Sync) Roles can be assigned via SCIM through [directory group role assignment](/directory-sync/identity-provider-role-assignment/directory-group-role-assignment). Admins can map group memberships to roles in the Admin Portal during SCIM or Google Workspace directory setup. These mappings are used to assign roles to organization memberships via [Directory Provisioning](/authkit/directory-provisioning). ### SSO Roles can also be assigned via [SSO group role assignment](/sso/identity-provider-role-assignment/sso-group-role-assignment). Groups returned in the SSO profile can be mapped to roles in the WorkOS Dashboard. If an AuthKit user authenticates via SSO and belongs to a mapped group, the corresponding role will be set on the [organization membership](/reference/authkit/organization-membership) and reflected in the [user’s session](/authkit/sessions/integrating-sessions/access-token). > Ensure [SSO JIT provisioning](/authkit/jit-provisioning/sso-jit-provisioning) is enabled for each organization using SSO role assignment. ### Enabling in Admin Portal Organization admins can assign roles to identity provider groups in the [Admin Portal](/admin-portal) during SSO or directory setup. From the _Roles and Permissions_ section in the WorkOS Dashboard, role assignment is an environment-level setting. However, it can also be configured per organization via the _Roles_ tab on that organization's page. If enabled, all Admin Portal sessions for the relevant SSO connection or directory will support group role assignment. ![Enable directory group role assignment dashboard setting](https://images.workoscdn.com/images/fe19e3ac-6370-404e-9590-cdb06b3de127.png?auto=format&fit=clip&q=50) Whether to enable role assignment for SSO or directory groups depends on your application’s setup. When [provisioning users with Directory Sync](/authkit/directory-provisioning), we recommend enabling directory group role assignment due to [limitations of SSO role assignment](/sso/identity-provider-role-assignment/considerations/drawbacks). If you’re not yet using directory provisioning, you can enable SSO group role assignment as the environment default. Because this setting is configurable per organization, choose a sensible default based on your customers' typical setup: - **A. All organizations use SSO:** If no organizations are using Directory Sync, enable SSO group role assignment in Admin Portal at the environment level. - **B. Some organizations use Directory Sync:** Enable directory group role assignment in Admin Portal for those specific organizations. - **C. Most organizations use Directory Sync:** Enable directory group role assignment in Admin Portal at the environment level, and override the setting for organizations that only use SSO. ### Migrating role assignment source It’s recommended to use only one role assignment source per organization. If your organization currently uses SSO group role assignment and you'd like to switch to [directory group role assignment](/directory-sync/identity-provider-role-assignment/directory-group-role-assignment), consider the following paths: - **A. Directory is not yet configured:** [Enable directory group role assignment](/authkit/roles-and-permissions/role-assignment/enabling-in-admin-portal) for this organization via the **Roles** tab under an organization in the WorkOS Dashboard. The organization admin will be prompted to set up directory group role assignments in the Admin Portal. - **B. Directory is already configured:** Manually assign roles to directory groups in the WorkOS Dashboard, or regenerate an Admin Portal link so the organization admin can set the role mappings there. Directory group role assignments take precedence and will override any SSO group role assignments on the organization membership. Once directory group roles are properly set up and reflected, you can delete the SSO group mappings. ### Role source priority AuthKit enforces strict priority rules for assigning roles. When roles are sourced from SSO group role assignment: - An explicit SSO group role assignment **overrides** any role manually assigned via the [organization memberships API](/reference/authkit/organization-membership) or the [WorkOS Dashboard](https://dashboard.workos.com/). However, a default SSO group role assignment **does not override** a manual one. - The system may allow a temporary override through the [organization memberships API](/reference/authkit/organization-membership), but it **reapplies** the SSO-assigned role when the user next authenticates, provided the assignment came from an explicit SSO group. - The system **always overwrites** previous SSO role assignments with new ones, whether they originate from an explicit or default mapping. Role assignments sourced from [Directory Provisioning](/authkit/directory-provisioning): - An explicit directory group role assignment **overrides** any role manually assigned via the [organization memberships API](/reference/authkit/organization-membership) or the [WorkOS Dashboard](https://dashboard.workos.com/), or any SSO group role assignment. - The system **does not allow** SSO to override these roles. - You **can override** these roles temporarily via the [organization memberships API](/reference/authkit/organization-membership), but directory provisioning reapplies them during the next sync. - The system **always replaces** previous directory provisioned role assignments with new ones, regardless of whether they came from an explicit or default mapping. ## Role-aware sessions When a user signs into your app, a [user session](/authkit/sessions) is initiated. The authentication response includes an access token, a JSON Web Token (JWT), with role claims indicating the user organization membership's role(s) for that session. ## Organization roles Organization roles are custom roles scoped to a particular organization. They are managed via the "Roles" tab under an organization in the WorkOS Dashboard. ![Roles tab for organization](https://images.workoscdn.com/images/5c09cd78-041f-4bb9-9e76-f7267106b22c.png?auto=format&fit=clip&q=50) ### Why might I use organization roles? In some cases, an application's fixed set of roles may not meet the needs of certain organizations. For example, an organization may require a lesser privileged set of permissions for their members. Organization roles allow you to create custom roles, with the organization's desired set of permissions, without affecting access control for other organizations. ### Creating organization roles By default, organizations have no custom organization roles and simply inherit the environment-level roles. You can create an organization role by clicking the "Create role" button on the organization's "Roles" tab. All organization role slugs are automatically prefixed with `org`. ![Create an organization role](https://images.workoscdn.com/images/90f3f3c0-3c66-48b2-b962-04b34f30599e.png?auto=format&fit=clip&q=50) ### Organization role configuration Once you create the first role for an organization, that organization will have its own [default role](/authkit/roles-and-permissions/configure-roles-and-permissions/default-role) and [priority order](/authkit/roles-and-permissions/configure-roles-and-permissions/priority-order), independent from the environment. New roles added to the environment will be available to the organization and placed at the bottom of the organization's role priority order. ### Using organization roles Like environment-level roles, organization roles can be used in [role assignment](/authkit/roles-and-permissions/role-assignment), [sessions](/authkit/roles-and-permissions/role-aware-sessions), and the [organization membership API](/reference/authkit/organization-membership). No additional action is required to enable this behavior after creating organization roles. ### Deleting an environment role When attempting to delete an environment role that's the default role for one or more organizations, you'll be prompted to select a new default role for all affected organizations. Organization members previously assigned the deleted role will be assigned the new organization default role. ![Select a replacement role](https://images.workoscdn.com/images/5e6f3e51-5de5-4bb1-a850-52b2196282b9.png?auto=format&fit=clip&q=50) ### Radar Protecting against bots, fraud and abuse. ## Introduction Radar adds automated protections on top of AuthKit by collecting signals on the behavior of users as they sign in to your app. These signals feed into an engine that identifies abusive or anomalous behavior. When Radar detects a suspicious authentication attempt, it can block or challenge that attempt based on the settings you configure. Radar leverages device fingerprinting to identify which client is being used to authenticate with AuthKit. This enables Radar to differentiate between legitimate and malicious users, so that automated protections won't impact your app's availability during an attack. It's also a signal for suspicious behavior, such as when a device is used for multiple accounts or multiple devices are using the same account. ## Getting Started Radar works with AuthKit without additional integration effort. You can enable Radar directly from the WorkOS dashboard. If you are interested in using Radar but are not an AuthKit customer, please reach out to [our team](mailto:support@workos.com), or for current customers, drop a note in your shared Slack channel. ## Dashboard Radar's dashboard provides a summary of authentication activity in your app. The top chart shows counts of suspicious events that Radar is detecting, along with automated actions that Radar took based on configuration. The counts are updated in real time to make it easy to spot spikes in anomalous behavior. To see historical trends, the time range for the chart can be toggled between 24 hours, 7 days and 30 days. ![Radar dashboard](https://images.workoscdn.com/images/87812b47-e72f-4edb-8164-e171545c9d8d.png?auto=format&fit=clip&q=50) Below the top chart is a set of cards that show Radar detection activity for different user identifiers. This is helpful to understand which types of devices, locations, users, etc. have been detected most often by Radar. Each card is linked to the events page to drill into a list of individual event activity. ![Radar identifier cards](https://images.workoscdn.com/images/a2239641-2ef4-4742-bf9c-97189069ddaa.png?auto=format&fit=clip&q=50) ## Event list A complete list of Radar events appears under the "Events" tab. This list can be filtered by detection type, action taken, or a specific user ID or email. By clicking into a single event, you can view all of the metadata related to that action including device, location, user agent and IP address. Reviewing events in Radar can help inform when custom restrictions may be useful, such as allowing a known legitimate user to bypass detections, or blocking an IP range that is abusing your sign-in. ![Radar events](https://images.workoscdn.com/images/bde4e906-d680-4f18-baa5-d33fac803a7d.png?auto=format&fit=clip&q=50) ## Configuration Radar gives you full control over the automated actions that are taken to suppress suspicious activity. By enabling a detection, you can choose to block or challenge an authentication attempt that exhibits the detection's behavior. **Blocking** an attempt will cause the authentication to fail, even if valid credentials are provided. The user will see a message indicating their sign-in was not successful, and can reach out to an administrator for more detail. **Challenging** an attempt will send the user an email with a one-time passcode (OTP). The user is then prompted to enter that code to continue authentication. Challenging suspicious authentication attempts with an OTP is effective in stopping bots that are capable of solving CAPTCHAs, as well as malicious users who have stolen credentials but don't have access to the user's email account. > Radar supports SMS challenges for sign ups in preview. > Reach out to support via [email](mailto:support@workos.com) or Slack if you are interested in using SMS challenges. > Additional fees may apply. **Notifying** on an attempt will send an informational email to users and/or admins when Radar detects a suspicious behavior. This is helpful to proactively make individuals aware that an attack might be taking place, or their account was compromised. ![Radar configuration](https://images.workoscdn.com/images/f9f112c8-e731-4b8a-9e83-7bcea4527ac9.png?auto=format&fit=clip&q=50) Out of the box, Radar ships with the following detections: ### Bot detection Block or challenge sign-in attempts that are initiated by a bot or program. In addition to detecting that the client is a bot, Radar can differentiate between different types of bots such as AI agents or search engine crawlers, giving developers the ability to control which kinds of bots are restricted. ![Radar bot configuration](https://images.workoscdn.com/images/9191ad0f-e898-4044-8947-cfb388ea7952.png?auto=format&fit=clip&q=50) ### Brute force Block or challenge sign-in attempts that are part of an attempt to break into accounts using brute force. These are attacks where a bad actor is trying many sign-ins over a short period of time. Radar leverages the device fingerprint to identify and isolate bad actors from legitimate traffic, ensuring that your users can use your app even when it’s under attack. ![Radar brute force configuration](https://images.workoscdn.com/images/28988276-a698-4517-8d9b-48e75d4e1b2b.png?auto=format&fit=clip&q=50) ### Impossible travel Block or challenge sign-in attempts that occur from different geolocations in short succession. By tracking device geolocation, Radar can detect when subsequent authentication requests are spread around the globe. Radar will detect if these attempts happen over a short period where it's not possible for the person to physically travel that distance ![Radar impossible travel configuration](https://images.workoscdn.com/images/458b59af-a3e8-4646-b8a2-1bc04ae27e8e.png?auto=format&fit=clip&q=50) ### Repeat sign up Block or challenge repeat sign up attempts from the same email. By default, AuthKit fully deletes users. If your application allows for account deletion and has a free-trial, then users may be able to delete their account and sign up again to get a new free-trial. This protection restricts an email to a max of three uses before denying further sign ups. ![Radar Repeat Sign Up protection modal](https://images.workoscdn.com/images/3e4a6937-c891-4076-b2bf-a2ed829c8004.png?auto=format&fit=clip&q=50) ### Stale accounts Get notified when an account that has been dormant without use becomes active In contexts such as financial services, a dormant account becoming active might be an indication that the account has been taken over from the user and is being used for fraud. For these kinds of apps, Radar can notify the user and administrator if an account that hasn’t been used in a while has a sign-in attempt. Accounts are considered stale if there have been no successful sign-in in the past 60 days. ![Radar stale account configuration](https://images.workoscdn.com/images/f7a1a8e9-61ba-4c54-9cdb-d54ae7890092.png?auto=format&fit=clip&q=50) ### Unrecognized device Get notified when a device that has never been used before signs in to an account Using the device fingerprint, Radar checks if the device being used has been part of a successful sign-in before. If it hasn’t, both the user and an administrator can be notified by email. ![Radar unrecognized device configuration](https://images.workoscdn.com/images/f574e3d9-feed-43bc-aadb-2790cbfd2ce0.png?auto=format&fit=clip&q=50) ## Managed lists ### Disposable email domains Radar maintains a constantly updated list of email domains known to provide disposable email services. Disposable email services may be used to bypass free account or free trial limits in your application. You can choose to block or log registrations that match an email domain in this list. Logging is useful to verify no adverse impact will occur before blocking all the domains. ![Radar Disposable Email List Protection](https://images.workoscdn.com/images/33d5c007-a5c3-4451-8da2-745bb4096268.png?auto=format&fit=clip&q=50) ### U.S. Sanctioned countries Block users from countries under US Sanctions from signing up or logging into your application. Contact [support](mailto:support@workos.com) to get the current list of countries. > If you need to block a different set of countries, please reach out to support via [email](mailto:support@workos.com) or slack to configure regional blocks. > Radar supports any region in the [ISO 3166-1 specification](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes). ![Radar US sanctions country managed lists](https://images.workoscdn.com/images/a2cff432-daf6-4c8f-a192-f33071afacf5.png?auto=format&fit=clip&q=50) ## Custom restrictions Specific user identifiers can be configured to always allow or deny an authentication attempt. Examples of using a custom restrictions: - Restricting sign-ins to a corporate IP range - Allow a script with a specific user agent to bypass bot detection - Banning specific devices (i.e. iPods) from using your app - Allowing certain users to bypass detections that are false positives > Note: the allow list takes preference -- if an user matches an identifier that is in the allow list, they will bypass all other Radar rules. ![Radar restrictions configuration](https://images.workoscdn.com/images/bda02327-1d15-4e9c-b559-08b101930880.png?auto=format&fit=clip&q=50) ### Pipes Enable your customers to connect their third-party accounts to your application. ## Introduction Pipes allows your users to securely connect their third-party accounts to your application. With Pipes, you can easily integrate with popular services like GitHub, Slack, Google, Salesforce, and many more without managing OAuth flows, token refresh logic, or credential storage. > Reach out to support via [email](mailto:support@workos.com) or Slack if you are interested in early access. ## Configuring providers To make an provider available to your users, you will need to configure it in the WorkOS Dashboard. Visit the _Pipes_ section of the WorkOS Dashboard to get started. Click _Connect provider_ then choose the provider from the list. If you don’t see the provider you need, please reach out to [our team](mailto:support@workos.com). ![A screenshot of a GitHub provider being configured via the Pipes page in the WorkOS Dashboard](https://images.workoscdn.com/images/88a1f135-53ba-4d26-92ef-6c61e924e178.png?auto=format&fit=clip&q=50) ### Shared Credentials For the fastest setup, you can use WorkOS-managed shared credentials in sandbox environments. This allows users to connect immediately without requiring you to create OAuth applications with each provider. 1. Specify the required **scopes** for your application. 2. Provide an optional **description**. This will be used in the widget to inform users on how your application will use their data from the provider. ### Custom Credentials For production applications, configure the provider with your own OAuth credentials: 1. **Create an OAuth application** within the provider's dashboard. 1. You can find instructions on setting up the provider in the documentation section of the setup modal. 1. Use the provided **redirect URI** when configuring the provider. 1. Set the **client ID and secret** from the provider. 1. Specify the required **scopes** for your application. 1. You may need to set these scopes in the provider configuration as well. 1. Provide an optional **description**. This will be used in the widget to inform users on how your application will use their data from the provider. Commonly used scopes are provided in-line, but you should consult each provider's documentation for the full list of available scopes. ## Provider management in your application The [Pipes Widget](/widgets/pipes) provides a pre-built UI for users to connect and manage their connected accounts. The widget shows the user which providers are available, and lets them easily initiate the authorization flow. It communicates with the WorkOS API and stores the connection information for the user. If there's ever a problem with the user’s access token, the widget will let them know they need to reauthorize. ![Pipes widget screenshot](https://images.workoscdn.com/images/e84a33bb-0510-4d85-9041-33b1a0ce938c.png?auto=format&fit=clip&q=50) > The description in the widget is set in the provider's configuration in the WorkOS Dashboard. ## Fetching access tokens Once a user has connected a provider, you can [fetch access tokens](/reference/pipes) from your backend to make API calls to the connected service on their behalf. Pipes takes care of refreshing the token if needed, so you’ll always have a fresh token. If there’s a problem with the token, the endpoint will return information about the issue so you can direct the user to the correct it. This may require sending the user to re-authorize directly or via the page with the Pipes widget. ### Passkeys Configuring passkey authentication and enrollment. ## Introduction Passkey authentication allows users to sign up and sign in to your application using public-key cryptography, which is more secure than a traditional password. Passkeys are built on top of the [WebAuthn](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) standard that enable the user's device to securely store the passkey's private key, with access protected by biometrics, such as a fingerprint. When the user signs in, the private key is used to sign a payload that is verified with the matching public key. You can read more about how WebAuthn and passkeys work at the [official FIDO alliance passkey website](https://passkeys.dev/), the consortium behind passkey web standards. ## Passkey configuration Passkeys can be enabled in the _Authentication_ section of the [WorkOS Dashboard](https://dashboard.workos.com). ![The WorkOS Dashboard displaying the configuration dialog for passkeys](https://images.workoscdn.com/images/5ed77bef-cfa0-4a40-958f-d19b23a1ec1b.png) > **Developers should configure an [AuthKit custom domain](/custom-domains/authkit) before enabling passkeys in production**. Passkeys are bound to the domain they were registered on. Adding the domain later would prevent the usage of passkeys that were registered on the old domain. ### Enabling progressive enrollment Optionally, your users who are still using password-based authentication can be prompted to create a passkey on their next sign-in. This flow, known as "progressive enrollment", is disabled by default but can be enabled alongside passkey authentication in the WorkOS Dashboard. ![AuthKit displaying the passkey progressive enrollment prompt.](https://images.workoscdn.com/images/c541f4f6-5956-489d-be7e-c8b242c9923d.png) If users skip passkey enrollment they will be reminded every two weeks, and additionally have the option to never be prompted again if they prefer passwords. ### Multi-factor auth If [MFA](/authkit/mfa) is also enabled and required, users who sign in with a passkey will not be prompted for a separate TOTP code. AuthKit treats passkeys as both a first and second factor by requiring user verification when a passkey is presented. User verification in the context of a passkey means the passkey must be combined with another "authorization gesture", like the scanning of a fingerprint, or entering a separate PIN. --- ## Integrating via the API Passkey authentication is currently only available with the hosted UI in AuthKit. ### AuthKit Easy to use authentication APIs designed to provide a flexible, secure, and fast integration. ## Introduction WorkOS AuthKit is a user management platform that provides a set of user authentication and organization security features that securely power your application. Features are designed to be flexible, while offering a fast integration to handle all of the user management complexity that comes with advanced business and customer needs. ## Authentication AuthKit supports many authentication methods out of the box. They are designed to grow with your app, from the simplest use case all the way to complex Enterprise [SSO](/authkit/sso) for your largest customers, these include: - [Single Sign-On](/authkit/sso) - [Email & Password](/authkit/email-password) - [Social Login](/authkit/social-login) - [Multi-Factor Auth](/authkit/mfa) - [Magic Auth](/authkit/magic-auth) These features are available via [AuthKit](/authkit), or through the public [API](/reference/authkit). AuthKit provides an easy to integrate, pre-built authentication flow, while integrating against the API allows you to implement your own UI and Sign In flow. ## Fast integration The fastest way to integrate AuthKit features is with the [Hosted UI](/authkit/hosted-ui). ![AuthKit Sign In UI](https://images.workoscdn.com/images/b8286e7e-3ad9-4d43-99d5-e022e6bb36fb.png?auto=format&fit=clip&q=80) AuthKit abstracts away many of the UX and WorkOS API calling concerns automatically, allowing you to focus on building your application. See the [Quick Start](/authkit) guide for more information on how to get started. ## Security Adopting AuthKit in your app provides a wealth of security benefits. - Best-in-class [email verification](/authkit/email-verification), enabled by default. - Safe [identity linking](/authkit/identity-linking) and merging of duplicate accounts. This protects against spoofing and reduces the user support burden. - Identity Provider (IdP) differences are normalized, so that you get consistency across user profiles. This reduces the likelihood of security issues related to differing semantics across providers. - Automatic bot detection and blocking, to protect against brute force attacks. - [Multi-Factor Authentication (MFA)](/authkit/mfa) available per environment to further enhance your app’s security posture. ## Getting started Start integrating AuthKit into your app today, check out the [Quick Start](/authkit) guide to get started with AuthKit or review the [API Reference](/reference/authkit) material. ### Organization Authentication Policies Customize available authentication methods for each organization. ## Introduction Some organizations may prefer to limit their users to specific authentication methods to meet security requirements. These organization-level customizations can be configured on the organization page in the Dashboard. ## Domain policy A domain policy allows an organization to control authentication and membership behavior of users whose email domain matches one of the organization’s [verified domains](/authkit/domain-verification). Domain policies are enforced for _all_ users with email domains included in the policy, regardless of their membership status within the organization or the organization selected during sign-in. Additionally, users provisioned through a [directory](/authkit/directory-provisioning) with an email domain included in the organization's domain policy will be automatically added as active members of the organization without needing an invitation. ![Configuring a domain policy in the dashboard](https://images.workoscdn.com/images/b98493d9-f9fe-475d-a448-f9099558cd19.png?auto=format&fit=clip&q=50) > Only one organization can include a specific domain in its domain policy per environment. ### Requiring SSO by default When an SSO connection is first set up for an organization, all non-SSO authentication methods for the organization are automatically disabled. Typically, the IT admin who configures SSO intends for it to be the sole authentication method. Any additional methods can be enabled manually if the organization prefers. ## Organization policy Unlike the domain policy, which is enforced regardless of the organization selected during sign-in, the organization policy is enforced when a member selects the specific organization during sign-in. The organization policy can require authentication via its SSO connection or require MFA. This is particularly useful for guest members who do not have an organization email domain, or when the organization cannot include an email domain in its domain policy because the domain is managed by another organization. ![Configuring an organization policy in the dashboard](https://images.workoscdn.com/images/bcc25d91-602d-420f-a465-6ea790d27005.png?auto=format&fit=clip&q=50) ### Modeling Your App Learn how to architect your WorkOS integration ## Introduction WorkOS has a wide suite of products to solve your business needs. This guide explains some of the common choices when it comes to modeling your integration. WorkOS is designed to support a wide array of use cases and architectural scenarios, from simple business-to-consumer (B2C) user authentication to complex business-to-business (B2B) architectures with multiple organizations and authentication policy enforcement. Features are designed to grow with you, allowing you get started easily and expand your security options as you onboard larger and larger enterprise customers. Whether you are looking to add the initial authentication piece to a new application, or exploring migration from an existing vendor, you may find yourself asking: - Does WorkOS fit into my existing architecture? - Can I start small and later adopt more features? - I have very specific requirements, can I still use WorkOS? In most cases the answer is yes, and the aim of this guide is to help you understand how. We’ll cover the terminology used in this space, describe some common B2C and B2B flows, and finally demonstrate some scenarios that explain how everything fits together. ## Understanding the authentication flow Supporting Email + Password, Single Sign-On, OAuth, Magic Auth, and other authentication concerns on your own is a complex task. You'd need to understand the authentication process, as well as model your applications sign-in and signup user interfaces to account for and handle all possible routes, error states and edges cases. There are three main ways to add WorkOS authentication to your application: ### AuthKit A [hosted login solution](/authkit) that provides a customizable UI and supports a wide range of authentication methods. ### Custom AuthKit UI If you prefer to craft your own UI in your own stack, you can use the [AuthKit APIs](/reference/authkit) directly. ### Standalone Single Sign-On (SSO) For applications that are only interested in [SSO capabilities](/reference/sso). In the majority of cases we recommend using the hosted AuthKit solution. ![AuthKit authentication flow diagram](https://images.workoscdn.com/images/12d849cf-c710-493d-a189-48264d1c3ed7.png?auto=format&fit=clip&q=80)[border=false] On successful completion, AuthKit will return an authentication code to your application via your specified redirect URI, this is exchanged for the user object and used to create a session. See the [Quick Start guide](/authkit) for more information on how to implement this. ## Authentication methods Prior to building your integration, it is useful to think about which authentication methods are part of your requirements. Typical consumer authentication methods include the following: ### Email + Password The most common method of authentication, users sign up or sign in to your app with email and password. This method is enabled by default. ### OAuth OAuth, also known as Social Login, is when a user logs in with an account belonging to a different service. Examples include logging in with your Google, Microsoft or GitHub account instead of making a new account with your app. These authentication methods can be configured from the WorkOS dashboard. ### Magic Auth Also known as Passwordless, Magic Auth authentication works by emailing the user a unique, one-time-use 6 digit code which they then use to authenticate. A similar technique is Magic Link, where the user can log in by clicking a link emailed to them. This method has proven to be unreliable as IT teams often employ security measures that scan user emails and programmatically click any links found in the email, invalidating the Magic Links. As such, WorkOS has deprecated Magic Links in favour of Magic Auth. ### SSO The favored authentication method by enterprise sized companies, SSO allows an organization's users to sign in with a single ID to related, yet independent software systems. The AuthKit APIs make the above easy to implement using your own UI, or you can use AuthKit's Hosted UI for a fully hosted experience. ## Single-tenant and multi-tenant models You might encounter the concepts of single-tenant and multi-tenant when discussing an application’s authentication model. Single-tenant and multi-tenant architectures offer different approaches to managing resources and data in software applications, especially in cloud services or Software as a Service (SaaS) environments. ![Diagram of single and multi-tenant models](https://images.workoscdn.com/images/48ef829e-6758-4606-a696-7963beb803b2.png?auto=format&fit=clip&q=80)[border=false] ### Single-tenant In the context of authentication and authorization, single-tenant refers to a software architecture where a separate instance of the software is set up for each client on separate servers or virtual machines. Each organization is paired with its own instance of both the application and the underlying database. This approach offers full data isolation between customers, but comes at the cost of being more resource-intensive and costly. Each client’s setup may require separate maintenance, updates, and support. ### Multi-tenant Multi-tenant refers to a software architecture where a single instance of the software serves multiple customer organizations, known as tenants. Each tenant's data is isolated and remains invisible to other tenants because the software is designed to securely handle this data across all tenants. In the context of WorkOS, a multi-tenant application could be accomplished by the use of [Organizations](/reference/organization) and [Organization Memberships](/reference/authkit/organization-membership) to ensure that end-users only have access to the data they are authorized to. By default WorkOS comes with two environments: staging and production. The former is for development and testing, the latter for live traffic. For single-tenant applications, new environments can be added to your WorkOS account to accommodate each of your users. For more information or to request new environments, please reach out to [support](mailto:support@workos.com). ## Simple B2C model ![Simple B2C model](https://images.workoscdn.com/images/55ffa6da-ec2b-4f03-881c-3f68e5a2a818.png?auto=format&fit=clip&q=80)[border=false] In a simple B2C model, all users belong to the application, users do not require assignment or management by an organization in order to perform actions or access resources. In this model your customer is also the end-user, they sign up or sign in to your app in order to use your services without being associated with an organization. ### User data in B2C models It's common to have a single users table in your database linking to the WorkOS user (among other services), you may optionally decide to use WorkOS as the source of truth for other user information such as `firstName`, `lastName` or `email`, though this depends on your application requirements. In this model, WorkOS's primary role is to authenticate users and store them in a simple, flat structure. This is the default model and is the simplest to implement, but as your needs grow you may find yourself needing to add additional functionality. ## B2B modeling In contrast to the B2C example, a typical B2B model introduces the concept of Organizations. Organizations relate a set of users and provide a structure to manage and enforce authentication methods and resource access. We can extend our previous diagram to introduce this concept. ![B2B model](https://images.workoscdn.com/images/21e07368-ab1a-460e-8dcb-499d763cbdd4.png?auto=format&fit=clip&q=80)[border=false] In this model, we have a one-to-many relationship between users and organizations, a user can belong to many organizations and an organization can have many users, this relationship is expressed by our Organization Membership table. Unlike the B2C example, the customer here is a (usually enterprise) company that has its own users, typically employees or contractors. While you can still use all the authentication methods outlined above with B2C models, the main difference between B2C and B2B is that the latter tends to prefer SSO as its authentication method of choice. This model starts to become incredibly powerful as we can now capture more complex scenarios. For example, we could leverage features such as domain verification and domain policies to control authentication behavior and provision members automatically. ### Domain verification and domain policies [Domain verification](/authkit/domain-verification) is the process of proving ownership of a specific domain, typically handled by a company’s IT department. Once a domain is verified, all existing and future users with email addresses matching the domain are, by default, managed by the organization's [domain policy](/authkit/organization-policies/domain-policy). This allows the organization to control authentication and membership behavior for these users, such as requiring these users to authenticate via SSO. Users signing in with SSO with a verified email domain are automatically considered verified and do not need to complete the email verification process. ### Integrating SSO with the Admin Portal When onboarding a new enterprise customer, they will likely ask to integrate their SSO connection provided by their own Identity Provider (IdP) with your application. The Admin Portal provided by WorkOS makes this process easy to implement by providing a hosted UI that guides your user through SSO configuration. ![Admin Portal flow](https://images.workoscdn.com/images/77050e33-5dcc-480f-a0a7-3f46a6b33abf.png?auto=format&fit=clip&q=80)[border=false] With the Admin Portal, the process of configuring your customer’s SSO integration is reduced to creating an Organization in WorkOS, saving relevant data in your own database and then redirecting the user to the Admin Portal to guide them through the configuration flow. ### User data in B2B models As with B2C models, user data on the WorkOS side can be used as the source of truth, but the far more common scenario is to store user information in your own database which links to the WorkOS user. The AuthKit and SSO products can be used independently, with the latter acting as authentication middleware which intentionally does not handle user database management for your application. If you're unsure which is best for your business, it's recommended to stick with AuthKit as it gives you the aforementioned flexibility to add and/or remove features as your needs grow. ## Example scenarios As your application grows you may find yourself needing to add additional features to support customer needs. AuthKit is designed with this is mind. As you move upmarket and take on larger and larger customers, you can easily adopt and extend your feature set within an established architecture. The following scenarios explain some common use cases with specific feature sets. - [SSO with contractors](/authkit/sso-with-contractors) – Enforcing Organization SSO with external guest members. - [Invite-only Signup](/authkit/invite-only-signup) – An invite only application that allows existing users to invite new members. ### Migrating to AuthKit Guidance on moving your existing users to WorkOS. ## Introduction WorkOS provides a [range of guides](/migrate) to help you migrate your existing integration to AuthKit. ## Migrate from another service These guides will walk you through the process of moving your users and organizations to WorkOS from another service. ## Migrating an existing WorkOS integration If you already have an integration with WorkOS (for example, using the [standalone API](/sso) to provide SSO to your customers), you can migrate to AuthKit and take advantage of all of the features it provides by following [this guide](/migrate/standalone-sso). ### Multi-Factor Authentication Add an additional layer of security to your application. ## Introduction Multi-Factor Authentication (MFA) is an additional method of securing your application. MFA adds a layer of security during sign in that requires a user to provide an additional time-based one-time password (TOTP). ## Getting started AuthKit will make the necessary API calls to handle first-time configuration of users’ MFA factors automatically, and validate one-time codes as part of the authentication flow. ### Enabling MFA MFA can be enabled in the _Authentication_ section of the [WorkOS Dashboard](https://dashboard.workos.com). New and existing users will be required to set up multi-factor authentication with an authenticator app that supports one-time passcodes before they can sign in. > The MFA requirement **does not** apply to SSO users. ![Dashboard showing how to enable MFA](https://images.workoscdn.com/images/f660826c-cb2d-4912-ba10-1f622d6a447d.png?auto=format&fit=clip&q=80) ![AuthKit displaying MFA configuration](https://images.workoscdn.com/images/31fcbe12-63c2-47e2-9685-d45fe4d41fb5.png?auto=format&fit=clip&q=80) --- ## Integrating via the API If you’d prefer to build and manage your own authentication UI, you can do so via the AuthKit [Multi-Factor API](/reference/authkit/mfa). Examples of building custom UI are also [available on GitHub](https://github.com/workos/authkit). ### Metadata and External IDs Store additional information about users and organizations. ## Introduction Metadata is an attribute of organizations and users that allows you to store additional information about these objects, structured as key-value pairs. For example, you can use metadata to store information about a user's profile picture, or the organization's address. External identifiers allow you to associate organizations and users with an identifier in your own system. --- ## External identifiers External identifiers are an attribute of organizations and users that allows you to associate these objects with an identifier in your own system. Once you have set an external identifier for an object, you can query on it via dedicated endpoints in the WorkOS API. External identifiers must be unique within your environment and are limited to 64 characters. ## Metadata You can add up to 10 key-value pairs to an organization or user within these data limits: - **Key**: Up to 40 characters long. ASCII only. - **Value**: Up to 600 characters long. ASCII only. If your integration requires more than 10 key-value pairs, consider storing the additional data in your own external database and use an external identifier to associate the data with an organization or user. > Never store sensitive information in metadata such as passwords, API keys, or other private information. Metadata is returned in the response body for backend API operations that return organization or user objects, but not in the response body of the [User Authentication](/reference/authkit/authentication) operations. If you want to publicly expose metadata properties from users or organizations in your access tokens, you can use JWT templates to customize claims in your application's access tokens. ## Set an external identifier To set an external identifier for an organization or user, include the `external_id` property in the request body of the [Create an organization](/reference/organization/create) or [Create a user](/reference/authkit/user/create) endpoints. To update an external identifier, include the `external_id` property in the request body of the [Update an organization](/reference/organization/update) or [Update a user](/reference/authkit/user/update) endpoints. ## Query by external identifier To query an organization or user by their external identifier, use the [Get organization by external identifier](/reference/organization/get-by-external-id) or [Get user by external identifier](/reference/authkit/user/get-by-external-id) endpoints. ## Add and update metadata Updates to metadata are partial. This means that you only need to include the metadata attributes that you want to update. Metadata can be included in the request body of the following endpoints: - [Create an organization](/reference/organization/create) - [Update an organization](/reference/organization/update) - [Create a user](/reference/authkit/user/create) - [Update a user](/reference/authkit/user/update) To add a metadata attribute to an entity, include the key and value pair in the `metadata` object of the request body. ```json { "metadata": { "key": "value" } } ``` To update a metadata attribute, include the key and value pair in the `metadata` object of the request body. ```json { "metadata": { "key": "new_value" } } ``` To delete a metadata attribute, set the key to `null` in the `metadata` object of the request body. ```json { "metadata": { "key": null } } ``` To delete all metadata attributes, set the `metadata` property an empty object. ```json { "metadata": {} } ``` ## Exposing metadata in JWTs Custom metadata and external identifiers can be exposed as claims in JWTs using [JWT Templates](/authkit/jwt-templates). ### Model Context Protocol How to use AuthKit as the authorization server for your MCP server. ## Introduction [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) is a new protocol that standardizes how LLM-based clients can programmatically interact with applications. This includes querying data, in the form of resources, or taking direct actions in the application in the form of tools. This guide is intended for application developers implementing an MCP _server_ that requires authentication. WorkOS and AuthKit can provide a secure way to manage access to your MCP server with minimal effort. > If you have feedback or questions about MCP, we'd love to hear from you! Reach out to [WorkOS support](mailto:support@workos.com?subject=MCP%20Authentication%20with%20AuthKit) or via your team's WorkOS Slack channel. ## Authorization The MCP specification builds on industry-standard protocols like [OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc6749) in order to secure access to an MCP server. It makes the following distinctions between entities in the authorization flow: - **Resource Server** – This is your MCP server, which you may choose to build using the [official Model Context Protocol SDKs](https://github.com/modelcontextprotocol). - **Authorization Server** – This is AuthKit, which is a spec-compatible OAuth authorization server. While the spec allows the authorization and resource server to be the same, it can be architecturally simpler to delegate to an existing authorization server like AuthKit. Support for MCP authorization is built on top of [WorkOS Connect](/authkit/connect/oauth), which provides all of the necessary OAuth API endpoints MCP clients will use to authenticate. You can view your AuthKit metadata by making a request to its `/.well-known/oauth-authorization-server` endpoint: ```bash curl https://authkit_domain/.well-known/oauth-authorization-server | jq { "authorization_endpoint": "https://authkit_domain/oauth2/authorize", "code_challenge_methods_supported": ["S256"], "grant_types_supported": ["authorization_code", "refresh_token"], "introspection_endpoint": "https://authkit_domain/oauth2/introspection", "issuer": "https://authkit_domain", "registration_endpoint": "https://authkit_domain/oauth2/register", "scopes_supported": ["email", "offline_access", "openid", "profile"], "response_modes_supported": ["query"], "response_types_supported": ["code"], "token_endpoint": "https://authkit_domain/oauth2/token", "token_endpoint_auth_methods_supported": [ "none", "client_secret_post", "client_secret_basic" ] } ``` ## Integrating AuthKit handles the authentication flow so your MCP server only needs to implement the following concerns: 1. Verifying access tokens issued by AuthKit for your MCP server. 1. Direct clients to AuthKit using standardized metadata endpoints. ### Enabling Client ID Metadata Document (CIMD) MCP clients often have no prior relationship with your MCP server. The MCP protocol specifies that authorization servers (AuthKit) should support [Client ID Metadata Document](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-00) (CIMD) to allow MCP clients to identify themselves. Client ID Metadata Document is off by default, but you should enable it in the WorkOS Dashboard under _Connect_ → _Configuration_. Client ID Metadata Document was added to the MCP specification in November 2025. You can enable the previous approach, [Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591) (DCR), in the WorkOS Dashboard for backwards compatibility with MCP clients that don't yet support Client ID Metadata Document. ![A screenshot of the Connect Configuration page in the WorkOS Dashboard.](https://images.workoscdn.com/images/c0ed8f95-9b41-462d-98e8-934b8f022f22.png) ### Token Verification Your app needs to gate access to the MCP endpoints by verifying access tokens issued by AuthKit for your MCP server. This process is very similar to [the way any Connect JWT is verified](/authkit/connect/oauth/verifying-tokens), with one important addition: ```js ; const JWKS = createRemoteJWKSet(new URL('https://authkit_domain/oauth2/jwks')); const WWW_AUTHENTICATE_HEADER = [ 'Bearer error="unauthorized"', 'error_description="Authorization needed"', `resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource"`, ].join(', '); const bearerTokenMiddleware = async (req, res, next) => { const token = req.headers.authorization?.match(/^Bearer (.+)$/)?.[1]; if (!token) { return res .set('WWW-Authenticate', WWW_AUTHENTICATE_HEADER) .status(401) .json({ error: 'No token provided.' }); } try { const { payload } = await jwtVerify(token, JWKS, { issuer: 'https://authkit_domain', }); // Use access token claims to populate request context. // i.e. `req.userId = payload.sub;` next(); } catch (err) { return res .set('WWW-Authenticate', WWW_AUTHENTICATE_HEADER) .status(401) .json({ error: 'Invalid bearer token.' }); } }; ``` Note the addition of a [`WWW-Authenticate`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/WWW-Authenticate) header with the `resource_metadata` challenge parameter containing a `/.well-known/oauth-protected-resource` URL. This allows clients to dynamically discover the appropriate authorization server, enabling zero-config interoperability between different MCP clients and servers. ### Metadata Your MCP server should implement `/.well-known/oauth-protected-resource` endpoint mentioned in the previous section, returning the following minimal JSON response: ```js app.get('/.well-known/oauth-protected-resource', (req, res) => res.json({ resource: `https://mcp.example.com`, authorization_servers: ['https://authkit_domain'], bearer_methods_supported: ['header'], }), ); ``` MCP clients that support metadata discovery will automatically fetch this metadata when they initially encounter a `401 Unauthorized` error from the middleware implemented above. Since AuthKit is included in the metadata under `authorization_servers` the MCP client will redirect the user to AuthKit in order for them to sign in. ![The authorization prompt users will be shown when giving access to an MCP client.](https://images.workoscdn.com/images/ce1d133c-503c-4abc-8422-c274bbd8786c.png) Behind the scenes, AuthKit implements the necessary authorization and token endpoints so that your application doesn't need to. You can read more in the [latest version of the MCP authorization spec](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/901ac03e1c72827acb8017f80eeb14e38ad8ba42/docs/specification/draft/basic/authorization.mdx) but most apps can consider them implementation details of AuthKit as the authorization server. Upon successful authentication the client will receive credentials and can start making requests to your application's MCP endpoints. ## Compatibility The MCP space is rapidly evolving and not every client may support the latest version of the specification. In particular, some clients may not support [OAuth 2.0 Protected Resource Metadata](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-resource-metadata-13) and its `/.well-known/oauth-protected-resource` endpoint, instead attempting to fetch [OAuth 2.0 Authorization Server Metadata](https://datatracker.ietf.org/doc/html/rfc8414) directly from your application's MCP server. For these clients, your server can implement a metadata endpoint as a proxy with AuthKit as the upstream source of truth: ```js app.get('/.well-known/oauth-authorization-server', async (req, res) => { const response = await fetch( 'https://authkit_domain/.well-known/oauth-authorization-server', ); const metadata = await response.json(); res.json(metadata); }); ``` Clients will use AuthKit as the authorization server and the rest of the flow will be identical. ## Standalone MCP OAuth If you already have an existing authentication system in your application, you can use [Standalone Connect](/authkit/connect/standalone) to integrate AuthKit's OAuth capabilities with your MCP server while preserving your current authentication stack. Standalone Connect is particularly useful for MCP scenarios where you: - Want to add MCP support to an application with existing user authentication. - Need to maintain consistency with your current login experience and user management. - Require custom authentication logic. ### How it works With Standalone Connect for MCP, the authentication flow works differently from the standard AuthKit integration described above: 1. **MCP clients** initiate the OAuth flow for your MCP server with AuthKit as your authorization server. 2. **AuthKit redirects** users to your application's Login URI instead of showing AuthKit's login page. 3. **Your application** authenticates users using your existing authentication system. 4. **Your application** calls [AuthKit's completion API](/reference/workos-connect/standalone/complete) to complete the OAuth flow. 5. **AuthKit** handles the OAuth consent, token issuance, and returns control to the MCP client. This approach allows you to maintain full control over the user authentication experience while leveraging AuthKit's OAuth infrastructure for MCP client authorization. ### Implementation considerations When using Standalone Connect with MCP: - You'll still need to enable [Client ID Metadata Document](#enabling-client-id-metadata-document-cimd) to support MCP clients that register themselves. - [Token verification](#token-verification) works identically—your MCP server validates tokens using the same JWT verification process. - The [metadata endpoints](#metadata) remain the same, ensuring MCP clients can discover and interact with your server. - Your Login URI must be configured in the WorkOS Dashboard and handle the `external_auth_id` parameter from AuthKit. The key difference is in the authentication step: instead of users signing in through AuthKit's interface, they authenticate with your existing system, and AuthKit handles only the OAuth authorization and token issuance portions of the flow. For detailed implementation steps and code examples, see the [Standalone Connect documentation](/authkit/connect/standalone). ### Magic Auth Maximize user experience and security with passwordless authentication. ## Introduction Magic Auth is a passwordless authentication method that allows users to sign in or sign up via a unique, six digit one-time-use code sent to their email inbox. ## Getting started AuthKit will make the necessary API calls to issue one-time-use codes via email and provide input verification and authentication automatically. If desired, you can [send these emails yourself](/authkit/custom-emails). ### Enabling Magic Auth Magic Auth can be enabled in the _Authentication_ section of the [WorkOS dashboard](https://dashboard.workos.com). Users will then be able to sign in or sign up via Magic Auth on the AuthKit authentication page. One-time-use codes expire after **10 minutes**. ![Dashboard showing how to enable Magic Auth](https://images.workoscdn.com/images/78df279e-3bd5-451e-a0a0-7e93ed5e5bd5.png?auto=format&fit=clip&q=80) ![AuthKit displaying email sign-in](https://images.workoscdn.com/images/9129ad29-d488-462b-ad85-3a2a7908235d.png?auto=format&fit=clip&q=80) ![AuthKit displaying code input UI](https://images.workoscdn.com/images/1810724e-466f-4f76-b905-12167a051cdf.png?auto=format&fit=clip&q=80) --- ## Integrating via the API If you’d prefer to build and manage your own authentication UI, you can do so via the AuthKit [Magic Auth API](/reference/authkit/magic-auth). Examples of building custom UI are also [available on GitHub](https://github.com/workos/authkit). ### JWT Templates Customize the claims in your application's access tokens. ## Introduction JWT templates allow you to customize the claims in your application's access tokens issued by WorkOS. You can leverage core attributes of users and organizations, in addition to [custom metadata](/authkit/metadata) you set on these objects. --- ## Create a JWT template JWT templates are managed in the Authentication section of the [WorkOS Dashboard](https://dashboard.workos.com/). Under the sessions section, choose Configure JWT Template. ![WorkOS dashboard demonstrating the position of the "Configure JWT template" button](https://images.workoscdn.com/images/27daa36f-ca4e-4733-bd1b-ebb961f45454.png?auto=format&fit=clip&q=50) JWT templates are comprised of a template string which is rendered with the user and organization context after a user successfully authenticates. ## Example usage ## Syntax ### 1. **Basic Variable Interpolation** You can reference variables inside the template. ### 2. **Fallback Values** (`||` operator) If the first value is `null` or undefined, the next value in the fallback chain is used. ### 3. **String Literals** Strings can be used as fallback values. ### 4. **Concatenation in Strings** Multiple variables can be used within a single string. ### 5. **Object Interpolation** Interpolating entire objects and arrays is allowed if they are valid JSON objects. This is not allowed inside string literals and will throw a validation error. ### 6. **Reserved Keys Restriction** The following keys cannot be used in templates: - `iss` - `sub` - `exp` - `iat` - `nbf` - `jti` Any attempt to use these keys will result in a validation error. ## Whitespace Handling The rendering engine trims whitespace from the beginning and end of string values. ## Error Handling If the template contains invalid syntax, an error will be thrown: - **Template must render to an object with at least one explicitly defined top-level key:** If the template does not evaluate to a valid JSON object (e.g., an array or primitive value). Example: ```js [ {{ user.email }} ] ``` - **Keys reserved (`iss`, `sub`, `exp`, etc.):** These keys cannot be used in the template. ```js { "iss": {{ user.email }} } ``` - **String encapsulated expression cannot contain object reference:** Objects cannot be interpolated inside a string. ```js { "user": "{{ user.metadata }}" } ``` - **Invalid expression segment:** Logical operators (`||` with empty operands) or malformed expressions are not allowed. ```js {{ user.email && user user }} {{ user.email || || user.email }} ``` - **Template parse error: missing '}}':** A template block was opened but never closed. ```js {{ user.id ``` - **Expression cannot be empty:** An empty expression inside `{{ }}` is invalid. ```html {{}} ``` - **Missing closing braces:** `Template parse error: missing '}}'` - **Invalid key usage:** `Keys reserved (iss, sub, exp, etc.)` - **Unknown variables:** `Invalid path: "unknown.variable"` ## Null Handling JWT templates provide built-in handling for `null` values to ensure access tokens only contain populated claims. ### **1. Removing Top-Level Null Values** If an expression evaluates to `null`, the corresponding key is removed from the final JSON output. #### **Example** ### **2. Handling Null Values in Concatenated Strings** If a `null` value appears in a string concatenation, it is replaced with an empty string (`""`) instead of being removed. ### **3. Using Fallbacks to Avoid Null Values** The `||` operator can be used to provide a fallback value when an expression evaluates to `null`. ## Size limits JWT templates must render to a JSON object that is 3072 bytes or smaller due to cookie size constraints in web browsers. ### Just-in-time Provisioning Automatically provision users and memberships with JIT provisioning. ## Introduction JIT provisioning automatically creates users and organization memberships when a user signs in. This feature allows users to access an organization’s resources without requiring manual invitations from the IT admin. ## Automatically add users with verified domains as members Users with [verified email domains](/authkit/domain-verification) can be automatically added as members to an organization through the organization's [domain policy](/authkit/organization-policies/domain-policy). This feature is useful when an application or organization wants to automatically group individuals into the same workspace based on their email domain. ![Configuring a domain policy in the dashboard](https://images.workoscdn.com/images/b98493d9-f9fe-475d-a448-f9099558cd19.png?auto=format&fit=clip&q=50) ## SSO JIT provisioning When a user signs in, WorkOS detects when their email domain matches a verified domain of an organization and prompts the user to sign in through the organization's IdP. If the user existed in WorkOS previously, that existing user is automatically added to the organization. Otherwise, a new user is created and added to the organization. ![Configuring just-in-time provisioning for SSO users in the dashboard](https://images.workoscdn.com/images/90a85516-ed7a-4bd4-88a5-384b2f818436.png?auto=format&fit=clip&q=50) ### Guest provisioning SSO JIT provisioning is not fully supported for guests whose email domain has not been [verified](/authkit/domain-verification) by the organization. For example, an IT admin may want to gate all contractor access through their IdP (to enable access revocation across applications) but the contractor prefers to use their own email address. Instead, guest users must be [invited](/authkit/invitations) to join the organization before they are able to sign in with the organization's IdP. ## Disabling JIT provisioning Both automatic membership by email domain and SSO JIT provisioning are enabled by default but can be disabled in the [WorkOS Dashboard](https://dashboard.workos.com). Disabling these features may be useful if the IT admin prefers to manually control membership through [invitations](/authkit/invitations). ### Invite-only signup Modeling an invite-only application without a public signup page. ## Introduction In this scenario, we outline the considerations, concepts, and best practices for modeling a closed-registration application in which users may only be added to the application via an invitation. ## Goals & requirements Imagine a company that wishes to model an invite only application that requries an exclusive invite to access. The product is yet to launch, and as the initial release approaches they plan to seed memberships from a small subset of organizations and later allow existing users to invite new members from a quota. The requirements are as follows: - Signup should be unavailable to the general public. - An initial set of invites will be sent from a pre-existing mailing list. - Later, members should be able to invite other members, but only to a given quota. - Invites should be sent and accepted via email. ## Invite-only model In order to implement a invite only structure, the application must account for the following: - AuthKit must not expose sign up controls to the general public. - Invites will be performed programmatically from a seed script. - Members can invite other members via an invite UI within the application. ![Closed-registration authentication flow](https://images.workoscdn.com/images/4cb2c8f9-896d-4191-8b04-90d7bd908e6b.png?auto=format&fit=clip&q=80)[border=false] ## Disabling signup AuthKit provides an out-of-the-box signup form which handles validation UX, makes the necessary WorkOS API calls and handles the end-to-end lifecycle of the invite flow (emailing of members, accepting of invites, assignment of members to organizations where appropriate). In this scenario, the application should not expose the signup flow to the general public. It can be disabled per environment by toggling the "Sign up" setting in the authentication section of the WorkOS dashboard. ![Image of a modal in the WorkOS dashboard to disable sign-ups](https://images.workoscdn.com/images/76369560-2e4c-41bd-b3ba-1e7e1cf806e3.png?auto=format&fit=clip&q=80)[border=false] ## Inviting users User invitations can be issued in one of two ways: - Via the WorkOS dashboard. - Programmatically via the WorkOS SDK. The simplest way to get started is via the WorkOS dashboard. Invites can be created by navigating to "Invites" tab in the "Users" section of the dashboard. ![Image of a modal in the WorkOS dashboard to invite new users](https://images.workoscdn.com/images/94103735-c85e-43e2-aee1-3a46c33bf2a2.png?auto=format&fit=clip&q=80)[border=false] This is helpful in the early stages of product development where there may be a small number of potential users and the product is not yet mature enough to warrant development time spent implementing custom invitation controls, or when dealing with support requests from users who are having difficulty. ## Programmatic invitations Manually issuing invitations from the dashboard is not scalable nor always feasible when needing to issue a large number of invites, or if organic sign up growth is desired without a support team. In this case using the WorkOS API to perform and manage invitations is preferred. ### Seeding initial users from a script Typically, an application will implement a "seed" script which will be run once to issue a set of invites to a pre-existing mailing list. This can be done by using the WorkOS API to create an invite for each email address in the list. ## Inviting users within the application Custom invitation controls can be implemented within the application to allow members to invite other members. This generally requires adding a form to the UI to collect the email address of the user to invite alongside a button to trigger the API call. Additionally, a count of the number of invites a user has made might be stored and checked against a quota to ensure they don't exceed the number of invites they are allowed to send. A call can then be made to [the WorkOS API](/reference/authkit/invitation/send) by supplying the target users email address as well as the ID of the originating organization. The invited user can then accept this invite via email and move through the steps to gain access to the application. ## Summary This scenario covers some high-level considerations when thinking about closed-registration application. By using AuthKit, the WorkOS API, and the dashboard it's possible to limit signup and implement an invite flow within your application. In cases where the signup restriction is temporary, signup in AuthKit can be easily re-enabled via a setting in the WorkOS dashboard. ### Invitations Easily add users to your application or as members of an organization. ## Introduction Invitations are a way of adding a specific user to your application or as a member of an organization. They provide a flow for end-users to engage in collaboration that takes into consideration security and user choice. ## Invitation flow Each invitation is for a specific email address to a specific organization. Invitations are for both new users and existing users. Each invitation is a two step process: - The inviter expresses intent for someone to join an organization. - The invitee chooses to join that organization. ### Inviting new users to an organization If an invitation is created for an email address that does not yet exist, an email is sent to that user with a link to sign up for your application and join the organization. As part of signing up, they automatically join the organization. If a user is invited to multiple organizations, they only join the organization for which they clicked the invitation email for, indicating intent to join that specific organization. ### Inviting existing users to an organization If an invitation is for an existing user, clicking the link in the email and signing in adds the user as a member to the organization. If the user is already signed in, you can use the invitation code to validate that the signed-in user is eligible to use the invitation, by querying the [Invitation API](/reference/authkit/invitation). This offers choice for the end-user so that they aren’t automatically added to organizations that may be attempting phishing attacks. ## Application-wide invitations Invitations do not have to be specific to an organization. An invitation sent without specifying an organization is an invitation to join the application. This enables your existing users to help grow your application by inviting peers organically. When signup is disabled, users cannot register for a new account through [AuthKit](/authkit) or the [API](/reference/authkit/invitation). When a valid invitation code is present in the sign-in flow, registration is opened up both in AuthKit and the API so that a new user may sign up. This lets you model your application as a closed-registration invitation-only system. ## Sending invitations Invitations can be sent programmatically by your application with the [Invitation API](/reference/authkit/invitation), or viewed and manually created in the [WorkOS Dashboard](https://dashboard.workos.com/). By default, WorkOS sends these emails, but you can also [send the emails yourself](/authkit/custom-emails). ![Dashboard displaying a list of user invitations](https://images.workoscdn.com/images/18299a05-f824-410e-a17b-828fbe5826f1.png?auto=format&fit=clip&q=80) ## Email address used to accept an invite Often, a user might want to accept their invitation using an email address that’s different from the one that the invitation was sent to. ### Without organization membership When an invitation doesn’t include an organization to join, a user can accept the invitation using any email address. For example, an invitation sent to `user@example.com` can be used with `another-user@foo-corp.com` email address. ### With organization membership For organization-specific invitations, there are different rules based on the email domain on the invitation. - **Consumer email domains**, such as Gmail or Yahoo: the invited user must sign up using exactly the same email address to which the invitation was sent. - **Corporate domains**: the user can sign up with any email address from the same domain as the email on the invitation. For example, an invitation sent to `user@foo-corp.com` can be accepted with `another-user@foo-corp.com` ### AuthKit Easy to use authentication platform designed to provide a flexible, secure, and fast integration. ## Introduction {{ "visibility": "no-quick-nav" }} Integrating AuthKit into your app is quick and easy. In this guide, we'll walk you through adding a hosted authentication flow to your application using AuthKit. In addition to this guide, there are a variety of [example apps](/authkit/example-apps) available to help with your integration. ## Before getting started {{ "visibility": "no-quick-nav" }} To get the most out of this guide, you'll need: - A [WorkOS account](https://dashboard.workos.com/) - Your WorkOS [API Key](/glossary/api-key) and [Client ID](/glossary/client-id) Additionally you'll need to activate AuthKit in your WorkOS Dashboard if you haven't already. In the _Overview_ section, click the _Set up AuthKit_ button and follow the instructions. ![WorkOS dashboard with the AuthKit setup button highlighted](https://images.workoscdn.com/images/48aa13fa-0295-4027-8e08-e7bd14753fd3.png?auto=format&fit=clip&q=50) --- ## (1) Configure your project Let's add the necessary dependencies and configuration in your WorkOS Dashboard. ### Install dependencies - $ frontend="client-only" For a client-only approach, use the `authkit-react` library to integrate AuthKit directly into your React application. Start by installing the library to your project via `npm`. ```bash title="Install React SDK" npm install @workos-inc/authkit-react ``` - $ frontend="nextjs" For a Next.js integration, use the `authkit-nextjs` library. Start by installing it in your Next.js project via `npm`. ```bash title="Install Next.js SDK" npm install @workos-inc/authkit-nextjs ``` - $ frontend="remix" To use AuthKit with a Remix application, use the `authkit-remix` library. Start by installing it in your Remix project via `npm`. ```bash title="Install Remix SDK" npm install @workos-inc/authkit-remix ``` - $ backend="nodejs" First, install the required Node SDK via `npm`. ```bash title="Install Node SDK" npm install @workos-inc/node ``` - $ backend="ruby" First, install the WorkOS gem. ```bash title="Install Ruby SDK" gem install workos ``` - $ backend="python" First, install the Python SDK. ```bash title="Install Python SDK" pip install workos ``` ### Configure a redirect URI A redirect URI is a callback endpoint that WorkOS will redirect to after a user has authenticated. This endpoint will exchange the authorization code returned by WorkOS for an authenticated [User object](/reference/authkit/user). We'll create this endpoint in the next step. You can set a redirect URI in the _Redirects_ section of the [WorkOS Dashboard](https://dashboard.workos.com). WorkOS supports using wildcard characters in Redirect URIs, but not for the default Redirect URI. More information about wildcard characters support can be found in the [Redirect URIs](/sso/redirect-uris/wildcard-characters) guide. - $ frontend="client-only" ![Dashboard Redirect URIs](https://images.workoscdn.com/images/a7525cf3-ae4e-4dcd-91dd-27965b005472.png?auto=format&fit=clip&q=80) > For the client-only integration, make sure to set the callback URI as the same route where you require auth. - $ frontend="nextjs, remix, vanilla, react" ![Dashboard redirect URI](https://images.workoscdn.com/images/a7525cf3-ae4e-4dcd-91dd-27965b005472.png?auto=format&fit=clip&q=80) When users sign out of their application, they will be redirected to your app's [Sign-out redirect](/authkit/sessions/configuring-sessions/sign-out-redirect) location which is configured in the same dashboard area. ### Configure sign-in endpoint - $ frontend="client-only" All sign-in requests must originate at your application for the [PKCE](/reference/authkit/authentication/get-authorization-url/pkce) code exchange to work properly. In some instances, requests may not begin at your app. For example, some users might bookmark the hosted sign-in page or they might be led directly to the hosted sign-in page when clicking on a password reset link in an email. - $ frontend="nextjs, remix, vanilla, react" Sign-in requests should originate from your application. In some instances, requests may not begin at your app. For example, some users might bookmark the hosted sign-in page or they might be led directly to the hosted sign-in page when clicking on a password reset link in an email. In these cases, AuthKit will detect when a sign-in request did not originate at your application and redirect to your application's sign-in endpoint. This is an endpoint that you define at your application that redirects users to sign in using AuthKit. We'll create this endpoint in the next step. You can configure the sign-in endpoint from the _Redirects_ section of the WorkOS dashboard. ![Sign-in endpoint](https://images.workoscdn.com/images/25b53ea7-95ba-48cc-b6e7-ccd1b1bc35eb.png?auto=format&fit=clip&q=80) - $ frontend="client-only" ### Configure CORS Since your user's browser will be making calls to the WorkOS API directly, it is necessary to add your domain to the allow list in your WorkOS Settings. This can be configured in the _Configure CORS_ dialog on the _Authentication_ page of the WorkOS dashboard. ![Screenshot of the WorkOS dashboard showing the "Configure CORS" option in the "Authentication" section.](https://images.workoscdn.com/images/3b7863df-8c59-4d48-ab91-f537fd5c9f66.png?auto=format&fit=clip&q=50) While building your integration in the Staging environment you should add your local development URL here. In the example below we're adding `http://localhost:5173` to the list of allowed web origins. ![Screenshot of the WorkOS dashboard showing the CORS configuration panel.](https://images.workoscdn.com/images/e20fdbfb-965f-47b5-9c64-b83f6e6b8a39.png?auto=format&fit=clip&q=50) - $ frontend="nextjs, remix" ### Set secrets To make calls to WorkOS, provide the API key and the client ID. Store these values as managed secrets and pass them to the SDKs either as environment variables or directly in your app's configuration depending on your preferences. - $ frontend="nextjs" ```plain title="Environment variables" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' WORKOS_COOKIE_PASSWORD="" # generate a secure password here # configured in the WorkOS dashboard NEXT_PUBLIC_WORKOS_REDIRECT_URI="http://localhost:3000/callback" ``` The `NEXT_PUBLIC_WORKOS_REDIRECT_URI` uses the `NEXT_PUBLIC` prefix so the variable is accessible in edge functions and middleware configurations. This is useful for configuring operations like Vercel preview deployments. - $ frontend="remix" ```plain title="Environment variables" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' WORKOS_REDIRECT_URI="http://localhost:3000/callback" # configured in the WorkOS dashboard WORKOS_COOKIE_PASSWORD="" # generate a secure password here ``` - $ frontend="nextjs, remix" The SDK requires you to set a strong password to encrypt cookies. This password must be at least 32 characters long. You can generate a secure password by using the [1Password generator](https://1password.com/password-generator/) or the `openssl` library via the command line: ```bash title="Generate a strong password" openssl rand -base64 32 ``` - $ backend="nodejs, ruby, python" ### Set secrets To make calls to WorkOS, provide the API key and the client ID. Store these values as managed secrets and pass them to the SDKs either as environment variables or directly in your app's configuration depending on your preferences. ```plain title="Environment variables" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' ``` > The code examples use your staging API keys when [signed in](https://dashboard.workos.com) --- ## (2) Add AuthKit to your app Let's integrate the hosted authentication flow into your app. - $ frontend="client-only" ### Wrap your app with the AuthKit provider The `AuthKitProvider` component will handle the redirect from Hosted AuthKit, refresh the session when needed and provide context for hooks used in the components of your app. Initialize it with your client ID, which you can find in the WorkOS dashboard. You should also specify your custom authentication API domain. > If you have not set up a custom authentication domain in WorkOS, set `devMode={true}` on ``. This will keep the refresh token in local storage instead of a secure, HTTP-only cookie. > For security reasons, the client-only integration cannot be nested inside an `iframe`. ### Use the auth hook in your components The `useAuth` hook will return user information and loading status. It also provides functions to retrieve the access token and sign in and sign out the user. ### Protect routes with custom hooks If you have routes that you wish to only be accessible to logged in users, you can use a custom React hook. Then use that hook to protect your mandatory sign in routes. - $ frontend="nextjs" ### Provider The `AuthKitProvider` component adds protections for auth edge cases and is required to wrap your app layout. ### Middleware [Next.js middleware](https://nextjs.org/docs/app/building-your-application/routing/middleware) is required to determine which routes require authentication. #### Implementing the middleware When implementing, you can opt to use either the complete `authkitMiddleware` solution or the composable `authkit` method. You'd use the former in cases where your middleware is only used for authentication. The latter is used for more complex apps where you want to have your middleware perform tasks in addition to auth. - | Complete The middleware can be implemented in the `middleware.ts` file. This is a full middleware solution that handles all the auth logic including session management and redirects for you. With the complete middleware solution, you can choose between page based auth and middleware auth. #### Page based auth Protected routes are determined via the use of the `withAuth` method, specifically whether the `ensureSignedIn` option is used. Usage of `withAuth` is covered further down in the _Access authentication data_ section. #### Middleware auth In this mode the middleware is used to protect all routes by default, redirecting users to AuthKit if no session is available. Exceptions can be configured via an allow list. In the above example, the home page `/` can be viewed by unauthenticated users. The `/account` page and its children can only be viewed by authenticated users. - | Composable The middleware can be implemented in the `middleware.ts` file. This is a composable middleware solution that handles the session management part for you but leaves the redirect and route protection logic to you. ### Callback route When a user has authenticated via AuthKit, they will be redirected to your app's callback route. Make sure this route matches the `WORKOS_REDIRECT_URI` environment variable and the configured redirect URI in your WorkOS dashboard. ### Sign-in endpoint We'll need a sign-in endpoint to direct users to sign in using AuthKit before redirecting them back to your application. We'll do this by generating an AuthKit authorization URL server side and redirecting the user to it. ### Access authentication data AuthKit can be used in both server and client components. - | Server component The `withAuth` method is used to retrieve the current logged in user and their details. - | Client component The `useAuth` hook is used to retrieve the current logged in user and their details. ### Protected routes For routes where a signed in user is mandatory, you can use the `ensureSignedIn` option. - | Server component - | Client component ### Ending the session Finally, ensure the user can end their session by redirecting them to the logout URL. After successfully signing out, the user will be redirected to your app's [Sign-out redirect](/authkit/sessions/configuring-sessions/sign-out-redirect) location, which is configured in the WorkOS dashboard. - $ frontend="remix" ### Callback route When a user has authenticated via AuthKit, they will be redirected to your app's callback route. In your Remix app, [create a new route](https://remix.run/docs/en/main/discussion/routes) and add the following: ### Sign-in endpoint We'll need a sign-in endpoint to direct users to sign in using AuthKit before redirecting them back to your application. We'll do this by generating an AuthKit authorization URL server side and redirecting the user to it. ### Access authentication data in your Remix application We'll need to direct users to sign in (or sign up) using AuthKit before redirecting them back to your application. We'll do this by generating an AuthKit authorization URL server side and redirecting the user to it. Use `authkitLoader` to configure AuthKit for your Remix application routes. You can choose to return custom data from your loader, like for instance the sign in and sign out URLs. ### Protected routes For routes where a signed in user is mandatory, you can use the `ensureSignedIn` option in your loader. ### Ending the session Finally, ensure the user can end their session by redirecting them to the logout URL. After successfully signing out, the user will be redirected to your app's [Sign-out redirect](/authkit/sessions/configuring-sessions/sign-out-redirect) location, which is configured in the WorkOS dashboard. - $ frontend="vanilla, react" ### Set up the frontend To demonstrate AuthKit, we only need a simple page with links to logging in and out. - $ frontend="vanilla" - $ frontend="react" - $ frontend="vanilla, react" Clicking the "Sign in" and "Sign out" links should invoke actions on our server, which we'll set up next. - $ backend="nodejs, ruby, php, go, python, java" ### Add a sign-in endpoint We'll need a sign-in endpoint to direct users to sign in (or sign up) using AuthKit before redirecting them back to your application. This endpoint should generate an AuthKit authorization URL server side and redirect the user to it. You can use the optional state parameter to encode arbitrary information to help restore application `state` between redirects. - $ backend="nodejs" For this guide we'll be using the `express` web server for Node. This guide won't cover how to set up an Express app, but you can find more information in the [Express documentation](https://expressjs.com/en/starter/installing.html). - $ backend="ruby" For this guide we'll be using the `sinatra` web server for Ruby. This guide won't cover how to set up a Sinatra app, but you can find more information in the [Sinatra documentation](https://sinatrarb.com/intro.html). - $ backend="python" For this guide we'll be using the `flask` web server for Python. This guide won't cover how to set up a Flask app, but you can find more information in the [Flask documentation](https://flask.palletsprojects.com/en/stable/). - $ backend="nodejs, ruby, python" > WorkOS will redirect to your [Redirect URI](/glossary/redirect-uri) if there is an issue generating an authorization URL. Read our [API Reference](/reference) for more details. ### Add a callback endpoint Next, let's add the callback endpoint (referenced in [Configure a redirect URI](/authkit/1-configure-your-project/configure-a-redirect-uri)) which will exchange the authorization code (valid for 10 minutes) for an authenticated User object. - $ backend="nodejs" - $ backend="ruby" - $ backend="python" - $ backend="nodejs, ruby, python" ## (3) Handle the user session Session management helper methods are included in our SDKs to make integration easy. For security reasons, sessions are automatically "sealed", meaning they are encrypted with a strong password. ### Create a session password The SDK requires you to set a strong password to encrypt cookies. This password must be 32 characters long. You can generate a secure password by using the [1Password generator](https://1password.com/password-generator/) or the `openssl` library via the command line: ```bash title="Generate a strong password" openssl rand -base64 32 ``` Then add it to the environment variables file. ```plain title=".env" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' # +diff-start WORKOS_COOKIE_PASSWORD='' # +diff-end ``` ### Save the encrypted session Next, use the SDK to authenticate the user and return a password protected session. The refresh token is considered sensitive as it can be used to re-authenticate, hence why the session is encrypted before storing it in a session cookie. - $ backend="nodejs" ### Protected routes Then, use middleware to specify which routes should be protected. If the session has expired, use the SDK to attempt to generate a new one. Add the middleware to the route that should only be accessible to logged in users. ### Ending the session Finally, ensure the user can end their session by redirecting them to the logout URL. After successfully signing out, the user will be redirected to your app's [Sign-out redirect](/authkit/sessions/configuring-sessions/sign-out-redirect) location, which is configured in the WorkOS dashboard. - $ backend="ruby" ### Protected routes Then, use a helper method to specify which routes should be protected. If the session has expired, use the SDK to attempt to generate a new one. Call the helper method in the route that should only be accessible to logged in users. ### Ending the session Finally, ensure the user can end their session by redirecting them to the logout URL. After successfully signing out, the user will be redirected to your app's [Sign-out redirect](/authkit/sessions/configuring-sessions/sign-out-redirect) location, which is configured in the WorkOS dashboard. - $ backend="python" ### Protected routes Then, use a decorator to specify which routes should be protected. If the session has expired, use the SDK to attempt to generate a new one. Use the decorator in the route that should only be accessible to logged in users. ### Ending the session Finally, ensure the user can end their session by redirecting them to the logout URL. After successfully signing out, the user will be redirected to your app's Sign-out redirect location, which is configured in the WorkOS dashboard. > If you haven't configured a [Sign-out redirect](/authkit/sessions/configuring-sessions/sign-out-redirect) in the WorkOS dashboard, users will see an error when logging out. ### Validate the authentication flow Navigate to the authentication endpoint we created and sign up for an account. You can then sign in with the newly created credentials and see the user listed in the _Users_ section of the [WorkOS Dashboard](https://dashboard.workos.com). ![Dashboard showing newly created user](https://images.workoscdn.com/images/54fa6e6c-4c6f-4959-9301-344aeb4eeac8.png?auto=format&fit=clip&q=80) ### Impersonation Learn how to sign into your application as one of your users. ## Introduction Impersonation allows administrators and support team members to assume the identity of any of your users, allowing them to reproduce or debug issues the user may be having in your application. The ability to see the application in an identical state as the user helps to greatly speed up the support process. ## Enabling impersonation Since impersonation allows any member of your WorkOS team to bypass the normal authentication flow for a user, it is not enabled by default in any of your environments. You must have the **Admin** role in order to enable impersonation for an environment. ![A screenshot showing the WorkOS Dashboard configuration card for impersonation](https://images.workoscdn.com/images/bf2d2b47-1dbb-4dd2-a0e9-4d27192b6353.png?auto=format&fit=clip&q=80) Navigate to _Authentication_ → _User Impersonation_ and select _Configure_ to enable impersonation for your current environment. ## Using impersonation To impersonate one of your users, navigate to _Users_, select the user you'd like to impersonate, and under _Danger Zone_ select _Impersonate User_. ![A screenshot of the User details page in the WorkOS Dashboard](https://images.workoscdn.com/images/afcfc2b9-275c-4a08-9976-ab9b1b30a7b8.png?auto=format&fit=clip&q=80) You will be prompted for the reason your are impersonating the user. The reason is required and will be recorded internally on the `session.created` event that is emitted whenever impersonation is used. If the user is a member of more than one organization, you will also need to choose which of these organizations you will be signing-into as the user. You can read more about users and organizations in our [dedicated guide](/authkit/users-organizations). Finally, click _Impersonate user_ to start an impersonation session, redirecting your browser to your application's callback endpoint with an authorization code for the impersonated user. You can read more about how to implement a callback endpoint in our [Quick Start guide](/authkit/2-add-authkit-to-your-app/add-a-callback-endpoint). > Impersonation sessions automatically expire after 60 minutes. Be aware that impersonating a user usually generally gives the same level of access as that user, allowing the impersonator to see the user's information. If your application contains sensitive user data, see the [Integrating impersonation](/authkit/impersonation/integrating-impersonation) section about how to customize your application when using impersonation. ### Deep-linking to the impersonation flow You can deep-link to the impersonation flow in the WorkOS Dashboard from your own admin tool using the following URL structure: `https://dashboard.workos.com//users/?dialog=impersonate` ## Auditing impersonation usage User sessions that were initiated via impersonation will be clearly marked as such when viewing their details in the WorkOS Dashboard. Additionally, WorkOS emits a [`session.created`](/events/session) event which you can view under the events for the user, or listen for in your application via the [events API](/events). ![A screenshot of the User events page in the WorkOS Dashboard](https://images.workoscdn.com/images/e213fa51-4aa6-4260-8c31-84823fbcc77b.png?auto=format&fit=clip&q=80) The `session.created` event has an `impersonator` field that contains information about the impersonation session, like the `email` of your team member who performed the impersonation, along with their `reason` for doing so. ## Integrating impersonation No additional code is required to start using impersonation once you have integrated with WorkOS. However, many developers may want to augment their application's behavior when your team members are impersonating one of your users. The response from the [Authenticate with Code API](/reference/authkit/authentication/code) will include an additional `impersonator` field when the resulting session was created via impersonation, containing the impersonator's `email` and `reason` for using impersonation. Similarly, the `access_token` will include an `act` claim with the impersonator's `email`. Your application can use either in order to trigger impersonation-specific behavior. A common enhancement is to change the appearance of the application in order to make it obvious to the viewer they are currently impersonating one of your users, such as a "Staff Bar" displayed at the top of the viewport. You may also want to restrict access to sensitive views or redact certain fields in your application. ### Impersonation with `authkit-nextjs` If using the [`authkit-nextjs` library](https://github.com/workos/authkit-nextjs), impersonation can be easily added by using the provided helper component. After completing the setup instructions in the [quick start](/authkit) guide, add the Impersonation component to your app code. ```js title="Impersonation component" ; export default function RootLayout({ children }) { return ( {children} ); } ``` The above will automatically render a visually distinct frame on your page with an option to hide it or stop the impersonation session. ![A screenshot showing the Impersonation frame rendered over a page](https://images.workoscdn.com/images/c4305ab6-d4fa-4f36-be9c-5a60ee12a7b3.png?auto=format&fit=clip&q=80) ### Identity Linking Automatic deduplication of user credentials across identity providers. ## Introduction Users have unique email addresses, because each user’s access to their inbox represents ultimate access to all of their credentials and thus services they control. The [User object](/reference/authkit/user) unifies all of the identities they use so that your application does not have to consider different identity systems. Identity linking is the process in which WorkOS safely deduplicates various credentials across identity providers to offer a single, unified user interface. It does this by using the **email address** as the unique identifier and access to the email inbox as the source of truth. ## Credentials A credential is an authentication method in a specific identity provider. For example, WorkOS offers a [password credential](/authkit/email-password) for users to authenticate with. In this case, WorkOS is the identity provider and password is the authentication method. [Google OAuth](/authkit/social-login) is another credential, where Google is the identity provider and OAuth is the authentication method. Users may use multiple types of authentication methods based on preference, perhaps because one is more convenient to use on one of their devices, or they simply didn’t remember which method they used in the past. ## Email verification WorkOS ensures all user emails are unique via an [email verification process](/authkit/email-verification). By default, email verification is required by all users for authentication to succeed. This ensures that verified users are always returned to your application. When a user signs in with a new credential for the first time, e.g. they sign in through Google OAuth despite already having a password account, WorkOS will safely attach the new credential to the existing user. This is only performed if WorkOS can verify that the user has access to the email inbox referenced by that credential. WorkOS considers it a **security risk if the user cannot verify access to their email**. Some identity providers allow creating accounts with any email address. For instance, an IT admin of an organization with the domain `apple.com` could make an account for `billg@microsoft.com`. If access to `billg@microsoft.com` is not verified, the admin could sign in to the application as that user. > WorkOS does not complete the authentication flow when a new identity cannot be safely linked to an existing user to ensure account takeover risks are minimized. ## Domain verification When an IT admin [verifies a domain for their organization](/authkit/domain-verification), it means they have access to create email inboxes. Thus, a **verified domain implies the ability to verify all users with that email domain**. In practice, when a domain is verified and an SSO connection is configured, users who sign in through an organization’s IdP are automatically considered email verified if the domain matches. This shortcut reduces friction for your end users. > Users who sign-in through SSO with an email address that is not a verified domain are not considered verified and will have go through the [email verification](/authkit/email-verification) process. ## SSO identity linking Not only can a user have multiple credentials, they may also have multiple SSO credentials. This might happen when a user works with multiple organizations that require SSO authentication for all members. In this case, there is still only one [User object](/reference/authkit/user), but they would choose which organization’s SSO IdP to use when authenticating. ![Example UI showing organization selection](https://images.workoscdn.com/images/876aeb05-cd96-46b4-9adf-3e9dd0208e47.png?auto=format&fit=clip&q=80) The email verification safety still applies. When the user signs-in for the first time through an SSO IdP where the user’s email address is not a verified domain, the user is asked to verify their email before the SSO credential is linked to their account. Users without a verified domain **must be invited to the organization** before they have access via SSO for the first time. > An [invitation](/authkit/invitations) ensures that the authentication flow gives the user an opportunity to go to the SSO’s identity provider. ### Hosted UI Customizable sign-in UI that abstracts away all of the complexity associated with building secure authentication flows. ## Introduction Implementing authentication flows that handle every possible error state and edge case across multiple identity providers can be a daunting task. AuthKit makes this easy by providing a hosted, pre-built, customizable authentication UI with automatic handling of: - Sign up, sign in, password reset, and [email verification](/authkit/email-verification) flows. - Enterprise [SSO](/authkit/sso) routing and [MFA](/authkit/mfa) enrollment. - Automatic bot detection and blocking, to protect against brute force attacks. - Customizable [domain](/custom-domains/authkit) and [branding](/authkit/branding). ![AuthKit sign-in UI](https://images.workoscdn.com/images/4d736ca3-eec8-4a90-bd14-2530c4210415.png?auto=format&fit=clip&q=80) ## Authentication flow AuthKit is conceptually similar to a [Social Login (OAuth)](/authkit/social-login) experience, but with the added benefit of being able to authenticate users with any identity provider. AuthKit sits outside of your application code. When a user initiates a sign-in request, your application redirects them to the AuthKit URL. The user then completes the authentication process with WorkOS before being returned to the application. Your application will exchange the resulting authorization code to retrieve an authenticated [User object](/reference/authkit/user) and handle the session. ![AuthKit authentication flow diagram](https://images.workoscdn.com/images/0b3265fa-a209-4ca7-beaf-7d2514a3e00a.png?auto=format&fit=clip&q=80)[border=false] > The AuthKit flow abstracts away many of the UX and WorkOS API calling concerns automatically, for more guidance on integrating with AuthKit, see the [Quick Start](/authkit) guide. AuthKit also provides a signup flow for creating users. Available options are determined by the configured [authentication methods](/authkit/hosted-ui/authentication-methods). If a user’s email address is associated with an SSO connection, they will automatically be redirected to sign up via their IdP. ## Authentication methods AuthKit's hosted UI supports all of the authentication methods available and will automatically adjust the available options depending on the configured methods in the _Authentication_ section of the [WorkOS Dashboard](https://dashboard.workos.com). ![Dashboard displaying available authentication methods](https://images.workoscdn.com/images/ea3b2c3b-723e-462c-aa10-6b1cec1b635f.png?auto=format&fit=clip&q=80) Email + Password authentication is enabled by default, though set up may be required to enable additional methods. See the relevant feature section for more information: - [Single Sign-On](/authkit/sso) - [Email + Password](/authkit/email-password) - [Social Login](/authkit/social-login) - [Multi-Factor Auth](/authkit/mfa) - [Magic Auth](/authkit/magic-auth) ## Localization By default, AuthKit's hosted UI is automatically localized into many global languages. Your users will be served in the locale that closest matches their device's OS preference. All user-facing text, including error messages and transactional emails, are translated into the user's native tongue. - ### Supported locales | Locale code | Language | Autonym | | ----------- | ----------------------- | ----------------------- | | `af` | Afrikaans | Afrikaans | | `am` | Amharic | አማርኛ | | `ar` | Arabic | العربية | | `bg` | Bulgarian | Български | | `bn` | Bengali (Bangla) | বাংলা | | `bs` | Bosnian | Bosanski | | `ca` | Catalan | Català | | `cs` | Czech | Čeština | | `da` | Danish | Dansk | | `de` | German | Deutsch | | `de-DE` | German (Germany) | Deutsch (Deutschland) | | `el` | Greek | Ελληνικά | | `en` | English | English | | `en-AU` | English (Australia) | English (Australia) | | `en-CA` | English (Canada) | English (Canada) | | `en-GB` | English (UK) | English (UK) | | `en-US` | English (US) | English (US) | | `es` | Spanish | Español | | `es-419` | Spanish (Latin America) | Español (Latinoamérica) | | `es-ES` | Spanish (Spain) | Español (España) | | `es-US` | Spanish (US) | Español (EE.UU.) | | `et` | Estonian | Eesti | | `fa` | Farsi (Persian) | فارسی | | `fi` | Finnish | Suomi | | `fil` | Filipino (Tagalog) | Filipino | | `fr` | French | Français | | `fr-BE` | French (Belgium) | Français (Belgique) | | `fr-CA` | French (Canada) | Français (Canada) | | `fr-FR` | French (France) | Français (France) | | `fy` | Frisian | Frysk | | `gl` | Galician | Galego | | `gu` | Gujarati | ગુજરાતી | | `ha` | Hausa | هَرْشٜن هَوْس | | `he` | Hebrew | עברית | | `hi` | Hindi | हिन्दी | | `hr` | Croatian | Hrvatski | | `hu` | Hungarian | Magyar | | `hy` | Armenian | Հայերեն | | `id` | Indonesian | Bahasa Indonesia | | `is` | Icelandic | Íslenska | | `it` | Italian | Italiano | | `it-IT` | Italian (Italy) | Italiano (Italia) | | `ja` | Japanese | 日本語 | | `jv` | Javanese | ꦧꦱꦗꦮ | | `ka` | Georgian | ქართული | | `kk` | Kazakh | Қазақ тілі | | `km` | Khmer | ខេមរភាសា | | `kn` | Kannada | ಕನ್ನಡ | | `ko` | Korean | 한국어 | | `lt` | Lithuanian | Lietuvių | | `lv` | Latvian | Latviešu | | `mk` | Macedonian | Македонски | | `ml` | Malayalam | മലയാളം | | `mn` | Mongolian | Монгол | | `mr` | Marathi | मराठी | | `ms` | Malay | Bahasa Melayu | | `my` | Burmese | မြန်မာ | | `nb` | Norwegian Bokmål | Norsk Bokmål | | `ne` | Nepali | नेपाली भाषा | | `nl` | Dutch | Nederlands | | `nl-BE` | Flemish | Vlaams | | `nl-NL` | Dutch (Netherlands) | Nederlands (Nederland) | | `nn` | Norwegian Nynorsk | Norsk Nynorsk | | `no` | Norwegian | Norsk | | `pa` | Punjabi | ਪੰਜਾਬੀ | | `pl` | Polish | Polski | | `pt` | Portuguese | Português | | `pt-BR` | Portuguese (Brazil) | Português (Brasil) | | `pt-PT` | Portuguese (Portugal) | Português (Portugal) | | `ro` | Romanian | Română | | `ru` | Russian | Русский | | `sk` | Slovak | Slovenčina | | `sl` | Slovenian | Slovenščina | | `sq` | Albanian | Shqip | | `sr` | Serbian | Српски | | `sv` | Swedish | Svenska | | `sw` | Swahili | Kiswahili | | `ta` | Tamil | தமிழ் | | `te` | Telugu | తెలుగు | | `th` | Thai | ไทย | | `tr` | Turkish | Türkçe | | `uk` | Ukrainian | Українська | | `ur` | Urdu | اُردُو | | `uz` | Uzbek | Ózbekça | | `vi` | Vietnamese | Tiếng Việt | | `zh` | Chinese | 中文 | | `zh-CN` | Chinese (Simplified) | 中文 (中国) | | `zh-HK` | Chinese (Hong Kong) | 中文(香港) | | `zh-TW` | Chinese (Taiwan) | 中文(台灣) | | `zu` | Zulu | isiZulu | In cases where a user's browser does not send their preferred locale, or when AuthKit cannot identify a match, the user is served in the environment's **fallback language**. The fallback language can be configured [in the dashboard](https://dashboard.workos.com/environment/authentication/features) in the _Authentication > Features > Localization_ section. ![With localization, you can change the environment's fallback language](https://images.workoscdn.com/images/bb8c017b-f9cd-4882-baa2-b38e01a51875.png?auto=format&fit=clip&q=50) ## Integrating Integration into your app is quick and easy, though the route you choose varies depending on your specific requirements: ### (A) Integrate with AuthKit's Hosted UI In just a few lines of code, you can add AuthKit to your app and start authenticating users. See the [quick start](/authkit) guide for more information. ### (B) Build your own authentication flows While the hosted solution is the fastest way to get started, if you’d prefer to build and manage your own authentication UI, you can do so via the [AuthKit API](/reference/authkit). Examples of building custom UI are [available on GitHub](https://github.com/workos/authkit). ### Example apps View sample AuthKit apps. You can view minimal example apps that demonstrate how to use AuthKit to authenticate users: ### Email Verification Learn more about the email verification process. ## Introduction Email verification is a process in which a new user must validate ownership of their email inbox before they can access the application, ensuring authenticity of inbox ownership. ## The email verification flow Verification is a two-step process: - A user signs up to your application and an email is sent with a verification code. - The user inputs the verification code to complete the signup process. This applies to all authentication methods including [OAuth](/authkit/social-login) and [SSO](/authkit/sso). This unifying interface simplifies how your application considers the authenticity of your users. **Email verification is always on** to ensure that verified users are always returned to your application. ## Users with verified email domains Users signing in with SSO with a [verified domain](/authkit/domain-verification) are automatically considered verified and do not need to complete the email verification process. ## Sending verification emails [AuthKit](/authkit) automatically handles email verification out of the box. When a user signs up via the hosted signup form, AuthKit will automatically send the verification email, prompt the user to input the code and route them through the authentication process before they gain access to the application. If desired, you can [send these emails yourself](/authkit/custom-emails). ### Email + Password Configuring email and password authentication and requirements. ## Introduction Email + Password authentication allows users to sign up and sign in to your application using an email address and password combination. This is one of the most common forms of authentication and is enabled by default. ## Password configuration In the majority of cases, no additional configuration is required. However, depending on your application's security requirements you may wish to modify the password strength policy. ### Modifying the password strength policy A strong set of password rules are applied to all users by default. This ensures that: - All passwords meet a minimum required length - Low complexity passwords are rejected - Breached passwords (flagged by [haveibeenpwned](https://haveibeenpwned.com)) are rejected These defaults are recommended in the majority of cases, however, if you wish to modify the password policy you can do so in the _Authentication_ section of the [WorkOS dashboard](https://dashboard.workos.com). You can enable password history to prevent password reuse. When modifying your policy, you can reject up to 10 of each user’s most recently used previous passwords. Password history is disabled by default. AuthKit will enforce your policy within the sign up and password reset flows. ![Dashboard password strength policy](https://images.workoscdn.com/images/d9ab3375-78b8-4dc4-a15c-76af2fad671e.png?auto=format&fit=clip&q=80) ### Disabling Email + Password Disabling this method entirely will prevent users from signing up or signing in using a password. This is useful when you want to restrict access to your application to only those users who have been provisioned via SSO. --- ## Integrating via the API If you’d prefer to build and manage your own authentication UI, you can do so via the AuthKit [Authentication API](/reference/authkit/authentication). Examples of building custom UI are also [available on GitHub](https://github.com/workos/authkit). ### Domain Verification Verify organization domains for secure authentication and provisioning. ## Introduction Domain verification allows IT admins to prove they control specific domains. This allows WorkOS to trust actions from users with the verified domain and enables authentication and membership policy enforcement for those users. Verifying an organization domain enables the following features: 1. Users with the verified domain who sign in with the organization’s SSO connection don't need to [verify their email](/authkit/email-verification). 2. By default, users with the verified domain are managed by the organization's [domain policy](/authkit/organization-policies/domain-policy), allowing for enhanced control over authentication and membership. ## Self-serve domain verification Domain verification can be delegated to the [Admin Portal domain verification flow](/domain-verification). This out-of-the-box UI guides the IT admin to add a DNS TXT record to prove domain ownership. Once the DNS TXT record is correctly added, the organization domain is automatically verified. ## Manual domain verification Verified domains may also be added manually via the [WorkOS Dashboard](https://dashboard.workos.com) or [API](/reference/organization/update). This shortcut is useful if the IT admin has already proven domain ownership in another context. > Manually verified domains can be used to define a domain policy that applies to any users with email addresses on that domain. The organization that defines this [domain policy](/authkit/organization-policies/domain-policy) exerts authentication policy control over that domain across your application. For this reason, it is important to verify ownership of manually added domains. Additionally, WorkOS does not allow addition of common consumer domains, like `gmail.com`. ![Adding a verified domain in the dashboard](https://images.workoscdn.com/images/c015b42d-fc39-453c-a4c9-1be220c88a37.png?auto=format&fit=clip&q=80) ### Directory Provisioning Manage users and organization memberships via directory sync providers. > Please reach out to [support@workos.com](mailto:support@workos.com) or via your team’s WorkOS Slack channel if you would like Directory Provisioning enabled. ## Introduction Directory provisioning gives IT admins full control over user and membership management, eliminating the need for manually adding or removing members. Users from a directory are pre-provisioned and managed by their [Identity Provider](/glossary/idp). ## Initial configuration A [Directory Sync](/directory-sync) integration will need to be configured for every organization that wants to source users and memberships via directory provisioning. Directories can be set up via the [WorkOS Dashboard](https://dashboard.workos.com/) with [Setup Links](/admin-portal/a-setup-link-from-workos-dashboard). You can also [integrate the Admin Portal with your app](/admin-portal/b-integrate-with-your-app) to generate links to configure directories. ### Supported directory providers Directory provisioning is supported for all SCIM directory providers, Google Workspace, and SFTP. ## Provision users from a directory Users provisioned through a directory with an email domain matching a verified organization domain will be automatically added as members of the organization, without needing an invitation. Other users are created with `pending` memberships and receive an email [invitation](/authkit/invitations) to join the organization. Pending members cannot sign in until the invitation is accepted, at which point they become active organization members. > [Invitation emails](/authkit/custom-emails/disabling-default-emails) can be disabled if you prefer to manage invitations with a custom approach. ## Manage users from a directory In addition to provisioning new users, any updates to existing users and de-provisioning events will be reflected in AuthKit. Users with email addresses matching one of the organization’s verified domains are fully managed by the directory. Updates to their attributes from the directory will override changes made through SSO, the API, or manually in the dashboard. > If multiple organizations with directory provisioning contain the same verified domain, the user's name will always reflect the most recent directory update. Other users, with email domains not verified by the organization, will not be fully managed by the directory, so updates made via SSO, API, or manually in the dashboard will persist. When a user is de-provisioned in the directory, the [status](/reference/authkit/organization-membership) of their corresponding organization membership will be set to `inactive`. While the user will no longer be able to sign in to the organization, the membership and user are not automatically deleted. If a user is re-provisioned in the directory, their organization membership will be reactivated with its previous role and its [status](/reference/authkit/organization-membership) will be set to `active`. ## Directory provisioning actions Below is a list of directory provisioning and deprovisioning actions and the corresponding changes triggered in AuthKit. If you're using standalone Directory Sync, refer to the [standalone Directory Sync documentation](/directory-sync/api-overview/directory). | Directory Action | Changes triggered in WorkOS | Event(s) Emitted | | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | | Directory user provisioned | [User](/reference/authkit/user) and [organization membership](/reference/authkit/organization-membership) objects created. | [user.created](/events/user), [organization_membership.created](/events/organization-membership) | | Directory user info updated | If the user's email domain matches one of the organization's verified domains, any updates to the user's name will be reflected on the [user](/reference/authkit/user) object. Otherwise, the user object will not be modified. User email address is always immutable. | [user.updated](/events/user) | | Directory user deprovisioned | Organization membership deactivated and all sessions for the user are revoked. Their role is reset to the default role. | [organization_membership.updated](/events/organization-membership) | | Directory user reactivated | Organization membership reactivated. | [organization_membership.updated](/events/organization-membership) | --- ## Frequently asked questions ### I am using directory provisioning, but some directory users aren't being provisioned in AuthKit. Why would a directory user not be provisioned in AuthKit? Directory users need to have a primary email address to be provisioned in AuthKit. If the directory user is missing a primary email, they won't be provisioned. Additionally, if the primary email of a directory user is shared by another directory user, only one will be provisioned in AuthKit, as emails are unique to AuthKit users. ### If a user's email is changed in the directory, will this change be reflected on the user's email in WorkOS? The email address on the [User object](/reference/authkit/user) is immutable, but the email on the underlying [directory user](/reference/directory-sync/directory-user) object will be modified. ### Custom Emails Learn how to send your own emails for user lifecycle events. ## Introduction By default, WorkOS will send emails related to AuthKit for you, such as password reset and Magic Auth. If you'd like to customize email content or have more control over deliverability, you can turn off the default emails and deliver your own emails using the WorkOS API. --- ## Disabling default emails To change email settings for an environment, navigate to _Authentication_ → _Emails_ and select _Configure emails_. You should have an **Admin** role for to update this setting. ![A screenshot showing the WorkOS Dashboard configuration card for emails](https://images.workoscdn.com/images/01c99f2b-8813-4c72-9480-9898e1dabd4a.png?auto=format&fit=clip&q=80) ![A screenshot showing the WorkOS Dashboard dialog for email settings](https://images.workoscdn.com/images/7b4f4713-3381-49aa-b77c-679c9698b429.png?auto=format&fit=clip&q=80) --- ## Invitations Once you've turned off the default user invitation emails, use the information below to send custom invitation emails. **[invitation.created](/events/invitation)** : Event emitted when an invitation is created, which can be consumed using the events API or webhooks. **[Get Invitation API](/reference/authkit/invitation/get)** : Used to retrieve the invitation object from the ID in the invitation created event. **[Send Invitation API](/reference/authkit/invitation/send)** : Used to create an invitation via the API without handling the invitation created event. ### Set up your user invitation URL {{ "visibility": "no-quick-nav" }} Make sure you have the correct user invitation URL set on your _Redirects_ page. The default setting is the AuthKit URL for accepting invitations. If you are using your own authentication UI, make sure the URL path is configured on your end to capture the `invitation_token` query parameter, and [pass it into one of the authenticate methods](/reference/authkit/authentication/code). ![A screenshot showing the WorkOS Dashboard configuration card for user invitation URL](https://images.workoscdn.com/images/540542e4-8fd8-4a0f-8715-b5ae1715d46e.png?auto=format&fit=clip&q=50) ### (A) Handle manually creating invitations {{ "visibility": "no-quick-nav" }} If you’re creating invitations using the WorkOS dashboard, you’ll need to handle `invitation.created` events using the events API or webhooks. Due to security concerns, the events do not contain the sensitive information you’ll need to send the email. To retrieve the full invitation object with this information, use the invitation ID from the event to call the Get Invitation API. You can skip this step if you don't plan to create the invitations manually in the dashboard. ### (B) Handle invitations created via the API {{ "visibility": "no-quick-nav" }} If you’re creating invites via the Send Invitation API, you can send your own email using the information returned in the invitation object. If you also plan to create invitations manually in the dashboard, you can just handle `invitation.created` events as described above. ### Send your email {{ "visibility": "no-quick-nav" }} The recipient of the email should match the `email` attribute in the invitation object retrieved via the API. The body of the email should include a link where the user can accept the invitation. For most use cases, you can use the `accept_invitation_url` as this link. If you are building your own authentication app, and your invitation acceptance path diverges from this pattern, you may want to construct your own URL with the `token`, rather than using the `accept_invitation_url`. Additionally, if the invitation object contains an organization ID and/or an inviter user ID, you may want to include that information in the body of the email. --- ## Magic Auth Once you've turned off the default Magic Auth emails, use the information below to send custom Magic Auth emails. **[magic_auth.created](/events/magic-auth)** : Event emitted when a user initiates a Magic Auth authentication, which can be consumed using the events API or webhooks. **[Get Magic Auth API](/reference/authkit/magic-auth/get)** : Used to retrieve the Magic Auth object from the ID in the Magic Auth created event. **[Create Magic Auth API](/reference/authkit/magic-auth/create)** : Used to create a Magic Auth code via the API without handling the Magic Auth created event. ### (A) Handle Magic Auth codes created via AuthKit {{ "visibility": "no-quick-nav" }} If you are using AuthKit, you’ll need to handle `magic_auth.created` events, using the events API or webhooks. Due to security concerns, the events do not contain the sensitive information you’ll need to send the email. To retrieve the full Magic Auth object with this information, use the Magic Auth ID from the event to call the Get Magic Auth API. You can skip this step if you're building your own authentication app. ### (B) Handle Magic Auth codes created via the API {{ "visibility": "no-quick-nav" }} If you’re initiating Magic Auth authentication via the Create Magic Auth API, you can send your own email using the information returned in the Magic Auth object. ### Send your email {{ "visibility": "no-quick-nav" }} The recipient of the email should match the `email` attribute for the Magic Auth object retrieved via the API, and the email should include the `code`. Recipients will input that code into AuthKit, or your own authentication UI, to authenticate into your application via Magic Auth. --- ## Email verification Once you've turned off the default email verification emails, use the information below to send custom email verification emails. **[email_verification.created](/events/email-verification)** : Event emitted when a user requires email verification, which can be consumed using the events API or webhooks. **[Get Email Verification API](/reference/authkit/email-verification/get)** : Used to retrieve the email verification object from the ID in the email verification created event. **[Email Verification Required error](/reference/authkit/authentication-errors/email-verification-required-error)** : Returned in the API when attempting to authenticate a user that requires email verification. ### (A) Handle email verification codes created via AuthKit {{ "visibility": "no-quick-nav" }} If you are using AuthKit, you’ll need to handle `email_verification.created` events, using the events API or webhooks. Due to security concerns, the events do not contain the sensitive information you’ll need to send the email. To retrieve the full email verification object with this information, use the email verification ID from the event to call the Get Email Verification API. You can skip this step if you're building your own authentication app. ### (B) Handle email verification codes created via the API {{ "visibility": "no-quick-nav" }} If you are using the [authentication API](/reference/authkit/authentication), an `email_verification_required` error will be returned if the user you're authenticating needs to verify their email. This error contains an `email_verification_id` that can be used to call the Get Email Verification API endpoint which returns the email verification object that contains the information needed to send the email. ### Send your email {{ "visibility": "no-quick-nav" }} The recipient of the email should match the `email` attribute for the email verification object retrieved via the API, and the email should include the `code`. Recipients will input that code into AuthKit, or your own authentication UI, to verify their email. --- ## Password reset Once you've turned off the default password reset emails, use the information below to send custom password reset emails. **[password_reset.created](/events/password-reset)** : Event emitted when a user requests to reset their password, which can be consumed using the events API or webhooks. **[Get Password Reset API](/reference/authkit/password-reset/get)** : Used to retrieve the password reset object from the ID in the password reset created event. **[Create Password Reset API](/reference/authkit/password-reset/create)** : Used to create a password reset object via the API without handling the password reset created event. ### Set up your password reset URL {{ "visibility": "no-quick-nav" }} Make sure you have the correct password reset URL set on your _Redirects_ page. The default setting is the AuthKit URL for resetting passwords. If you are using your own authentication UI, make sure the URL path is configured on your end to capture the `token` query parameter, and [use it to reset the password](/reference/authkit/password-reset/reset-password). ![A screenshot showing the WorkOS Dashboard configuration card for password reset URL](https://images.workoscdn.com/images/2b6abd95-459b-4f33-aab5-8217f412aed2.png?auto=format&fit=clip&q=50) ### (A) Handle password resets created via AuthKit {{ "visibility": "no-quick-nav" }} If you are using AuthKit, you’ll need to handle `password_reset.created` events, using the events API or webhooks. Due to security concerns, the events do not contain the sensitive information you’ll need to send the email. To retrieve the full password reset object with this information, use the password reset ID from the event to call the Get Password Reset API. You can skip this step if you're building your own authentication app. ### (B) Handle password resets created via the API {{ "visibility": "no-quick-nav" }} If you’re creating password resets via the Create Password Reset API, you can send your own email using the information returned in the password reset object. ### Send your email {{ "visibility": "no-quick-nav" }} The recipient of the email should be the `email` attribute in the password reset object retrieved via the API. The body of the email should include a link where the user can reset their password. For most use cases, you can use the `password_reset_url` as this link. If you're building your own authentication app, and your password reset path diverges from this pattern, you may want to construct your own URL with the `password_reset_token`, rather than using the `password_reset_url`. ### Custom Email Providers Learn how to send emails through your own email service provider. ## Introduction By default, WorkOS will send emails via our default email service provider, either through our domain or through your own [custom email domain](/custom-domains/email). If you would like to have more control over deliverability, reputation, and compliance, while still offloading the heavy lifting of email handling, you can configure a custom email provider. This option is also ideal if you already have an existing email service provider configuration. --- ## Configure a custom email provider To configure a custom email provider for an environment, navigate to [_Emails_ → _Providers_](https://dashboard.workos.com/environment/emails/providers) and click _Enable_ next to the provider you would like to use and enter the required information. > If the email service provider you'd like to use is not listed, please [contact support](mailto:support@workos.com). ![A screenshot showing the WorkOS Dashboard email providers page](https://images.workoscdn.com/images/660bd317-6240-40ce-8cb7-d80dccac294a.png?auto=format&fit=clip&q=80) ### Amazon SES To connect WorkOS to Amazon SES, you'll need to [create an IAM user](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html) with an access key, and [verify email sending identities](https://docs.aws.amazon.com/ses/latest/dg/creating-identities.html). Ensure the IAM user has a policy like the following: ```json { "Version": "2012-10-17", "Statement": [ { "Sid": "SendEmailAccess", "Effect": "Allow", "Action": "ses:SendEmail", "Resource": [ "arn:aws:ses:::identity/*", "arn:aws:ses:::configuration-set/*" ] }, { "Sid": "IdentityManagementAccess", "Effect": "Allow", "Action": ["ses:GetIdentityVerificationAttributes", "ses:ListIdentities"], "Resource": "*" } ] } ``` You'll need to update the resource scope with your Amazon SES region and account ID. For additional ways to restrict access, refer to the [Amazon SES documentation](https://docs.aws.amazon.com/ses/latest/dg/control-user-access.html). > If you're interested in using temporary security credentials to access Amazon SES, please [contact support](mailto:support@workos.com). Once you have an IAM user with the necessary permissions and have verified sending identities, you can configure the Amazon SES custom email provider in the [WorkOS Dashboard](https://dashboard.workos.com/): ![A screenshot showing the WorkOS Dashboard Amazon SES custom email provider configuration](https://images.workoscdn.com/images/4df55e43-d68c-410c-9452-32978e0ca874.png?auto=format&fit=clip&q=50) ### Mailgun Before configuring the Mailgun custom email provider in WorkOS, you'll need to [verify your domain in your Mailgun account](https://help.mailgun.com/hc/en-us/articles/32884700912923-Domain-Verification-Setup-Guide). Once you've verified a domain, you'll need an API key, which you can create on the [API Security page of the Mailgun dashboard](https://app.mailgun.com/settings/api_security). The API key is used to validate verified domains in your account and send emails. ![A screenshot showing the Mailgun API Security page](https://images.workoscdn.com/images/fc6d06dd-790e-419e-ba0d-5a1783e8748d.png?auto=format&fit=clip&q=80) Once you've verified your domain and obtained an API key, you can configure the Mailgun custom email provider in the [WorkOS Dashboard](https://dashboard.workos.com/): ![A screenshot showing the Mailgun custom email provider configuration](https://images.workoscdn.com/images/5e287a26-7851-49f5-95b5-bc74ab58b506.png?auto=format&fit=clip&q=80) ### Postmark Before configuring the Postmark custom email provider in WorkOS, you'll need to [verify sender signatures in your Postmark account](https://postmarkapp.com/developer/user-guide/managing-your-account/managing-sender-signatures). Once you've verified a sender signature, you'll need an account and server token, which you can find on the [API Tokens page of the Postmark dashboard](https://postmarkapp.com/account/api-tokens). ![A screenshot showing the Postmark API Tokens page](https://images.workoscdn.com/images/e441ca41-2768-4887-83f1-8f298ab25847.png?auto=format&fit=clip&q=50) The account token is used to validate sender signatures in your account, and the server token is used to send emails. Once you've verified your sender signature and obtained your account and server token, you can configure the Postmark custom email provider in the [WorkOS Dashboard](https://dashboard.workos.com/): ![A screenshot showing the Postmark custom email provider configuration](https://images.workoscdn.com/images/21f94d07-b661-4a24-9e2b-940cd0bbfdaa.png?auto=format&fit=clip&q=50) Upon enabling the Postmark custom email provider, a WorkOS transactional message stream with the ID `workos-transactional-s` will be created for you. All WorkOS emails will be sent using this message stream. ### Resend Before configuring the Resend custom email provider in WorkOS, you'll need to [verify domains in your Resend account](https://resend.com/docs/dashboard/domains/introduction). Once you've verified your domain, you'll need to create an API key with the "Full access" permission on the [Resend API Keys page](https://resend.com/api-keys). ![A screenshot showing creating an API key in the Resend dashboard](https://images.workoscdn.com/images/ce0ae76c-7ab4-4506-9e48-78a61243a42d.png?auto=format&fit=clip&q=50) "Full access" permission is required to fetch verified domains and send emails. Once you've verified your domain and obtained an API key, you can configure the Resend custom email provider in the [WorkOS Dashboard](https://dashboard.workos.com/): ![A screenshot showing the Resend custom email provider configuration](https://images.workoscdn.com/images/25efadf6-405f-416b-aaa0-7e7fb266034a.png?auto=format&fit=clip&q=50) ### SendGrid Before configuring the SendGrid custom email provider in WorkOS, you'll need to verify your domain in the [Sender Authentication settings in your SendGrid dashboard](https://app.sendgrid.com/settings/sender_auth). Once you've verified your domain, you'll need to create an API key under _Settings_ → _API Keys_ in the [SendGrid dashboard](https://app.sendgrid.com/settings/api_keys). ![A screenshot showing the SendGrid API Keys side panel](https://images.workoscdn.com/images/61bf31b4-0e7f-4616-988f-69319d542866.png?auto=format&fit=clip&q=50) For API key permissions, select "Full Access" for Mail Send, and "Read Access" for Sender Authentication. Once you've verified your domain and obtained an API key, you can configure the SendGrid custom email provider in the [WorkOS Dashboard](https://dashboard.workos.com/): ![A screenshot showing the SendGrid custom email provider configuration](https://images.workoscdn.com/images/4502c8ad-2bdf-481b-82a7-0d8829032da4.png?auto=format&fit=clip&q=50) --- ## Re-enable the WorkOS default provider At any time when you are using a custom email provider, you can re-enable the WorkOS default provider by navigating to [_Emails_ → _Providers_](https://dashboard.workos.com/environment/emails/providers) and clicking _Enable_ next to the WorkOS provider. ![A screenshot showing re-enabling the WorkOS default provider](https://images.workoscdn.com/images/7b4f4713-3381-49aa-b77c-679c9698b429.png?auto=format&fit=clip&q=80) Alternatively, you can also remove your current custom email provider, which will automatically re-enable the WorkOS default provider. ![A screenshot showing removing a custom email provider](https://images.workoscdn.com/images/7b4f4713-3381-49aa-b77c-679c9698b429.png?auto=format&fit=clip&q=80) --- ## Frequently asked questions ### What types of emails are sent through custom email providers? All transactional emails for your users will be sent through your custom email provider when configured. This includes AuthKit invitations and magic codes, Radar challenges, and Admin Portal notification emails. ### If I am using a custom email provider, do I need to set up a custom email domain in WorkOS? No. When using a custom email provider, you configure the sending domain in that provider, not in WorkOS. Any custom email domain set up in WorkOS will not be used. ### What happens if emails fail to send via my custom email provider? If emails fail to send via your custom email provider, you will be notified according to your notifications preferences via the [WorkOS Dashboard](https://dashboard.workos.com/), email, or Slack. You can also utilize the [_Emails_ → _Events_ page](https://dashboard.workos.com/environment/emails/events) in the WorkOS Dashboard to track email delivery failures. ### Connect Enable other applications to access your users and their identities. ## Introduction Connect is a set of controls and APIs that developers can use to allow different types of applications to access their users' identity and resources. Connect is built on top of industry-standard specifications like OAuth 2.0 and OpenID Connect in order to support many common use-cases out of the box. Unlike AuthKit's other features that help users sign into **your application**, Connect enables **other applications** to authenticate and access your users' data through secure, managed APIs. ## Common use-cases **Customer applications** : Enable your customers to build custom integrations with your platform. This can include allowing them to add a "Sign in with [your app]" button on their login page. **Auxiliary applications** : Allow secondary applications that support your primary application, such as support tools or discussion forums, to authenticate using the same user identities in AuthKit. **Partner integrations** : Issue credentials for trusted partners to authenticate with when calling your application's API. ## Getting started Each Connect integration is defined as an Application, which can be created inside of the WorkOS Dashboard. When creating an application, you first choose the type of integration: **OAuth** or Machine-to-Machine (**M2M**). ### OAuth applications Select OAuth when building web or mobile applications where the actor being authenticated is a [User](/reference/authkit/user). Integrating with an OAuth application uses the underlying `authorization_code` OAuth flow which is supported by many libraries and frameworks out of the box. Upon successful authorization, the issued tokens will contain information about the user who signed in. [Learn more about OAuth applications →](/authkit/connect/oauth) ### M2M applications Select M2M when the application will be a third-party service, such as one of your customer's applications. Integrating with an M2M application uses the underlying `client_credentials` flow. Unlike OAuth applications, the actor being authenticated is not an individual user. Instead issued access tokens will contain an `org_id` claim which represents the customer you are granting access to via the M2M application. The M2M application will use its `client_id` and `client_secret` to authenticate requests to your application's API or services. [Learn more about M2M applications →](/authkit/connect/m2m) ## Concepts All Connect applications share the following concepts: ### Participants When using Connect, there are several actors involved with the integration of each Application: - **Relying Party**: The application that receives Connect-issued tokens and identity information. It may also use the access token to make requests to your API. - **Resource server**: The service (generally your app) that allows other clients to authenticate using the Connect-issued tokens. - **Authorization server**: This is Connect, the issuer of identity and access tokens to requesting clients after authenticating the user. ### Credentials Applications can have up to 5 credentials. These are only shown once upon creation and do not expire. The application `client_id` and `client_secret` from a credential can be used to authenticate to the [Connect APIs](/reference/workos-connect). When sharing app credentials with an external party, use a secure method — like encrypted email or file sharing — and make sure the recipient is properly authenticated. ### CLI Auth Quickly add authentication to your command-line application. ## Introduction CLI Auth enables your command-line applications to authenticate users through the web via your WorkOS app. Based on the [OAuth 2.0 Device Authorization Flow](https://datatracker.ietf.org/doc/html/rfc8628), this flow is optimized for devices that lack a web browser or have limited input capabilities. With CLI Auth, your command-line app requests a device authorization from WorkOS, which includes a code for the user and a code for your app. After the user confirms the code, your app can exchanges its device code for tokens. ## (1) Request device authorization To begin the authentication flow, your CLI application makes a request to the `/authorize/device` endpoint to obtain the necessary codes and URLs for user authentication. After you get a response, your app can provide next steps to the user. ![Screenshot of a command-line application showing login information](https://images.workoscdn.com/images/89680848-5c40-4ba1-860f-a7212cfbb47b.png?auto=format&fit=clip&q=50) Your application should display the `user_code` from the response, along with the `verification_uri` in the terminal. If you offer the ability to open in a browser easily like in this screenshot, we suggest using the `verification_uri_complete` for that. Never display the `device_code` to the user. That is only for the device to poll the token endpoint. ## (2) User confirms the code Next the user needs to confirm the code in their browser. ### (A) Manual code entry If the user navigates to the `verification_uri`, they'll be presented with a form to enter the code manually. If they are not logged in they'll be prompted to do that first and then returned to the code entry screen. ![Screenshot of the manual-code-entry form in AuthKit](https://images.workoscdn.com/images/03c1961a-547a-4886-bb9a-2f080dd31ca9.png?auto=format&fit=clip&q=50) ### (B) One-click confirmation If the user goes to the `verification_uri_complete`, (for example, `https:///device?user_code=ABCD-EFGH`, they'll instead need to confirm that the code matches what is displayed in the terminal. ![Screenshot of the pre-filled code-confirmation form in AuthKit](https://images.workoscdn.com/images/3e02f36c-0dea-4ff4-9dc5-a2f2fa964114.png?auto=format&fit=clip&q=50) ## (3) Request tokens While the user is completing authentication in their browser, your CLI application should poll the token endpoint to check for authorization completion. Make requests to the token endpoint using `device_code` from the authorization response from step 1: ### Polling best practices - Poll at the interval specified in the authorization response (every 5 seconds) - Respect `slow_down` errors by increasing your polling interval - Stop polling when you receive `access_denied` or `expired_token` errors - Implement a reasonable timeout to avoid infinite polling ## Connect CLI Auth is available for [Connect](/authkit/connect/oauth) applications, allowing you and third-party developers to build CLI tools that integrate with your app's credentials. The flow is the same but uses Connect endpoints: - **Authorization**: `https:///oauth2/device_authorization` - **Token**: `https:///oauth2/token` Since command-line applications are distributed to end users, you should avoid embedding the client secret in the app. To make this work, set up your Connect app as a [_Public_ application](/authkit/connect/oauth/public-applications). Third-party Connect applications will require users to [grant consent](/authkit/connect/oauth/first-party-vs-third-party-applications) to the third-party app. ### Branding Customize AuthKit to fit natively with your app’s unique design. ## Introduction You can customize the look and feel of AuthKit via the _Branding_ section of the [WorkOS Dashboard](https://dashboard.workos.com/branding). The brand editor allows you to: - Upload logos and favicons - Set brand colors for buttons, links, and backgrounds - Manage visual properties such as page layouts, corner radius, and dark mode appearance - Include custom copy, images, and links to your app’s terms-of-service and privacy policy - Preview auth screens and emails in various languages, and translate custom text into every supported locale The AuthKit preview will update in real-time as you make changes and accurately reflect the available authentication methods, giving you a clear picture of the authentication experience with AuthKit. ![Branding in the Dashboard](https://images.workoscdn.com/images/fc67ec10-44e1-467c-a094-32ed3ff5bd92.png?auto=format&fit=clip&q=80) ## Custom domains WorkOS supports custom domains for both email and [ACS URLs](/glossary/acs-url). For for information, see the [custom domains documentation](/custom-domains). ## Appearance AuthKit supports both light and dark mode; each brand configuration option is split across both so that they can be configured independently. You can enforce a specific appearance, or allow the user’s OS system settings to determine which to use. The corner radius applied to UI elements can also be configured; a lower value will result in a more formal aesthetic while a higher value has a more rounded, playful feel. ![Appearance options highlighted in the branding editor](https://images.workoscdn.com/images/3465072a-87a2-46cc-8577-4e9d4213009a.png?auto=format&fit=clip&q=50) ## Font Family You can customize the font family used across AuthKit pages to match your brand's typography. The font family selector allows you to choose from a wide variety of Google Fonts to align with your product's brand. Only Google Fonts are supported for font family customization. This ensures optimal loading performance and reliability across all devices and browsers. ![Font family options in the branding editor](https://images.workoscdn.com/images/4db463c8-4eb6-414d-801b-e7460407b238.png?auto=format&fit=clip&q=80) ## Assets You can upload custom brand assets to display in AuthKit, transactional emails, and the [Admin Portal](/admin-portal). ![Asset options highlighted in the branding editor](https://images.workoscdn.com/images/2a6e77b6-c1fe-4850-a95b-f3e7b7d8bf87.png?auto=format&fit=clip&q=50) There are three types of assets you can upload: 1. **Logo:** Your full size brand logo, styles vary but this would typically include the wordmark. Must be at least 160x160 px (JPG, PNG, or SVG. 100 KB max size) 2. **Logo icon:** A smaller, square version of the logo. This is often simply the logomark. Must be at least 160x160 px with a 1:1 aspect ratio (JPG, PNG, or SVG. 100 KB max size) 3. **Favicon:** A small icon that serves as branding for your website. It is often displayed in the browser tab alongside the address bar. Must be at least 32x32 px with a 1:1 aspect ratio (JPG, PNG, GIF, SVG, WebP, AVIF, or ICO. 100 KB max size) ### Logo style Either the logo or the logo icon can be displayed in AuthKit. To select which to use, click the logo in the AuthKit preview after uploading both assets. ![Logo selection dialog open in the branding editor](https://images.workoscdn.com/images/2fbd9b69-3434-412b-ab53-e73568f3eb9a.png?auto=format&fit=clip&q=50) ## Color You can control four colors across light and dark mode: - Page background color - Button background colors - Button text color - Link color Other colors used in the UI, like the focus outline, hover styles, or borders, are created automatically based on the four colors you provide, ensuring a consistent look and feel. ![Color options in the branding editor](https://images.workoscdn.com/images/b6a2eb40-2510-4e54-bdca-0c91953fb84d.png?auto=format&fit=clip&q=50) ## Localization You can preview how your auth pages and emails appear in various different languages. AuthKit is [localized](/authkit/hosted-ui/localization) in many languages by default, and users are served in their preferred language automatically. To preview your brand in different languages, use the language picker in the AuthKit preview pane. ![A preview of a user-facing email, translated in Spanish](https://images.workoscdn.com/images/663ee483-a14c-420b-9ba5-5c4c1f277b2c.png?auto=format&fit=clip&q=50) ## Copy The page title and alternate action link text on AuthKit pages can be customized to fit your brand’s tone of voice. They can be edited directly inside the AuthKit preview pane. > An _alternate action_ refers to the action a user will take to navigate between AuthKit pages. For example, if a user is on the sign-in page and they don’t have an account, the alternate action will navigate to the signup page. Start by selecting the page you want to edit. Then, click on the text you want to change from the preview pane. ![AuthKit page selector in the branding editor](https://images.workoscdn.com/images/6b2c0b3d-9f2f-404f-a893-23c3ec8a2d6f.png?auto=format&fit=clip&q=50) ![Text customization highlighted in the branding editor](https://images.workoscdn.com/images/07734ffb-c639-4abd-8d99-bd1feb9d5eda.png?auto=format&fit=clip&q=50) When you edit copy in English, it automatically gets translated into [every supported language](/authkit/hosted-ui/localization). A loading indicator appears next to the language picker during this process. After you save, your users will be served the translation that closest matches their locale. ## Page settings AuthKit pages can optionally display a link to your app’s privacy policy and/or terms-of-service. The link will then appear below the authentication form. AuthKit also allows you to choose whether or not first name and last names are required when signing up. To toggle either of these, select the _Page Settings_ panel and update the respective field. ![Page settings in the branding editor](https://images.workoscdn.com/images/6b2e6b35-5658-42ab-8c6a-6b6aa0d9b381.png?auto=format&fit=clip&q=80) ## Page layout The layout for AuthKit pages can be customized to fit your brand’s needs. You can choose between a centered, one-column layout, or a two-column layout using [custom HTML and CSS](#custom-code-details-and-limitations) for the secondary column. ![Page settings in the branding editor](https://images.workoscdn.com/images/70acf0d4-caf8-435e-bedd-1960e8cd27c4.png?auto=format&fit=clip&q=80) ### Split layouts Split page layouts allow you to add a secondary panel on AuthKit pages that can be customized with HTML and CSS. This can be used to display marketing content or decorative elements on the page. To enable this feature, select the page you want to customize. Then, select the _Split_ layout option under _Page Settings_. The secondary panel can be displayed to the left or right of the primary panel, and optionally hidden on mobile devices. ![Split layout setting in the branding editor](https://images.workoscdn.com/images/057b92eb-bf5d-4832-b8c3-33f470e766f1.png?auto=format&fit=clip&q=80) Click on the secondary column from the preview pane. This will open a dialog where you can enter your HTML and CSS. > Note: content in the content panel will not automatically be [localized](/authkit/hosted-ui/localization). ![Custom code editor dialog in the branding editor](https://images.workoscdn.com/images/e0c512c9-dee0-470b-aa55-7d89c1b44a5c.png?auto=format&fit=clip&q=80) ### Custom code details and limitations Any HTML and CSS entered into the custom code dialog will only be applied to the secondary column of the selected page. This allows you a high level of flexibility without impacting content elsewhere on the page. For security purposes, all code input is sanitized and stripped of any potentially harmful elements. This means that you can’t use JavaScript or any other dynamic content in your HTML. This includes `script`, `iframe`, `form`, and `object` elements—as well as inline event handlers for any elements. For example, the following code will be sanitized from this: ```html Welcome to SuperApp const onClick = () => alert('Warning!'); ``` …to this: ```html Welcome to SuperApp ``` HTML `style` elements will also be removed to prevent overriding any content outside of the secondary panel. All custom CSS should be entered into the CSS editor. CSS selectors will be scoped to the secondary column via [CSS nesting](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting/Using_CSS_nesting). For compatibility with older browsers, we use a light transform step to convert the nested CSS to a flat structure. For example, the following CSS will be transformed from this: ```css h1 { color: var(--primary-color); } ``` …to this: ```css :where([data-hak-custom-html]) h1 { color: var(--primary-color); } ``` ## Last used sign-in badge AuthKit sign-in pages can optionally display a _Last used_ badge on an authentication method. This will indicate the most recent sign-in method for the user. The badge is shown by default and only shown when multiple sign-in methods are available. ![AuthKit Last used sign-in badge](https://images.workoscdn.com/images/2f0e3778-08f3-4eb4-b590-0b39ff92e0d7.png?auto=format&fit=clip&q=50) ## Custom CSS For more granular control over AuthKit branding, element styles can be overridden using custom CSS. Custom CSS applies globally across all AuthKit pages to ensure consistency across the entire authentication experience. It does not affect emails or Admin Portal. > AuthKit is powered by [Radix](https://www.radix-ui.com/) which has built-in accessibility and dark mode. If overriding styles, please make sure to test thoroughly, especially if removing original element styles. ![AuthKit Custom CSS in the brand editor](https://images.workoscdn.com/images/0f48c7f3-b99c-417a-bee9-2e54780515df.png?auto=format&fit=clip&q=80) ### Customize a specific page Target specific pages using the `data-hak-page` attribute selector: ```css .ak-Header { /* focus-start */ [data-hak-page='sign-up'] & { .ak-Heading { font-size: 3rem; line-height: 1; } } /* focus-end */ } ``` - #### List of all available pages **`sign-in`** : Main sign-in page **`sign-in/password`** : Password-based sign-in **`sign-in/passkey/enroll`** : Passkey enrollment during sign-in **`sign-up`** : Main signup page **`sign-up/password`** : Password-based signup **`sign-up/passkey`** : Passkey-based signup **`sign-up/magic-auth`** : Magic link signup **`sign-up/registration`** : Custom registration form **`oauth`** : OAuth provider selection **`magic-code`** : Magic code verification **`magic-code/send`** : Magic code request form **`mfa/enrollment`** : MFA setup/enrollment **`mfa/verification`** : MFA code verification **`email-verification`** : Email verification page **`radar-challenge`** : Fraud detection challenge **`radar-challenge/send`** : Phone number input for SMS challenge **`radar-challenge/verify`** : SMS verification code input **`invite`** : Invitation acceptance page **`reset-password`** : Password reset flow **`organization-selection`** : Organization picker **`device`** : Device activation page **`device/success`** : Successful device connection **`device/denied`** : Device connection denied **`application-authorization`** : App consent/authorization page **`default-redirect`** : Default redirect after successful auth **`not-found`** : 404 error page **`auth-disabled`** : Authentication disabled message ### Light and dark theme Use the [light-dark](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark) CSS function to easily target both light and dark themes with a single declaration: ```css .ak-PrimaryButton { /* focus-start */ color: light-dark(#333333, #f0f0f0); /* focus-end */ } ``` For more control, target the parent theme selectors directly: ```css .ak-Background { /* focus-start */ .dark-theme & { background: linear-gradient(0deg, #333, #111); } .light-theme & { background: linear-gradient(0deg, #fff, #ccc); } /* focus-end */ } ``` > Media queries targeting `prefers-color-scheme` are not supported – use only the `.dark-theme` and `.light-theme` selectors. ### Nested selectors AuthKit provides intelligent autocomplete support for CSS selectors. When you type a period (`.`) in the custom CSS editor, a popover will automatically appear showing available nested selectors for AuthKit elements, making it easier to target specific components and their child elements. ![Nested CSS selectors](https://images.workoscdn.com/images/e8e41033-9e08-40c5-bfc9-0e223b1bd890.png?auto=format&fit=clip&q=80) ### Examples #### Custom background image You can use external images as background images by specifying the URL in the `background-image` property. ```css .ak-Background { /* focus-start */ background-image: url('https://i.imgur.com/HO2EBgR.jpeg'); background-size: cover; /* focus-end */ } ``` #### Reorder OAuth buttons You can target an individual provider button by its `data-method` attribute. ```css .ak-AuthButton { /* focus-start */ /* Display Microsoft OAuth button first */ &[data-method='microsoft'] { order: -1; } /* focus-end */ } ``` #### Adding custom text Use CSS pseudo-elements to add custom text content. Custom text content in CSS cannot be [localized](/authkit/hosted-ui/localization). To learn how to automatically localize the text of your custom headings and links, read the [Copy](/authkit/branding/copy) section. ```css .ak-Header { /* focus-start */ &::after { content: 'Sub heading'; display: block; } /* focus-end */ } ``` > Some elements may already style the `::before` and `::after` pseudo-elements, so test your changes carefully. ### API Keys Provide secure, self-service API key management to your customers. ## Introduction API keys provide a secure way for your application's users to authenticate with your API. With the [API Keys Widget](/widgets/api-keys), your customers can create and revoke [organization](/authkit/users-organizations/organizations)-scoped API keys with a simple component. The WorkOS API and SDKs provide functions for your API code to validate keys. API keys are one of two ways WorkOS enables you to issue credentials to your customers that they use to programmatically access your application. The other is [M2M applications](/authkit/connect/m2m). The [API Keys vs M2M Applications guide](https://workos.com/blog/api-keys-vs-m2m-applications) can help you decide which is best for your use case. ## Configuring API keys Before your users can manage API keys, you need to configure your WorkOS environment. ### Setting up role permissions To enable API key management for your users, ensure at least one role includes the `widgets:api-keys:manage` permission. This permission allows users to access the [API Keys Widget](/widgets/api-keys) and manage keys within their organization. You can [assign permissions to roles](/authkit/roles-and-permissions/configure-roles-and-permissions/assign-permissions-to-roles) in the WorkOS Dashboard under _Roles & Permissions_. ### Configuring available permissions You can control which permissions your users can assign to API keys by configuring API key permissions in your environment. For example, you might create permissions like: - `posts:read` - Read access to posts - `posts:write` - Write access to posts - `users:read` - Read access to user data By configuring only `posts:read` and `posts:write` as available API key permissions, your users can create API keys with granular access controls, such as read-only keys that only have the `posts:read` permission. You can configure API key permissions in the WorkOS Dashboard on the _Roles & Permissions_ page under _Organization API Key Permissions_. ## API key management in your application The easiest way to enable API key management for your users is through the [API Keys Widget](/widgets/api-keys). This widget provides a complete interface for creating, viewing, and revoking API keys. The widget allows your users to: - Create new API keys with custom names - Select specific permissions for each key - View existing API keys (with obfuscated values for security) - Revoke API keys when they're no longer needed The widget interacts with the WorkOS API and renders the user interface in your app, so your customers get full control over their API keys in just a few lines of code. ## Validating API keys Once your users have created API keys through the widget, your application needs to validate these keys when they're used to authenticate API requests. When an API request includes an API key (typically in the `Authorization` header), your application should validate it with WorkOS to ensure it's legitimate and retrieve the associated permissions. The [validate API key endpoint](/reference/authkit/api-keys/validate) returns the complete [API key object](/reference/authkit/api-keys), including: - The organization that owns the key - The permissions assigned to the key - Usage metadata like creation and last-used timestamps This information allows your application to not only authenticate the request but also authorize it based on the specific permissions granted to that API key. ## Viewing organization API keys in the WorkOS Dashboard You can view and revoke your customers' API keys through the WorkOS Dashboard: 1. Navigate to the **Organizations** section in your WorkOS Dashboard 2. Click on the organization you want to view 3. Select the **API Keys** tab From this view, you can see all API keys created by the organization, including their names, permissions, creation dates, and last usage information. This provides valuable visibility into how your customers are using API keys. ## Auditing API key usage API key lifecycle changes are tracked via the [`api_key.created`](/events/api-key) and [`api_key.revoked`](/events/api-key) events. You can view these events in the [events page](https://dashboard.workos.com/environment/events) or listen for them in your application via the [events API](/events). ### Actions Customize authentication flows with your own logic. ## Introduction Actions allow you to change the behavior of various flows within the WorkOS platform including user registration and authentication using your own custom logic. When an action is configured for a particular request type, WorkOS synchronously calls the associated action endpoint and waits for a response that allows or denies the operation. When WorkOS calls an actions endpoint, the request includes contextual metadata such as the profile of the user performing the operation, the organization associated with the operation, or the IP address, all of which you can use for decisioning within the endpoint. ### Action types WorkOS allows you to configure actions that execute during various user operations: - **Authentication**: Authentication actions run after a user completes Email + Password, Magic Auth authentication, SSO, or Social Login and before they are redirected to your application. - **User registration**: User registration actions run after a user attempts to register for your application using Email + Password, Magic Auth sign up, SSO, or Social Login and before they are provisioned. ## Configuring actions To configure actions, you'll need to: - Host an actions endpoint that receives requests from WorkOS - Register your endpoints with WorkOS - Implement the custom logic of your endpoint - Test your endpoints ## Set up your endpoint Create a public endpoint that WorkOS can make requests to. This endpoint should use HTTPS and should accept POST requests with the `workos-signature` header. This header is used for verifying the request's authenticity from WorkOS. > WorkOS sends the header as `WorkOS-Signature`, but many web servers normalize HTTP request headers to their lowercase variants. --- ## Register your endpoint Set the actions endpoint URL in the [WorkOS Dashboard](https://dashboard.workos.com/). Set _Enable action_ and choose **Save changes**. ![WorkOS Dashboard Actions UI](https://images.workoscdn.com/images/84c8a62b-d8bc-4c46-8ccd-eda4c245645e.png?auto=format&fit=clip&q=80) ### Choosing error handling behavior Each actions endpoint must specify its error handling behavior. By default, if there is an issue reaching your endpoint or validating the response, WorkOS will deny the operation. If this is not the desired behavior for your use case, you can choose a different behavior depending on the action endpoint type; for example, for authentication actions, you can choose _Allow authentication_. --- ## Implement your endpoint Upon receiving a request, you should respond with an `HTTP 200 OK` as well as a valid response body to signal to WorkOS that the request was successfully handled. ### (A) Validate the requests using the SDK Before processing the request payload, verify the request was sent by WorkOS and not an unknown party. WorkOS includes a unique signature in each actions request that it sends, allowing you to verify the authenticity of the request. In order to verify this signature, you must obtain the secret that is generated for you when you set up your actions endpoint in the WorkOS dashboard. Ensure that this secret is stored securely on your actions endpoint server as an environment variable. The SDKs provide a method to validate the timestamp and signature of an actions. Examples using these methods are included below. The parameters are the payload (raw request body), the request header, and the actions secret. There is an optional parameter, tolerance, that sets the time validation for the actions request in seconds. The SDK methods have default values for tolerance, usually 3–5 minutes. ### (B) Validate the requests manually If implementing actions request validation yourself, you’ll need to use the following steps: First, extract the timestamp and signature from the header. There are two values to parse from the `WorkOS-Signature` header, delimited by a `,` character. | Key | Value | | ------------------ | ----------------------------------------------------------------------------------------------- | | `issued_timestamp` | The number of milliseconds since the epoch time at which the event was issued, prefixed by `t=` | | `signature_hash` | The HMAC SHA256 hashed signature for the request, prefixed by `v1=` | To avoid replay attacks, we suggest validating that the `issued_timestamp` does not differ too much from the current time. Next, construct the expected signature. The expected signature is computed from the concatenation of: 1. `issued_timestamp` 2. The `.` character 3. The request’s body as a utf-8 decoded string Hash the string using HMAC SHA256, using the actions secret as the key. The expected signature will be the hex digest of the hash. Finally, compare signatures to make sure the actions request is valid. Once you’ve determined the event request is validly signed, it’s safe to use the event payload in your application’s business logic. ### Create an IP allowlist WorkOS sends actions requests from a fixed set of IP addresses. It’s recommended to restrict access to your actions endpoint to only these IP addresses: ```plain title="WorkOS IP addresses" 3.217.146.166 23.21.184.92 34.204.154.149 44.213.245.178 44.215.236.82 50.16.203.9 52.1.251.34 52.21.49.187 174.129.36.47 ``` --- ## Build the endpoint response The endpoint must respond with a signed JSON object indicating a `verdict` of `Allow` or `Deny` as well as an optional `error_message` in the event the `verdict` is `Deny`. Based on the payload data received, you can determine whether to allow or deny the operation. Each action type receives a different payload model, so be sure to handle the appropriate data in your handler. ### (A) Respond using the SDK The SDK provides a method to create the signed response. ### (B) Respond manually If implementing the construction of the actions response yourself, you’ll need to use the following steps: First, store the current epoch timestamp to a variable. Next, construct the JSON response. The JSON response must contain the following: - `timestamp`: The epoch timestamp you recorded - `verdict`: Indicates whether to allow or deny the action. Allowed values: `'Allow' | 'Deny' | 'allow' | 'deny'` - `error_message`: An optional, 500 character maximum string. This should only be provided with a `verdict` of `deny` or `Deny` Next, construct the signature. The expected signature is computed from the concatenation of: 1. The current epoch timestamp 2. The `.` character 3. The JSON response body as a utf-8 encoded string Hash the string using HMAC SHA256, using the actions secret as the key. The expected signature will be the hex digest of the hash. Finally, the endpoint should respond with a JSON object containing the following properties: - `object`: `'authentication_action_response' | 'user_registration_action_response'` - `payload`: The JSON response you formed above - `signature` The hex digest of the hash you created above ## Test your endpoint From the dashboard, you can send test actions after configuring an endpoint. Go to the actions _Test_ tab and click the **Send test action** button. ![A screenshot showing how to send a test action in the WorkOS dashboard.](https://images.workoscdn.com/images/8d998ae0-2efa-435a-9818-6873fcdc73ac.png?auto=format&fit=clip&q=80) If you would like to test against your local development environment, we recommend using a tool like [ngrok](https://ngrok.com) to create a secure tunnel to your local machine, and sending test webhooks to the public endpoint generated with ngrok. See our [blog post](https://workos.com/blog/test-workos-webhooks-locally-ngrok) to get more details on how you may want to test webhooks locally with ngrok. --- ### Standalone Connect Integrate Connect's OAuth API with your existing authentication stack. ## Overview Standalone Connect allows applications with existing authentication systems to use AuthKit as their OAuth authorization server. You maintain your existing authentication stack while leveraging AuthKit's OAuth infrastructure for token issuance and management. Unlike standard AuthKit integration, Standalone Connect delegates authentication to your application, then handles the OAuth flow and token issuance for OAuth clients. This feature works with [OAuth applications](/authkit/connect/oauth) only—[M2M applications](/authkit/connect/m2m) use the `client_credentials` flow which doesn't involve user authentication. ## When to use Standalone Connect Use Standalone Connect when you: - Have an existing authentication stack in your application. - Need to enable OAuth-based integrations, like a [CLI](/authkit/cli-auth) app or [MCP](/authkit/mcp) server. - Want to support third-party applications accessing your users' resources. ## Getting started ### Create an OAuth application Before testing your Standalone Connect integration, you'll need to [create an OAuth application](/authkit/connect/oauth) in the WorkOS Dashboard. If you need to support MCP auth, you'll need to enable Client ID Metadata Document (CIMD), which you can read more about in the [MCP guide](/authkit/mcp). ### Configure your Login URI Navigate to _Connect_ → _Configuration_ in the [WorkOS Dashboard](https://dashboard.workos.com) and provide your **Login URI**. The **Login URI** is where AuthKit will redirect users to authenticate with your existing system. You can only configure one Login URI per environment. Your Login URI must: - Use HTTPS in production. - Accept an `external_auth_id` query parameter. - Authenticate users with your existing system. - Call the AuthKit completion API after successful authentication. More on that below. Example: `https://your-app.example.com/auth/login` ## Authentication flow ### (1) OAuth client initiates flow OAuth clients start the authorization flow with AuthKit following standard OAuth 2.0. This could be a third-party application, partner integration, or any OAuth-enabled client. ### (2) AuthKit redirects to your application AuthKit redirects users to your Login URI with an `external_auth_id` parameter: ```txt https://your-app.example.com/auth/login?external_auth_id=01J3X4Y5Z6A7B8C9D0E1F2G3H4 ``` The `external_auth_id` is a temporary identifier used to complete the flow with AuthKit. ### (3) Authenticate the user Your application authenticates users with your existing system. If users have an active session, skip to the next step. AuthKit handles OAuth consent separately, so your application doesn't need to display any consent screens. ### (4) Complete authentication with AuthKit Call the [AuthKit completion API](/reference/workos-connect/standalone/complete) after authenticating the user, passing the `external_auth_id` that your Login URI originally received: ```js const response = await fetch('https://api.workos.com/authkit/oauth2/complete', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.WORKOS_API_KEY}`, }, body: JSON.stringify({ external_auth_id: externalAuthId, user: { id: user.id, email: user.email, first_name: user.firstName, last_name: user.lastName, metadata: { department: user.department }, }, }), }); const { redirect_uri } = await response.json(); ``` ### (5) Return control to AuthKit Redirect users to the `redirect_uri` from the API response. AuthKit displays a consent screen if needed, issues tokens, and completes the OAuth flow. ## Integrating via the API ### Dynamic consent options You can provide `user_consent_options` to display options during the OAuth consent screen. This is useful when users need to choose specific resources or contexts (like a parent resource in your application) to grant access to. Each consent option must include: - `claim`: The name of the access token claim that will hold the user's selected value. - `type`: The format of the option. Only `enum` is supported currently. - `label`: Display text for the option. - `choices`: Array of choices (can be flat or grouped). ```js const response = await fetch('https://api.workos.com/authkit/oauth2/complete', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.WORKOS_API_KEY}`, }, body: JSON.stringify({ external_auth_id, user: { id: user.id, email: user.email }, user_consent_options: [ { claim: 'urn:example:tenant', type: 'enum', label: 'Environment', choices: [ { group: 'Production', choices: [ { value: 'prod_us', label: 'US-East' }, { value: 'prod_eu', label: 'EU-West' }, ], }, { group: 'Development', choices: [ { value: 'dev_main', label: 'Development' }, { value: 'staging', label: 'Staging' }, ], }, ], }, ], }), }); ``` The selected values appear as custom claims in the issued tokens. For example, if the user selects one of the above options, the token will include: ```json { "sub": "user_123", "email": "user@example.com", "urn:example:tenant": "prod_us" // ... } ``` ### Error handling If the `external_auth_id` is invalid, the call to the AuthKit completion API will fail. Your application is free to choose how to handle this case, but redirecting to your application's homepage is recommended. ### Token verification Resource servers verify tokens issued by AuthKit using standard Connect token verification: ```js ; const JWKS = createRemoteJWKSet(new URL('https://authkit_domain/oauth2/jwks')); async function verifyToken(token) { const { payload } = await jwtVerify(token, JWKS, { audience: 'client_123456789', issuer: 'https://authkit_domain', }); return payload; } ``` See the [Connect documentation](/authkit/connect/oauth/verifying-tokens) for details on token expiration, refresh tokens, and revocation. ### OAuth Applications Integrate OAuth applications with WorkOS Connect for web and mobile authentication. ## Overview OAuth applications are designed for applications where the actor being authenticated is a [User](/reference/authkit/user). These include web applications, mobile, desktop, and CLI tools. OAuth applications use the underlying `authorization_code` OAuth flow which is supported by many libraries and frameworks out of the box. > For server-to-server requests from a third-party without user interaction, use [M2M applications](/authkit/connect/m2m) instead. ## First-party vs Third-party Applications When creating OAuth applications, you choose the level of trust: first-party or third-party. ### First-party applications Select first-party when the application is one that your team controls, such as supporting services that are deployed separately from your main application but still need access to your users' identities. Examples include community forums or customer support portals. ### Third-party applications Select third-party when the application is one built by your customers or partners, but you do not directly control the integrating application. For this reason, you must also associate third-party applications with an [Organization](/reference/organization) that represents the customer or partner. A third-party OAuth application will generally have a "Sign in with [your application]" button on their login page, in the same way many sites have a "Sign in with Google" button, allowing you to offer similar functionality to your customers or partners. Unlike first-party applications, your users will be prompted in AuthKit to explicitly authorize the application before their identity is shared. ![Screenshot of the application authorization screen in AuthKit.](https://images.workoscdn.com/images/afde561f-9378-4aa6-995c-cda8f3ec0a63.png) ## Receiving Tokens After an application has been issued credentials from a Connect Application, it can receive identity and access tokens using the OAuth 2.0 `authorization_code` flow. Many OAuth and OIDC libraries support Connect applications out of the box, needing only configuration: ## Public Applications By default, OAuth applications are confidential and must authenticate with a client secret when exchanging authorization codes for tokens. However, certain types of applications cannot securely store client secrets, such as command-line tools or mobile applications. For these use cases, you can configure an OAuth application as **Public**. Public applications: - Cannot securely store client secrets - Must use [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636) in order to authenticate with the [Token Endpoint](/reference/workos-connect/token) OAuth applications can be set as _Public_ during creation in the WorkOS Dashboard. ## Verifying Tokens Your application must verify the tokens sent by OAuth applications using the JWKS for your environment. User information in the token can be used to look up related resources and perform further access control checks. In addition to fast stateless verification, you can use the [Token Introspection API](/reference/workos-connect/introspection) to synchronously check whether a token is still valid. ## Organization Access When a user who is a member of multiple Organizations authorizes an OAuth Application, they will be prompted to select one of their Organizations to grant access to. Or, if the user only has a single Organization membership, that Organization will be automatically selected. The selected Organization will be made available as the `org_id` claim in the issued [access token](/reference/workos-connect/token/authorization-code-grant/access-token), which your app can use to scope the access of requests made using the token. ## Configuration OAuth applications require the following configuration: ### Redirect URI This is the final location users will be redirected to after successful authentication. Clients should use the [Token Endpoint](/reference/workos-connect/token) to exchange the `code` for tokens at this location. ### Name and Logo For third-party OAuth applications, the name and logo will be displayed to your users when they are prompted to authorize access. Both light and dark-mode logos are supported. ### Credentials OAuth applications use the `client_id` and `client_secret` from a credential to authenticate to the [OAuth-based Connect APIs](/reference/workos-connect). ## Next Steps - [Connect API Reference](/reference/workos-connect) - Complete API documentation ### M2M Applications Implement machine-to-machine authentication with WorkOS Connect. ## Overview Machine-to-machine (M2M) applications are designed for use-cases where clients are other services, such as one of your customer's applications. M2M applications use the underlying `client_credentials` flow for authentication. M2M access tokens will contain an `org_id` claim which represents the third-party you are granting access to via the M2M application. > M2M applications can only be configured as third-party. M2M applications are one of two ways WorkOS enables you to issue credentials to your customers that they use to programmatically access your application. The other is [API keys](/authkit/api-keys). The [API Keys vs M2M Applications guide](https://workos.com/blog/api-keys-vs-m2m-applications) can help you decide which is best for your use case. ## Common Use Cases M2M applications are commonly used to provide API access credentials to customers or partners, allowing them to programmatically access your APIs and integrate your services into their applications. They're also ideal for partner integrations that run server-to-server without user interaction, where you need to track and control access on a per-organization basis. ## Receiving Tokens Machine-to-machine applications can use the `client_credentials` grant type with the [Token Endpoint](/reference/workos-connect/token) to obtain an `access_token` to authenticate calls to your API. In addition to fast stateless verification, you can use the [Token Introspection API](/reference/workos-connect/introspection) to synchronously check whether a token is still valid. ## Configuration M2M applications require the following configuration: ### Credentials M2M applications use the `client_id` and `client_secret` from a credential to authenticate to the [Connect APIs](/reference/workos-connect) using the client credentials flow. ### Name and Description While not displayed to users (since M2M apps don't have user interaction), the name and description help you manage and identify different M2M applications in your dashboard. ## Next Steps - [Connect API Reference](/reference/workos-connect) - Complete API documentation ### Stripe Connect your WorkOS account to Stripe to automatically provision access tokens with entitlements and sync organization seat counts. ## Introduction WorkOS provides two powerful Stripe integrations that help you manage billing and access control for your B2B application: - **Stripe Entitlements**: Automatically provision access tokens with subscription-based entitlements from Stripe - **Stripe Seat Sync**: Automatically sync organization member counts to Stripe billing meters for usage-based billing Both features use [Stripe Connect](https://stripe.com/connect) to connect your WorkOS account to your Stripe account, allowing WorkOS to manage these integrations on your behalf. --- ## Connect to Stripe To use either Stripe Entitlements or Stripe Seat Sync, you'll first need to connect your WorkOS account to Stripe using Stripe Connect. Navigate to the _Authentication_ section of the [WorkOS Dashboard](https://dashboard.workos.com/) and click _Add-ons_. From that page, find the Stripe Add-on and click _Enable_. ![Authentication Add-ons page](https://images.workoscdn.com/images/75c987b7-d946-4e37-b46d-043fa994cfb4.png?auto=format&fit=clip&q=80) This will open a Dialog to pick the Stripe features you would like to use. When clicking _Continue_ you'll be directed to Stripe where you can approve the connection. Once that's complete, close the tab. > WorkOS does not currently support connecting to a Stripe Sandbox account. Connect WorkOS to a standard Stripe account, and use Stripe’s test mode for development and testing your integration. ![Stripe Dialog](https://images.workoscdn.com/images/5953bd10-b966-4b1f-8d9f-7cd490bc19d3.png?auto=format&fit=clip&q=80) In the connection dialog, you can choose to enable one or both features: - **Use Stripe entitlements**: Include entitlement data in access tokens - **Sync organization seat counts**: Send member counts to Stripe billing meters If you decide to disconnect your Stripe account later or toggle features on and off, you can do so from the same section. Click the _Manage_ button to disable features or disconnect entirely. --- ## Set Stripe Customer IDs To use either of these features, you'll need to set the Stripe customer ID on each WorkOS organization. Once you have a WorkOS organization ID and a Stripe customer ID, you can set the Stripe customer ID for the organization. One way to handle this is to create a Stripe customer and then set the created Stripe customer ID on the WorkOS organization. This can be done via the WorkOS API or SDK. Here's an example using the SDK: --- ## Stripe Entitlements Entitlements are a way to provision an account in your application with specific features or functionality based on the subscription plan a user is on. For example, you might have an "Enterprise" plan that allows users to access certain features like [Audit Logs](/audit-logs), and a "Basic" plan that does not. The WorkOS Entitlements integration makes it easy to get Stripe's entitlement information into your application without needing to listen to Stripe webhooks or explicitly track them in your application. ### Use the entitlements in your application The access token will now include the `entitlements` claim, containing the user's entitlements. You can use this information to gate access to features in your application. > Entitlements added mid-cycle will appear in the next Stripe billing cycle or when a new subscription is created, per Stripe’s billing logic. Entitlements will show up in the access token the next time the user logs in or the session is refreshed. You can manually [refresh the session](reference/authkit/authentication/refresh-token) after the user has completed their subscription purchase. Here's an example in Express: --- ## Stripe Seat Sync Stripe Seat Sync automatically sends active organization member counts to Stripe as billing meter events under [Usage-based billing](https://docs.stripe.com/billing/subscriptions/usage-based), enabling usage-based billing based on the number of seats (members) in each organization. ### How it works When Stripe Seat Sync is enabled: - WorkOS creates a billing meter in your Stripe account called **"User Seat Count"** with the event name `workos_seat_count` - Whenever a member is added, removed, deactivated, or activated from an organization, WorkOS automatically sends a meter event to Stripe with the updated seat count - You can use this meter in Stripe to create usage-based pricing based on the number of active seats The meter uses Stripe's ["last" aggregation method](https://docs.stripe.com/billing/subscriptions/usage-based/meters/configure), which means Stripe will bill based on the most recent seat count reported during each billing period. ### Using the seat count meter in Stripe Once enabled, WorkOS will automatically send meter events to Stripe whenever organization memberships change. You can: - View the meter events in your Stripe Dashboard under **Billing → Meters** - Create pricing models that bill based on the `workos_seat_count` meter - Use the meter in subscription items to charge customers based on their current seat count The meter event includes: - **Event name**: `workos_seat_count` - **Customer ID**: The Stripe customer ID associated with the organization - **Value**: The current number of active members in the organization No additional code is required in your application—WorkOS handles all meter event reporting automatically as members join or leave organizations. ### Segment Send AuthKit events to your Segment destinations. ## Introduction The Segment AuthKit Add-on allows you to register AuthKit as a Segment source and receive events about logins, sign ups, and many other AuthKit activities. You can forward that data to your Segment destinations, allowing you to better understand the effectiveness of your marketing campaigns and your users' full journeys across your website and AuthKit. --- ## Configuring the Add-on ### (1) Confirm your domain To use the Add-on, your [Authentication API Domain](./custom-domains/auth-api) must share the same root as the domain where you set up Segment through Analytics.js. This gives the Add-on access to your users' anonymous IDs, which the Add-on uses to identify users. For example, if your Segment Analytics.js script lives at www.example.com: - **Valid:** auth.example.com is a valid Authentication API Domain - **Invalid:** auth.workos.com is not a valid Authentication API Domain ### (2) Visit the Add-ons page In the WorkOS Dashboard, click the _Authentication_ icon in the sidebar. Then click _Add-ons_. ![Add-ons page in the Authentication section of the WorkOS Dashboard](https://images.workoscdn.com/images/d5b867bb-8f04-440b-8443-4f9a1026a0cb.png?auto=format&fit=clip&q=50) ### (3) Enable the Add-on Click _Enable_ next to _Segment._ ![Segment modal containing a Write Key field in the WorkOS Dashboard](https://images.workoscdn.com/images/18d3da6b-0b59-4973-8a71-851e1ad4e5dc.png?auto=format&fit=clip&q=50) In another browser tab, visit Segment to get your credentials. Click _Connections_ in the left sidebar. ![Connections link in Segment](https://images.workoscdn.com/images/78899ff2-be15-4fc0-a9d4-1482af04703e.png?auto=format&fit=clip&q=50) Next to _Sources_, click _Add more_. ![Add more link on the Connections page in Segment](https://images.workoscdn.com/images/5feab1ce-89d3-4998-b16e-9ffdb48b4b0f.png?auto=format&fit=clip&q=50) Under _Choose a Source_, search "HTTP API." Below, click _HTTP API_. Then, in the lower right corner, click _Next._ ![HTTP API source in Segment](https://images.workoscdn.com/images/c6be5d31-307f-4371-82de-9486a034f478.png?auto=format&fit=clip&q=50) Under _Create your source_, give your source a name, like _WorkOS AuthKit Add-on_. Click _Create Source_. Under _Configure this source in your HTTP API codebase_, find your _Write Key_, and click the _Copy_ button next to it. ![Copy button next to a new Write Key for an HTTP API source in Segment](https://images.workoscdn.com/images/82093be1-5a27-4985-bdef-ce3899832ee6.png?auto=format&fit=clip&q=50) Paste your write key in the _Write Key_ field in the WorkOS Dashboard. Click _Save changes_. The Segment AuthKit Add-on is enabled and will begin sending AuthKit events to Segment. --- ## Events sent to Segment The Add-on sends events to Segment when certain [WorkOS Events](/events) occur: - _Authentication_ events - _Email verification_ events - _Magic Auth_ events - _Password reset_ events - `session.created` - `user.created` All names of events in Segment will match the names of the [WorkOS Events](/events). --- ## Verifying events After enabling the Add-on, visit your website, click your sign in button, and sign in to your application. Visit Segment and click _Connections_ in the sidebar. Click the source you created. Then click the _Debugger_ tab. You should see an identify call including your anonymous ID and a track call with an authentication event. If you do not see an authentication event, visit the Add-ons page in the WorkOS Dashboard to verify your Write Key matches the value from Segment. If after confirming the values match you still need support, please reach out to us in Slack. ### Google Analytics Track user activity on AuthKit pages in Google Analytics. ## Introduction The Google Analytics AuthKit Add-on gives you data about logins, sign ups, and many other AuthKit activities inside of Google Analytics. You can use that data to better understand the effectiveness of your marketing campaigns and your users' full journeys across your website and AuthKit. --- ## Configuring the Add-on ### (1) Confirm your domain To use the Add-on, your [Authentication API Domain](./custom-domains/auth-api) must share the same root as the domain where you set up Google Analytics through Google Tag Manager or gtag.js. This gives the Add-on access to your users' Google Analytics client IDs, which the Add-on uses to associate events in AuthKit with users from your website. For example, if your Google Analytics script lives at www.example.com: - **Valid:** auth.example.com is a valid Authentication API Domain - **Invalid:** auth.workos.com is not a valid Authentication API Domain ### (2) Visit the Add-ons page In the WorkOS Dashboard, click the _Authentication_ icon in the sidebar. Then click _Add-ons_. ![Add-ons page in the Authentication section of the WorkOS Dashboard](https://images.workoscdn.com/images/d5b867bb-8f04-440b-8443-4f9a1026a0cb.png?auto=format&fit=clip&q=50) ### (3) Enable the Add-on Click _Enable_ next to _Google Analytics._ ![Google Analytics modal with Measurement ID and Measurement Protocol API Secret fields in the WorkOS Dashboard](https://images.workoscdn.com/images/40f61f05-32d2-4439-ae68-3c3b8f8aaf87.png?auto=format&fit=clip&q=50) In another browser tab, visit Google Analytics to get your credentials. Click the _Admin_ icon in the bottom left corner. ![Admin icon on the Google Analytics website](https://images.workoscdn.com/images/21267275-4fde-431b-95d6-8e1ec3cc8190.png?auto=format&fit=clip&q=50) Under _Data collection and modification_, click _Data streams._ ![Data steams link on the Google Analytics website](https://images.workoscdn.com/images/8f967c62-d63f-4130-8510-dc97a249d0b4.png?auto=format&fit=clip&q=50) Click the data stream that you used to set up Google Analytics on your website. Under _Measurement ID_, click the copy icon. Paste your Measurement ID in the Measurement ID field in the WorkOS Dashboard. ![Measurement ID on the Google Analytics website](https://images.workoscdn.com/images/68dbf576-dae1-4940-b3d4-6840086f94b5.png?auto=format&fit=clip&q=50) Under _Events_, click _Measurement Protocol API secrets_. ![Measurement Protocol API Secrets section on the Google Analytics website](https://images.workoscdn.com/images/cdf958e3-6714-4700-9c77-71e46af96bc5.png?auto=format&fit=clip&q=50) Click _Create_. Give your new secret a name, like _WorkOS AuthKit_ _Add-on_. Copy the _Secret value._ The secret value may be cut off on narrower windows, so try double clicking the value before copying it to ensure you have selected the full value. ![Measurement Protocol API Secret value on the Google Analytics website](https://images.workoscdn.com/images/8bd84bdf-eb85-4987-97a2-c13c863508a3.png?auto=format&fit=clip&q=50) Paste the secret value in the API Secret field in the WorkOS Dashboard. Click _Save changes_. The Google Analytics AuthKit Add-on is enabled and will begin sending AuthKit events to Google Analytics. ![Google Analytics AuthKit Add-on enabled in the WorkOS Dashboard](https://images.workoscdn.com/images/0e47d2b4-29ad-4a47-9ab6-470dee7cc63c.png?auto=format&fit=clip&q=50) --- ## Events sent to Google Analytics The Add-on sends events to Google Analytics when certain [WorkOS Events](/events) occur: - `user.created` sends Google a [`sign_up` recommended event](https://developers.google.com/analytics/devguides/collection/ga4/reference/events?client_type=gtag#sign_up) - `authentication.magic_auth_succeeded`, `authentication.mfa_succeeded`, `authentication.oauth_succeeded`, `authentication.passkey_succeeded`, `authentication.password_succeeded`, and `authentication.sso_succeeded` send Google a [`login` recommended event](https://developers.google.com/analytics/devguides/collection/ga4/reference/events?client_type=gtag#login) including a `method` parameter matching the login method - The remaining _Authentication_ events, _Email verification_ events, _Magic Auth_ events, _Password reset_ events, and `session.created` send Google events based on the WorkOS event name, with underscores replacing periods - `authentication.email_verification_succeeded` is shortened to `auth_email_verification_succeeded` to meet Google's requirement that event names be 40 characters or shorter --- ## Verifying events After enabling the Add-on, visit your website, click your sign in button, and sign in to your application. Visit Google Analytics and click _Reports_ in the sidebar. Then click _Realtime overview_. Within five minutes, you should see a `login` event under _Event count by Event name_. If you do not see a login event, visit the Add-ons page in the WorkOS Dashboard to verify your Measurement ID and API Secret match the values from Google Analytics. If after confirming the values match you still need support, please reach out to us in Slack. ## Audit Logs {#audit-logs} ### Metadata Schema Define strict JSON Schema for validating event metadata. ## Metadata Schema Audit Log Events can contain arbitrary metadata for adding additional details to your events. Normally this data can take any shape. However, custom metadata schemas can be defined when configuring the event for additional type safety and data consistency. When an event is emitted that does not match the provided schema, an error will be returned. When first creating an event schema, check the “Require metadata schema validation” checkbox. You will then be navigated to the schema editor where you can modify the underlying [JSON Schema](https://json-schema.org/) for all `metadata` objects. ![A screenshot showing how to require metadata schema validation in the WorkOS Dashboard.](https://images.workoscdn.com/images/24a410e1-72aa-4f5b-8854-98a4307602ff.png?auto=format&fit=clip&q=50) There are `metadata` objects located at the root of the event, and within `actor` and `targets` objects. Each can contain a unique JSON Schema. To add to a `metadata` object, click the "+" sign. > Metadata objects have a limit of 50 keys. Key names can be up to 40 characters long, and values can be up to 500 characters long. ![A screenshot showing the schema editor in the WorkOS Dashboard.](https://images.workoscdn.com/images/7d9e37a3-2e8d-4910-b85d-34c224e375be.png?auto=format&fit=clip&q=50) ### Log Streams Stream Audit Log Events to your customers’ SIEM providers. ## Understanding Log Streams Log Streams allow your customers to stream Audit Logs directly to their Security Incident and Event Management (SIEM) providers like Datadog or Splunk and object storage solutions like AWS S3 or Google Cloud Storage. There is also a generic provider (HTTP POST) available to stream logs to any configured endpoint. This gives your customers greater control over their Audit Logs by allowing them to apply custom indexing and monitoring of their events in the SIEM provider along with events from other cloud services they use. Log Streams can be created by either configuring the Log Stream through your WorkOS Dashboard or by allowing your customer's IT admin to configure it themselves through the WorkOS Admin Portal. ### IP allowlist WorkOS streams audit logs from a fixed set of IP addresses. If audit logs are being streamed to a host that restricts access based on IP address, the following IP addresses should be allowed: ```plain title="WorkOS IP addresses" 3.217.146.166 23.21.184.92 34.204.154.149 44.213.245.178 44.215.236.82 50.16.203.9 52.1.251.34 52.21.49.187 174.129.36.47 ``` ## Dashboard To configure a Log Stream through the WorkOS Dashboard, navigate to an organization and click “Configure”. ![A screenshot showing where to find "Configure" in the WorkOS Dashboard.](https://images.workoscdn.com/images/b555ad16-fce2-4014-997d-3d75b85f7860.png?auto=format&fit=clip&q=50) You will be prompted to select a destination from a dropdown, click “Save connection”. You will then be prompted to provide specific configuration for the selected destination. ![A screenshot showing "Save connection" in the WorkOS Dashboard.](https://images.workoscdn.com/images/75ced694-5dbd-48c3-9784-5fdaf81e0420.png?auto=format&fit=clip&q=50) ## Admin Portal The Admin Portal can be accessed via a Setup Link found in the Organization page within the Dashboard. Click “Generate” and select “Log Streams”. Copy the link and send it to the organization's IT admin who will be configuring Log Streams. ![A screenshot showing where the "Generate" button is located in the WorkOS Dashboard.](https://images.workoscdn.com/images/f6410460-40e4-478c-b663-5920ac15b8a8.png?auto=format&fit=clip&q=50) You can also guide users to the Admin Portal by redirecting them to a programmatically generated Admin Portal link directly from your application. Once redirected to the Admin Portal, the user will be prompted to select a destination and will be provided with step-by-step configuration instructions for the selected destination. ![A screenshot showing log stream destination options in the WorkOS Admin Portal.](https://images.workoscdn.com/images/a6249873-d221-49eb-9c6a-c7706b2b4f77.png?auto=format&fit=clip&q=50) ## Streaming Destinations and Payload Formats WorkOS supports streaming audit log events to five different types of destinations, each with its own payload format and configuration requirements: ### Datadog Events are sent to Datadog's HTTP Log Intake API with regional endpoint support. **Example Payload:** ```json [ { "message": { "id": "01HY123456ABCDEFGHIJK", "action": "user.signed_in", "targets": [ { "id": "user_123", "type": "user" } ], "actor": { "id": "user_456", "type": "user" }, "context": { "location": "192.168.1.1", "user_agent": "Chrome/91.0" }, "occurred_at": "2024-01-15T10:30:00.000Z" }, "ddsource": "team-name", "service": "audit-logs" } ] ``` **Configuration:** - API Key authentication - Regional endpoints (US1, US3, US5, EU1, US1-FED, AP1) - Optional team name as source identifier ### Splunk Events are sent to Splunk's HTTP Event Collector (HEC) endpoint. **Example Payload:** ```json [ { "event": { "id": "01HY123456ABCDEFGHIJK", "action": "user.signed_in", "targets": [ { "id": "user_123", "type": "user" } ], "actor": { "id": "user_456", "type": "user" }, "context": { "location": "192.168.1.1", "user_agent": "Chrome/91.0" }, "occurred_at": "2024-01-15T10:30:00.000Z" }, "time": 1705314600000, "source": "team-name" } ] ``` **Configuration:** - HEC Token authentication - Custom Splunk instance URL - Optional source identifier ### AWS S3 Events are stored as individual JSON files in an S3 bucket. We use a cross-account IAM role with an external ID ([details](https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html)) to authenticate to the destination bucket. We upload S3 objects with a `ContentMD5` header to support [uploading objects to Object Lock enabled buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock-managing.html#object-lock-put-object). | Property | Description | | ------------------- | -------------------------------------------------------------- | | File Format | Individual JSON files per event with pretty-printed formatting | | File Naming Pattern | `YYYY-MM-DD/{timestamp}_{keySuffix}.json` | | Example Filename | `2024-01-15/2024-01-15T10:30:00.123Z_abc123def456.json` | **Example File Content:** ```json { "id": "01HY123456ABCDEFGHIJK", "action": "user.signed_in", "targets": [ { "id": "user_123", "type": "user" } ], "actor": { "id": "user_456", "type": "user" }, "context": { "location": "192.168.1.1", "user_agent": "Chrome/91.0" }, "occurred_at": "2024-01-15T10:30:00.000Z" } ``` **Configuration:** WorkOS authenticates to the destination S3 bucket using an AWS cross-account IAM role delegation with an external ID for enhanced security. This requires the following configuration: | Field Name | Code | Description | | -------------- | ------------ | ------------------------------------------------------------------------ | | AWS Account ID | `accountId` | Destination AWS account ID where the S3 bucket is located | | AWS Region | `region` | The AWS region for the destination S3 bucket (defaults to `us-east-1`) | | IAM Role Name | `roleName` | The name of the IAM role WorkOS will assume to access destination bucket | | S3 Bucket Name | `bucketName` | The name of the destination S3 bucket | | Bucket Path | `bucketPath` | Optional path prefix within the bucket where logs will be stored | **Authentication Flow:** 1. WorkOS uses AWS Security Token Service (STS) to assume a role in the destination AWS account 2. The role must be configured to trust WorkOS' AWS account ID (`workosAccountId`) as an external trusted entity 3. The role must require an External ID (`externalId`) that matches the unique value provided by WorkOS 4. The role must have an attached IAM policy granting `s3:PutObject` permissions on the bucket (and optional path prefix) 5. WorkOS receives temporary credentials from STS and uses them to upload audit log events to the destination S3 bucket **IAM Policy Requirements:** The IAM role must include a policy that allows `s3:PutObject` actions on the destination bucket. The policy resource should target destination bucket and optional path prefix: `arn:aws:s3:::bucket-name/optional-path/*`. Example policy that you need to create in the destination AWS account: ```json { "Version": "2012-10-17", "Statement": [ { "Sid": "LogStreamBucketPolicy", "Effect": "Allow", "Action": ["s3:PutObject"], "Resource": ["arn:aws:s3:::bucket-name/optional-path/*"] } ] } ``` ### Google Cloud Storage Events are stored as individual JSON files using Google Cloud Storage's S3-compatible API. | Property | Description | | ------------------- | --------------------------------------------------- | | File Format | Individual JSON files per event (same format as S3) | | File Naming Pattern | `{timestamp}_{keySuffix}.json` | **Example File Content:** ```json { "id": "01HY123456ABCDEFGHIJK", "action": "user.signed_in", "targets": [ { "id": "user_123", "type": "user" } ], "actor": { "id": "user_456", "type": "user" }, "context": { "location": "192.168.1.1", "user_agent": "Chrome/91.0" }, "occurred_at": "2024-01-15T10:30:00.000Z" } ``` **Configuration:** - Access Key ID and Secret Access Key are required when configuring a log stream to GCS - GCS bucket with S3-compatible access ### Generic HTTPS Events are sent to custom HTTP endpoints with configurable authentication and format options. **JSON Format Example:** ```json [ { "event": { "id": "01HY123456ABCDEFGHIJK", "action": "user.signed_in", "targets": [ { "id": "user_123", "type": "user" } ], "actor": { "id": "user_456", "type": "user" }, "context": { "location": "192.168.1.1", "user_agent": "Chrome/91.0" }, "occurred_at": "2024-01-15T10:30:00.000Z" }, "keySuffix": "abc123def456", "timestamp": "2024-01-15T10:30:00.123Z", "source": "team-name" } ] ``` **NDJSON Format Example:** ```json {"event":{"id":"01HY123456ABCDEFGHIJK","action":"user.signed_in",...},"keySuffix":"abc123def456","timestamp":"2024-01-15T10:30:00.123Z"} ``` **Configuration:** - Custom HTTP endpoint - Configurable authentication headers - Support for JSON or NDJSON formats - Content-Type handling (application/json or application/x-ndjson) ## Stream States and Management Audit log streams can be in one of four states that determine their operational status: ### Stream States | State | Description | | ------------ | --------------------------------------------------------- | | **Active** | Stream is functioning normally and delivering events | | **Inactive** | Stream is incomplete, manually disabled or paused | | **Error** | Stream encountered a retry-able error and will be retried | | **Invalid** | Stream has invalid credentials or configuration | ### State Transitions Streams automatically transition between states based on delivery outcomes: - **Active → Error**: When a retry-able error occurs during event delivery - **Active → Invalid**: When authentication or authorization fails - **Error → Active**: When retry succeeds after a previous error - **Invalid → Active**: When credentials are fixed and validation succeeds - **Any → Inactive**: When manually disabled through Dashboard or Admin Portal ### Updating Stream Configuration Stream configurations can be updated through: 1. **WorkOS Dashboard**: Navigate to the organization and modify the log stream configuration 2. **Admin Portal**: Generate a setup link for the organization's IT admin to update settings ### Audit Logs Ingest and export Audit Log Events from your application. ## Introduction Audit Logs are a collection of events that contain information relevant to notable actions taken by users in your application. Every event in the collection contains details regarding what kind of action was taken (`action`), who performed the action (`actor`), what resources were affected by the action (`targets`), and additional details of when and where the action took place. ```json { "action": "user.signed_in", "occurred_at": "2022-08-29T19:47:52.336Z", "actor": { "type": "user", "id": "user_01GBNJC3MX9ZZJW1FSTF4C5938" }, "targets": [ { "type": "team", "id": "team_01GBNJD4MKHVKJGEWK42JNMBGS" } ], "context": { "location": "123.123.123.123", "user_agent": "Chrome/104.0.0.0" } } ``` These events are similar to application logs and analytic events, but are fundamentally different in their intent. They aren’t typically used for active monitoring/alerting, rather they exist as a paper trail of potentially sensitive actions taken by members of an organization for compliance and security reasons. ## What you’ll build This guide will show you how to: 1. Configure and emit Audit Log Events 2. Export Audit Log Events 3. Create custom metadata schemas for Audit Log Events 4. Create new versions of Audit Log Event schemas ## Before getting started To get the most out of this guide, you’ll need: - A [WorkOS account](https://dashboard.workos.com/) ## API object definitions [Audit Log Event](/reference/audit-logs/create-event) : An individual event that represents an action taken by an actor within your app. [Audit Log Export](/reference/audit-logs/audit-log-export) : A collection of Audit Log Events that are exported from WorkOS as a CSV file. [Organization](/reference/organization) : Describes a customer where Audit Log Events originate from. ## Emit an Audit Log Event ### Install the WorkOS SDK WorkOS offers native SDKs in several popular programming languages. Choose a language below to see instructions in your application’s language. ### Set secrets To make calls to WorkOS, provide the API key and, in some cases, the client ID. Store these values as managed secrets, such as `WORKOS_API_KEY` and `WORKOS_CLIENT_ID`, and pass them to the SDKs either as environment variables or directly in your app's configuration based on your preferences. ```plain title="Environment variables" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' ``` ### Sign in to your WorkOS Dashboard account and configure Audit Log Event schemas Before you can emit any Audit Log Events you must configure the allowed event schemas. To start, click “Create an event” and enter `user.signed_in` for action, `team` for targets, and click “Save event”. ![A screenshot showing how to create an audit log event in the WorkOS dashboard.](https://images.workoscdn.com/images/7658a3b2-1467-4c38-a98f-f99f933c5969.png?auto=format&fit=clip&q=50) ### Get an Organization ID All events are scoped to an Organization, so you will need the ID of an Organization in order to emit events. ![A screenshot showing where to find an Organization ID in the WorkOS dashboard.](https://images.workoscdn.com/images/b76c7593-1d85-4f28-951e-24f177b8c233.png?auto=format&fit=clip&q=50) ### Emit Events Using the ID from the Organization, emit an Audit Log Event with the `action` and `targets` previously configured. #### Idempotency WorkOS Audit Logs supports idempotency to ensure events are not duplicated when retrying requests. You can provide an `idempotency-key` header with your event creation request. If you don't provide one, WorkOS will automatically generate one based on the event content. When you provide an idempotency key: - WorkOS creates a hashed key combining your provided key with the event data - Subsequent requests with the same idempotency key and event data will return the same response - This prevents duplicate events from being created due to network retries or other issues When you don't provide an idempotency key: - WorkOS automatically generates one using the event content - This provides basic duplicate protection based on event data alone ### View ingested events in the Dashboard Once you have successfully emitted events with the WorkOS SDK, you can view them in the Dashboard under the Organization that the events are associated with. ![A screenshot showing Audit Log events for an organization in the WorkOS dashboard.](https://images.workoscdn.com/images/b03dfaa4-c76a-4d08-a322-53458ba8b24d.png?auto=format&fit=clip&q=50) ### Exporting Events Export Audit Log Events through the WorkOS Dashboard and API. ## Exporting Events You may need to export Audit Log Events in large chunks. WorkOS supports exporting events as CSV files through both the Dashboard and API. Exports are scoped to a single organization within a specified date range. Events from the past three months can be included in the export. You may define additional filters such as `actions`, `actors`, and `targets`. ### Creating an export through the Dashboard Exports can be manually created under the Organization page when viewing Audit Log Events by selecting "Export CSV" from the "Actions" dropdown. Set your filters and select "Generate CSV file". ![A screenshot showing how to generate an Audit Log export in the WorkOS Dashboard.](https://images.workoscdn.com/images/a5386939-652f-4cbb-aa88-7159e2ffc1dd.png?auto=format&fit=clip&q=50) ### Creating an export through the API Once the export has been created, fetch the export at a later time to access the `url` of the generated CSV file. > The URL will expire after 10 minutes. If the export is needed again at a later time, refetching the export will regenerate the URL. If the `state` of the export is still `pending`, poll the export until it is ready for download. ### Editing Events Modify existing event configuration with backwards compatibility. ## Editing Events Once you’ve successfully configured Audit Logs in the WorkOS Dashboard and begun emitting events, how do you go about modifying an event schema without breaking your existing integrations? This is where versioning comes into place. When you make a modification to an existing schema it will create a new version rather than overwriting the existing schema. The reason for this behavior is to ensure backwards compatibility. Schema configuration is immutable to prevent you from accidentally making changes that are incompatible with events that are already being emitted from your application. Rather you must first create a new version of the schema, and then explicitly emit events for that version leveraging the event `version` field. ### Creating a new event version In the WorkOS Dashboard navigate to the Audit Logs configuration page. Locate the event that you would like to modify the schema for and click the “Edit Event” item under the context menu. ![A screenshot showing the "Edit Event" option in the WorkOS Dashboard.](https://images.workoscdn.com/images/8ee56828-fc59-4c18-ae64-008a754cd2a6.png?auto=format&fit=clip&q=50) You will be navigated to a page where you can edit both the `targets` associated with the event, and optionally the metadata JSON schema. Once you’re done making changes, clicking save will create a new version of the event schema. ![A screenshot showing the "Save as new version" button in the schema editor in the WorkOS Dashboard.](https://images.workoscdn.com/images/65d234a3-f530-4051-95a0-0162cfef122e.png?auto=format&fit=clip&q=50) ### Emitting event with version Now that a schema exists with a new version, the `version` field must be provided when emitting an event so that WorkOS knows which version to use for validation. ### Admin Portal View Audit Log events for an organization in the WorkOS Admin Portal. ## Creating Admin Portal Link Audit Log events can be viewed in the WorkOS [Admin Portal](/admin-portal). Links can be generated through the WorkOS API and sent to your customers for viewing events associated with their Organization. When creating a link for an Admin Portal session, you must provide the Organization ID whose events will be displayed in the Admin Portal, and specify the intent as `audit_logs`. Navigating to the provided link will result in the following view. Users will be able to view and export Audit Log events just as can be done through the WorkOS Dashboard. ![A screenshot showing Audit Log events in the WorkOS Admin Portal.](https://images.workoscdn.com/images/e08a07dd-4539-4c5a-9802-63d7c774b2c9.png?auto=format&fit=clip&q=50) ## Admin Portal {#admin-portal} ### Admin Portal A first-class Single Sign-On and Directory Sync onboarding experience for organization admins. ## Introduction The Admin Portal provides an out-of-the-box UI for IT admins to verify domains, configure SSO and Directory Sync connections, and more. Designed to remove friction, custom walk-through documentation for each identity provider means that organization admins can onboard their organizations without high-touch support from your team. Easy to integrate and fully maintained and hosted by WorkOS, the Admin Portal makes Domain Verification, SSO, and Directory Sync setup simple, fast, and secure. ![A screenshot showing the IdP selection in the WorkOS Admin Portal.](https://images.workoscdn.com/images/dd00d92d-2810-484a-a3c7-4e0fdb8703a7.png?auto=format&fit=clip&q=50) ## Workflow Options There are two main workflows for initiating an Admin Portal session for IT admins. You can either share a link to the Admin Portal from the WorkOS dashboard, or you can seamlessly integrate Admin Portal into your application through WorkOS SDKs or APIs. ![A screenshot showing the different workflows for creating an Admin Portal shareable link.](https://images.workoscdn.com/images/33851982-5baf-4ffe-8b41-71054b95948b.png?auto=format&fit=clip&q=50) If you want to provide an IT admin with a link to the Admin Portal, in a email for example, then you would need to create that link in the WorkOS dashboard. However, if you are adding a button to open the Admin Portal from within your application, then you would need to use the API. | Workflow | Use cases | Security | Return URL and Success URLs | | ------------------------------- | :--------------------------- | :------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------- | | Share a link from the dashboard | Setup only | Can be revoked; Automatically revoked on setup completion; Expires after 30 days | Not applicable | | Generate a link via the API | Setup and post-configuration | Cannot be revoked; Expires after 5 minutes | Can be configured on the [Redirects](https://dashboard.workos.com/redirects) page in the dashboard or specified as a parameter for the API | --- ## Before getting started To get the most out of these guides, you’ll need: - A [WorkOS account](https://dashboard.workos.com/) ## API object definitions [Connection](/reference/sso/connection) : Represents the method by which users of an organization sign in to your application. [Organization](/reference/organization) : Describes an organization whose users sign in with an SSO connection, or whose users are synced with a Directory Sync connection. [Portal link](/reference/admin-portal/portal-link) : A temporary link to initiate an Admin Portal session. ## (A) Setup link from WorkOS dashboard The Admin Portal setup link gives your customer access to a guided configuration experience through our Admin Portal. It instructs them how to verify a domain, configure their identity or directory provider, and more. If successfully configured, no other action is required and you’ll see verified domains and/or active connections appear under the organization. First decide whether your customer will be configuring Domain Verification, Single Sign-On, Directory Sync, Log Streams, or all of the above. Once you generate a link, the customer will have access for 30 days or until configured. You’ll need a [WorkOS dashboard account](https://dashboard.workos.com/) to create an organization that will represent the enterprise you are onboarding. ### Create organization Sign in to your WorkOS dashboard account and create a new organization. ![WorkOS dashboard UI showing organization creation](https://images.workoscdn.com/images/1c69fd98-01be-491d-9255-58363bc6a983.png?auto=format&fit=clip&q=50) ### Generate a setup link Click the “Invite admin” button, select the features to include and then click “Next." Enter the email of the IT admin for the organization to automatically send them a setup link, or click "Copy setup link." Only one link can be active at a time. After creating the initial link, you can click the “Manage” button to revoke the existing link before creating a new one. ### Sharing a setup link If you chose to copy the setup link you can share it over email, Slack or direct message. We also recommend including details on what the link does and how long the link is active. ## (B) Integrate with your app In this guide, we’ll walk you through the full end-to-end integration of the Admin Portal into your application. > [Sign in](https://dashboard.workos.com/) to your WorkOS dashboard account to see code examples pre-filled with your test API keys and resource IDs. ### Configure Admin Portal redirect links In order to integrate, you must configure your app's default return URI in the production environment. A button in the Admin Portal will use this value to allow users to return to your app unless otherwise specified when generating the Admin Portal link. ![A screenshot showing the Admin Portal Redirect Links tab to set redirect URIs in the WorkOS dashboard.](https://images.workoscdn.com/images/9df0f214-0350-466c-b54b-8a1e0be6b678.png?auto=format&fit=clip&q=50) Additionally, you can configure success URIs to redirect users upon successfully setting up Single Sign-On, Directory Sync, or Log Streams. ![A screenshot showing the Admin Portal redirect URI variations in the WorkOS dashboard.](https://images.workoscdn.com/images/3d75975c-b36a-4bfc-b05d-d745b8ba916b.png?auto=format&fit=clip&q=50) > All redirect links must use HTTPS. You can configure these links in the [dashboard](https://dashboard.workos.com/). ### Install the WorkOS SDK WorkOS offers native SDKs in several popular programming languages. Choose a language below to see instructions in your application’s language. ### Set secrets To make calls to WorkOS, provide the API key and, in some cases, the client ID. Store these values as managed secrets, such as `WORKOS_API_KEY` and `WORKOS_CLIENT_ID`, and pass them to the SDKs either as environment variables or directly in your app's configuration based on your preferences. ```plain title="Environment variables" WORKOS_API_KEY='sk_example_123456789' WORKOS_CLIENT_ID='client_123456789' ``` ### Create a new organization Each Admin Portal session is scoped to a specific organization resource, meaning a session is only capable of managing a connection that belongs to its associated organization. Organizations may only have one connection. For every customer in your application that would like access to the Admin Portal, you must create an organization and maintain a reference to its ID. > Create an organization when onboarding a new customer. ### Redirect an IT admin to the Admin Portal A Portal link is your enterprise user's gateway to accessing the Admin Portal, where they can set up and manage resources scoped to their organization. To generate a Portal link using the API, you must provide the organization ID and specify one of the following intents: [`sso`](admin-portal/c-using-admin-portal/managing-sso-connections), [`dsync`](admin-portal/c-using-admin-portal/managing-directories), [`audit_logs`](audit-logs/admin-portal/creating-admin-portal-link), [`log_streams`](audit-logs/log-streams/admin-portal), [`domain_verification`](domain-verification/admin-portal-domain-verification), or [`certificate_renewal`](sso/signing-certificates/saml-response-signing-certificate/renewing-certificates). For security reasons, Portal links expire 5 minutes after they’re created, so we recommend redirecting users immediately (i.e. don’t email the user Portal links). > The endpoint that redirects a user to the Admin Portal should be guarded by auth in your application and only available to IT admins. An [optional return_url parameter](/reference/admin-portal/portal-link/generate) can be used to describe exactly where a user should be sent when they are finished in the Admin Portal. If one is not provided, the success URL configured on the [Redirects](https://dashboard.workos.com/redirects) page of the dashboard will be used. ## (C) Using Admin Portal In this guide, we’ll review some of the features of Admin Portal from an IT admin's perspective. ### Verifying a domain In the Admin Portal [Domain Verification](/domain-verification/admin-portal-domain-verification) flow, you can view instructions on adding a DNS TXT record to prove ownership of your organization's domain(s). > Unless an organization [allows any domain](/sso/domains/allowing-any-domain), a verified domain is required in order to activate SSO. Domains can also be [manually verified](authkit/domain-verification/self-serve-domain-verification) outside of the self-serve Admin Portal flow if the IT admin has already proven domain ownership in another context. ### Managing SSO connections On the Admin Portal SSO screen, you can view the identity provider details and connection status, metadata configuration details, and a list of recent connection sessions. You may test your SSO connection from the Admin Portal by using the “Test sign-in” button. ![A screenshot showing the Admin Portal SSO screen and where to click the “Test Single Sign-On” button.](https://images.workoscdn.com/images/b9ab3cc1-c524-4eae-9a25-f4c6a4059683.png?auto=format&fit=clip&q=50) You may also edit your metadata configuration from the Admin Portal. ![A screenshot showing the Admin Portal SSO screen and where to "Edit Metadata Configuration".](https://images.workoscdn.com/images/2ada73aa-dfa4-45c8-afc8-2e69a3a9b4fc.png?auto=format&fit=clip&q=50) The Sessions section displays a list of recent sessions by timestamp, and can be sorted by `state`. ![A screenshot showing the Admin Portal SSO screen and how to sort "Sessions" by "state".](https://images.workoscdn.com/images/0b1b05a0-8c18-4c99-8d02-22f2b4f2bf46.png?auto=format&fit=clip&q=50) Click on a session in the list to see session details, such as the request made to the IdP, and the response. ![A screenshot showing the "Session Details" within the Admin Portal SSO screen.](https://images.workoscdn.com/images/6655ae75-c0c2-4b0c-be7b-b21dbfb6aadd.png?auto=format&fit=clip&q=50) If you wish to reset your SSO connection and set it up from scratch, select “Reset Connection” and follow the prompts. ![A screenshot showing how to "Reset Connection" within the Admin Portal SSO screen.](https://images.workoscdn.com/images/b0f2919d-07f2-457d-8499-1b617235c485.png?auto=format&fit=clip&q=50) ### Managing directories On the Admin Portal Directory Sync screen, you can view the directory provider details and connection status, user and group counts, and last sync time. There is also an option to reset the directory. ![A screenshot showing Admin Portal Directory Sync screen details.](https://images.workoscdn.com/images/13be17b8-46da-4c2c-801f-029be3686101.png?auto=format&fit=clip&q=50) You may also view and edit the attribute map from the synced directory by clicking "Edit Attribute Map". ![A screenshot showing editing the attribute map in the Admin Portal Directory Sync screen.](https://images.workoscdn.com/images/c6dd347f-15dc-4918-9820-946f38361c2e.png?auto=format&fit=clip&q=50) If you wish to update the groups that are being synced, select "Edit groups sync” and follow the prompts on the next page. ![A screenshot showing editing user groups in the Admin Portal Directory Sync screen.](https://images.workoscdn.com/images/05fc69da-3688-4c90-873b-505be64779b9.png?auto=format&fit=clip&q=50) You can also view a complete list of users from all selected groups in your synced directory. ![A screenshot showing the user list in the Admin Portal Directory Sync screen.](https://images.workoscdn.com/images/f581e97e-2052-4635-805c-fad3c47f792e.png?auto=format&fit=clip&q=50) ### Example Apps View sample Admin Portal apps for each SDK. You can view minimal example apps that demonstrate how to use the WorkOS SDKs to power the Admin Portal: ### Custom Branding Use your own logo and colors in the Admin Portal. ## Introduction You can customize the look and feel of the Admin Portal from the WorkOS Dashboard. Go to [Branding settings](https://dashboard.workos.com/branding) where you can: - Upload your logos - Set your brand color - View your custom domains Custom branding can be tested for free in the staging environment. You need the [WorkOS Enterprise plan](https://workos.com/pricing) to enable custom branding in the production environment ![A screenshot showing the WorkOS Dashboard branding settings page.](https://images.workoscdn.com/images/fc67ec10-44e1-467c-a094-32ed3ff5bd92.png?auto=format&fit=clip&q=80) ## Logos and icons You can upload custom branding assets which will be used in the Admin Portal as well as emails. ### Logo Image with your company's logo and wordmark. - **Usage:** Shown in the top left corner of the Admin Portal. - **Requirements:** At least 160x160 px (JPG, PNG, or SVG. 100 KB max size) ![A screenshot showing the WorkOS Admin Portal and highlighting the custom logo.](https://images.workoscdn.com/images/ca579b3c-6a50-41aa-ad3e-62b32740b6c8.png?auto=format&fit=clip&q=50) ### Logo icon A smaller, square version of the logo. This is often simply the logomark. {` .tight-bullets p { margin-bottom: var(--space-2); } .tight-bullets .rt-Box:has(.rt-Box) { margin-bottom: var(--space-2); } `} - **Usage:** - Displayed in Admin Portal emails - Available for IT admins to download from the Admin Portal for configuring IdP-initiated SSO in Okta, Entra ID and Google Workspace. - **Requirements:** At least 160x160 px with a 1:1 aspect ratio (JPG, PNG, or SVG. 100 KB max size) ![A screenshot showing an email from WorkOS and highlighting the custom logo icon.](https://images.workoscdn.com/images/df8b54e6-a3fc-431b-8086-a01fb03388c7.png?auto=format&fit=clip&q=50) ![A screenshot showing the WorkOS Admin Portal and highlighting the custom logo icon download.](https://images.workoscdn.com/images/d07c701e-a051-4444-ae66-fc35eecb6791.png?auto=format&fit=clip&q=50) ### Favicon A small icon that serves as branding for your website. - **Usage:** Displayed in the address bar of the Admin Portal website. - **Requirements:** At least 32x32 px with a 1:1 aspect ratio (JPG, PNG, GIF, SVG, WebP, AVIF, or ICO. 100 KB max size) ![A screenshot showing the WorkOS Admin Portal and highlighting the custom favicon.](https://images.workoscdn.com/images/15dd6370-961d-4d8b-97b1-6bfc3ef80143.png?auto=format&fit=clip&q=50) ### Brand color Hex value used as the background color for buttons in the Admin Portal and emails. ![A screenshot showing the WorkOS Admin Portal and highlighting the custom button color.](https://images.workoscdn.com/images/080c0c45-08ee-44c4-b153-7b419174fc5e.png?auto=format&fit=clip&q=50) ![A screenshot showing an email from WorkOS and highlighting the custom button color.](https://images.workoscdn.com/images/6da61ac8-82f1-44e6-ab55-33d699841739.png?auto=format&fit=clip&q=50) ## Custom domains WorkOS allows you to customize the domain you send API calls to, the domain used by the Admin Portal, and the from address used in emails sent to your customer's IT admin. ![A screenshot showing the WorkOS Dashboard branding settings page highlighting the custom domains section](https://images.workoscdn.com/images/b6afe130-219c-4e0e-8209-49b1a0fb6098.png?auto=format&fit=clip&q=80) ### Auth link domain Controls the domain you send API calls to and the domain used in URL’s that face your customer’s IT admin such as ACS URL and SP Entity ID. ### Admin Portal domain Controls the domain of Admin Portal setup links and Admin Portal sessions opened by your customer’s IT admin. ### Email domain Controls the from address for emails sent to your customer's IT admin. To configure custom domains, please reach out to [customer support](mailto:support@workos.com) for assistance. ## Team name Your team name is visible in the Admin Portal and in the emails received by your customers’ organization admins. ![A screenshot showing the WorkOS Admin Portal and highlighting the page title.](https://images.workoscdn.com/images/0fd29434-3a5a-43ed-a446-45aec90f75da.png?auto=format&fit=clip&q=50) ![A screenshot showing an email by WorkOS and highlighting the sender name.](https://images.workoscdn.com/images/8d679e97-ceaa-4b94-bb75-290619c94085.png?auto=format&fit=clip&q=50) ## Support email address Add a support email in the Dashboard to streamline communication with your customers’ organization admins. This email will be included in the footer of messages sent to them and set as the reply-to address, making it easy for admins to reach out with any questions. ![A screenshot showing an email with a custom support email address](https://images.workoscdn.com/images/8eb036ab-5fd0-44fe-81f3-6a69a8c38530.png?auto=format&fit=clip&q=50)