SSO, SAML and end-user authentication
Forumulate supports both enterprise SSO (so your organization's members sign in through your identity provider) and a set of end-user login methods for everyone else. This guide covers configuring SSO, enforcing it, and the auth options available to members.
End-user login methods
Out of the box, members can authenticate with:
Email and password — register, verify email, sign in; with forgot/reset/change-password flows.
Google sign-in — available when the platform has Google configured.
Two-factor authentication (TOTP) — app-based 2FA (Google Authenticator, 1Password, etc.), with backup codes. Enrol under
auth/mfa.Passkeys (WebAuthn) — register a passkey and sign in with it.
Enterprise SSO — SAML 2.0 or OIDC/OAuth2 (below).
There is no "magic link" / passwordless-email login. Passwordless in Forumulate means an SSO- or Google-provisioned account with no password set.
Requiring 2FA for everyone
Two org security settings govern sessions and MFA:
security.require_mfa— require every member to have 2FA enabled.security.session_idle_hours— idle hours before a member must re-authenticate (default 720).
Enterprise SSO for your org
You can connect your identity provider two ways, both configured per-org and both requiring the Manage SSO permission (org.manage_sso). Configure them in the console at /o/{orgId}/sso.
Option A — OIDC / OAuth2 ("SSO")
Pick a provider preset or generic OIDC, then supply:
Provider — generic
oidc, or a preset (Google, Microsoft, Apple, GitLab, LinkedIn, Amazon, GitHub, Discord, Facebook, Twitter).Issuer — your IdP's issuer URL (required for generic OIDC).
Client ID and Client secret.
Allowed domain (optional) — restrict sign-in to an email domain.
Default role — the role new members get (Owner / Admin / Maintainer / Editor / Moderator / Member / Guest).
Enabled, and Require SSO (enforcement — see below).
The redirect URI to register with your provider is fixed at https://forumulate.com/api/auth/sso/callback. Give your members the login URL https://forumulate.com/sso/{orgId}, which starts the flow.
Option B — SAML 2.0
Supply:
IdP entry point — your identity provider's SSO URL.
IdP certificate — the signing certificate.
Allowed domain (optional) and Default role.
Enabled.
The Service Provider values you give your IdP are derived automatically:
SP metadata:
https://forumulate.com/api/auth/saml/{orgId}/metadataACS (Assertion Consumer Service):
https://forumulate.com/api/auth/saml/{orgId}/acsLogin init:
https://forumulate.com/api/auth/saml/{orgId}/login
Assertions must be signed. The member's email is taken from the assertion's email attribute or the nameID.
The same settings area also supports SCIM directory provisioning, LTI 1.3, and Discourse Connect, if your organization uses them.
SCIM 2.0 — directory provisioning
Your directory creates, updates and deactivates members; you do not invite them one at a time.
Mint the provisioning token:
POST /orgs/{orgId}/scim/token. It is shown once.GETthe same path to see whether one exists (configured) without revealing it.In your IdP, set the SCIM base URL to
https://forumulate.com/api/scim/v2and the bearer token to the one you just minted.
Two resources are served: /scim/v2/Users and /scim/v2/Groups. A deactivation (active: false) removes the member's access without deleting the person, so their authorship survives.
The token is a provisioning credential, not an API key: minting it needs the admin scope, because directory-driven provisioning can add members.
LTI 1.3 — launch from an LMS
A launch is an OIDC flow started by the LMS, so the platform is the identity provider and we are the tool.
Register the tool with your LMS using:
Value | What to give the LMS |
|---|---|
OIDC login init |
|
Redirect / launch URI |
|
Then record the LMS's own values with PUT /orgs/{orgId}/lti — issuer, clientId, authLoginUrl and jwksUrl. GET it back to check configured and enabled.
The launch is verified against the LMS's JWKS, and the state, nonce and LTI message-type claims are all checked before a member is provisioned. A nonce is accepted once — a replayed launch is refused rather than signing somebody in twice.
Discourse Connect
For an organization already running Discourse Connect (formerly DiscourseSSO). It works in both directions, which is the thing to decide first:
mode: "provider"— Forumulate is the identity provider and your Discourse is the client. Point Discourse at theproviderEndpointthatGET /orgs/{orgId}/discourse-connect/configreports for you.mode: "client"— your Discourse signs readers in to Forumulate. SetproviderUrlto your Discourse, and the flow runs at/discourse-connect/{orgId}/startand/callback.
allowedDomain restricts which email domains may arrive, and defaultRole (MEMBER unless you say otherwise) is what a new arrival gets.
Enforcing SSO
Set Require SSO on the OIDC/OAuth2 config to force members whose email domain matches your configured domain through SSO. When enforced:
Password login for a matching email is blocked with a clear "your organization requires single sign-on" message.
Google sign-in for a matching email is blocked the same way.
Members must sign in through your identity provider. (Enforcement is keyed by the email domain, because the check happens before the org context is known at login time.)