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

# Troubleshooting: SAML SSO and SCIM setup failures

> Resolve setup-time failures on SAML SSO and SCIM: a certificate that never sticks past the [REDACTED] mask, ACS callback 401s, owner-only write refusals on /api/v1/settings/saml, and SCIM orgSlug/Bearer token mismatches.

# Troubleshooting: SAML SSO and SCIM setup failures

This runbook covers **setup-time** failures when you enroll SAML SSO or wire
SCIM provisioning — the misconfiguration class that blocks enrollment before
any real user signs in. It complements the
[enrollment guide](/guides/saml-sso-enrollment), which is the happy path;
this page is what you reach for when the happy path breaks.

SAML and SCIM are per-organization, tenant-owned controls: an owner writes the
SAML configuration under **Settings → Security** over the `GET`/`PATCH` pair
on `/api/v1/settings/saml`, and SCIM runs against the org-scoped base URL
`/scim/v2/{orgSlug}` with a dedicated Bearer token minted under
**Settings → SCIM**. The conceptual model is on
[Identity federation: SAML and SCIM](/concepts/identity-federation-saml-scim).

## Symptom table

Match the behavior you see to the cause column before changing anything:

| Symptom                                                                                 | Most likely cause                                                                                                 | Where to fix                                                                                                            |
| --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| SSO login fails at the IdP callback and the ACS returns 401                             | The stored signing certificate is stale or malformed, or the clock skew vs `NotBefore`/`NotOnOrAfter` is too wide | Re-pull the IdP metadata XML and re-paste the certificate (Settings → Security); check server clock/NTP on the IdP side |
| `GET /api/v1/settings/sso` shows `[REDACTED]` for the certificate even after a re-paste | Working as designed — the stored certificate is masked on every read and never returned                           | Confirm the fix by running a fresh SP-initiated login loop, not by reading the value back                               |
| `PATCH /api/v1/settings/saml` returns 403                                               | The caller's role is below owner — admins can read the config and run probes, but writes are owner-only           | Have an organization owner submit the write                                                                             |
| IdP push to SCIM returns 401/403 on every request                                       | Wrong Bearer token, or the request omits the `Authorization: Bearer …` header                                     | Re-copy the token from **Settings → SCIM** and verify the IdP's auth header                                             |
| IdP push to SCIM returns 404/422 on the base URL                                        | The `orgSlug` segment in `/scim/v2/{orgSlug}` does not match your organization slug                               | Re-copy the exact base URL from **Settings → SCIM** — the slug is org-scoped, not a tenant ID                           |
| SSO works for you but a teammate hits an attribute error at callback                    | The assertion's claim names don't match `attrEmail` / `attrName`                                                  | Compare the claim names to the IdP defaults table in the [enrollment guide](/guides/saml-sso-enrollment)                |
| The signing algorithm never validates                                                   | The IdP signs with SHA-1 while the config expects SHA-256 (or vice versa)                                         | Align the signature algorithm on the IdP app with what your policy requires — SHA-256 is the expected default           |

<Note>
  The `[REDACTED]` mask is the load-bearing difference between a read failure
  and a healthy config: `GET /api/v1/settings/sso` and the settings read never
  return the stored certificate, by design. If the mask flips back to
  `[REDACTED]` after your re-paste, that means the write landed. Diagnose
  further only if login still fails.
</Note>

## Causes by category

### Certificate and metadata problems

* **PEM whitespace or stripped headers.** The certificate field expects the
  X.509 PEM value. Pasting from some IdP consoles carries smart quotes,
  line-wrap whitespace, or drops the `BEGIN/END CERTIFICATE` markers. Always
  re-pull the **metadata XML** (Okta: "Identity Provider metadata" link;
  Entra ID: "Federation metadata document") and copy the
  `<ds:X509Certificate>` value from inside it rather than re-copying from a
  rendered certificate blade.
* **Algorithm mismatch: SHA-1 vs SHA-256.** A stale Okta/Entra app that signs
  with SHA-1 while your validation expects SHA-256 (or the reverse) fails on
  every assertion with a signature error. Align the algorithms on both sides;
  SHA-256 is the expected default.
* **Clock skew vs `NotBefore`/`NotOnOrAfter`.** SAML assertions carry a
  validity window. If your IdP's clock drifts, assertions arrive outside
  their window and the ACS rejects them. Sync the IdP-side clock (NTP) before
  you re-test; this is the only cause in this list that fails even with a
  perfect certificate.

### Permission and write-refusal problems

* **Non-owner 403.** `PATCH /api/v1/settings/saml` (and the Settings →
  Security SAML form) are owner-only writes. Admins can `GET` the config and
  run the `test-connection` probe, but cannot save. The 403 is deterministic
  — retrying from the same non-owner session returns the same refusal.
* **Wrong orgSlug in the SCIM path.** The base URL is `/scim/v2/{orgSlug}` —
  the slug is the exact org-scoped value shown under **Settings → SCIM**,
  not a tenant ID and not a bare org name. A 404 or 422 from every push means
  the slug segment is wrong.
* **Missing or wrong Bearer token.** SCIM requests authenticate with the
  dedicated token minted under **Settings → SCIM**, sent as
  `Authorization: Bearer <token>`. A 401 on every push means the header is
  missing or the token was rotated and the IdP still sends the old one.

## Fix sequence

Work in this order. Stop at the first step that clears the failure.

1. **Re-pull the IdP metadata XML.** In Okta, open the app's **Sign On** tab
   and copy the "Identity Provider metadata" link; in Entra ID, open the
   enterprise application's **Single sign-on** blade and download the
   "Federation metadata document". Extract the signing certificate from the
   `<ds:X509Certificate>` element — this avoids the whitespace/header
   corruption that rendered certificate screens introduce.
2. **Re-paste in Settings → Security.** Have an **owner** paste the fresh
   certificate into the SAML configuration. The read-back shows `[REDACTED]`
   — that's the mask, not a failed write.
3. **Run a fresh SP-initiated loop.** Open `/auth/saml/{orgSlug}/login`, let
   it 302 to the IdP, and confirm the callback lands a session. A clean
   SP-initiated loop is the proof the fix landed — not the read response.
4. **Break-glass owner.** If `enforced` locked the only owner out, a second
   owner opens the dashboard via SSO and flips `enforced: false` to re-open
   password sign-in. Keep enforcement **off** until the loop above passes for
   your team and a second owner can still break-glass.
5. **Flip to enforced last.** Re-stage `enforced: true` only after the
   SP-initiated loop passes for a non-owner test member. Enforcement is the
   final step, not a debugging step.

<Warning>
  Never flip `enforced: true` while debugging. If the loop fails under
  enforcement, every member — including other owners — loses the fallback
  sign-in path and the break-glass route narrows to a support escalation.
</Warning>

## SCIM-specific fix order

1. Verify the **base URL** exactly as shown under **Settings → SCIM** — the
   orgSlug segment is org-scoped and case-sensitive.
2. Verify the **Bearer token** is the current one from **Settings → SCIM**;
   rotate it there if you suspect the IdP holds a stale copy, then update the
   IdP's connection settings.
3. Trigger a manual push from the IdP (Okta: **Push now**; Entra: **Provision
   on demand**) and read the IdP-side error. The IdP error string is the
   fastest signal: 401 → token/header, 404/422 → orgSlug, 400 → schema or
   attribute mapping.

## What to send support

If the fix sequence above still fails, open a ticket with:

* Your **organization slug** and **tenant ID** (Settings → Organization).
* The **exact SAML failure**: the ACS 401 response, the IdP error string, or
  the SCIM status code — plus the `request_id` from the `meta` block of an
  API response when you have one.
* The **IdP vendor and app type** (Okta / Entra ID / other SAML 2.0 IdP) so
  the support engineer can compare against the enrollment guide's mapping
  table.

Never include the certificate, the SCIM Bearer token, or a session JWT in
the ticket.

## See also

* [Enroll SAML SSO](/guides/saml-sso-enrollment) — the happy-path walkthrough:
  metadata probe, writing the config, enforcement, and the common-failures
  table.
* [Identity federation: SAML and SCIM](/concepts/identity-federation-saml-scim) —
  what gets federated, the create → update → deactivate → deprovision
  lifecycle, and the tenant-ownership model.
* [SSO / SCIM FAQ](/reference/faq) — conceptual answers: what SSO, SP-initiated
  vs IdP-initiated SAML, and SCIM provisioning each do, and how the
  staged `enabled` → `enforced` rollout works.
* [Authentication, key mode, and IP allowlist](/troubleshooting/auth-and-api-keys) —
  the sibling runbook for runtime SSO rejection codes on the login path.
