SSO, SAML and end-user authentication

Embed
Preview of the card
<a href="https://forumulate.com/guides/sso-and-auth"><img src="https://forumulate.com/guides/_api/public/orgs/046a9bc0-d530-43ae-9bae-af7945008cda/spaces/36aa4df0-1e95-4cef-8ae9-795169441345/pages/81ffd38f-e352-4c05-bc77-7654f9754d0d/social-card.svg?v=3e7ae33eec8b" alt="SSO, SAML and end-user authentication" width="600" height="315"></a>

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}/metadata

  • ACS (Assertion Consumer Service): https://forumulate.com/api/auth/saml/{orgId}/acs

  • Login 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.

  1. Mint the provisioning token: POST /orgs/{orgId}/scim/token. It is shown once. GET the same path to see whether one exists (configured) without revealing it.

  2. In your IdP, set the SCIM base URL to https://forumulate.com/api/scim/v2 and 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

https://forumulate.com/api/lti/{orgId}/login

Redirect / launch URI

https://forumulate.com/api/lti/{orgId}/launch

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 the providerEndpoint that GET /orgs/{orgId}/discourse-connect/config reports for you.

  • mode: "client" — your Discourse signs readers in to Forumulate. Set providerUrl to your Discourse, and the flow runs at /discourse-connect/{orgId}/start and /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.)

The Forumulate teamUpdated