Provisioning with SCIM¶
With SCIM (System for Cross-domain Identity Management, version 2.0) your identity provider (IdP) pushes people and groups to Specivo instead of waiting for them to sign in:
- People exist before their first sign-in, so you can add them to projects, assign issues to them and mention them on day one.
- Disabling or deleting someone at the IdP takes effect in Specivo at once: the account is deactivated, every session ends and every API key is switched off. You do not have to wait for the session check or a back-channel logout, and API keys are covered too.
- Groups follow the IdP: an IdP group becomes a Specivo user group, and its members are kept in step.
SCIM works next to single sign-on, not instead of it: people still sign in through the same provider's button on the login page. Set up the provider first (see Single sign-on), then add SCIM to it.
What Specivo supports¶
| Resources | Users and groups. |
| Operations | Create, read, list, replace (PUT), update (PATCH) and delete, for both. |
| Filters | userName eq, externalId eq, emails[type eq "work"].value eq (users), displayName eq and externalId eq (groups), id eq, joined with and. Other filters get 400 invalidFilter. |
| Paging | startIndex and count, at most 200 results per page (SCIM_MAX_RESULTS). |
| Not supported | Bulk requests, sorting, ETags, passwords. A password sent by the IdP is ignored. |
| Authentication | A bearer token per provider, generated in Specivo. |
The base URL of each provider is {APP_URL}/scim/v2/{slug}, for example
https://specivo.example.com/scim/v2/entra (with a stealth prefix, the prefix comes before
/scim; the provider page shows the exact URL). Specivo also answers the discovery requests
(/ServiceProviderConfig, /ResourceTypes, /Schemas) that some IdPs send first.
Turning it on in Specivo¶
- Open Administration → Single sign-on and the provider. Save it first if it is new.
- In the Provisioning (SCIM) card, copy the SCIM base URL.
- Press Generate token. Copy the token at once: it is shown only this time. Specivo keeps only a hash of it, like an API key.
- Enter the base URL and the token at the IdP (see the steps for your IdP below).
- Tick Accept provisioning from this provider. Until then every SCIM request is refused.
The card shows the start of the current token, when the IdP last made a request, and how many users and groups it provisioned.
Rotate token replaces the token: the old one stops working at once, so enter the new one at the IdP straight away. Revoke token removes it and turns provisioning off. Accounts and groups already provisioned stay as they are. Generating, rotating and turning provisioning on need an administrator signed in to Specivo; an administrator's API key can revoke the token but not create one.
A wrong or missing token, a provider with provisioning off, a provider that is switched off
(Enabled unticked) and a provider that does not exist all get the same 401 answer, so the
answer does not tell anyone which providers exist. Switching the provider off therefore stops
provisioning as well as sign-in.
authentik¶
authentik provisions through a SCIM provider attached to the application you created for sign-in.
- In the admin interface, open Applications → Providers and press Create. Choose SCIM Provider.
- URL: the SCIM base URL from Specivo. Token: the token from Specivo.
- Under Attribute mapping, keep authentik default SCIM Mapping: User and
authentik default SCIM Mapping: Group. They send the username as
userName, the email, the name andactive. - Leave Exclude service accounts on. Under Group filters, pick the groups to send to Specivo; with none picked, every group is sent (each with only its provisioned members).
- Open Applications → Applications → Specivo and add the new provider under Backchannel Providers. Save.
authentik provisions the users the application lets in: the users, groups and policies bound to it under Policy / Group / User Bindings. An application without bindings lets everyone in, so every user is provisioned. To provision only some people, bind a group to the application (which also limits who can sign in), or give the SCIM provider an application of its own, bound to the group to provision, and add the provider there as the backchannel provider instead.
authentik provisions when a user or group changes, and runs a full sync on a schedule. To start one now, open the SCIM provider and press Run sync again. Its result, with any error Specivo returned, is shown there and under Events → Logs.
Microsoft Entra ID¶
Entra ID provisions from the enterprise application of your app registration.
- Open Microsoft Entra admin center → Enterprise applications → Specivo → Provisioning. Press Get started (or New configuration) and set Provisioning Mode to Automatic.
- Tenant URL: the SCIM base URL from Specivo. Secret Token: the token from Specivo. Press Test Connection.
-
Under Mappings, open Provision Microsoft Entra ID Users and check these attributes:
Specivo (SCIM) attribute Entra ID attribute userNameuserPrincipalName(the default)emails[type eq "work"].valuemailactiveSwitch([IsSoftDeleted], , "False", "True", "True", "False")(the default)displayNamedisplayNameexternalIdobjectId(the default ismailNickname; change it, see below)preferredLanguagepreferredLanguage(optional)Other attributes in the default list (job title, addresses, phone numbers, the enterprise extension) are accepted and ignored. Every Specivo account needs an email address, so a user whose
mailis empty is refused (see Users without a mailbox). 4. To provision groups, keep Provision Microsoft Entra ID Groups enabled. Only groups assigned to the application, and their members who are also assigned, are sent. 5. Under Settings, set Scope to Sync only assigned users and groups, assign the users and groups under Users and groups, and set Provisioning Status to On.
Entra ID runs a cycle about every 40 minutes. To test one person, use Provision on demand.
Disabling someone in Entra (or removing their assignment) sends active false in the next cycle;
deleting them sends a delete about 30 days later, after the soft-delete period.
Entra's email claim is never verified, so for the first sign-in map externalId to objectId
(step 3) and set SCIM externalId claim to oid under Claims on the Specivo provider page.
Specivo then finds the provisioned account by the object id; see
Signing in after provisioning.
Users without a mailbox¶
Entra ID fills mail only for users with an Exchange mailbox (or one set by hand). For a user
whose mail is empty it leaves emails out of the request, and Specivo answers
400 invalidValue: "A user needs an email address". The provisioning log shows the user as
failed. Give those users an address one of these ways:
- Set
mailon the user in Entra (Users → the user → Edit properties → Contact information → Email). Best when the address really receives mail. - Fall back to the user principal name. In the attribute mapping of step 3, edit the
emails[type eq "work"].valuerow: set Mapping type to Expression and the expression toCoalesce([mail], [userPrincipalName]). Users with a mailbox keep sendingmail; the others send their UPN. Use this only when the UPNs are real addresses on your mail domain: Specivo sends notifications and password-reset links to that address, and an@your-tenant.onmicrosoft.comUPN usually receives nothing. If the provider lists Allowed email domains, the UPN domain must be in the list.
After saving the mapping, test one user with Provision on demand, or wait for the next cycle.
Okta¶
Okta provisions from the application integration you created for sign-in.
- Open the application, then General → App Settings → Edit, tick Enable SCIM provisioning and save.
- On the new Provisioning tab, under Integration, press Edit:
- SCIM connector base URL: the SCIM base URL from Specivo.
- Unique identifier field for users:
userName. - Supported provisioning actions: Push New Users, Push Profile Updates and Push Groups.
- Authentication Mode: HTTP Header, with the token from Specivo as Bearer token. Press Test Connector Configuration, then Save.
- Under Provisioning → To App, enable Create Users, Update User Attributes and Deactivate Users.
- Assign people under Assignments. To provision groups, add them under Push Groups.
Okta deactivates a user (active false) when you unassign or deactivate them; it does not delete
users over SCIM.
Keycloak and other providers¶
Keycloak has no built-in SCIM client; use the session check and back-channel logout there. Any other IdP that speaks SCIM 2.0 works the same way: give it the base URL and the token as a bearer token.
What each IdP action does in Specivo¶
| At the IdP | In Specivo |
|---|---|
| Create a user | A Specivo account is created: the userName becomes the login (see below), the email is marked verified because the IdP vouches for it, and the account has no password. If an account with that email already exists, it is linked instead; see Existing accounts. |
| Change a user | Email, display name, language and time zone follow. The login follows a changed userName when the new login is free. |
Disable a user (active false) |
The account is deactivated at once, exactly like Deactivate account on the user's admin page: every session ends and every API key is switched off. |
Enable a user again (active true) |
The account is active again, if SCIM deactivated it. API keys stay off: the person switches them back on or creates new ones. An account deactivated in Specivo (by an administrator, or by a refused sign-in) stays deactivated until an administrator reactivates it. |
| Delete a user | The account is deactivated as above, removed from the groups this provider manages, and no longer visible to the IdP. It is not deleted, so issues, comments and history keep their author. If the IdP creates the same person again later, the same account comes back. |
| Create a group | A Specivo user group with that name. Give the group roles on projects under Administration → Groups or on a project's members page. |
| Change a group's members | People are added to or removed from the Specivo group. |
| Rename a group | The Specivo group is renamed. |
| Delete a group | The Specivo group is deleted, with its memberships and the project memberships it held. |
SCIM never sets a password, administrator rights or the service-account flag, whatever the IdP sends. To make someone an administrator, do it in Specivo, or with the administrator groups of single sign-on.
Administrators and service accounts are never deactivated, deleted or given another email
address through SCIM. This matters for an account that became an administrator (or a service
account) in Specivo after it was provisioned. If the IdP disables, deletes or re-addresses such an
account, Specivo answers 400 with the reason and records the refusal (scim_request_refused);
the IdP shows it as a provisioning error. Remove the administrator rights in Specivo first, or
deactivate the account there. The other attributes (display name, language, time zone, group
memberships) still follow the IdP.
Logins¶
The login is made from the userName the way single sign-on makes logins: lower case, letters,
digits, _ and -, and only the part before the @ of an email address. [email protected]
becomes alice-smith. When an email-shaped userName gives a login that another account already
has, the new account gets alice-smith-2. A userName starting with $ is refused: such logins
belong to system accounts.
Existing accounts¶
Most installs already have accounts when SCIM is turned on. When the IdP creates a user and an
account with the same email address (ignoring case) already exists, Specivo links that account
instead of creating a second one, but only when the provider's Existing accounts setting is
Link automatically by verified email (never for administrators). That is the same choice that
lets sign-in link existing accounts (Linking an existing account);
with the default, the IdP gets 409 uniqueness and you link or rename the account by hand. The existing login and password stay, and the profile follows the IdP from then on. A
linked account that was deactivated in Specivo stays deactivated.
SCIM never changes the email address of an account that has a Specivo password: the IdP gets
400 mutability. A password reset goes to the account's email, so moving it would hand the
password to whoever the IdP names. Change it in Specivo, or remove the password first. Accounts
that sign in only through the IdP follow its email changes.
When the provider lists Allowed email domains, SCIM applies them as well: a user created or
updated with an email outside them gets 400 invalidValue.
An account is never linked, and the IdP gets 409 uniqueness, when it is:
- an administrator,
- a service account,
- a system account (a login starting with
$), - already provisioned by another provider's SCIM, or by this one under another
userName.
An existing account whose email address was never verified (or that still waits for
verification) is linked too, but nothing on it is trusted: whoever set it up with that address may
not be the person the IdP provisions. Before it is marked verified, Specivo removes its password,
ends its sessions, switches off its API keys, deletes pending password-reset links and
disconnects its single sign-on identities. The audit log records this as scim_user_created with
the action adopted_unverified. The person then signs in through the IdP. Accounts with a
verified email keep their password, sessions and keys.
When the userName is itself a valid login (alice, not [email protected]) and an account
already has that login, that account must have the user's email too: an account with the same
login and another email is 409 uniqueness rather than linked, because the same login says
nothing about the same person. Resolve those by hand: change the email or the login of the
Specivo account, or remove the administrator flag if the account should be managed by the IdP.
A user, or a group, belongs to one provider's SCIM at most. A group name that any Specivo group
already uses is 409 uniqueness too: an existing group, and the project roles it holds, is never
taken over by the IdP. Rename one of the two.
Signing in after provisioning¶
At a provisioned person's first sign-in through the same provider, Specivo connects their IdP identity to the provisioned account (whatever Existing accounts says in the provider's sign-in policy) when one of these matches:
- the email in the token, under the same rules as automatic linking: the provider is trusted
to verify email addresses (This provider really verifies email addresses) and the token says
email_verified: true; - the SCIM
externalId, only if you set SCIM externalId claim under Claims to a claim the IdP guarantees to equal theexternalIdit sends over SCIM. It is off by default. For Microsoft Entra ID, mapexternalIdtoobjectIdand set the claim tooid.
The username alone never connects an account. If the username claim (preferred_username
unless you changed Username claim) equals a provisioned person's SCIM userName but the token
has no trusted, verified email, or another one, the sign-in is refused with
sso_account_not_provisioned and logged (sso.account.scim_link_refused). Specivo then does not
create a second account either, even with Create accounts on first sign-in on. Otherwise
somebody who can choose their own username at the IdP (or an IdP that sends no email) could
reach another person's account.
So set up one of the two matches before people sign in: trusted email where the IdP really
verifies it (Okta, Google, Keycloak with verified addresses), or the externalId claim (Entra ID,
whose email is never verified). authentik's default mapping sends email_verified: false; change
it to send true only if authentik really verifies addresses, then turn the trust setting on.
An account another provider provisioned is never connected, also not by Link automatically by verified email. An account that became an administrator in Specivo after it was provisioned is not connected automatically either; connect it from the person's profile.
Groups: SCIM or the groups claim¶
With provisioning on, the provider's Update Specivo group memberships from the mappings below at every sign-in setting is skipped: the IdP manages memberships through SCIM, and the groups claim in the sign-in token would otherwise undo SCIM's changes at every sign-in. The provider page says so under that setting. Required groups and the administrator groups still use the groups claim.
Memberships an administrator added by hand to a SCIM group stay; SCIM adds and removes only the memberships it made. Only people provisioned by the same provider can be SCIM members of a group.
Limits¶
| Setting | Default | Meaning |
|---|---|---|
SCIM_RATE_LIMIT_PER_MINUTE |
600 |
Requests per minute per provider. Over it, 429 with Retry-After; IdPs retry. |
SCIM_UNAUTHENTICATED_RATE_LIMIT_PER_MINUTE |
30 |
Requests with a wrong token, per client address. They never use up the provider's own allowance. |
SCIM_MAX_BODY_BYTES |
1048576 |
Largest request body. Larger requests get 413. |
SCIM_MAX_RESULTS |
200 |
Most resources in one list response. |
Every SCIM change is logged (specivo.scim) and recorded in the security audit log as
scim_user_created, scim_user_updated, scim_user_deprovisioned, scim_group_created,
scim_group_updated, scim_group_deleted or scim_request_refused, with the provider as the
source. Deactivations are also recorded as user_deprovisioned with the reason
scim_deprovision. Token changes are recorded as scim_config_changed.
Troubleshooting¶
| Symptom | Check |
|---|---|
401 on every request, also on the IdP's connection test |
The provider is switched off, provisioning is not ticked in Specivo, the token was rotated or revoked, or the IdP sends it in another way than Authorization: Bearer. The slug in the base URL must be the provider's. |
401 after it worked |
Somebody rotated or revoked the token. Generate a new one and enter it at the IdP. |
409 uniqueness when creating a user |
The userName exists already, the email belongs to an account that is never linked (an administrator, a service account, an account of another provider), or an account has that login with another email. See Existing accounts. |
409 uniqueness when creating a group |
A Specivo group with that name exists. Rename one of them. |
400 invalidValue: "A user needs an email address" |
The user has no email at the IdP, or the email mapping is missing. Entra ID: map mail; for users without a mailbox see Users without a mailbox. |
400 invalidValue: "Members must be users provisioned by this identity provider" |
The group has members that are not provisioned (yet). Provision them first, or assign them to the application. |
400: "This account is an administrator in Specivo" |
The IdP tried to disable, delete or change the email of an administrator (or a service account). Remove the administrator rights in Specivo first. |
| A user stays inactive although the IdP enables them | The account was deactivated in Specivo, not through SCIM. Reactivate it under Administration → Users. |
400 invalidFilter |
The IdP sent a filter Specivo does not support. Check its attribute mapping for the matching attribute: it must be userName, externalId or the work email. |
The person is provisioned but sign-in says sso_account_not_provisioned |
Neither a trusted, verified email nor the externalId claim matched; a matching username alone is not enough. Turn on This provider really verifies email addresses where that is true, or set SCIM externalId claim (Entra ID: oid, with externalId mapped to objectId). The log line sso.account.scim_link_refused names the reason. |
| Group memberships from the token no longer change | Expected while provisioning is on; see Groups: SCIM or the groups claim. |
429 |
The IdP sends more than SCIM_RATE_LIMIT_PER_MINUTE requests a minute. It retries on its own; raise the limit for a large first sync. |