SAML SSO Setup
Configure Single Sign-On for Mistvine with Google Workspace, Microsoft Entra, or Okta. Covers wizard, domain verification, enforcement, and troubleshooting.
Last updated
Single Sign-On lets your team log in to Mistvine using your company's identity provider (IdP) instead of an email code. Once configured, users whose email ends in a verified domain are routed to your IdP automatically at sign-in.
Mistvine supports SAML 2.0 against any IdP. We ship first-class runbooks for Google Workspace and Microsoft Entra ID (Azure AD).
Who can configure SSO
| Action | Required role in Mistvine | Required role in your IdP |
|---|---|---|
| Create / delete connection | Admin or Owner | Varies per IdP — see below |
| Verify domain | Admin or Owner | DNS access |
| Toggle enforcement | Admin or Owner | — |
The overall flow
- Pick your IdP in Mistvine at
/settings/sso. - Copy the three SP values Mistvine shows you (ACS URL, Entity ID, SP Metadata URL).
- Create a SAML app in your IdP using the runbook for your specific provider (below).
- Copy the metadata URL (Entra/Okta) or download the metadata XML (Google) from your IdP.
- Paste it back into Mistvine and submit the connection form.
- Verify your email domain by adding a DNS TXT record.
- Test — sign in from an incognito window with a user at the verified domain.
- Flip to Required once your whole team has confirmed SSO works.
Microsoft Entra ID
Plan required: Entra ID P1 or higher. Custom SAML is not in the Free tier. Role required: Global Administrator or Cloud Application Administrator.
-
Sign in to entra.microsoft.com.
-
Entra ID → Applications → Enterprise applications → New application → Create your own. Select Integrate any other application (Non-gallery) and name it "Mistvine". Click Create.
-
Open the app → Users and groups → + Add user/group → assign one pilot user. Without this, every login attempt fails with
AADSTS50105: User not assigned to application. -
Single sign-on → SAML. A five-panel page opens.
-
Panel 1 — Basic SAML Configuration → Edit. Paste the values from Mistvine's "Values to paste" card:
- Identifier (Entity ID) — the Entity ID from Mistvine
- Reply URL (ACS URL) — the ACS URL from Mistvine
- Logout URL —
https://auth.mistvine.com/auth/v1/sso/saml/slo - Save.
-
Panel 2 — Attributes & Claims → Edit. Delete the four default
http://schemas.xmlsoap.org/...claims. Add four unnamespaced claims:Name Source attribute emailuser.mail(fallbackuser.userprincipalname)givennameuser.givennamesurnameuser.surnamedisplaynameuser.displaynameLeave Name ID as
user.userprincipalname. Format can be Persistent or Email Address — both work with Supabase. -
Panel 3 — SAML Signing Certificate → Set the Notification email to an IT distribution list. Entra sends 60- and 7-day expiry warnings. Cert lifetime is 3 years; rolling rotation is supported as long as Mistvine stores the metadata URL (not raw XML).
-
Panel 4 — Set up Mistvine → Copy the App Federation Metadata URL (looks like
https://login.microsoftonline.com/{tenant}/federationmetadata/2007-06/federationmetadata.xml?appid={app}). -
Back in Mistvine → Step 3 → pick URL, paste the Federation Metadata URL, enter your email domain, Create connection.
Entra troubleshooting
| Error | Likely cause | Remediation |
|---|---|---|
AADSTS50105 |
User not assigned to app | Entra → Mistvine app → Users and groups → Add the user |
AADSTS7500514 |
NameID format mismatch | Panel 2 → set NameID format to Persistent or Email Address |
AADSTS50020 |
B2B guest not resolvable | Key on email, not UPN (guests have …#EXT#@tenant.onmicrosoft.com UPNs) |
AADSTS50011 |
Reply URL mismatch | Trailing slash or http vs https. Recopy from Mistvine. |
| No obvious error | Conditional Access policy blocked sign-in | Entra → Monitoring → Sign-in logs → filter app "Mistvine" → Conditional Access tab |
Group claims (v2 feature): Panel 2 → Add a group claim → Groups assigned to the application → Source: Group ID. Hard cap: 150 groups per assertion before the groups overage claim fires.
SCIM: Available on the same app via the Provisioning tab. Not yet consumed by Mistvine — deferred to v3.
Google Workspace
Plan required: Any paid Workspace SKU, or Cloud Identity Free/Premium. Role required: Super Admin.
-
Sign in to admin.google.com.
-
Menu → Apps → Web and mobile apps → Add app → Add custom SAML app.
-
App details → Name it "Mistvine", upload a 256×256 PNG icon, Continue.
-
Google Identity Provider details → click Download Metadata and save the XML file. (Google does not expose a metadata URL — you'll paste the XML contents into Mistvine.) Continue.
-
Service provider details → paste the values from Mistvine:
- ACS URL — the ACS URL from Mistvine
- Entity ID — the Entity ID from Mistvine
- Start URL — leave blank
- Signed response — unchecked
- Name ID format —
EMAIL - Name ID —
Basic Information → Primary email - Continue.
-
Attribute mapping:
Google directory attribute App attribute Primary email emailFirst name first_nameLast name last_name(Optional) Google Groups groupsFinish. (Groups are capped at 75 per assertion.)
-
On the app detail page → User access → pick an Org Unit or ON for everyone. Propagation can take up to 24 hours. Pilot with one OU first — if Test SSO fails with
app_not_configured_for_userduring rollout, this is why. -
Back in Mistvine → Step 3 → pick XML, open the metadata file you downloaded in step 4, select all, paste into the textarea, enter your email domain, Create connection.
Google troubleshooting
| Error | Likely cause | Remediation |
|---|---|---|
| "SAML assertion does not contain email address" | NameID not mapped to email | Step 5 → set Name ID format to EMAIL and Name ID to Primary email |
app_not_configured_for_user |
OU not yet propagated | Wait up to 24h; or move user to a different OU that has access |
| Signature verification failed | Metadata cert stale | Re-download metadata XML and re-upload in Mistvine |
Cert rotation: Google certs have a 5-year lifetime. When Google rotates, re-download the XML and re-upload.
Domain verification (DNS TXT)
After saving the connection, Mistvine shows a TXT record you must add to your DNS to prove ownership of the email domain.
| Field | Value |
|---|---|
| Record type | TXT |
| Host / Name | _mistvine (most registrars auto-append the domain) |
| Value / Content | mistvine-domain-verify=<token> (copy from the settings page) |
| TTL | default (300–3600 seconds) |
Cloudflare clickpath: Dashboard → select the zone → DNS → Records → + Add record → Type TXT, Name _mistvine, Content mistvine-domain-verify=…, Proxy status greyed out (TXT can't be proxied), TTL Auto.
Route 53 clickpath: Hosted zone → Create record → Record type TXT, Record name _mistvine, Value "mistvine-domain-verify=…" (Route 53 expects quotes; other registrars don't).
Propagation: Cloudflare and Route 53 typically propagate in under a minute. Some registrars take up to an hour. Verify locally first with:
dig +short @1.1.1.1 TXT _mistvine.<your-domain>
Click Check now in Mistvine once the dig command returns the expected value.
How your team joins (JIT provisioning)
Short version: once an SSO connection is active and you've verified at least one domain, everyone at that domain is auto-added on their first sign-in. You don't send individual invites.
What happens on first sign-in
- Employee types their work email (e.g.
alice@acme.com) at your workspace login page. - Mistvine sees that
acme.comis a verified domain for your org and routes them through your IdP (or accepts their email code). - They authenticate successfully.
- A Just-in-Time provisioning step creates their
membershipsrow withrole = member,is_active = true— identical to what they'd get if you'd invited them manually and they'd accepted. - They land in the workspace.
There's no "pending invite" step and no email from Mistvine. Just direct access.
Role assigned
JIT always assigns the Member role. To promote someone to Admin, visit the Members page after they've signed in at least once and change their role. Owner status can then be added on top of Admin from the same page (every Owner is also an Admin). There is no way to pre-provision someone as an Admin before their first sign-in — you invite them at Member level (either JIT or manual), then promote.
When manual invites still matter
Use the invite form on Members for anyone whose email doesn't match a verified domain:
- Contractors at their own company's domain (e.g.
@freelancer.com) - External agencies
- Investors, advisors, board members
- Consultants working across multiple client orgs
Manual invites produce identical memberships rows to JIT — same role, same permissions. The only difference is the path: manual invites require the recipient to click an email link within 7 days; JIT is zero-touch.
Important: JIT fires for email-code sign-in too
Verifying a domain does more than enable SSO routing — it makes the domain auto-join-eligible for any authentication method. If acme.com is a verified domain and someone at @acme.com signs in via magic link or email code (because enforcement is Optional), JIT still provisions them. The rationale: once you've proven domain ownership via DNS TXT, Mistvine treats email-at-that-domain as equivalent proof of employment.
If you want tighter control — e.g. SSO only, no other sign-in methods at all for your domain — flip enforcement to Required (see below). That rejects email-code sign-in for verified-domain emails.
What this means for billing
Mistvine bills per active member on a monthly or annual subscription; the active-member count reconciles daily, with a prorated charge issued when members are added (immediate) and a prorated credit on next invoice when members are removed. A JIT-provisioned member counts from the day they first signed in.
- A Monday-morning workspace-wide rollout of an SSO connection to a 200-person company would add 200 billable members over the first day or two as each person signs in.
- A JIT-provisioned member who never signs in a second time still counts until you mark them inactive on the Members page.
- Employees who leave the company should be deactivated — in Mistvine's Members page. Removing them from your IdP prevents future sign-in but doesn't automatically deactivate their Mistvine membership. Budget a deprovisioning checklist that includes Mistvine.
Runaway-provisioning safety
Today Mistvine does not cap daily JIT provisions. If your IdP auto-assigns the Mistvine app to everyone in the tenant, you could onboard several hundred billable members in a few minutes. We recommend:
- Assign the Mistvine app to a pilot OU / group first (as noted in both runbooks above).
- Expand to the full tenant only after a quality check.
- Watch the Members count the day after expansion and deactivate anyone you didn't intend to add.
A daily cap is planned as a future safety valve.
Enforcement: Optional vs Required
| Mode | Behaviour |
|---|---|
| Optional (default after first successful verification) | Users at verified domains are routed through SSO by default, but email-code sign-in stays available as a fallback. Safe during rollout. |
| Required | Users at verified domains can only sign in via SSO. Email-code is rejected for them. Non-verified-domain users (e.g. contractors at an external agency) are unaffected. |
Flip to Required only after your team has confirmed SSO works end-to-end. You can switch back to Optional at any time if you hit an issue.
Deleting a connection
When you delete an SSO connection:
- Supabase immediately invalidates every session issued by that IdP — anyone currently signed in via SSO is logged out.
- Users who had email-code accounts before SSO was turned on can still sign in with email code.
- The upstream Supabase SAML provider is removed, so future
signInWithSSOcalls for this domain fail over to email-code.
There is no reverse migration — you can re-create a new connection at any time.
Multi-org users
A user can belong to multiple Mistvine orgs. If some orgs use SSO and others use email-code, they'll have separate sessions per auth method — an SSO login shows only SSO-workspace memberships; an email-code login shows only email-code-workspace memberships. This is standard enterprise-SAML behavior and matches how Supabase scopes SSO sessions.
Security notes
- Domain verification via DNS TXT is mandatory before you can flip enforcement to Required. Without it, someone could register
admin@competitor.comagainst their own IdP and force competitor.com users through it. - Mistvine never stores your IdP's private signing key — only its metadata (entityID, certificate, endpoints).
- Mistvine's service-provider endpoints are at
auth.mistvine.com— your IdP config should reference those URLs, notsupabase.co. - Session tokens (JWTs) have a maximum lifetime of 24 hours, even if the IdP would allow longer. Single Logout (SLO) is advertised but inert — use the session-token timeout as your deprovisioning guarantee.