# Enterprise SSO

> **Enterprise plan.** Single sign-on lets your team log into the panel with
> your own identity provider (IdP) — Okta, Microsoft Entra ID, Google
> Workspace, Keycloak, Auth0, or any standards-compliant **OpenID Connect** or
> **SAML 2.0** provider.

With SSO enabled, people from your organisation sign in with their corporate
account instead of an email/password or personal GitHub login. Accounts are
provisioned automatically on first sign-in and placed on your Enterprise plan.

## How it works

1. An admin on the Enterprise plan adds an SSO **provider config** in
   **Settings → Enterprise SSO** (one for OIDC or SAML).
2. The config names the **email domains** it covers (e.g. `acme.com`).
3. A user clicks **Sign in with SSO** on the login page and enters their work
   email. The panel matches the email's domain to your provider and redirects
   to your IdP.
4. After the IdP authenticates them, the panel verifies the response, reads
   their email (and name), and signs them in — creating the account on first
   visit.

Only the email domains you list are accepted. A response for any other domain is
rejected, so configuring a provider never lets in users outside your
organisation.

## Set up OpenID Connect (OIDC)

In your IdP, create an **OIDC / OAuth web application** and note its **issuer
URL**, **client ID**, and **client secret**. Set the application's redirect URI
to the value the panel shows you:

```
https://<your-panel-host>/auth/sso/oidc/callback
```

Then in **Settings → Enterprise SSO → Add provider**:

| Field | Value |
|-------|-------|
| Protocol | **OpenID Connect** |
| Display name | e.g. "Acme Okta" |
| Allowed domains | `acme.com` (comma-separate multiple) |
| Issuer URL | your IdP's issuer (the panel runs OIDC discovery on it) |
| Client ID / Client secret | from the IdP application |

Save, then toggle the provider **Enabled**. The panel requests the `openid
email profile` scopes and validates the ID token signature, issuer, audience,
and a per-login nonce.

## Set up SAML 2.0

When you create a SAML provider the panel generates a **Service Provider (SP)
certificate** and shows you the values your IdP needs:

| Panel value | Use in your IdP |
|-------------|-----------------|
| **SP entity ID / metadata URL** | `…/auth/sso/saml/metadata?config=<id>` |
| **ACS (reply) URL** | `…/auth/sso/saml/acs` |
| **SP certificate** | upload if your IdP wants the SP signing cert |

In your IdP, create a **SAML application** and either point it at the SP
metadata URL or paste the ACS URL + entity ID. Configure it to release the
user's **email** (NameID or an `email`/`mail` attribute) and optionally a
display name.

Back in the panel, give the panel your IdP's details — the easiest is the IdP's
**metadata URL**; alternatively paste the **IdP SSO URL** and its **signing
certificate (PEM)**. Set the allowed domains, save, and enable.

The panel validates the assertion signature against your IdP certificate, checks
the audience and timing, and reads the email/name attributes.

## Attribute mapping

By default the panel reads the `email` claim (OIDC) or a standard email
attribute / NameID (SAML), and a `name` / `preferred_username` for the display
name. If your IdP uses non-standard names, set **Email attribute** / **Name
attribute** overrides under *Advanced* in the provider form.

## The sign-in experience

- Login page → **Sign in with SSO** → enter work email → redirected to your IdP
  → back to the dashboard.
- IdP-initiated sign-in (launching the app from your IdP dashboard) is supported
  for SAML.

## Provisioning & deprovisioning

Users are created on first SSO sign-in. To **automatically deactivate** people
when they leave your organisation, connect your IdP's **SCIM** provisioning —
see [SCIM provisioning](/docs/scim). A deactivated account can no longer sign in
by any method.

## Troubleshooting

| Symptom | Likely cause |
|---------|--------------|
| "No SSO provider is configured for your email domain" | The email's domain isn't in any **enabled** provider's allowed domains. |
| "Your email domain is not authorized" | The IdP returned an email outside the allow-list. |
| "did not return a valid email" | The IdP isn't releasing an email claim/attribute — check attribute mapping. |
| OIDC discovery / metadata fetch fails | The issuer or metadata URL is wrong or unreachable from the panel. |
| SAML assertion validation failed | The IdP signing certificate in the config doesn't match what signed the response. |

Every sign-in attempt (success or failure, with a reason) is recorded for your
account so an admin can diagnose issues.

## Related

- [Connect GitHub](/docs/connect-github) — for individual (non-SSO) accounts
- [Trust ladder & plans](/docs/trust-and-plans)
