> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Generic SAML SSO

> Set up SAML Single Sign-On with any SAML 2.0 identity provider.

export const idp_0 = "your IdP"

Connect any SAML 2.0 identity provider (IdP) to StackOne, so users sign in with their IdP credentials.

<Tip>
  If the IdP is Okta or Microsoft Entra ID, follow the [Okta](/secure/identity-and-access/authentication/sso/okta) or [Microsoft Entra](/secure/identity-and-access/authentication/sso/microsoft-entra) guide instead.
</Tip>

Before setting up SAML SSO, you need:

* The **Organization Admin** role in StackOne.
* Admin access to the IdP, to create and configure a SAML application.
* The ability to add a DNS TXT record for your email domain, which proves you own it.

## Start the connection in StackOne

<Steps>
  <Step title="Choose Other SAML 2.0 provider">
    1. Go to [**Organization > Security > SSO**](https://app.stackone.com/organization/security/sso).
    2. Click **Get started**.
    3. Select **Other SAML 2.0 provider**, then click **Continue**.
  </Step>

  <Step title="Name the connection and set the domain">
    On the **Connection details** step, fill in both fields, then click **Continue**:

    * **Connection name**: a name for the connection. StackOne generates the connection's unique ID from it.
    * **Domain**: the email domain your users sign in with.
  </Step>

  <Step title="Copy the service provider values">
    The **Configure your identity provider** step has the values you need when you create the app in your IdP. Field names vary by IdP:

    * **ACS URL (Single sign-on URL)**: where the IdP posts the SAML assertion. Often called Assertion Consumer Service URL or Reply URL.
    * **SP Entity ID (Audience)**: identifies StackOne to the IdP. Often called Audience URI, Entity ID or Identifier.
    * **Default RelayState**: the dashboard URL, where an IdP-initiated sign-in lands. Set it only if the IdP supports IdP-initiated sign-in.

    <Note>
      Keep this StackOne tab open. You return to the wizard to register the provider after you build the app in your IdP.
    </Note>

    <Frame>
      <img src="https://mintcdn.com/stackone-60/z6bSbDsMY4CzvXKv/images/secure/identity-and-access/authentication/sso/sso-configure.png?fit=max&auto=format&n=z6bSbDsMY4CzvXKv&q=85&s=3c0ece55474bc1766d881c92a885bd1c" alt="The Configure your identity provider step showing the ACS URL, SP Entity ID, and Default RelayState" style={{ maxWidth: "360px" }} width="862" height="1400" data-path="images/secure/identity-and-access/authentication/sso/sso-configure.png" />
    </Frame>
  </Step>
</Steps>

## Create the SAML app in your IdP

<Steps>
  <Step title="Create the SAML application">
    1. In the IdP's admin console, create a new SAML 2.0 application for StackOne.
    2. Set the following:
       * **Single sign-on URL** (or Assertion Consumer Service URL): the **ACS URL** from StackOne.
       * **Audience URI** (or Entity ID): the **SP Entity ID** from StackOne.
       * **Relay State** (optional): the **Default RelayState** from StackOne.
  </Step>

  <Step title="Set the Name ID to the user's email">
    Set the following:

    * **Name ID format**: `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`.
    * **Name ID value**: the user's work email, not a username, UPN or object ID.

    Optionally, also send the email as an attribute named `email`. StackOne uses it when present, and falls back to the Name ID otherwise.
  </Step>

  <Step title="Send the user's name">
    Add attributes named `givenName` and `surname`, or a single `displayName`. These set the user's display name in StackOne.

    <Note>
      Adding these to an existing app only sets names for new users. To sync names for existing users, use [SCIM Provisioning](/secure/identity-and-access/manage-team/scim/overview).
    </Note>
  </Step>

  <Step title="Sign the assertion">
    Enable assertion signing in the IdP. StackOne validates the signature against the certificate you register in StackOne.

    <Warning>
      Register the exact certificate the IdP signs with. A mismatch makes every sign-in fail with a certificate error, even when every other value is correct.
    </Warning>
  </Step>

  <Step title="Assign users">
    Assign the users or groups who should sign in to StackOne through this application, then save the app.

    Only assigned users can complete SSO.
  </Step>

  <Step title="Get the identity provider metadata">
    From the IdP's SAML settings, get the values StackOne needs.

    <Tabs>
      <Tab title="Metadata XML">
        Download the IdP's SAML metadata XML.
      </Tab>

      <Tab title="Manual values">
        Copy these values for StackOne:

        * **Issuer (Entity ID)**: the IdP's unique identifier.
        * **Single Sign-On URL**: the IdP's login endpoint.
        * **X.509 signing certificate**: in PEM format.
      </Tab>
    </Tabs>
  </Step>
</Steps>

## Register the provider in StackOne

Switch back to the StackOne tab and continue to the **Register your SSO provider** step.

<Steps>
  <Step title="Provide the IdP values">
    Supply the three values from the IdP.

    <Tabs>
      <Tab title="Metadata XML">
        1. Click **Upload SAML metadata file**.
        2. Select the metadata XML you downloaded. StackOne fills in **Entity ID (Issuer)**, **SSO URL (Entry Point)**, and **X.509 Certificate**.
        3. Review the imported values before continuing.
      </Tab>

      <Tab title="Manual values">
        Set the following:

        * **Entity ID (Issuer)**: the IdP's **Issuer (Entity ID)**.
        * **SSO URL (Entry Point)**: the IdP's **Single Sign-On URL**.
        * **X.509 Certificate**: the IdP's **X.509 signing certificate**.

        <Frame>
          <img src="https://mintcdn.com/stackone-60/z6bSbDsMY4CzvXKv/images/secure/identity-and-access/authentication/sso/sso-register-filled.png?fit=max&auto=format&n=z6bSbDsMY4CzvXKv&q=85&s=d9e842acf91bace5237e148767ddb808" alt="The Register your SSO provider step with the Entity ID, SSO URL, and X.509 Certificate fields" style={{ maxWidth: "360px" }} width="952" height="1250" data-path="images/secure/identity-and-access/authentication/sso/sso-register-filled.png" />
        </Frame>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Register the connection">
    Select **Continue**. The connection is registered, but stays inactive until the domain is verified.
  </Step>
</Steps>

## Verify the domain

Verification proves the organization owns the domain and activates SSO. Once it's verified, existing StackOne users on the domain are linked to the SSO connection, so they keep one account.

<Steps>
  <Step title="Copy the DNS TXT record">
    On the wizard's **Verify your domain** step, copy the record's **Name** and **Value**. The **Value** has this form:

    ```
    _stackone-sso-verification-token-{providerId}={token}
    ```

    <Frame>
      <img src="https://mintcdn.com/stackone-60/z6bSbDsMY4CzvXKv/images/secure/identity-and-access/authentication/sso/sso-verify-domain.png?fit=max&auto=format&n=z6bSbDsMY4CzvXKv&q=85&s=9b7b1f0ab83e666df9083f1c859b250e" alt="StackOne's Verify your domain step showing the DNS TXT record name and value." width="1028" height="822" data-path="images/secure/identity-and-access/authentication/sso/sso-verify-domain.png" />
    </Frame>
  </Step>

  <Step title="Add the record to DNS">
    In the domain's DNS panel, add a TXT record:

    * **Name/Host**: the domain. Use `@` if it's the root of the DNS zone, or the subdomain label if the email domain is a subdomain.
    * **Value**: the full `_stackone-sso-verification-token-...` string, as its own value. Don't append it to an existing TXT value, such as an SPF record.

    <Warning>
      Add the `_stackone-sso-verification-token-...` string as the record's **Value**, not its Name. It looks like a DNS host label, as `_dmarc` and `_domainkey` do, so it's easy to paste into **Name/Host** by mistake. A record on the wrong name fails verification without an error.
    </Warning>

    <Accordion title="Add the record in common DNS providers">
      <Tabs>
        <Tab title="Cloudflare">
          1. Go to **DNS > Records** and select **Add record**.
          2. Set **Type** to `TXT` and **Name** to `@` for the root domain, or the subdomain label, such as `eu` for `eu.acme.com`.
          3. Paste the token into **Content**.

          Cloudflare allows several TXT records at the same name, so add a new record rather than editing an existing one.
        </Tab>

        <Tab title="AWS Route 53">
          1. Open the hosted zone and select **Create record**.
          2. Set **Record type** to `TXT`. Leave **Record name** blank for the root domain, or enter the subdomain label, such as `eu` for `eu.acme.com`.
          3. Paste the token in quotes.

          If a TXT record already exists at that name, edit it and add the token as a new line instead.
        </Tab>

        <Tab title="Google Cloud DNS">
          1. Open the zone and add a standard record set.
          2. Set the type to `TXT`, with the DNS name set to the email domain, such as `acme.com` or `eu.acme.com`.
          3. Paste the token.

          If a TXT record set already exists, edit it and add the token as a new item instead.
        </Tab>

        <Tab title="GoDaddy">
          1. Open the domain's DNS records and select **Add New Record**.
          2. Set **Type** to `TXT` and **Name** to `@` for the root domain, or the subdomain label, such as `eu` for `eu.acme.com`.
          3. Paste the token into **Value**.
        </Tab>

        <Tab title="Namecheap">
          1. Open **Advanced DNS** and select **Add New Record**.
          2. Choose **TXT Record**, and set **Host** to `@` for the root domain, or the subdomain label, such as `eu` for `eu.acme.com`.
          3. Paste the token into **Value**.
        </Tab>
      </Tabs>
    </Accordion>

    <Note>
      DNS changes can take up to 48 hours to propagate, though they often complete within minutes. Check what's publicly visible with [Google Admin Toolbox Dig](https://toolbox.googleapps.com/apps/dig/#TXT/).
    </Note>
  </Step>

  <Step title="Verify in StackOne">
    1. Select **Verify**. Once the record is visible, the domain is verified and SSO is active.
    2. Select **Finish** to close the wizard.

    If the check fails, wait for DNS to propagate and try again.

    <Note>
      To finish setup first, select **Verify Later**, then verify afterward from the **Trusted Domain** card on the connection's **General** tab.
    </Note>

    <Frame>
      <img src="https://mintcdn.com/stackone-60/z6bSbDsMY4CzvXKv/images/secure/identity-and-access/authentication/sso/sso-connection-verified.png?fit=max&auto=format&n=z6bSbDsMY4CzvXKv&q=85&s=5b06e7048c8c6faf0c51e2221e4c16f2" alt="StackOne SSO connection card showing the domain as verified and SSO active" width="1568" height="716" data-path="images/secure/identity-and-access/authentication/sso/sso-connection-verified.png" />
    </Frame>
  </Step>
</Steps>

## Manage the connection

Open the connection from [**Organization > Security > SSO**](https://app.stackone.com/organization/security/sso). The **General** tab is where you maintain it after setup:

* Select **Edit SAML** to update the identity provider values, either by uploading new metadata XML or by editing the **Entity ID (Issuer)**, **SSO URL (Entry Point)**, and **X.509 Certificate** directly.
* Select **Edit Domain** to change the trusted domain. Changing it resets verification, so users stop being redirected until you verify it again. You can't change it while SSO is enforced.

<Frame>
  <img src="https://mintcdn.com/stackone-60/z6bSbDsMY4CzvXKv/images/secure/identity-and-access/authentication/sso/sso-connection-general.png?fit=max&auto=format&n=z6bSbDsMY4CzvXKv&q=85&s=5c5aa471ae3d123dc2f76a56cebe9e20" alt="The connection's General tab, showing the SAML 2.0 Configuration values (Single sign-on URL, Audience URI, Default Relay State) and the Trusted Domain verification status." width="1568" height="716" data-path="images/secure/identity-and-access/authentication/sso/sso-connection-general.png" />
</Frame>

From the connection's page header:

* **Settings** edits the **Connection name**. The **Provider ID** is generated at setup and can't be changed.
* **Delete** removes the SSO connection. It's disabled while SSO is enforced, so turn off enforcement on the **Authentication** tab first.

To require users to sign in through {idp_0}, see [Require SSO](/secure/identity-and-access/authentication/sso/overview#require-sso).

<Warning>
  Deleting the connection sends users on the domain back to email and password sign-in, so make sure they have another way in first. To change SAML values, use **Edit SAML** instead.

  Deleting it also removes SCIM Provisioning, if linked, and revokes its token. Provisioning from {idp_0} then fails with `401` until you link SCIM again and paste the new token into {idp_0}. Users already provisioned keep their access.
</Warning>

<Tip>
  To add, update and deactivate users automatically from your IdP, set up [SCIM Provisioning](/secure/identity-and-access/manage-team/scim/overview) once the domain is verified.
</Tip>

## Troubleshooting

| Symptom | Likely cause | Fix |
| - | - | - |
| `403 Forbidden` when opening SSO | You lack the **Organization Admin** role. | Ask an **Organization Admin** to make the change or to grant you the role. |
| `ERROR_UNMATCH_CERTIFICATE_DECLARATION_IN_METADATA` | The registered certificate doesn't match the one the IdP signs with. | Re-copy the active **X.509 signing certificate** from the IdP and update it on the connection's **General** tab via **Edit SAML**. |
| `ERR_UNMATCH_ISSUER` | The **Entity ID (Issuer)** doesn't match the issuer the IdP sends. | Copy the issuer from the IdP's SAML metadata and update it via **Edit SAML**. |
| Sign-in fails or signs in the wrong user | The Name ID value isn't the user's email, the format is set to email address, but the value is still a username, UPN, or object ID. | Set the Name ID value to the user's work email (see [Set the Name ID to the user's email](#create-the-saml-app-in-your-idp)). |
| "Provider domain has not been verified" | Domain verification hasn't completed. | Finish [Verify the domain](#verify-the-domain). |
| Domain verification keeps failing | The TXT record is on the wrong name, was appended to an existing value, or DNS hasn't propagated. | Use `@` for a root domain or the subdomain label otherwise, add the token as its own TXT value, and check propagation with [Dig](https://toolbox.googleapps.com/apps/dig/#TXT/). |
| Users not redirected to the IdP | The domain isn't verified, or the user isn't assigned to the SAML application. | Verify the domain, and confirm the user is assigned in the IdP. |

## Next steps

<CardGroup cols={2}>
  <Card title="Single Sign-On" icon="shield-halved" href="/secure/identity-and-access/authentication/sso/overview">
    How SSO, SCIM Provisioning, and domain verification fit together.
  </Card>

  <Card title="Okta SSO" icon="https://stackone-logos.com/api/okta/filled/svg" href="/secure/identity-and-access/authentication/sso/okta">
    The same setup with Okta's field names and screenshots.
  </Card>

  <Card title="Microsoft Entra SSO" icon="https://stackone-logos.com/api/microsoft-entra/filled/svg" href="/secure/identity-and-access/authentication/sso/microsoft-entra">
    The same setup with Microsoft Entra ID.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.