Skip to main content

Enroll SAML SSO

Connect your identity provider so your team signs into the Orbit dashboard through SAML 2.0 single sign-on: they authenticate at your IdP (Okta, Microsoft Entra ID, or any SAML 2.0 IdP) and land in Orbit with a session — no separate Orbit password. This guide walks the full enrollment: probing your IdP metadata, writing the config, enforcing SSO, testing the flow, and rotating certificates. For the endpoint spec, see the Settings API single sign-on table; for the public login endpoints, see Authentication. SAML and SCIM are independent controls that pair well together: SAML controls how users sign in, SCIM controls which users exist. Both are per-organization, tenant-owned controls — nothing enables SAML except an owner in your workspace, an organization without an IdP keeps password sign-in, and Orbit does not require SSO for any compliance certification. It’s your enforcement option, not a mandate.

Before you start

Collect these before touching Orbit:
  1. An owner role in the Orbit organization. Creating and changing SAML configuration is owner-only; admins can read the config and probe metadata but cannot save changes.
  2. Your IdP’s signing certificate (X.509, PEM format). Okta shows it under the app’s Sign On tab; Entra ID under the enterprise application’s Certificates blade.
  3. Your IdP’s SSO URL and entity ID. If you don’t have them handy, the metadata probe below can suggest them from a metadata URL.
  4. An attribute mapping plan — decide which assertion attributes carry email and name (the canonical table below covers Okta and Entra defaults).
  5. A decision on enforcement: will password sign-in stay available while you test, and when (if ever) do you flip to SSO-only? Plan a staging window before you enforce.

Step 1 — Discover the IdP with a metadata probe

Most IdPs publish a metadata URL (Okta’s “Identity Provider metadata” link, Entra’s “Federation metadata document”) that describes the SSO endpoint and entity ID. Probe it before you write anything, so you save known-good values:
The probe fetches the URL (public https only — private, internal, or loopback addresses are rejected), confirms it returns SAML metadata, and answers with:
  • oktrue when the document fetched and looked like SAML metadata.
  • suggested_sso_url — the URL from the <SingleSignOnService> element, when present.
  • suggested_entity_id — the document’s entityID, when present.
Use the suggestions directly in the next step. If your IdP has no metadata URL, skip the probe and paste the SSO URL and entity ID from the IdP admin console by hand.

Step 2 — Write the SAML configuration

Save the config through the dashboard (Settings → Security → Single sign-on) or the API. First-time setup must include x509Cert:
  • ssoUrl — the IdP’s sign-on endpoint (https, publicly resolvable).
  • entityId — the IdP’s issuer identifier (often a URN or URL).
  • x509Cert — the PEM signing certificate. Required on first setup; stored afterwards — omit it on later PATCHes to keep the existing certificate while you change other fields.
  • attrEmail / attrName — the assertion attribute names Orbit reads for the sign-in’s email and display name (see the IdP table below).
  • enabledtrue turns SSO on. Keep enforced: false while you test.
  • enforced — leave false until step 5.
The response echoes the saved config with cert_fingerprint_sha256 — the raw certificate is never returned. Compare the fingerprint to the one your IdP renders to confirm you saved the right certificate. You can also preview a certificate before saving with POST /api/v1/settings/saml/parse-certificate (sends { "pem": "..." }, returns subject, issuer, and validity window without persisting anything).

IdP attribute defaults

Whatever you set must match what your IdP actually sends in the assertion. If the IdP asserts a claim you haven’t mapped (Okta stock templates assert mail; Entra stock templates assert displayname and emailaddress, exact casing depends on your app), wire the mapped names to match — a mismatch means users authenticate at the IdP but the sign-in fails reading attributes.

Step 3 — Point the IdP at Orbit

In your IdP admin console, add an Orbit application (or reuse the one you provisioned for SCIM) with:
  • ACS URL (Assertion Consumer Service): https://api.orbit.devotel.io/auth/saml/{orgSlug}/callback
  • SSO entry point: https://api.orbit.devotel.io/auth/saml/{orgSlug}/login
  • SP metadata to import rather than type: https://api.orbit.devotel.io/auth/saml/{orgSlug}/metadata
  • Single logout URL: https://api.orbit.devotel.io/auth/saml/{orgSlug}/logout
Find {orgSlug} under Settings → Organization. Every public SAML endpoint is keyed by it.

Step 4 — Test the flow end-to-end

With enabled: true and enforced: false, test as a non-owner member would:
  1. Open https://api.orbit.devotel.io/auth/saml/{orgSlug}/login in a fresh browser profile (SP-initiated login — the standard path).
  2. Orbit 302-redirects to your IdP. Authenticate as a test user assigned to the Orbit app.
  3. The IdP POSTs the signed assertion to /auth/saml/{orgSlug}/callback; on success you land in the dashboard with a session.
Verify on the way through:
  • The email matches an Orbit member — the assertion’s mapped email attribute must match an existing member of the organization. If it doesn’t, invite that person first.
  • Attribute mapping is the first failure to check — a successful IdP login followed by an Orbit error almost always means the assertion’s attribute names don’t line up with attrEmail / attrName. Inspect the raw assertion in your IdP’s SAML tracer and compare the claim names.
  • IdP-initiated login also works — users clicking the Orbit tile inside Okta/Entra post directly to the ACS callback without the SP-initiated redirect. It works once the app is assigned; SP-initiated is still the recommended entry point because the slug determines the organization.
Confirm operation afterwards with GET /api/v1/settings/saml/health — it reports the stored certificate’s validity window (cert.expiresInDays, with cert.expired once it lapses), the last successful SSO login, the last failure with its reason, and the last metadata-test outcome.

Step 5 — Enforce SSO

Once sign-in works for at least one other owner (so you are not locked out by your own change), flip password login off:
enforced: true disables password sign-in for every member of the organization — everyone goes through SAML from then on. Keep a second owner account verified on SSO before you flip this, and leave the change to an owner deliberately staging it after testing.

Rotate or revoke the certificate

IdP signing certificates expire. Rotate through the same PATCH endpoint with a new x509Cert; the stored certificate is replaced and the fingerprint changes. POST /api/v1/settings/saml/parse-certificate previews the new cert’s identity and validity window before you commit it, and GET /api/v1/settings/saml/health reports cert.expiresInDays so you can watch the deadline ahead of expiry. Disabling SSO entirely is a PATCH with enabled: false: the configuration stays stored (cert, URLs, mappings intact) and password sign-in becomes available again. enforced: false loosens to “SSO offered alongside passwords”; enabled: false turns SSO off altogether. To fully remove the configuration, an owner clears it from Settings → Security → Single sign-on — one more deliberate click, since a wrong lock-out decision puts every member in front of an IdP that may be gone.

Common failures

See also