Descope
The Descope connector reads identity and access data from a Descope project (https://www.descope.com) via the Descope Management API and surfaces it to ConductorOne. It syncs users, tenants, roles, and permissions, and can grant and revoke role assignments and tenant memberships.Supported Resources
Setup
- Log in to the Descope console as a project admin.
- Find your Project ID under Project → Settings → Project ID (it
starts with
P). - Create a Management Key under Company → Management Keys, scoped to the project you want to connect. Copy it — Descope shows it only once.
- In ConductorOne, add the Descope integration and provide:
- Project ID — the
P…value above. - Management Key — the key you just created.
- Base URL — use
https://api.descope.comunless you are on a non-default Descope deployment. - Tenant IDs — optional. Leave empty to sync every tenant in the
project. When set, only these tenants are synced: their tenant resources,
their memberships, the assignments of roles scoped to them, and the
tenant-scoped roles themselves. Project-level roles and every user still
sync — the role catalogue is read in one project-wide call and the user
directory is not filtered.
The connector checks on every sync that each ID here is a tenant in the
project. A configured ID the search does not return fails that whole
sync — users, roles and permissions included, not just that tenant —
naming the ID, so a tenant that was deleted in Descope stops syncing
until its ID is removed from this field. An ID that does
not exist, or that carries whitespace from a comma-separated value, would
otherwise drop that tenant’s resources and membership grants from every
sync without an error — the listing simply returns fewer tenants. Find the
IDs in the Descope console under Tenants (they start with
T).
- Project ID — the
ProjectID:ManagementKey.
Required Permissions
The management key needs read access to users, tenants, roles, and permissions, plus user-management write access for provisioning (role assignment and tenant membership). A project-scoped management key with the project admin role covers all of these.Sync Behavior
- Paginates
/v2/mgmt/user/searchvia the request-bodyoffset/limitfields (page size 100), terminating on the responsetotal. - Lists tenants, roles, and permissions in single unpaginated calls.
- Lists tenants through
POST /v1/mgmt/tenant/search. With Tenant IDs unset the request carries an empty payload, which Descope documents as returning every tenant. With the field set the request filters bytenantIds, so the response — and the memory it occupies — is bounded by the configured tenants instead of by the project’s tenant count. Without that bound, a project that auto-provisions a tenant per end-user can return a tenant listing large enough to exhaust the connector’s memory. - Fails validation when a configured Tenant IDs value is not returned by
that search. Descope answers an unmatched
tenantIdsfilter with a normal empty result, so without the check a wrong ID would just sync less. - Scopes tenant-scoped roles, resources and walks together. A role scoped to a
tenant that Tenant IDs excludes is not emitted as a role resource (so its
tenant id does not reach ConductorOne in the role display name or the
tenant_idprofile), and its member walk is skipped. Project-level roles (tenant_idempty) are never filtered. The permission → role grants below are derived from the same role catalogue, so they are filtered the same way — a grant never names a role resource that was not emitted. - Reads the role catalogue itself in one project-wide call per sync, cached for the session; the scope filter above is applied to what it emits, not to what it fetches.
- Does not filter the user directory: users are project-level in Descope, and a user can belong to a tenant that is not synced without being scoped to one. Every user is emitted, whoever its tenants are.
- Refuses to grant access outside the sync scope. A project previously synced without Tenant IDs still holds ConductorOne entitlements for every tenant, so a grant request can name an excluded tenant; the connector fails that grant with an actionable error instead of writing it. Revokes are not guarded, so legacy out-of-scope grants can be cleared.
- Resolves tenant and role grants with a server-side filtered
/v2/mgmt/user/searchper resource —tenantIdsfor tenant membership,tenantRoleNamesfor tenant-scoped roles, androleNamesfor project-level roles — so no full user directory is cached in the session store. - Reports tenant membership as direct membership only, via
includeSubTenants: false. A user’suserTenants[]lists only the tenants they belong to directly, so members of a child tenant are not reported against its parent. - Re-checks project-level role holders against the user’s project
roleNames. TheroleNamesfilter matches a role name at any scope, so a user holding the role only inside a tenant would otherwise be reported as holding the project-level role of the same name. - Resolves permission grants from the inline
permissionNameson the role list (cached once per sync; the role list is small and bounded). - Treats HTTP 429 and 5xx as transient and retries with exponential back-off.
- Caps concurrency at
maxParallelFetches: 6.
Provisioning
- Every grant and revoke first resolves the principal’s login via
GET /v1/mgmt/user?userId=…, because the mutation endpoints below take aloginIdwhile user resources are keyed on the stableuserId. - Role assignment (
role→assigned): grants and revokes project-level and tenant-scoped roles via/v1/mgmt/user/update/role/addand/remove(tenant-scoped roles include thetenantId). - Tenant membership (
tenant→member): adds and removes users via/v1/mgmt/user/update/tenant/addand/remove. - Permission → role grants are read-only; manage them by editing roles in Descope.