Available on the Corporate plan. This functionality is part of woku’s enterprise capabilities. Talk to our sales team.
Reference case. RE/MAX Chile uses SSO with woku, integrating its
Active Directory from Microsoft Azure AD (Entra ID).
Model
- One woku company ↔ one Stytch
Organization. Every company that enables SSO is linked to an organization in Stytch. - One Stytch organization ↔ one or more SAML/OIDC connections. The connections are configured in the Stytch dashboard (IdP XML metadata, attribute mapping, certificates, etc.).
- Domain allowlist. Every company that enables SSO declares which email domains may use SSO against that organization. This prevents cross-tenant impersonation attacks.
- Identity scoped by organization + Stytch member. Once
a woku user logs in via SSO, we link them to the tuple
(stytchOrganizationId, stytchMemberId). Subsequent logins resolve by that tuple, not by email, which closes the impersonation window even if the email changes or is reused. - Per-company opt-in. By default SSO is off and users log in with email + password + (optional) MFA TOTP.
Enabling SSO in your company
Prerequisites:- Have a Stytch organization created (the first time we create it for you).
- Have at least one SAML or OIDC connection configured in that organization against your IdP.
- Go to Company → Security → SSO.
- Check Enabled and enter what Stytch gives you:
- Stytch Organization ID (format
organization-prod-...). - Stytch Connection ID (format
saml-connection-prod-...oroidc-connection-prod-...).
- Stytch Organization ID (format
- Add at least one allowed email domain (for example
acme.com). Only users whose email ends in one of those domains will be able to complete SSO against this company. - Save.
The backend refuses to enable SSO without an Organization ID, Connection ID,
and at least one allowed domain (400 BadRequest). This prevents
leaving the company with SSO enabled but with no destination or control
over who can log in.
Why the domain list
Without this list, a malicious (or misconfigured) IdP could assert an email from another company (someone@other-company.com) and gain
access to the wrong tenant. With the list, the backend rejects with
403 any SSO assertion whose email domain is not among
the company’s authorized ones.
What the login flow looks like (SP-initiated)
As seen by the user:- The user opens the admin login page and types their email. They click Continue.
- The admin queries the discovery service to resolve
which method to show:
- If the email domain belongs to a company with SSO enabled, the Continue with SSO button appears.
- Otherwise, the Password field appears.
- If it was SSO: the browser is redirected to Stytch, Stytch to the IdP, the IdP back to Stytch, and Stytch to our callback. After exchanging the token, it redirects to the admin with the woku tokens in the URL fragment and the session is started.
- Discovery resolves whether the email domain belongs
to a company with SSO active. The response indicates the mode
(
ssoorpassword) and has a stable shape regardless of whether the user exists in woku, so as not to leak enumeration data. - When the user clicks Continue with SSO, the backend validates that the company has SSO enabled and responds with a 302 redirect to Stytch’s public URL.
- Stytch redirects to the IdP where the user authenticates.
- The IdP redirects back to Stytch, which validates the assertion and redirects to the woku callback.
- woku exchanges the token (
stytch.sso.authenticate), resolves the company byorganization_id, verifies that the asserted email domain is inssoEmailDomains, looks up the user first by(stytchOrganizationId, stytchMemberId)and, if it is the first time, does JIT provisioning + records the identity. Finally it ensures theUserCompanymembership, issues a pair of woku tokens (access + refresh) and redirects to the admin with the tokens in the URL fragment. - The admin’s callback page reads the fragment, persists the token in the authentication store, opens the real time channel and clears the fragment from history before redirecting the user to the dashboard.
Just-In-Time provisioning
When a user logs in via SSO for the first time:- Resolution by scoped identity. First we look for a woku
user that already has the identity
(stytchOrganizationId, stytchMemberId)recorded. If it exists, we use it. - Email fallback. If there was no recorded identity, we look up by normalized email. If the user exists we link them to the new identity for subsequent logins.
- JIT. If the email does not exist either, we create it automatically with a username derived from the email and a random password (that the user never uses). We mark the account as confirmed.
- Membership. In all cases we ensure the user has
UserCompanymembership in the corresponding company. The default role ismember. If you need SSO users to log in with theadminrole, contact support (the role mapping UI is on the backlog).
auth.sso.login with
actorEmail, companyId, stytchOrganizationId, stytchMemberId,
newlyLinked (true when the identity was just recorded) and IP.
Guarantees
- The Stytch secret never touches the client. Only the
STYTCH_PUBLIC_TOKEN(public by design) is included in the start URL; theSTYTCH_SECRETlives only in the backend. - Server-side validation. The woku session is issued only after Stytch confirms the authentication. The Stytch token is single-use.
- Per-company isolation. The callback rejects with
403if the Stytch organization is not linked to any woku company. - Cross-tenant anti-impersonation. The callback rejects with
403if the email domain asserted by the IdP is not inssoEmailDomains, and the woku identity is resolved by the tuple(stytchOrganizationId, stytchMemberId)before by email. - No enumeration. The discovery response does not depend on whether the user exists in woku; only on the email domain. It is rate-limited to discourage sweeps.
- Auditable. Every step is recorded.
Known limitations (V1)
- The detailed SAML/OIDC configuration (XML metadata, attribute mapping, certificates) is done in the Stytch dashboard, not in the woku panel. Only the IDs and the domains live in woku.
- SP-initiated only. IdP-initiated requires an additional endpoint; it arrives in the next iteration.
- No automatic role mapping: all SSO users log in as
memberby default. Upgrades toadmin/ownerare done manually from Company → Members. - The SSO add-on is opt-in and monetizable: the commercial
model (add-on price) is documented separately. In the meantime the flag
ssoEnabledis turned on manually.
Loss of access
If the IdP’s SAML/OIDC connection breaks, if the user’s email domain changes, or if you need to add/remove an allowed domain without access to the panel, contact support (team@woku.app) to temporarily disable SSO or reassign
the membership manually.