You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The SCIM docs are organized as three provider setup walkthroughs with no shared statement of what SCIM actually does. A reader can't answer basic questions ("can SCIM assign roles?", "does deprovisioning delete the user?", "will my IdP work?") without reading all three pages and inferring. Several cross-provider facts are stated on exactly one page, which makes them read as provider-specific quirks when they're universal.
Verified against the implementation in pulumi/pulumi-service (cmd/service/api/scim/, cmd/service/api/{users,teams}_scim*.go, routes at cmd/service/main.go:1652-1692).
Unlike VCS integrations, there is one SCIM 2.0 implementation. Every IdP hits the same routes, schemas, attributes and limits. There is no per-provider config, no capability matrix, and no supported-provider enum in the codebase. Only the IdP-side setup differs.
The only two places an IdP affects server behavior are compatibility accommodations available to everyone: GET /Users is registered for search because some IdPs only search via GET, and a userName reactivation quirk is tolerated leniently.
Practical implication: any spec-compliant SCIM 2.0 IdP should work, not just the three we document. The docs currently read as if those three are the only options. (Flagging that this is a support-commitment statement — worth product sign-off on how strongly to word it.)
Bugs to fix
Stale team-name limit. All three provider pages warn that team names "must not exceed 40 characters". The real limit is 100 (maxDefaultNameLength = 100, enforced in teams_scim.go:549; column widened 40→100 by migrations/328_bump_scim_display_name_size.up.sql in Nov 2024). Stale for ~21 months. Locations: okta.md:143, entra.md:33, onelogin.md (group provisioning section).
Broken anchor.onelogin.md:20 links to #known-limitations, but the OneLogin page has no such section. Okta and Entra both do.
FAQ attribute list is incomplete. The "Unknown path" answer lists userName, displayName, givenName, familyName, active — it omits emails[type eq "work"].value, which is supported and which the Entra guide tells you to mark as required.
Entra intro undersells scope. It says "provisioning/deprovisioning of your users"; Okta and OneLogin say "users and groups". Entra supports groups, and the page already has a group-provisioning section.
Add a capability section to the SCIM index page
_index.md is 32 lines and documents no feature surface at all. Proposed content:
Supported
Capability
Notes
User provisioning
Create, read, update (PUT/PATCH), search
User deprovisioning
Soft only — active: false. There is no DELETE /Users.
userName eq (Users) and displayName eq (Groups) only; eq is the only operator
Pagination
Users only. Max 100/page. Group search returns all results in one response.
Supported attributes — this is the complete list
Users:userName (immutable after creation), displayName, name.givenName, name.familyName, emails[type eq "work"].value, active
Groups:displayName, members
Anything else returns 400 invalidPath.
Not supported
Notes
Role / admin provisioning
No roles or entitlements. Org role and team role can't be set via SCIM; SCIM users are always created as members and team members are always added as plain members.
externalId
Accepted on Users but never stored; Groups have no externalId field at all. This is why the Entra guide says to delete the objectId→externalId group mapping.
Bulk operations
bulk: false
Sorting
sort: false
ETag
etag: false
Password sync
changePassword: false
Enterprise User extension
Core 2.0 schemas only
Secondary emails
Only the primary work email is used
Editions
Business Critical (Pulumi Cloud) and self-hosted Enterprise.
Promote single-page facts to the shared page
These are universal but currently appear on one page each:
Deprovisioning never deletes. OneLogin's "Suspend (DO NOT set to Delete)" is the only place this appears, but it's true for every IdP — there is no DELETE /Users route at all. Okta and Entra readers never learn this.
userName is immutable after creation. Okta's page explains the "Create only" mapping and Entra's explains "Only during object creation"; neither says why, and OneLogin doesn't mention it.
Group members must already be provisioned and active before the group is pushed, or the request returns 400. Currently only in the Okta page and the FAQ.
externalId on groups is ignored — documented only on the Entra page today, universal in fact.
Also worth a warning
GET /Groups returns all teams matching the display-name filter, including Pulumi-local and GitHub-backed teams, not only SCIM-provisioned ones (cmd/service/model/teams.go:515-523). Since the docs explicitly encourage running local teams alongside SCIM teams, an IdP reconciling group state may see teams it doesn't own.
Group member validation also caps at 3000 SAML identities per query, which is an undocumented practical ceiling on team size.
Problem
The SCIM docs are organized as three provider setup walkthroughs with no shared statement of what SCIM actually does. A reader can't answer basic questions ("can SCIM assign roles?", "does deprovisioning delete the user?", "will my IdP work?") without reading all three pages and inferring. Several cross-provider facts are stated on exactly one page, which makes them read as provider-specific quirks when they're universal.
Verified against the implementation in
pulumi/pulumi-service(cmd/service/api/scim/,cmd/service/api/{users,teams}_scim*.go, routes atcmd/service/main.go:1652-1692).Pages in scope:
/docs/administration/access-identity/scim/(_index.md)/docs/administration/access-identity/scim/okta//docs/administration/access-identity/scim/entra//docs/administration/access-identity/scim/onelogin//docs/support/faq/scim/Key context: SCIM is provider-agnostic
Unlike VCS integrations, there is one SCIM 2.0 implementation. Every IdP hits the same routes, schemas, attributes and limits. There is no per-provider config, no capability matrix, and no supported-provider enum in the codebase. Only the IdP-side setup differs.
The only two places an IdP affects server behavior are compatibility accommodations available to everyone:
GET /Usersis registered for search because some IdPs only search via GET, and auserNamereactivation quirk is tolerated leniently.Practical implication: any spec-compliant SCIM 2.0 IdP should work, not just the three we document. The docs currently read as if those three are the only options. (Flagging that this is a support-commitment statement — worth product sign-off on how strongly to word it.)
Bugs to fix
maxDefaultNameLength = 100, enforced inteams_scim.go:549; column widened 40→100 bymigrations/328_bump_scim_display_name_size.up.sqlin Nov 2024). Stale for ~21 months. Locations:okta.md:143,entra.md:33,onelogin.md(group provisioning section).onelogin.md:20links to#known-limitations, but the OneLogin page has no such section. Okta and Entra both do.userName,displayName,givenName,familyName,active— it omitsemails[type eq "work"].value, which is supported and which the Entra guide tells you to mark as required.Add a capability section to the SCIM index page
_index.mdis 32 lines and documents no feature surface at all. Proposed content:Supported
active: false. There is noDELETE /Users.userName eq(Users) anddisplayName eq(Groups) only;eqis the only operatorSupported attributes — this is the complete list
userName(immutable after creation),displayName,name.givenName,name.familyName,emails[type eq "work"].value,activedisplayName,membersAnything else returns
400 invalidPath.Not supported
rolesorentitlements. Org role and team role can't be set via SCIM; SCIM users are always created as members and team members are always added as plain members.externalIdexternalIdfield at all. This is why the Entra guide says to delete theobjectId→externalIdgroup mapping.bulk: falsesort: falseetag: falsechangePassword: falseEditions
Business Critical (Pulumi Cloud) and self-hosted Enterprise.
Promote single-page facts to the shared page
These are universal but currently appear on one page each:
DELETE /Usersroute at all. Okta and Entra readers never learn this.userNameis immutable after creation. Okta's page explains the "Create only" mapping and Entra's explains "Only during object creation"; neither says why, and OneLogin doesn't mention it.externalIdon groups is ignored — documented only on the Entra page today, universal in fact.Also worth a warning
GET /Groupsreturns all teams matching the display-name filter, including Pulumi-local and GitHub-backed teams, not only SCIM-provisioned ones (cmd/service/model/teams.go:515-523). Since the docs explicitly encourage running local teams alongside SCIM teams, an IdP reconciling group state may see teams it doesn't own.Group member validation also caps at 3000 SAML identities per query, which is an undocumented practical ceiling on team size.
Related