Skip to content

Identity & SSO panel

If you’re a security lead or platform engineer wiring your IdP to a fresh Upwarden tenant, this is where you start. Land on the org page (/admin/ui/orgs/<slug>) and the Identity & SSO card is the first thing under the in-page nav — before Policies, Blocklist, and Audit. The panel is anchored at #identity-sso, so the sidebar’s “Identity & SSO” link jumps you there directly.

The card has two states: Unbound (no Stytch organization yet) and Bound (a Stytch organization id is recorded). Everything else on this page — the SSO connection list, domain claims, the dedicated SSO settings page — keys off the bound state. Get the bind right first; the rest follows.

A short explainer reading “Bind this Upwarden tenant to a Stytch organization so its members can sign in with Stytch and land here. Find your org id under Stytch dashboard → Organizations → ID.” sits above a single-field form labelled Stytch organization id, with the wire-key chip stytch_org_id underneath. The input is required, max length 256, placeholder organization-live-.... Submitting fires a confirm dialog (“Bind this Upwarden tenant to the entered Stytch organization id?”), then POSTs to /admin/ui/orgs/<slug>/bind-stytch-org.

Common error banners surfaced above the form:

  • “Stytch organization id is required” — empty submission.
  • “Stytch organization id exceeds 256 characters” — paste of a wrapper URL instead of the bare id.
  • “This Stytch organization id is already bound to another tenant — currently held by org <slug>. Re-issue with the admin API and ?force=1 to move the binding.” — another Upwarden tenant already owns this Stytch org. Moving the binding requires the admin API; the dashboard form will not force-rebind for you.

The explainer flips to “This Upwarden tenant is bound to a Stytch organization. Members of that org authenticated via Stytch land here after sign-in.” followed by Stytch org id: <organization-live-...> with a Copy button next to it. Beneath, a single Unbind organization button rendered in the destructive (red) style.

The Unbind button confirms with “Unbind this Stytch organization? Stytch logins for this org will no longer reach this tenant.” before POSTing to /admin/ui/orgs/<slug>/unbind-stytch-org. Unbinding does not delete data — projects, members, blocklist, and audit history all stay attached to the Upwarden tenant — but Stytch-authenticated sessions for that organization will fail tenant resolution on their next request.

Both bind and unbind are listed in the sensitive-operations registry (bind_stytch_org and unbind_stytch_org, both factor: "strong", 5-minute freshness window). If your last password / passkey / MFA factor was outside that window, the form POST 303s you through /admin/ui/step-up?next=… before applying the change. This is the same flow used for passkey removal and recovery-code generation; the operator experience is one extra re-auth, then the bind/unbind lands and you 303 back to the org page with a flash banner.

The flash messages on success are exactly “Stytch organization bound” and “Stytch organization unbound”. Both land you back at #identity-sso.

The Identity & SSO panel itself only carries the Stytch org binding. SAML and OIDC connections live one click away on the Single sign-on page, reachable from the in-page nav strip (top of the org page) or directly at /admin/ui/orgs/<slug>/settings/sso. Capability gate: sso:r to view, sso:w to create, edit, enable, disable, or delete.

You’ll see two prerequisite warnings before the configuration form unlocks:

  • “SSO configuration is an Enterprise-tier feature. Upgrade your tier to add SAML or OIDC connections.” — your tier isn’t enterprise. Lower tiers can still read the list but the create form is hidden.
  • “This org isn’t bound to a Stytch organization. SSO connections live on Stytch’s side; bind the org first (Identity & SSO panel on the org page).” — go back to the org page and complete the bind first.

With both prerequisites satisfied, the Connections (N) table lists each connection with columns: name (display name + Stytch connection id), type (SAML/OIDC badge), domains (chips), default role, status (enabled/disabled badge), and per-row Disable/Enable, Edit, Delete actions. Empty state reads “No SSO connections configured.”

The Add a connection form takes:

  • Connection type — SAML or OIDC.
  • Display name — what operators see in the list. Placeholder: Acme — Okta.
  • Email domains — comma-separated, e.g. acme.com, acme.co.uk. Sign-ins from these domains route through this IdP. Each domain can map to at most one connection across the system.
  • Default role for SSO-joined membersmember, admin, or viewer.
  • Identity provider (optional) — one of: okta, microsoft-entra, google-workspace, onelogin, jumpcloud, classlink, cyberark, duo, keycloak, miniorange, pingfederate, rippling, salesforce, shibboleth, generic. Hints the Stytch hosted UI; not load-bearing for routing.

A note under the submit button reads “After creating the connection, edit it to paste the IdP-side metadata (entity ID + SSO URL + X.509 certificate for SAML; issuer + client ID + secret for OIDC). Stytch sends the connection to pending until those are filled in.” The create round-trip echoes your form values on validation failure so you don’t retype.

Deleting a connection prompts “Delete the SSO connection <name>? Members signing in via this IdP will fall back to magic links.” — useful to remember during incident response.

Domain claims live on /admin/ui/orgs/<slug>/domains (also reachable from the org page nav strip). Capability: members:r / members:w. A claim says “any verified email at this domain auto-joins this org at the configured default role”. Verification is by DNS TXT — Upwarden polls the record when you click Verify. Public providers (gmail.com, outlook.com, etc.) cannot be claimed.

If you reach this page on an unbound tenant you’ll see “This org isn’t bound to a Stytch organization. Domain claims will still trigger Upwarden-side JIT auto-join, but Stytch’s own email-allowed-domain enforcement won’t engage until the binding lands. Configure it on the org’s main page (Identity & SSO).” Functional, but you’re operating with one enforcement layer instead of two.

Magic links are the default sign-in path; there’s no on-screen config for them on this panel. When a member’s email domain matches an enabled SSO connection, the magic-link form silently 303s the browser into Stytch’s hosted SSO start URL instead of mailing a code — that’s the routing logic the SSO page’s “Members signing in with an email at a mapped domain are routed through the configured IdP; everyone else continues to use magic links or social OAuth.” refers to. If you delete or disable the connection, sign-ins from that domain fall back to magic links automatically.

The JWKS URL surfaces at the bottom of the Policies card (just below Identity & SSO on the same page), rendered as “JWKS URL:” followed by a <code>-wrapped URL. This is the per-tenant public-key set your CI / build agents use to verify Upwarden-signed verdict tokens. Copy it once, drop it into your verifier config, and forget about it — it doesn’t rotate on bind/unbind. If the row is missing, your tenant hasn’t been issued signing keys yet; that’s a platform-side provisioning step, not something the dashboard can repair.

  • Onboarding a new tenant. Bind the Stytch organization first, then walk down to Policies, Blocklist, and Members.
  • Migrating IdPs. Add the new SSO connection (it lands disabled until you paste IdP metadata in Edit), test sign-in for a pilot domain, then flip the old connection to disabled.
  • Reacting to a compromised IdP. Disable the SSO connection from the row’s Disable action. Sign-ins from mapped domains fall back to magic links. Pair with the steps in Sign-in & access control for the broader incident response.
  • Moving a Stytch org between Upwarden tenants. Unbind on the holding tenant, then bind on the new one. The conflict banner with the ?force=1 hint exists for the admin-API path, not the dashboard form — the form refuses to overwrite an existing binding.