SSO — SAML identity providers
If your organization runs an enterprise identity provider — Okta, ADFS, OneLogin, Shibboleth, an internal IdP — you can wire it into GreekManage so members sign in without a separate password. This page walks the SAML 2.0 setup end-to-end: what to give your IdP, what to paste back into GreekManage, and how to test the connection before you turn it on.
Before you start
Have these from your IdP admin (or your own IdP admin console):
- The IdP entity ID — usually a URL like
https://idp.example.com/saml/metadata - The SSO URL (also called the SingleSignOnService URL) — where GreekManage redirects users to sign in
- Optionally an SLO URL (SingleLogoutService URL) — where GreekManage sends sign-out requests
- The IdP's X.509 signing certificate — the PEM-encoded public certificate that signs SAML assertions. You'll paste this into GreekManage so it can verify responses.
You'll also need to know how your IdP releases identity claims — specifically which attributes carry the user's email, given name, and surname.
Create the identity provider
- Open Org → Settings → Identity Providers.
- Click Add Provider.
- Fill out:
- Name — a human label for this connection (e.g., "University SSO", "Acme Okta"). Members never see this directly; it's for your admin team.
- Type — choose SAML.
- Slug — a short URL-safe identifier (auto-generated from the name). The slug appears in your IdP-facing endpoint URLs and must be globally unique across GreekManage. Once you've pointed your IdP at these URLs, changing the slug breaks the connection — pick something stable on day one.
- Allowed Domain (optional) — restrict sign-in to a specific email domain (e.g.,
example.edu). If a user authenticates successfully at the IdP but their email is on a different domain, GreekManage refuses the sign-in with a 403. Leave blank to accept any domain your IdP releases.
- Click Create. The provider is created in the inactive state — members can't use it yet. You'll flip it on after you finish wiring and testing.
Add Identity Provider dialog with Type set to SAML and slug + allowed-domain fields.
Give your IdP the endpoint URLs
Now give your IdP team four pieces of data. All four URLs include the slug you just picked. Replace [your-app-domain] with the public hostname your members use (e.g., app.greekmanage.com) and [slug] with the slug.
| What your IdP needs | URL pattern |
|---|---|
| Service Provider metadata (XML) | https://[your-app-domain]/api/auth/sso/saml/[slug]/metadata/ |
| Assertion Consumer Service (ACS) | https://[your-app-domain]/api/auth/sso/saml/[slug]/acs/ |
| Single Logout Service (SLS) | https://[your-app-domain]/api/auth/sso/saml/[slug]/sls/ |
| Initiate (login) URL | https://[your-app-domain]/api/auth/sso/saml/[slug]/login/ |
Most IdPs accept the metadata URL and read everything else from it automatically. If your IdP doesn't support metadata import, paste the ACS URL by hand.
Binding choices:
- ACS (IdP → GreekManage): HTTP-POST. The IdP posts the signed SAML response to the ACS URL.
- SSO (GreekManage → IdP): HTTP-Redirect. GreekManage sends the user to your SSO URL with a redirect.
- SLS: HTTP-Redirect.
The NameID format GreekManage requests is emailAddress — the user's primary identifier is their email. Your IdP should release the user's primary email as the NameID value (or in an attribute statement you map below).
Paste the IdP details into GreekManage
Back in Identity Providers, find the SAML provider you just created and click the pencil icon to open its config form. Fill in:
- IdP Entity ID — the IdP's entity ID URL.
- SSO URL — the IdP's SingleSignOnService URL.
- SLO URL — optional. Leave blank if your IdP doesn't support Single Logout.
- X.509 Certificate — paste the full PEM, including the
-----BEGIN CERTIFICATE-----and-----END CERTIFICATE-----lines. The certificate is stored encrypted at rest. If you ever re-paste a new certificate (e.g., rotating after expiry), it replaces the old one. - SP Entity ID — leave blank to auto-generate from your metadata URL. Set this only if your IdP requires a specific entity ID different from the metadata URL.
Click Save SAML Configuration.
SAML config form with all fields filled in
Attribute mapping (optional)
By default, GreekManage reads three SAML attributes using the standard OID-based claim URIs:
| User field | Default SAML attribute |
|---|---|
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress | |
| First name | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname |
| Last name | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname |
If your IdP releases different attribute names (e.g., mail, givenName, sn), override them in the attribute mapping config. If your IdP doesn't release an email attribute at all, GreekManage falls back to the NameID — which works as long as the NameID itself is an email address.
:::note Google Workspace sends no attributes by default (v0.66.15+) A Google Workspace custom SAML app releases no attributes at all until you add them under Google Admin → Web and mobile apps → your app → SAML attribute mapping. Sign-in still works without them — GreekManage identifies the user from the NameID — but first and last name arrive blank.
To populate names, map Google's Basic Information → First name / Last name to attributes named for the claim URIs in the table above, or pick your own names and add matching rows here.
Before v0.66.15 a missing attribute statement rejected the login outright with an opaque invalid_response. If you're on an older build, adding the mappings is mandatory rather than optional.
:::
Test the connection
After saving, click the test tube icon next to the provider in the list. GreekManage validates that:
- The SAML configuration record exists and has all required fields
- A valid SP metadata document can be generated from your settings
This is a static config check — it does not initiate a live SAML flow against your IdP. To verify the live flow, flip the provider to active (the toggle next to its name), open a private/incognito browser window, and sign in by selecting your IdP on the GreekManage sign-in page. On success the user lands on the dashboard.
Turn the provider on
Once the live flow works, leave the Active toggle on. The provider now appears as a sign-in option for members whose email domain matches your allowed domain (or for everyone, if you didn't set an allowed domain). When a member signs in via your IdP for the first time, GreekManage looks up an existing user by email and links the SSO subject to that account.
By default, no Membership is created on first SSO sign-in — the user must already be a member of a chapter in your org. New members are added through the normal member onboarding or PNM intake flows. The Auto-provisioning toggle (below) opts your IdP into creating a Membership on first sign-in.
Auto-provisioning (optional, v0.63.37+)
If you want first-time SSO sign-in to also create a Membership for new users (e.g., your IdP is the authoritative roster for your org and you'd rather have GreekManage trust it), open the IdP edit form and configure:
- Auto-provision enabled — turn on.
- Default chapter — the chapter newly-provisioned members are dropped into. Required when auto-provision is enabled (the save is rejected without it).
- Default role — typically
member. Officers/admins should still go through the regular promotion flow. - Default status — typically
undergrador whatever your org's default active status is.
What happens on first sign-in after this is enabled:
- The IdP authenticates the user and returns their email.
- GreekManage looks up an existing user by email.
- If the user exists and has a Membership in your org, sign-in proceeds as before.
- If the user exists but has no Membership in your org, a new Membership is created with the configured default chapter / role / status. An
AuditLogrow (operation="sso_auto_provision") records the action. - If the user doesn't exist, the User row is created first, then the Membership.
A toggle, not a button — you can flip it off any time. Existing memberships are untouched.
Cross-org email collision block (v0.63.37+)
A guardrail is always on, regardless of the auto-provision toggle: if the resolved email already maps to a user whose existing Membership is in a different organization, the SSO sign-in is rejected with HTTP 409 and a clear message. This prevents a stolen IdP credential from pivoting an existing user into your org.
In plain English: SSO can create new memberships in your org, but it cannot move someone from another org into yours. Use the regular member onboarding flow with explicit consent for cross-org transfers.
Common failure modes
"SAML response error: invalid_response (...)" (v0.66.12+)
invalid_response on its own is a bucket code covering around forty distinct validation failures — it is not a diagnosis. Since v0.66.12 the specific reason follows in parentheses, and that parenthetical is what to act on:
| Reason in the message | What it means | Fix |
|---|---|---|
The response was received at X instead of Y | Your IdP's ACS / Reply URL doesn't byte-for-byte match ours — most often a missing trailing slash. | Set the IdP's ACS URL to exactly the Callback (ACS) URL shown on this settings page. |
Invalid audience for this Response | The IdP's Audience URI / Identifier doesn't match our SP Entity ID. | If you left SP Entity ID blank it defaults to the .../metadata/ URL shown on this page — put that in the IdP's Audience field, or paste the IdP's audience into SP Entity ID. |
Signature validation failed. SAML Response rejected | The certificate here doesn't match the key your IdP signs with — wrong cert pasted, rotated on the IdP side, or expired. | Re-export the current signing cert from your IdP and re-paste it. |
No Signature found. SAML Response rejected | The IdP isn't signing at all. | Enable response or assertion signing on the IdP. |
NameID not found in the assertion of the Response | The IdP isn't sending a NameID in the assertion's Subject. We require one. | Configure the IdP to send NameID, format emailAddress. |
Could not validate timestamp: expired | Clock skew between your IdP and our servers, or a stale assertion from a re-submitted browser tab. | Retry the sign-in; if it persists, check the IdP host's NTP sync. |
Invalid issuer in the Assertion/Response | The IdP Entity ID saved here doesn't match what the IdP actually sends. | Copy the exact entity ID from your IdP's metadata. |
:::tip Importing our metadata doesn't fix everything Pointing your IdP at our metadata URL configures their side from our details — ACS URL, audience, SLO, NameID format. It does not fill in the two fields you type by hand on our side: IdP Entity ID and the X.509 certificate. If sign-in still fails after a clean metadata import, those two are the first place to look. :::
If the message has no parenthetical, your deployment predates v0.66.12 — upgrade to get the reason, or read it from the backend logs, which record the same detail at WARNING alongside the provider slug.
"SAML authentication failed" The IdP returned a response, but it failed validation — usually a clock skew between servers, an unexpected audience restriction, or a NameID format mismatch. Check your IdP logs for the assertion it sent and verify the audience is set to your SP entity ID.
"Email domain must be example.edu" The user authenticated, but their email is on a different domain than the Allowed Domain you set on the provider. Either widen the allowed domain or leave it blank.
"No email in user info response" / blank email on the new SSO user Your IdP isn't releasing an email attribute and the NameID isn't an email either. Configure the IdP to release the user's primary email in the standard email claim, or override the email attribute in GreekManage's attribute mapping to whatever your IdP releases.
Member sees "No account found" after IdP sign-in The IdP authenticated them, but no GreekManage user exists with that email. Confirm the user is a member of a chapter in your org. If their primary email at the IdP differs from their GreekManage email, add the IdP's email as an additional verified email on their profile — multi-email auth will match it.
Disabling the provider
Toggle Active off and the SAML option disappears from the sign-in page. Existing users who previously signed in via this IdP fall back to their other sign-in methods (password, passkey, OAuth). Deleting the provider entirely is also fine — it doesn't delete user accounts, only the IdP wiring.
Related
- SSO — OAuth & OIDC identity providers
- Approvals queue (org admin) — once members sign in via SSO, any pending account requests still go through review
- Permissions matrix — who can configure IdPs
- Glossary — SAML 2.0, SSO, JWT
Last verified against v0.66.12 (2026-07-27). Auto-provisioning + cross-org collision block shipped v0.63.37; per-reason invalid_response detail shipped v0.66.12.