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

# Okta SAML

> Connect Modem to Okta with a SAML 2.0 app integration

This guide sets up [Enterprise SSO](/docs/enterprise/sso) with Okta using a SAML 2.0 app integration. Read the overview first if you haven't — it covers domain verification, roles, and the limitations that apply to every provider.

Okta's admin console is redesigned regularly, so treat the menu paths and field labels below as a guide; the exact labels move between Okta releases.

## Prerequisites

* Enterprise SSO enabled for your Modem organization, and the **owner** role in it
* Administrator access to your Okta org, with permission to create app integrations
* Access to DNS for the email domain you are claiming

## Setup

Setup runs in two passes, because Okta needs an Audience URI that Modem only issues once the provider exists.

<Steps>
  <Step title="Create the SAML app integration in Okta">
    In the Okta Admin Console, go to **Applications** → **Applications** → **Create App Integration**, choose **SAML 2.0**, and give
    the app a name such as `Modem`.
  </Step>

  <Step title="Fill in the Configure SAML step">
    On the **Configure SAML** step:

    * **Single sign-on URL** — the ACS URL from Modem, `https://app.modem.dev/api/auth/sso/saml2/sp/acs/org-<id>`. Leave **Use this
      for Recipient URL and Destination URL** checked.
    * **Audience URI (SP Entity ID)** — a placeholder for now, for example `https://app.modem.dev`. You replace this in step 6 with the
      SP Entity ID Modem generates.
    * **Name ID format** — `Unspecified` or `Persistent`. Either works.
    * **Application username** — see [Sending the Okta user id](#sending-the-okta-user-id) below. This is the setting that decides the
      NameID *value*, and it is the one thing worth getting right the first time.

    Leave **Response** and **Assertion Signature** at their defaults. Okta signs the assertion out of the box, which is what Modem
    requires; Modem rejects unsigned assertions, and signing the response as well is fine but not required.
  </Step>

  <Step title="Add the attribute statements">
    Still on **Configure SAML**, under **Attribute Statements**, add three attributes. The names have to match exactly — Modem looks
    them up by name.

    | Name        | Value            |
    | ----------- | ---------------- |
    | `email`     | `user.email`     |
    | `givenName` | `user.firstName` |
    | `surname`   | `user.lastName`  |
  </Step>

  <Step title="Copy Okta's SAML details">
    Finish the wizard, then open the app's **Sign On** tab and click **View SAML setup instructions** (in some Okta versions this is a
    **More details** panel). Copy:

    * **Identity Provider Single Sign-On URL**
    * **Identity Provider Issuer**
    * The **X.509 Certificate**

    Alternatively, open the **Identity Provider metadata** link and copy the XML document it serves. Modem accepts either the
    certificate or the metadata XML itself — paste the XML, not the link, since Modem does not fetch it for you.
  </Step>

  <Step title="Register Okta in Modem">
    In the [Modem dashboard](https://app.modem.dev), go to **Settings** → **SSO**, choose SAML 2.0, and enter the sign-on URL, issuer,
    and certificate (or the metadata XML) you just copied, along with the email domain you are claiming.
  </Step>

  <Step title="Paste Modem's SP Entity ID back into Okta">
    The SSO settings page now shows Modem's **SP Entity ID (Audience URI)**. Copy it exactly, return to the Okta app's **General** tab
    → **SAML Settings** → **Edit**, and replace the placeholder **Audience URI (SP Entity ID)** with it. Save.

    <Note>
      The SP Entity ID will look like your Okta org's own issuer URL. That is expected — copy it exactly as Modem shows it rather
      than adjusting it to look more like a Modem URL.
    </Note>
  </Step>

  <Step title="Assign the app to your users">
    On the app's **Assignments** tab, assign it to the people or groups who should have access to Modem. Anyone not assigned cannot
    sign in.
  </Step>

  <Step title="Verify your email domain">
    Publish the DNS TXT record Modem shows on the SSO settings page and click verify. Sign-in is refused until this succeeds — see
    [Domain verification](/docs/enterprise/sso#domain-verification).
  </Step>
</Steps>

## Sending the Okta user id

In Okta, the NameID *value* comes from the app's **Application username** setting, not from the Name ID format. To send the Okta user id, set **Application username** to **Custom** and use the expression:

```
user.id
```

Do not use `user.email` or `user.login`.

<Warning>
  The NameID is the key Modem hangs the account off, and it must be a stable, immutable id. [Directory
  Sync](/docs/enterprise/scim) matches directory users to Modem users by **`externalId`**, which has to be the **same value** — the Okta
  user id. Okta's SCIM integration sends the Okta user id as `externalId` by default, so `user.id` here pairs cleanly with it. See
  [Okta provisioning](/docs/enterprise/scim-okta).

  Email addresses change. Matching on email is how an account ends up handed to the wrong person.
</Warning>

## Attribute mapping

| What Modem wants | Okta value                                        | Notes                                             |
| ---------------- | ------------------------------------------------- | ------------------------------------------------- |
| Account identity | NameID, from **Application username** = `user.id` | The immutable Okta user id                        |
| Email            | Attribute `email` = `user.email`                  | Modem falls back to the NameID if this is missing |
| First name       | Attribute `givenName` = `user.firstName`          |                                                   |
| Last name        | Attribute `surname` = `user.lastName`             |                                                   |

## Testing the sign-in

Sign out of Modem, or use a private window, then:

1. Go to `https://app.modem.dev`
2. Click **Continue with SSO**
3. Enter your work email address, or your Modem organization slug
4. Complete the Okta prompt

You should land back in Modem signed in. A user who has never used Modem before gets an account and joins as a **member**, unless they had a pending invitation carrying a different role.

<Warning>
  Do not test by clicking the Modem tile on your Okta dashboard. Modem accepts **SP-initiated** sign-in only, so an IdP-initiated launch
  is rejected with "Start single sign-on from Modem". This is the single most common support question — it is worth telling your team up
  front to start from the Modem sign-in page.
</Warning>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Start single sign-on from Modem">
    The sign-in started from the Okta dashboard tile rather than from Modem. Go to `https://app.modem.dev` and click **Continue with
    SSO**. If it helps, edit the app's tile in Okta to link to `https://app.modem.dev` so the tile sends people to the right place.
  </Accordion>

  <Accordion title="Single sign-on is not finished being set up">
    The domain has not been verified yet. Publish the DNS TXT record from the SSO settings page and click verify. DNS can take minutes
    to hours to propagate; retrying is safe.
  </Accordion>

  <Accordion title="Okta reports an audience or destination mismatch">
    The **Audience URI (SP Entity ID)** in Okta does not match the SP Entity ID Modem shows, or the **Single sign-on URL** is not the
    ACS URL from Modem. Copy both again from the SSO settings page, character for character.
  </Accordion>

  <Accordion title="Users sign in but their names or emails are wrong">
    Check the attribute statements. The names have to be exactly `email`, `givenName`, and `surname` — Okta will happily save a
    misspelled name, and Modem then falls back to the NameID.
  </Accordion>

  <Accordion title="The certificate expired or was rotated">
    Okta signing certificates have an expiry. When you roll one in Okta, copy the new **X.509 Certificate** from **View SAML setup
    instructions** and update it on the Modem SSO settings page, otherwise assertions stop validating.
  </Accordion>

  <Accordion title="A user is not assigned">
    Okta refuses the sign-in before it ever reaches Modem if the person is not assigned to the app. Check the app's **Assignments** tab.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Enterprise SSO" icon="https://mintcdn.com/modem-844d7a4a/Wr2r4IRr97lNQiQb/icons/shield.svg?fit=max&auto=format&n=Wr2r4IRr97lNQiQb&q=85&s=ee1ca3093fcbdf45ec5dc1a74652bed6" href="/docs/enterprise/sso" width="24" height="24" data-path="icons/shield.svg">
    Requirements, domain verification, and sign-in behaviour.
  </Card>

  <Card title="Team Management" icon="https://mintcdn.com/modem-844d7a4a/Wr2r4IRr97lNQiQb/icons/users.svg?fit=max&auto=format&n=Wr2r4IRr97lNQiQb&q=85&s=32a2de5620a3659206db1c3d1aff5a06" href="/docs/features/team-management" width="24" height="24" data-path="icons/users.svg">
    Roles, invitations, and auto-join.
  </Card>
</CardGroup>
