Just-in-Time Provisioning and Group Sync
- Self-hosted
Just-in-time (JIT) provisioning creates a Qualytics account the first time someone signs in through your Identity Provider (IdP). When group sync is enabled, that sign-in can also place the account on the Qualytics Teams that match the IdP groups the person belongs to. Nothing needs to be created in Qualytics ahead of time, and no separate synchronization service needs to run.
This page is written for administrators who want Qualytics Team membership to follow the directory groups they already maintain, such as Active Directory or Microsoft Entra ID security groups, Okta groups, Keycloak groups, or the equivalent group construct in another IdP.
Availability
Configure group sync separately for each OIDC or SAML provider under Sign-In Providers. Step 3 shows where to enable it. Managed deployments keep Team membership aligned with your directory using Directory Sync.
What Happens at Sign-In
Every sign-in through an OIDC or SAML identity provider produces the following outcome. The first four rows always apply. The last row applies only when group sync is turned on.
| What | Behavior |
|---|---|
| Account | Created on the person's first sign-in when it does not exist yet. Administrators can also create accounts ahead of time with an email invitation. |
| Role | New accounts receive the Member role. The very first account created in a brand new deployment receives Admin so that someone can administer the platform. |
| Public team | Every account joins the Public team, which cannot be removed. |
| Group listing | The group names your IdP presents are recorded on the account and refreshed whenever they change, as long as a groups claim is configured. Without one, nothing is read and nothing is recorded. Recording happens whether or not group sync is enabled, so you can see exactly what your IdP sends before you turn anything on. Read it back in the Identity Provider Groups field of the Edit User dialog. |
| Team membership | With group sync enabled, each presented group name is matched against existing Team names and the person is added to every Team that matches. |
Group sync deliberately does not do the following:
- It does not create Teams. A group with no matching Team is ignored.
- It does not remove anyone from a Team. See Keeping Membership Accurate Over Time.
- It does not set the platform role. Groups map to Team membership only, never to Member, Manager, or Admin.
- It does not assign datastores to Teams or set team permissions. Those stay under your control in Qualytics.
- It does not deactivate accounts when someone leaves a group.
Group Sync Compared With Directory Sync
Qualytics offers two ways to align Team membership with your directory. They solve the same problem with very different trade-offs.
| Aspect | Group sync at sign-in | Directory Sync |
|---|---|---|
| Trigger | The person signs in, and Team matching is re-checked while they use the platform | Your IdP pushes changes |
| Direction | Add-only | Full lifecycle, including removals |
| Creates Teams | ||
| Removes Team membership | ||
| Creates accounts before first sign-in | ||
| Network path from your IdP to Qualytics | Not required | Required |
| Extra setup in Qualytics | Create the Teams you want matched | Service User, restricted token, IdP provisioning app |
| Best for | Private-network deployments and low-friction onboarding | Environments that need automatic revocation |
Choose one source of Team membership
Do not run both methods against the same Teams. Group sync can add a membership back at the next sign-in after Directory Sync removed it, so the two methods will fight over the same Team. Pick one as authoritative. See Team Best Practices.
How Group Matching Works
- Your IdP presents a group listing in the claim you configured.
- Qualytics tidies each name before recording it. Spaces at the ends are trimmed, a run of spaces inside a name becomes a single space, letters are lowered, empty entries are dropped, and a name that appears twice is recorded once. A claim that arrives as one piece of plain text rather than a list is split on commas, so
analysts,engineersrecords two groups. - The resulting listing is recorded on the account, replacing whatever was recorded before.
- Each name is compared against existing Team names, ignoring letter case. A Team named
Data-Engineeringmatches the groupdata-engineering. Because the recorded copy is lowercase, the listing you read back will not always match the casing your IdP sent. Only the Team's Name takes part in the match; a Team's Display Name, when set, is ignored. - The person is added to every matching Team they are not already on. Nothing else changes.
- The match in steps 4 and 5 is repeated as the person keeps using the platform, against the listing recorded for that session. See When Changes Take Effect.
flowchart TD
A[User signs in via IdP] --> B{Group claim present?}
B -- No --> C[Keep the previously recorded listing]
B -- Yes --> D[Record the presented group names]
D --> E{Group sync enabled?}
E -- No --> F[Listing recorded for review only]
E -- Yes --> G{Group name matches an existing Team?}
G -- No --> H[Ignore the group]
G -- Yes --> I{Already a member?}
I -- Yes --> J[No change]
I -- No --> K[Add the user to the Team]
When a Group Claim Is Missing or Empty
The difference between a missing claim and an empty one matters, because a misconfigured claim should not look like a directory that reports no memberships.
| Situation | Recorded listing | Team membership |
|---|---|---|
| No groups claim is configured on the provider | Nothing is read, so the previously recorded listing is kept | Unchanged |
| The configured claim is absent from the IdP response | The previously recorded listing is kept | Unchanged |
| The claim is present and empty | Cleared | Unchanged, because sync never removes membership |
| The claim holds groups as plain text instead of a list | Split on commas and recorded | Matched normally |
| The claim holds an unexpected value, such as a number or an object | Recorded as empty | Unchanged |
An absent claim usually shows up as an account with no recorded groups, which is the first thing to check when someone reports that they were not added to a Team.
An absent claim does block sign-in when Allowed Groups is set
The one exception is a provider that also restricts sign-in with Allowed Groups. There the claim is what the restriction is evaluated against, so a claim name that does not match what the IdP actually sends cannot be treated as "no groups". Sign-in is refused with a message naming the claim that was not found. Go back to Step 1, confirm the exact claim name your IdP sends, correct the provider's Groups Claim, and have the person sign in again.
When Changes Take Effect
Two different clocks apply here, and mixing them up is the usual source of confusion.
The group listing comes from the sign-in itself and stays fixed for the life of that session. Adding someone to a directory group, or removing them from one, is picked up the next time they sign in. To apply a directory change right away, have the person sign out and sign back in.
Team matching is re-checked continuously while someone is signed in, against the listing already recorded for their session. Creating a Team whose name matches a group that session already carries therefore adds them to that Team on their next page load, with no new sign-in. Turning group sync on behaves the same way: people who are already signed in start matching without signing in again.
Step 1: Confirm What Your IdP Sends
Before you enable anything, confirm the exact claim name and the exact values your IdP puts in it. Many IdPs need an extra scope before they include groups at all, and several send group identifiers rather than group names.
| Identity Provider | What to check |
|---|---|
| Microsoft Entra ID (Azure AD) | Add the optional groups claim under Token configuration. Entra sends group object IDs by default. To send names instead, select the sAMAccountName source, which is available for groups synchronized from on-premises Active Directory. Cloud-only groups are sent as object IDs. |
| Okta | Add a groups claim to the authorization server with a filter that selects the groups you want to send. Okta sends group names. |
| Keycloak | Add a Group Membership mapper to the client and turn off Full group path so names are sent without a leading slash. |
| Google Workspace | Google does not include a groups claim by default. |
| PingFederate, ADFS, OneLogin | Add a group attribute to the token or user information response, then confirm whether it carries names or identifiers. |
Identifiers cannot be matched to Team names
If your IdP can only send group object IDs or other opaque identifiers, group sync has nothing readable to match against Team names. Either configure the IdP to send names, or use Directory Sync instead.
You do not have to guess. Because the presented listing is recorded even while group sync is off, you can turn on the claim in your IdP first, have a test user sign in, and read back exactly what arrived in the Identity Provider Groups field of the Edit User dialog. See Step 4.
Step 2: Create Matching Teams
Group sync never creates Teams, so every group you want honored needs a Team whose name matches it, ignoring letter case.
- List the directory groups that should govern access in Qualytics.
- Add a Team for each one, using the group name exactly as your IdP presents it.
- Assign datastores and set the team permission for each Team. Group sync controls who is on a Team, never what that Team can reach.
Keep the naming boring
A directory group and its Qualytics Team should share one literal name. Resist prefixes such as AD- or suffixes such as Team on the Qualytics side, because they break the match and the failure is silent. When a directory name is unreadable, such as WF-DQ-PROD-ANALYSTS-RW, keep it as the Team's Name and give the Team a Display Name. The display name is what people see across the platform, while the match keeps using the name underneath.
Groups that have no matching Team are ignored, so an over-broad claim is harmless. Sending your entire directory group list is not a security problem by itself, but it does make the recorded listing noisy to review, and a Team created later with a colliding name will start receiving members as soon as the people carrying that group use the platform again. Prefer a claim filtered to the groups that are relevant to Qualytics.
Step 3: Enable Group Sync
Group sync is off by default because Team membership can grant access to data, so neither a new provider nor an upgrade ever starts adding people to Teams on its own. Enable it only after Step 1 and Step 2 are complete.
The setting belongs to each OIDC or SAML provider, so each one can be turned on independently.
- Go to Settings > Access and open the Providers tab.
- Open the provider and find the Access Restriction section.
- Enter the claim confirmed in Step 1 in Groups Claim, if it is not set already.
- Turn on Sync groups to Teams.
- Save the provider.
The toggle stays unavailable until Groups Claim holds a value, because without a claim no group memberships are read and nobody would ever be added to a Team. Clearing the claim turns the toggle back off. See Add an OIDC Provider or Add a SAML Provider.
Step 4: Review What Your IdP Presented
Reviewing the recorded listing answers three questions at once: whether the claim arrived, whether the values are names rather than identifiers, and whether they match your Team names. Check one account in the platform, or every account through the API.
In the Edit User Dialog
- Go to Settings > Access and open the Users tab.
- Find the person, click the vertical ellipsis on their row, and choose Edit .
- Read the Identity Provider Groups field, below Teams. Each group presented at that person's most recent sign-in appears as its own entry. When nothing was presented, the field reads "No groups presented by the identity provider".
Comparing this field with Teams in the same dialog is the quickest way to see why someone did or did not land on a Team. A group listed here with no matching Team means the Team does not exist yet. An empty field on a provider that has a groups claim means the claim did not arrive, or arrived with no groups in it.
The field is read-only, because the identity provider owns the listing and an edit here would be discarded at the next sign-in. Change group membership in the identity provider instead. The field is absent for Service accounts, which never sign in through an identity provider, and on the dialog that creates a user, since nothing has been presented yet.
The same groups drive the sign-in restriction
A provider's Allowed Groups restriction is evaluated against the same groups, but before anything is recorded. A refused sign-in therefore records nothing: the field keeps showing the groups from the person's last successful sign-in, or stays empty if they have never signed in. To see what the IdP sends, read the field of someone the restriction admits.
Through the API
For a bulk or scripted review, the same listing is available through the Personal Account API in the oidc_groups field. The field keeps its original name, but it holds the groups presented by SAML providers as well.
curl -H "Authorization: Bearer $QUALYTICS_TOKEN" \
"https://your-qualytics-domain/api/users?name=Jane"
Each user in the paginated results carries both what the IdP presented and the Teams the account currently belongs to:
{
"id": 42,
"name": "Jane Doe",
"email": "jane.doe@example.com",
"role": "Member",
"oidc_groups": ["data-engineering", "finance-analysts", "all-employees"],
"teams": [
{ "name": "Public", "permission": "Reporter" },
{ "name": "Data-Engineering", "permission": "Editor" }
]
}
Reading this example: finance-analysts was presented but produced no membership, which means no Team of that name exists yet. all-employees was presented and ignored for the same reason. The recorded names are lowercase even though the Team they matched is not, which is expected and does not affect matching. Listing users requires the Manager or Admin role. See the Personal Account API.
Keeping Membership Accurate Over Time
Group sync is add-only. This is the single most important thing to plan around, because it means a directory change that grants access is applied automatically while a directory change that revokes access is not.
Removing someone from a directory group has no effect on the Team they were already added to. They keep that Team membership, and the access it carries, until an administrator removes it in Qualytics.
Plan for two separate paths:
- Granting access is automatic. Add the person to the directory group and their next sign-in puts them on the matching Team.
- Revoking access is manual. Remove the person from the directory group, then remove their Team membership in Qualytics.
A Reconciliation Routine
The recorded group listing reflects the directory as of the person's last successful sign-in that carried the groups claim. It is not refreshed by a refused sign-in, by a sign-in whose claim was absent, or while someone stays away, so a group removed in the directory can remain listed until the person signs in again. Before relying on the listing for an access review, check the Last Active column of the Users list and treat anyone not seen since the directory change as carrying a stale listing. For a single account, compare Identity Provider Groups against Teams in the Edit User dialog. For a periodic review of everyone, run the following on the cadence your access policy requires.
- List users through the API and read
oidc_groupsalongsideteamsfor each account. - Compare each Team name against
oidc_groupsignoring letter case, since the recorded names are lowercase while Team names keep their casing, and flag any Team membership with no matching entry. That is a membership the directory no longer justifies. - Confirm the exceptions. A membership granted deliberately in Qualytics, or one predating group sync, will also show up here and is legitimate.
- Remove the memberships that remain by editing the user.
- Deactivate the account for anyone who has left the organization. Removing a Team membership limits reach, but only deactivation ends access.
Do not treat sign-in as an access review
A successful sign-in confirms that your IdP still authenticates the person. It does not confirm that their Qualytics Team memberships still reflect their directory groups. Only the reconciliation above does that.
When to Use Directory Sync Instead
If your access policy requires that revoking a directory group revokes Qualytics access without an administrator acting, group sync is not sufficient on its own. Use Directory Sync, which manages the full lifecycle including removals, and leave group sync off.
Limitations
| Limitation | Consequence |
|---|---|
| Membership is add-only | Removing a directory group does not revoke Team membership |
| Teams are never created | A group with no matching Team is silently ignored |
| Matching is by Team name only | Group identifiers, such as object IDs, cannot be matched to Team names, and a Team's Display Name never takes part in the match |
| Roles are not mapped | Platform roles stay under administrator control in Qualytics |
| Directory changes apply at sign-in | A new group membership is picked up at the person's next sign-in, while a newly created Team matches without one |
| Public team is always present | Every account is on the Public team regardless of group membership |
| Nested groups depend on your IdP | Only the groups your IdP actually includes in the claim are considered |
Troubleshooting
| Symptom | Likely Cause | Solution |
|---|---|---|
| Identity Provider Groups is empty for everyone | The provider has no Groups Claim, so nothing is read, or the claim is configured but not being sent | Set the provider's Groups Claim, confirm the claim name, and add any scope your IdP requires, then have a user sign in again |
| Sign-in fails with a message that the groups claim was not found | The provider restricts sign-in with Allowed Groups and its Groups Claim does not match what the IdP sends | Confirm the exact claim name your IdP sends (Step 1) and set Groups Claim to it |
| The recorded listing is populated but no Team was joined | Group sync is off for that provider, or no Team name matches | Confirm Sync groups to Teams is on for the provider the person signed in with, then compare the listed names against your Team names |
| Only some groups produce Team membership | Teams exist for some group names only | Create the missing Teams, or accept that the extra groups are meant to be ignored |
| Identity Provider Groups holds long identifiers instead of names | The IdP sends group object IDs | Configure the IdP to send names, or use Directory Sync |
| A Team was renamed to match a group but nobody joins it | Only the Display Name was changed; the match uses the Team's Name | Set the Team's Name to the group name and move the friendly label to Display Name |
| A user was added to the wrong Team | A directory group name collides with an unrelated Team name | Rename the Qualytics Team, or filter that group out of the claim |
| A directory change has not appeared | The person is still on an older session | Have them sign out and sign back in |
| Someone kept access after leaving a group | Expected behavior, because sync is add-only | Remove the Team membership in Qualytics and adopt the reconciliation routine above |
| Membership reappears after being removed | Both group sync and Directory Sync are managing the same Team | Choose one authoritative method and disable the other |