SCIM Setup

Automate user provisioning from Okta or Microsoft Entra into Mistvine. Covers token issuance, IdP setup, rotation, billing impact, and deactivation semantics.

Last updated

SCIM (System for Cross-domain Identity Management) lets your identity provider push user lifecycle events into Mistvine automatically — create accounts when employees join, update names when HR changes them, deactivate when they leave. It runs on top of SAML SSO, which must be configured first.

Mistvine ships first-class SCIM support for Okta and Microsoft Entra ID. Google Workspace SCIM is not available — see Google Workspace customers below for what to do instead.

What SCIM gives you that SAML alone doesn't

Scenario SAML SSO only SAML SSO + SCIM
New hire Sarah joins the company Account created the first time she logs in (JIT). Account provisioned as soon as IT adds her to the IdP group — before her first login.
Sarah's last name changes Stale in Mistvine until she logs in next. Synced within ~40 minutes (Entra) or instantly (Okta).
Sarah leaves the company Someone logs into Mistvine and clicks "deactivate". If they forget, you keep paying. IdP marks her inactive → Mistvine sets is_active=falseshe stops counting toward your bill the next day, with a prorated credit on your next invoice.

The last row is the PLG win. Mistvine bills only for active members; SCIM makes deactivation automatic the moment IT removes someone from your IdP, which is exactly when every other system revokes their access.

Who can configure SCIM

Action Required role in Mistvine Required role in your IdP
Issue / rotate / revoke SCIM token Admin or Owner
Configure IdP provisioning Application Administrator (Entra) or Okta Admin

Prerequisites

  • SAML SSO must already be active for your workspace — you'll see the green status pill on /settings/sso. If not, finish SAML SSO setup first.
  • At least one of your email domains must be verified (DNS TXT record). SCIM will refuse to provision a user whose email domain isn't in the verified set — that's the cross-org safety anchor.

The overall flow

  1. Issue a SCIM token in Mistvine at /settings/sso → SCIM provisioning. You'll see the plaintext once — copy it immediately.
  2. Copy the SCIM endpoint URL (also shown on the same panel).
  3. Paste both into your IdP's provisioning settings — the exact UI path is below per IdP.
  4. Enable provisioning and run a test sync.
  5. Verify a pilot user appears in Mistvine's /settings/members.
  6. (Important) Leave "Push groups" off in your IdP — group sync is a v2 feature.

Okta

Plan required: any Okta SSO plan that lets you configure custom SAML apps. Role required: Super Admin, or a custom role with app-editing permissions.

These steps assume you already set up the SAML app per the SSO runbook. We're now adding SCIM provisioning to the same app.

  1. Sign in to your Okta admin console.
  2. Applications → Applications → Mistvine → General tab.
  3. Scroll to App Settings and click Edit. Check Enable SCIM provisioning and Save. A new Provisioning tab appears.
  4. Open the Provisioning tab → Integration sub-section → Edit.
  5. Fill in:
    • SCIM connector base URL — the SCIM endpoint URL from Mistvine.
    • Unique identifier field for usersuserName.
    • Supported provisioning actions — check Push New Users, Push Profile Updates, and Import New Users and Profile Updates (if you want reconciliation).
    • Authentication ModeHTTP Header.
    • Authorization — paste the bearer token from Mistvine.
  6. Click Test Connector Configuration. If it fails, see Troubleshooting.
  7. Save → then under To AppEdit, enable Create Users, Update User Attributes, and Deactivate Users.
  8. Assignments tab → assign the people or group who should sync. Okta will push them within a minute.

Okta gotchas

  • externalId must be stable. Okta uses its internal user ID as externalId. If you merge Okta orgs, the IDs change and you'll end up with duplicate Mistvine users — contact support first.
  • Okta concurrency is ~75 simultaneous transactions. If you push hundreds of users at once, Okta paces them; Mistvine returns 429 + Retry-After: 30 if we hit our own rate limit, and Okta honors it.
  • Group push stays off. Do not enable the Push Groups feature. Mistvine will reject /Groups requests with 501 until v2 ships.

Microsoft Entra ID

Plan required: Entra ID P1 or higher (same as SAML — Free tier doesn't include provisioning). Role required: Application Administrator or Global Administrator.

  1. Sign in to entra.microsoft.com.
  2. Applications → Enterprise applications → Mistvine (the app you already set up for SAML).
  3. Open the Provisioning blade → Get started → set Provisioning Mode to Automatic.
  4. Admin Credentials section:
    • Tenant URL — the SCIM endpoint URL from Mistvine. Don't strip the /scim/ segment — Entra rejects URLs that don't contain it.
    • Secret Token — paste the bearer token from Mistvine.
  5. Click Test Connection. You should see "Testing connection to Mistvine… The supplied credentials are authorized."
  6. Mappings section → open Provision Microsoft Entra ID Users → confirm attribute mappings. The defaults work for Mistvine; at minimum you need userName, emails[type eq "work"].value, name.givenName, name.familyName, and active. Disable the roles mapping — Mistvine ignores it in v1.
  7. Back on the Provisioning overview → set Scope to either:
    • Sync only assigned users and groups (recommended — lets you pilot with one user first)
    • Sync all users and groups (use only after pilot)
  8. Flip Provisioning Status to OnSave.
  9. Entra runs the first cycle within ~40 minutes. Use Provision on demand to test immediately with one user.

Entra gotchas

  • The Provisioning interval is ~40 minutes. If Entra misses a cycle, the next one picks up the backlog. You cannot reduce this interval below the Microsoft default.
  • PATCH format is non-standard. Mistvine's SCIM handler accepts Entra's capitalized op values ("Replace", "Add") and stringified booleans ("False") — you don't need to enable the aadOptscim062020 compliance flag.
  • Deactivation is PATCH active=false, not DELETE. Entra never hard-deletes users from Mistvine (which is correct — you'd lose feedback history and wave attribution).
  • Groups: set "Groups" scope to "Do not provision". Mistvine will return 501 for /Groups and Entra will error-loop if group push is on.

Google Workspace customers

Google Workspace does not push SCIM to third-party apps outside Google's curated automated-provisioning catalog — and Mistvine is not yet in that catalog. Two options:

  1. Stay on SAML JIT (default). Users get provisioned on first login. When someone leaves, an admin manually deactivates them in Mistvine. Works fine for teams under ~100 people.
  2. Funnel through Okta or Entra as a SCIM hub. If you already use Okta or Entra alongside Google Workspace, point SCIM at those — they read from Google (or HRIS) and push to Mistvine. This is the common enterprise pattern.

Mistvine is applying for the Google catalog; we'll update this doc when it lands.

Token lifecycle

Tokens are managed from /settings/sso → SCIM provisioning:

  • Issue — Mistvine generates a 32-byte random token. The plaintext is shown once in a read-only field; the hash is stored. The expiry default is one year.
  • Rotate — issues a new active token. The old token stays valid for 14 days so you have time to update your IdP, then expires automatically. During the overlap, either token authenticates the same SCIM endpoint.
  • Revoke — immediate 401. Use when a token is suspected leaked or when retiring an IdP.

Token format: scim_pk_<base64url>. The scim_pk_ prefix is recognizable by GitHub secret scanning and other leak-detection tools.

What gets synced

SCIM syncs users, not groups, not roles:

  • userName (the primary email) → auth.users.email
  • name.givenName / familyName / displayNameprofiles.full_name
  • activememberships.is_active (billing follows this)
  • externalId → stored in a mapping table for IdP reconciliation

SCIM-provisioned users land with role = 'member' and is_owner = false. Promote to Admin / Owner inside Mistvine — role sync from IdP attributes is not supported in v1.

Deactivation and re-activation

When your IdP sends active = false (or DELETE /Users/{id}, which Mistvine treats the same):

  1. memberships.is_active flips to false immediately.
  2. Active sessions are invalidated — the user is signed out the next time their session token refreshes (usually within the hour).
  3. The daily billing meter stops counting the user at next midnight UTC.
  4. The user's history, feedback, and objectives are preserved. Re-activating (active = true) restores access.

To permanently delete a user's data, use /settings/members → delete inside Mistvine. SCIM DELETE is deliberately non-destructive — it behaves like active = false so an accidental IdP misconfiguration can't wipe your feedback history.

Mass-deactivation safety

If your IdP misconfiguration flips every member to active = false at once (we've seen it happen), Mistvine will show a banner on /settings/billing when the active-member count drops more than 20% in a day. The banner gives you a one-click path to:

  • Revoke the offending SCIM token (stops the bleeding)
  • Re-activate members in bulk

Troubleshooting

Symptom Cause Fix
Test connection fails with 401 Token wrong or expired Re-issue in Mistvine; paste exact value (no leading/trailing whitespace)
Entra: "The endpoint does not implement SCIM 2.0" /scim/ missing from Tenant URL Keep the full URL as shown in Mistvine — /scim/ is required
User created in IdP doesn't appear in Mistvine Email domain not verified /settings/sso → verify the domain via DNS TXT record
409 Conflict on POST /Users externalId already mapped to a different Mistvine user Usually an IdP migration — contact support for manual mapping reconciliation
IdP reports "provisioning running", Mistvine unchanged Attribute mapping broken (likely userName) Confirm userName maps to primary email; re-run provisioning on demand
Deactivation doesn't reduce billing Meter runs daily at 00:00 UTC Wait until the next billing day; check /settings/billing next-day usage
Users appear with missing names name.givenName / name.familyName unmapped Add the mappings in your IdP's provisioning attribute list

Security notes

  • Tokens are org-scoped. A leaked token can only affect its own workspace — never another customer's.
  • Every SCIM mutation is audit-logged to audit_logs with the IdP label, source IP, and before/after values. Reviewable via /settings/audit-logs.
  • Last-used IP and timestamp are surfaced in the token list. Unfamiliar IPs are a signal the token may have been exfiltrated.
  • No user data leaves Mistvine via SCIM. SCIM is pull-free from the IdP's perspective — your IdP reads its own directory and writes to us, not the other way around.