Add SCIM Schemas discovery endpoint
What does this MR do and why?
Second MR of a stacked series that adds the SCIM service provider discovery endpoints (RFC 7644 §4). Depends on !257943 (merged), which adds the schema definitions.
This MR adds GET /Schemas and GET /Schemas/:id to both SCIM APIs:
- Group SCIM (GitLab.com):
/api/scim/v2/groups/:group_path/Schemasreturns theUserschema only. - Instance SCIM (Self-Managed):
/api/scim/v2/application/Schemasreturns theUser(including the read-onlygroupsattribute) andGroupschemas.
Implementation details:
- Both APIs share one implementation in
API::Scim::DiscoveryEndpoints. Each API provides its ownauthenticate_scim_discovery!(existing SCIM token, SAML, and license checks) andscim_discovery_base_url. - Schema IDs are URNs containing dots (
...:core:2.0:User), so the:idroute uses a custom requirement; otherwise Grape would parse.0:Useras a format extension. meta.locationis the absolute URL of each schema resource.- Responses use the SCIM
ListResponseandErrorformats.
Feature flag: all discovery endpoints are behind scim_discovery_endpoints (wip, disabled by default), as discussed in #452118. The flag is wip while the endpoints are split across this stack; it moves to beta once !258175 (merged) and !258176 (merged) are merged, and then gets rolled out. For group SCIM the actor is the group, so it can be enabled for specific customer groups on GitLab.com first; instance SCIM uses :instance. When disabled, the endpoints return a SCIM 404. Rollout issue: #632176.
Docs are added to the internal API docs (Group SCIM API and Instance SCIM API sections), because doc/api/scim.md documents the non-RFC SCIM identities API.
Stacked MRs
- !257943 (merged): schema definitions (merged)
- gitlab-org/cells/http-router!1406 (merged): HTTP Router routes for all three discovery endpoints (merge right before this MR)
- This MR:
/Schemas+ feature flag + docs - !258175 (merged):
/ServiceProviderConfig - !258176 (merged):
/ResourceTypes
HTTP Router
This MR adds routes to config/routing/gitlab_routes.json. The HTTP Router routes for all three discovery MRs are added at once in gitlab-org/cells/http-router!1406 (merged), which is merged right before !257947 (merged). Because cells-routes:router-in-sync requires the router snapshot to be byte-identical to this branch's, and the router MR also contains the routes of the later MRs in the stack, this MR uses the pipeline:skip-router-sync label: the routes it adds are already in the HTTP Router through gitlab-org/cells/http-router!1406 (merged).
References
- #452118: Complete implementation of SCIM 2.0 per RFC7644
- #373996: Support CyberArk as SCIM identity provider (
/Schemasendpoint)
Screenshots or screen recordings
Not applicable (API only). Example response in the docs changes.
How to set up and validate locally
- Enable group SAML in GDK (
gdk config set omniauth.group_saml.enabled true && gdk reconfigure). - In the Rails console, create a group with SAML SSO and a group SCIM token, then enable the flag:
user = User.find_by(username: 'root') group = Groups::CreateService.new(user, name: 'SCIM Demo', path: 'scim-demo', organization_id: user.organization_id).execute.payload[:group] SamlProvider.create!(group: group, sso_url: 'https://idp.example.com/sso', certificate_fingerprint: '11:22:33:44:55:66:77:88:99:00:aa:bb:cc:dd:ee:ff:11:22:33:44', enabled: true) token = GroupScimAuthAccessToken.create!(group: group).token Feature.enable(:scim_discovery_endpoints) - List the schemas:
curl "http://gdk.test:3000/api/scim/v2/groups/scim-demo/Schemas" --header "Authorization: Bearer <token>" - Get a schema by URN:
curl "http://gdk.test:3000/api/scim/v2/groups/scim-demo/Schemas/urn:ietf:params:scim:schemas:core:2.0:User" --header "Authorization: Bearer <token>" - Disable the flag (
Feature.disable(:scim_discovery_endpoints)) and verify both requests return404.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.