SCIM Provisioning
Provision and deprovision users and teams in Duro automatically from your identity provider.
Overview
SCIM 2.0 lets your IdP — Okta, Microsoft Entra ID, JumpCloud, OneLogin, and others — push user and group changes to Duro. When someone joins a group in your IdP, they appear on the matching Duro team. When they leave the company, their Duro access is revoked without a manual step.
Duro exposes a SCIM 2.0 endpoint at a per-tenant host — https://<tenant>-scim.durohub.com/scim/v2 — separate from the API host you use for GraphQL. Your IdP authenticates with a bearer token pinned to one organization.
What SCIM manages, and what it doesn't
Users (create, update, deactivate)
Roles on teams — organization role plus library overrides
Groups → Teams
Which teams get which access
Group membership → Team membership
—
Roles are always assigned in Duro, never by the IdP. SCIM provisions team membership only; Duro does not consume the SCIM roles attribute. After a team is provisioned, a Duro administrator assigns its organization role and any per-library overrides. See Role-Based Access Control.
Before you start
SAML SSO already enabled for the organization. Enabling SCIM without it is rejected — complete Enterprise SSO first
A role with the
organization.scim.managepermission — Site Admin by defaultAdministrator access to your IdP to configure a provisioning app
A plan including the
SCIMentitlement, or enabling it fails withFEATURE_NOT_IN_PLAN. See Entitlement Errors
Where this lives in Duro:
Or navigate there: Organization settings → Authentication. SCIM sits under Single sign-on, and shows Requires SAML SSO until SAML is on.
Step 1 — Enable SCIM
Toggle SCIM provisioning, or:
Step 2 — Generate a token
Click Generate token in the SCIM section, or:
The token is shown exactly once and cannot be retrieved afterwards. Copy it straight into your IdP.
expiresAt is optional. To see what exists:
To rotate: generate the new token, update your IdP, then revoke the old one.
Revoking your last active token releases every SCIM-managed team back to Duro-managed control, and generating a new one does not undo that. Always generate first.
Step 3 — Configure your IdP
In your IdP's provisioning settings for the Duro application:
SCIM version
SCIM 2.0
Authentication method
HTTP Header / Bearer token
SCIM base URL
https://<tenant>-scim.durohub.com/scim/v2 — no trailing slash
Bearer token
The token from Step 2
Run Test Connection, then activate provisioning. Most IdPs then sync every user and group already assigned to the app.
Step 4 — Map groups and assign roles
Assign groups to the Duro provisioning app in your IdP. Each becomes a Duro team, with its members added
Assign roles in Duro. For each provisioned team, set its organization role and any per-library overrides
Groups map to teams
Create Group (POST /Groups)
Creates a team
Add / remove members (PATCH /Groups)
Adds or removes those users from the team
Replace members (PUT /Groups)
Replaces the team's membership
Delete Group (DELETE /Groups)
Archives the team
Deactivate user (PATCH /Users, active: false)
Removes the user from all teams, revoking access
SCIM-managed teams are locked in Duro
Renaming the team
Assigning the team's organization role
Adding or removing members
Assigning per-library role overrides
Archiving or restoring the team
Adjusting the team's library access
Your IdP owns who is on the team; Duro owns what the team can do.
Deprovisioning
Deactivating a user in your IdP — or removing them from every group assigned to Duro — removes their team memberships and revokes their organization access. It also ends every live Duro session for that user, including any CAD plugin session, within one access-token lifetime.
Live enforcement
The SCIM-enabled state is checked on every request. Disabling SCIM — directly, or by disabling SAML — stops the bearer token authenticating immediately, and your IdP starts receiving 401 Unauthorized.
Testing your setup
Confirm SAML is enabled and SCIM shows as enabled
Run your IdP's Test Connection against the
/scim/v2base URLAssign a test user, confirm they appear as active in Duro
Assign a group with members, confirm a matching team is created
Assign a role to the team in Duro, confirm a member's access reflects it
Deactivate the test user, confirm access is revoked and the account remains
Troubleshooting
Provisioning suddenly returns 401 Unauthorized Expected if SCIM was disabled, or SAML was disabled (which disables SCIM). Re-enable SAML, then SCIM, and generate a fresh token if the old one was revoked.
Test Connection fails before any users sync Check the host first. A wrong hostname fails at DNS or routing, before your token is ever read, so most IdPs report it as a generic connection problem with nothing to go on — and Duro shows the token as never used, because it never arrived. Run the curl check above: 401 means the host is right, 404 or a connection error means it is not. Only then check that the base URL ends in /scim/v2 with no trailing slash, that the token was copied correctly and is not revoked, and that both SCIM and SAML are enabled.
A team can't be renamed or edited in Duro SCIM-managed teams are locked. Make membership and naming changes in your IdP; assign roles and library access in Duro.
Teams stayed locked after revoking the last token Release them: mutation { scimTokens { forceRelease } }
A provisioned user's SSO sign-in fails SCIM is not involved in sign-in itself — that is the SAML flow. A rejected assertion returns the user to whichever page they started from with saml_failed or saml_no_account in the URL; work from Where a failed sign-in lands and the SSO troubleshooting section. A user provisioned through SCIM already has an account, so saml_no_account points at an address mismatch between your directory and the assertion, not at a missing account.
A provisioned user can sign in but sees no access Access flows through teams. Confirm they are on a provisioned team, and that the team has a role assigned in Duro.
Next steps
Role-Based Access Control — how team roles combine with a user's direct roles.
Last updated
Was this helpful?