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/Schemas returns the User schema only.
  • Instance SCIM (Self-Managed): /api/scim/v2/application/Schemas returns the User (including the read-only groups attribute) and Group schemas.

Implementation details:

  • Both APIs share one implementation in API::Scim::DiscoveryEndpoints. Each API provides its own authenticate_scim_discovery! (existing SCIM token, SAML, and license checks) and scim_discovery_base_url.
  • Schema IDs are URNs containing dots (...:core:2.0:User), so the :id route uses a custom requirement; otherwise Grape would parse .0:User as a format extension.
  • meta.location is the absolute URL of each schema resource.
  • Responses use the SCIM ListResponse and Error formats.

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

  1. !257943 (merged): schema definitions (merged)
  2. gitlab-org/cells/http-router!1406 (merged): HTTP Router routes for all three discovery endpoints (merge right before this MR)
  3. This MR: /Schemas + feature flag + docs
  4. !258175 (merged): /ServiceProviderConfig
  5. !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 (/Schemas endpoint)

Screenshots or screen recordings

Not applicable (API only). Example response in the docs changes.

How to set up and validate locally

  1. Enable group SAML in GDK (gdk config set omniauth.group_saml.enabled true && gdk reconfigure).
  2. 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)
  3. List the schemas:
    curl "http://gdk.test:3000/api/scim/v2/groups/scim-demo/Schemas" --header "Authorization: Bearer <token>"
  4. 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>"
  5. Disable the flag (Feature.disable(:scim_discovery_endpoints)) and verify both requests return 404.

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.


🤖 Generated with Claude Code

Edited by Ricardo Amarilla

Merge request reports

Loading
Loading