SCIM Provisioning
Let your identity provider create, update and deactivate Grovs accounts automatically with SCIM 2.0.
Single sign-on handles who can log in. SCIM handles joiners and leavers: when someone is assigned to Grovs in your directory they get an account, when their name changes it follows, and when they leave their access is removed the same day, without anyone touching the Grovs dashboard.
Grovs implements SCIM 2.0 (RFC 7643 and RFC 7644) for the User resource and passes the Microsoft SCIM validator. This guide walks through Entra ID; other providers use the same endpoint and token.
Before you start
- A working Entra ID connection with at least one verified domain.
- An Entra ID P1 licence in the tenant. Provisioning is not available on the free tier. A 30-day trial can be started from the Microsoft 365 admin center under Marketplace → Security and identity.
- Every user you will license needs a Usage location set in Entra, or the licence assignment fails.
Entra cannot turn on provisioning for an enterprise app that was created from an app registration. SCIM therefore uses a second, non-gallery enterprise application next to the one you use for sign-in. This is how every custom SCIM integration works in Entra, not a Grovs limitation.
Connect Entra to Grovs
Generate the token in Grovs
Settings → Single sign-on → SCIM provisioning → Generate token. Copy it; it is shown once. The card now reads "Waiting for your identity provider".
Create the provisioning app
Entra admin center → Enterprise applications → New application → Create your own application → name it, for example Grovs Provisioning → choose Integrate any other application you don't find in the gallery (Non-gallery) → Create.
Connect it
In the new app: Provisioning → Connect your application. Authentication method Bearer authentication, Tenant URL from the Grovs card (https://api.sqd.link/scim/v2 on SaaS), Secret token pasted. Test connection, then Create. Leave scoping filters and attribute mappings at their defaults. The Grovs card flips to Connected as soon as the test succeeds.
Assign the same people
Users and groups on the provisioning app → add everyone who is assigned to the sign-in app. Provisioning syncs this app's list, so keep the two lists the same. Roles on this app do not matter; the sign-in app decides who is an admin.
Try one user
Provision on demand → pick a user → Provision. Entra shows the request and Grovs' answer, and the person appears under Team Members as a member.
Start provisioning
On the Overview, Start provisioning. From then on Entra syncs every assignment change automatically, roughly every 40 minutes.
Nothing is sent to Grovs when you change an assignment; Entra only talks to Grovs during a provisioning run. While testing, trigger Provision on demand after each change. In normal operation the cycle takes care of it.
What each directory change does
| In your directory | Entra sends | In Grovs |
|---|---|---|
| User assigned to the app | POST /Users | Account created without a password, member role on the project. An existing account with that email is adopted instead of duplicated, and a pending invitation is consumed. |
| Display name or email changed | PATCH /Users/:id | Name and email updated. A new email must be on a verified domain. |
| User unassigned, disabled or deleted | PATCH with active: false | Member role removed, every session and API token revoked. The account itself is kept. |
| User assigned again | PATCH with active: true | Member role restored, never admin. |
| User deleted in Entra with the app configured to delete | DELETE /Users/:id | Same as deactivation. |
Entra's default mapping sends the user principal name as userName and the mail nickname as externalId; Grovs stores both and answers Entra's lookups on either. Users without a mailbox send no email address; Grovs uses the user principal name.
Two refusals worth knowing
- The last admin of a project cannot be deactivated through SCIM. Entra shows a
409in its provisioning log and retries; promote someone else first. - Operator accounts cannot be provisioned or deactivated by a customer's SCIM token.
Deactivation and sign-in
Deactivation removes the project role and revokes sessions. While SCIM is enabled, a deactivated user who still manages to sign in through the organisation is refused with "Your account was deactivated by your organisation" and gets no role back. Only a SCIM reactivation, or turning SCIM off, lets them in again.
Keep "Assignment required" on in the sign-in app anyway and manage both apps through the same group, so leavers are refused at the identity provider and never reach Grovs.
The token
- One token per project. Rotate token issues a new one and stops the current one immediately; update Entra straight after.
- Disable turns provisioning off without touching accounts.
- The token is stored hashed; Grovs cannot show it again.
- The card shows the time of the last request from your identity provider, which makes it a quick health check when someone asks why a user has not appeared.
Endpoint reference
Base URL: the Tenant URL shown on the card. Authentication: Authorization: Bearer <token>. Requests without a valid token, or for a connection whose subscription lapsed, answer 401 with a SCIM error body.
/scim/v2/ServiceProviderConfigCapabilities: patch and filter supported, no bulk, no sorting.
/scim/v2/UsersList or filter users on this project. Filters: userName eq, externalId eq, emails.value eq. Paged with startIndex and count.
/scim/v2/UsersCreate or adopt a user. 409 uniqueness when the user is already provisioned; 400 invalidValue when the email domain is not verified.
/scim/v2/Users/:idOne user. 404 when not on this project.
/scim/v2/Users/:idReplace userName, externalId, name, displayName, emails and active.
/scim/v2/Users/:idRFC 7644 patch operations, including Entra's dialect: Replace with no path and a value object, and booleans sent as the strings True and False.
/scim/v2/Users/:idDeactivate and answer 204. The account is kept.
ResourceTypes and Schemas are served as well. userName and emails filters are case-insensitive; externalId is matched exactly, as the standard requires. Provisioning requests are rate-limited per token generously enough for a full initial sync; a limit answers 429 with Retry-After, which Entra honours.