Summary
Sentry's SCIM 2.0 implementation currently exposes provisioning endpoints (/Users, /Users/{id}, /Groups, /Groups/{id}) and a /Schemas index, but does not implement the SCIM 2.0 service discovery endpoints defined in RFC 7644 §4.
Specifically, the following endpoints return 404:
GET /scim/v2/ServiceProviderConfig
GET /scim/v2/ResourceTypes
GET /scim/v2/Schemas/{schemaUri} (per-URI lookup, e.g. urn:ietf:params:scim:schemas:core:2.0:User)
Reference in code: src/sentry/api/urls.py only registers Users, Users/{id}, Groups, Groups/{id}, and Schemas (index only).
Why this matters
Several Identity Governance and Administration (IGA) platforms run a SCIM 2.0 compliance pre-flight against the target service before allowing an integration to be enabled. These pre-flight validators follow RFC 7644 strictly and require:
ServiceProviderConfig to advertise supported features (filter, patch, bulk, sort, etag, auth schemes).
ResourceTypes to enumerate supported resources (User, Group).
- Per-URI
/Schemas/{uri} lookups to retrieve attribute definitions for each resource.
When these endpoints return 404, the validator marks the service as not SCIM 2.0 compliant and blocks the integration from being configured, even though the actual provisioning endpoints work correctly against Okta and Microsoft Entra ID (which hardcode the schemas client-side and skip discovery).
Example validator output
Service is not SCIM 2.0 compliant.
- HTTP GET on .../scim/v2/ServiceProviderConfig failed: not found (404).
- HTTP GET on .../scim/v2/ResourceTypes failed: not found (404).
- User is not present in ResourceTypes
- Group/Role/Entitlement is not present in ResourceTypes
- HTTP GET on .../scim/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:User failed: not found (404).
Proposed solution
Implement the three missing read-only endpoints, scoped per organization under the existing /api/0/organizations/{org_slug_or_id}/scim/v2/ prefix:
GET /ServiceProviderConfig returning a static document describing Sentry's actual capabilities (e.g. filter.supported = true with eq only, patch.supported = true, bulk.supported = false, etag.supported = false, bearer token auth scheme).
GET /ResourceTypes returning entries for User and Group, mapped to the schema URIs already defined in src/sentry/core/endpoints/scim/constants.py (SCIM_SCHEMA_USER, SCIM_SCHEMA_GROUP).
GET /Schemas/{schemaUri} returning the per-URI schema document. The schema definitions already exist in src/sentry/core/endpoints/scim/schemas.py (SCIM_USER_ATTRIBUTES_SCHEMA, SCIM_GROUP_ATTRIBUTES_SCHEMA), so this is largely a routing addition that returns the matching object by id.
All three endpoints are read-only and require no new persistent state, so the implementation cost is relatively low.
Acceptance criteria
References
Summary
Sentry's SCIM 2.0 implementation currently exposes provisioning endpoints (
/Users,/Users/{id},/Groups,/Groups/{id}) and a/Schemasindex, but does not implement the SCIM 2.0 service discovery endpoints defined in RFC 7644 §4.Specifically, the following endpoints return
404:GET /scim/v2/ServiceProviderConfigGET /scim/v2/ResourceTypesGET /scim/v2/Schemas/{schemaUri}(per-URI lookup, e.g.urn:ietf:params:scim:schemas:core:2.0:User)Reference in code:
src/sentry/api/urls.pyonly registersUsers,Users/{id},Groups,Groups/{id}, andSchemas(index only).Why this matters
Several Identity Governance and Administration (IGA) platforms run a SCIM 2.0 compliance pre-flight against the target service before allowing an integration to be enabled. These pre-flight validators follow RFC 7644 strictly and require:
ServiceProviderConfigto advertise supported features (filter, patch, bulk, sort, etag, auth schemes).ResourceTypesto enumerate supported resources (User, Group)./Schemas/{uri}lookups to retrieve attribute definitions for each resource.When these endpoints return
404, the validator marks the service as not SCIM 2.0 compliant and blocks the integration from being configured, even though the actual provisioning endpoints work correctly against Okta and Microsoft Entra ID (which hardcode the schemas client-side and skip discovery).Example validator output
Proposed solution
Implement the three missing read-only endpoints, scoped per organization under the existing
/api/0/organizations/{org_slug_or_id}/scim/v2/prefix:GET /ServiceProviderConfigreturning a static document describing Sentry's actual capabilities (e.g.filter.supported = truewitheqonly,patch.supported = true,bulk.supported = false,etag.supported = false, bearer token auth scheme).GET /ResourceTypesreturning entries forUserandGroup, mapped to the schema URIs already defined insrc/sentry/core/endpoints/scim/constants.py(SCIM_SCHEMA_USER,SCIM_SCHEMA_GROUP).GET /Schemas/{schemaUri}returning the per-URI schema document. The schema definitions already exist insrc/sentry/core/endpoints/scim/schemas.py(SCIM_USER_ATTRIBUTES_SCHEMA,SCIM_GROUP_ATTRIBUTES_SCHEMA), so this is largely a routing addition that returns the matching object byid.All three endpoints are read-only and require no new persistent state, so the implementation cost is relatively low.
Acceptance criteria
GET /scim/v2/ServiceProviderConfigreturns a200with a valid SCIMServiceProviderConfigresource.GET /scim/v2/ResourceTypesreturns a200withUserandGroupresource type entries.GET /scim/v2/Schemas/{schemaUri}returns a200for the User and Group core schema URIs and a SCIM-compliant404for unknown URIs.References