# Sign people in with your identity provider

> Canonical HTML: https://screenrig.ai/docs/single-sign-on

People at your organization's verified domains sign in to screenRIG through your
own identity provider: Microsoft Entra ID, Okta, Google Workspace, or any
OpenID Connect or SAML 2.0 provider. Access stays per project. Signing in
identifies a person and adds no project.

## What it does

- **One connection per organization.** An organization admin sets it up in the
  dashboard's Organization settings, under Single sign-on.
- **Your domains decide who uses it.** The sign-in page asks for an email first.
  An address at one of your verified domains continues to your provider.
- **Your provider decides who is let in.** A person nobody holds the address of
  is created at their first sign-in, unless you turn off **Create accounts at
  first sign-in** on the connection. A new person has no project until an
  invitation or a
  [provisioned group](https://screenrig.ai/docs/scim.md#groups-and-projects)
  gives them one.
- **Require single sign-on** refuses passwords and passkeys at your domains.

## Before you start

- You are an admin of the organization.
- The organization has a verified domain. In Organization settings, under
  Verified domains, enter it in **Add a domain**, choose **Get DNS record**,
  publish the TXT record shown, then choose **Verify example.com** (your own
  domain in its place). Keep the record in place: screenRIG checks it daily and
  removes a domain whose record stays missing for 7 days, and single sign-on
  stops for its addresses.
- Changes to the connection ask for your passkey or password. A single sign-on
  session counts instead as a recent sign-in for 10 minutes, but only when your
  provider says when the person authenticated (`auth_time` in OpenID Connect,
  `AuthnInstant` in SAML). Otherwise screenRIG asks the person to sign in again
  at the provider before the change.

Your provider asks for these values:

| Protocol | Value |
| --- | --- |
| OpenID Connect | Redirect URI `https://screenrig.ai/api/sso/oidc/CONNECTION_ID/callback` |
| SAML 2.0 | Entity ID (audience) `https://screenrig.ai/api/sso/saml/CONNECTION_ID` |
| SAML 2.0 | Assertion consumer service (ACS) address, HTTP-POST binding, `https://screenrig.ai/api/sso/saml/CONNECTION_ID/acs` |
| SAML 2.0 | Metadata address, the same address as the entity ID |

Each connection has its own redirect URI, because the connection ID is part of
the address. After you save a connection, the Single sign-on settings in
Organization settings show the exact value of each one under **Values for your
identity provider**, with your connection ID filled in.

## Microsoft Entra ID

The Entra preset signs in the people of one tenant over OpenID Connect.

1. In the Microsoft Entra admin center, open App registrations and choose New
   registration. Name it and choose Accounts in this organizational directory
   only. Leave the redirect URI empty: step 6 adds it.
2. Open Certificates & secrets, create a client secret and copy its **Value**
   now, not its ID.
3. Open Token configuration, choose Add optional claim, choose the type ID and
   add `email` and, beside it, `auth_time`. Without `auth_time` Entra does not
   say when the person authenticated, and a sensitive action sends the person
   back to Entra to sign in again (see [What people see](#what-people-see)).
4. On Overview, copy the Application (client) ID and the Directory (tenant) ID.
5. In Organization settings, under Single sign-on, choose **Set up single
   sign-on**, then **Microsoft Entra ID**. Enter a **Name**, which people see on
   the sign-in page, the **Tenant ID**, the **Client ID** and the **Client
   secret**, and choose **Save connection**.
6. Under **Values for your identity provider**, copy the **Redirect URI**,
   `https://screenrig.ai/api/sso/oidc/CONNECTION_ID/callback` with your
   connection ID. In Entra, open Authentication, add the platform **Web** (not
   Single-page application: the code exchange runs on our server) and enter the
   value.
7. Run a [test sign-in](#test-sign-in).

screenRIG knows a person by their Entra object ID, never by email or user
principal name, which Entra admins can edit: renaming a user keeps their
account. Tokens from any other tenant are refused. screenRIG reads the address
from the `email` claim and, for an Entra tenant, falls back to
`preferred_username` when `email` is absent; the optional claim in step 3 makes
it the person's mail address. Entra does not send `email_verified`, so screenRIG
accepts the address because it is at a domain you verified. Entra lets every user in the tenant sign in unless the enterprise
application's Assignment required is Yes.

## Okta and other OpenID Connect providers

This fits Okta, Auth0, Keycloak and any provider with a discovery document at
`/.well-known/openid-configuration`.

1. In the provider, create a web application that uses the authorization code
   flow. In Okta, choose Applications, Create App Integration, OIDC, Web
   Application. The provider may ask for a redirect URI before screenRIG has
   one for you: enter any https address now and replace it in step 4. Assign the
   people or groups who may sign in.
2. Copy the client ID, the client secret and the issuer, the https address the
   discovery document names. For Okta that is the org URL, such as
   `https://example.okta.com`, or a custom authorization server's address.
3. In Organization settings, under Single sign-on, choose **Set up single
   sign-on**, then **OpenID Connect**. Enter a **Name**, the **Issuer**, the
   **Client ID** and the **Client secret**, and choose **Save connection**.
4. Under **Values for your identity provider**, copy the **Redirect URI**,
   `https://screenrig.ai/api/sso/oidc/CONNECTION_ID/callback` with your
   connection ID, and enter it as the application's redirect URI at the
   provider.
5. Run a [test sign-in](#test-sign-in).

The provider must support PKCE with S256, the `form_post` response mode and ID
tokens signed with an asymmetric algorithm, and must allow the `openid`, `email`
and `profile` scopes. Its ID token must carry an `email` claim: only an Entra
tenant falls back to another claim. An `email_verified` claim, when sent, must
be true. Send an `auth_time` claim where the provider can: it is how screenRIG
learns when the person authenticated.

## SAML 2.0

This fits an Entra enterprise application, Okta, Google Workspace and any other
SAML 2.0 provider. Start in the provider, then enter its metadata in screenRIG,
which shows the values the provider needs.

screenRIG requires each response to meet these conditions:

- The response carries exactly one assertion, and it is not encrypted.
- The assertion itself is signed with RSA or ECDSA and SHA-256 or stronger.
  SHA-1 is refused, and so is a signed response around an unsigned assertion.
- The assertion's issuer is your provider's entity ID, and its audience
  restriction names the screenRIG entity ID.
- The sign-in starts at screenRIG. A tile in your provider's app portal
  (IdP-initiated sign-in) is refused; people start at the screenRIG sign-in page.
- Clocks differ by no more than 3 minutes, and each assertion is used once.
- The NameID is present, in the format persistent, email address or
  unspecified. A transient NameID, or any other format, is refused. The NameID
  is the person's identifier at screenRIG; for Entra it is the object ID
  attribute.
- The email arrives as the attribute `email`, `mail`, `urn:oid:0.9.2342.19200300.100.1.3`,
  `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` or
  `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn`, or as an
  email-format NameID.

### Entra ID

1. Open Enterprise applications, New application, Create your own application,
   and choose Integrate any other application you don't find in the gallery.
2. Open Single sign-on and choose SAML. Under SAML Certificates, download the
   **Federation Metadata XML** and set Signing Option to **Sign SAML assertion**
   or **Sign SAML response and assertion**.
3. In Organization settings, under Single sign-on, choose **Set up single
   sign-on**, then **SAML 2.0**. Enter a **Name**, paste the metadata XML into
   **Metadata document**, and choose **Save connection**. **Values for your
   identity provider** then shows the **Entity ID** and the **Assertion consumer
   service (ACS) address**.
4. In Entra, edit Basic SAML Configuration: the Identifier is the entity ID and
   the Reply URL is the ACS address.
5. Leave the default claims: they carry the person's object ID and mail
   address. Check that the people you assign have a mail address.
6. Assign people under Users and groups, then run a
   [test sign-in](#test-sign-in).

People already signed in over OpenID Connect keep their accounts when a tenant
moves to SAML, and the other way round: both protocols identify a person by the
tenant and the Entra object ID. The SAML response must carry the object
identifier claim, which Entra's default claims include. Without it screenRIG
falls back to the NameID, and an account linked over OpenID Connect no longer
matches (`subject_mismatch`).

### Okta

1. Choose Applications, Create App Integration, SAML 2.0. Okta asks for the
   Single sign-on URL and Audience URI before it shows its metadata: enter any
   https address for both now.
2. Set Name ID format to **Persistent** and Application username to **Email**,
   and add the attribute statement `email` with the value `user.email`. Under
   Show Advanced Settings, leave Assertion Signature on Signed with Signature
   Algorithm RSA-SHA256 and Digest Algorithm SHA256, and Assertion Encryption
   off.
3. Finish, open the Sign On tab and copy the Identity Provider metadata.
4. In Organization settings, under Single sign-on, choose **Set up single
   sign-on**, then **SAML 2.0**. Enter a **Name**, paste the metadata into
   **Metadata document**, and choose **Save connection**. Copy the **Entity ID**
   and the **Assertion consumer service (ACS) address** from **Values for your
   identity provider**.
5. In Okta, edit SAML Settings: the Single sign-on URL is the ACS address and the
   Audience URI is the entity ID.
6. Assign people, then run a [test sign-in](#test-sign-in).

### Google Workspace

1. In the Admin console, open Apps, Web and mobile apps, Add app, and choose
   Add custom SAML app. Name it.
2. Download the Google Identity Provider metadata and continue.
3. In Organization settings, under Single sign-on, choose **Set up single
   sign-on**, then **SAML 2.0**. Enter a **Name**, paste the metadata into
   **Metadata document**, and choose **Save connection**. Copy the **Entity ID**
   and the **Assertion consumer service (ACS) address** from **Values for your
   identity provider**.
4. In Google, enter the ACS address and the entity ID. Set Name ID format to
   **PERSISTENT** and Name ID to Basic Information, Primary email. Leave
   **Signed response** unchecked: Google then signs the assertion, which
   screenRIG requires.
5. Map the Google Directory attribute Primary email to the app attribute
   `email`.
6. Open the app's User access and turn it on for the people who sign in, then
   run a [test sign-in](#test-sign-in).

### Rotate a certificate

A connection trusts up to four signing certificates, so a rotation has no gap.
Paste the new certificate beside the old one (or paste the provider's new
metadata, which lists both) and save, switch the provider to the new
certificate, then remove the old one.

## Test sign-in

Press **Test sign-in** in Organization settings. You sign in at your provider and
return to the dashboard, which shows the address the provider sent and whether
it sent a stable identifier. A test signs nobody in. A failed test shows the
message for one of the [error codes](#troubleshooting). The address must be at a
verified domain.

A successful test, or a real sign-in, through the connection's current
provider, tenant, entity ID and protocol is what allows you to require single
sign-on.

## Require single sign-on

Choose **Require single sign-on** in Organization settings after a successful
test, pick the break-glass admins and confirm. For everyone at your verified
domains:

- The sign-in page offers only your provider. A password or a passkey is
  refused with `sso_required`. Passwords and passkeys stay on the account,
  unused, and work again if you turn the requirement off.
- An existing account whose verified address is at your domain signs in to the
  same account at its first single sign-on, whatever sign-in methods it holds,
  and keeps its projects. Your organization then manages it: its email follows
  your provider at each sign-in and the person cannot change it.
- **Break-glass admins.** Choose up to two organization admins who hold a
  passkey. They keep passkey sign-in for the day your provider is down, and
  each such sign-in is recorded. **Change break-glass admins** changes the
  choice later.
- While the requirement is on, the connection's issuer, tenant ID, entity ID
  and protocol cannot change and the connection cannot be removed. Certificates
  and the client secret can be rotated.

**Turning it off takes 72 hours.** Choose **Turn off requirement**: the requirement
stays in force until then, every admin gets an email, and any admin can choose
**Cancel removal**.

## What people see

- The sign-in page asks for the email first and continues to your provider. The
  answer depends on the domain alone, so it does not show whether a person has
  an account.
- A session lasts 24 hours from the sign-in at screenRIG, and use does not
  extend it. After 12 hours the dashboard renews it silently at the next page,
  and it signs in again the same way after a session ends. A silent start sends
  no login hint, so the provider answers for the account it holds a session for;
  if that is another person, the renewal fails with `subject_mismatch`. A person
  whose provider session is alive types nothing; otherwise they sign in again.
- An action that asks for a passkey or password, such as changing the
  connection, accepts instead a single sign-on session that counts as a recent
  sign-in for 10 minutes. It counts only when your provider says when the person
  authenticated: the provider's own time (`auth_time` in OpenID Connect,
  `AuthnInstant` in SAML), not the time of the sign-in at screenRIG. When the
  provider names no time, or names one older than 10 minutes, screenRIG asks the
  person to sign in again at the provider: the dashboard sends the person through
  the provider for a fresh authentication and returns them to where they were.
- A person your provider disables loses access within 24 hours, and at once with
  [user provisioning](https://screenrig.ai/docs/scim.md). Agents and OAuth
  grants a person approved keep working until the person is deactivated, by user
  provisioning or by screenRIG staff: requiring single sign-on and disabling the
  person at your provider do not end them.

## Link an existing account

A person at your verified domain who already has a screenRIG account with a
password or passkey is not signed in to it by a first single sign-on
(`account_exists`), unless you require single sign-on. They sign in as before,
open **Profile and sign-in** at `https://screenrig.ai/dashboard/me`, choose
**Link single sign-on** and sign in at the provider. From then on single
sign-on opens the same account, which keeps its own sign-in methods. Profile
and sign-in offers the link to every signed-in person at your domain who has
not linked yet.

## Troubleshooting

A failed sign-in returns to the sign-in page with the code in the address
(`#sso_error=CODE`). A failed test shows the message for its code on the
connection.

| Code | Cause | Fix |
| --- | --- | --- |
| `no_email` | The provider sent no email address, or one that is not an address | OpenID Connect: send the `email` claim (Entra: add the `email` optional claim). SAML: send the attribute `email`. Check the person has a mail address |
| `email_unverified` | The provider marked the address unverified | Verify the address at the provider |
| `domain_not_allowed` | The address is not at a verified domain | Verify the domain, or change the address the provider sends |
| `account_exists` | An account with its own sign-in holds the address, or another account holds this identity | The person signs in as before and [links](#link-an-existing-account) the account. If another account holds the identity, they use another address |
| `managed_elsewhere` | Another organization's provider manages this person | The person signs in through that organization, or uses another address |
| `subject_mismatch` | The account is linked to a different identity at this provider, as when an address passes to someone new; or a link, renewal or invitation names a different person than the one signed in | The person signs in with the identity linked to the account, or uses another address |
| `not_provisioned` | Nobody holds the address and the connection does not create people | [Provision](https://screenrig.ai/docs/scim.md) the person, or turn on Create accounts at first sign-in |
| `sso_required` | Your organization requires single sign-on for this address | Sign in through the provider |
| `staff_account` | A screenRIG staff account never signs in through a customer's provider | Use another address |
| `expired` | The sign-in took longer than 10 minutes, or the invitation it carried has expired | Start again from the sign-in page, or ask for a new invitation |
| `bad_state` | The sign-in does not match this browser, began at the provider's app portal or was already used; or its invitation was accepted already or can no longer be used | Start again in one browser from the sign-in page, not from the provider's app portal. Ask for a new invitation if needed |
| `interaction_required` | A silent renewal needs the person | Sign in again |
| `provider_refused` | The provider answered with an error, or its token endpoint refused the sign-in code | Assign the person to the application, check the client ID and client secret (Entra secrets expire) and, for Entra, that the redirect URI platform is Web, and read the provider's sign-in log |
| `provider_unavailable` | The provider could not be reached or read | Check the issuer or tenant ID, and that the provider's discovery document (OpenID Connect) or sign-in address (SAML) answers over https. Try again |
| `verification_failed` | The token or assertion failed verification, or the discovery document names another issuer | Check the tenant, issuer, client ID, entity IDs and clock; SAML: sign the assertion with SHA-256 or stronger, and add the provider's current certificate |
| `deactivated` | The person is deactivated | If user provisioning deactivated them, set them active in your provider. Otherwise contact screenRIG support |

## Related

- [User provisioning](https://screenrig.ai/docs/scim.md): create, update and remove people from your provider, and give groups access to projects.
- [Authentication](https://screenrig.ai/docs/authentication.md): how agents sign in and how access is approved.
- [API reference](https://screenrig.ai/docs/api.md): the connection, policy and sign-in routes.
