Introduce EE::Gitlab::Scim::GroupMembershipCacheService

Part of Implement SCIM group membership caching (#544045 - closed).

What does this MR do and why?

This MR adds SCIM group membership caching infrastructure to better support group operations through PUT/PATCH operations.

Unlike SAML which provides complete group membership state on each sign-in, SCIM provides incremental updates. This creates challenges for safe membership management, particularly when multiple IdP groups map to the same GitLab group and we need to preserve memberships correctly. This was first raised at this discussion and more details can be found in the parent issue.

This MR introduces a caching layer that tracks SCIM group memberships, enabling the system to make informed decisions about which users should be added or removed during SCIM operations.

NOTE: This MR provides ONLY the caching infrastructure that will be used by the SCIM PUT and PATCH endpoints at !194470 (merged). The code introduced here will remain unused until then.

Database Review

As discussed here, the scim_group_memberships table is not used by Gitlab.com and is not expected to grow into more than a few thousand records at most.

Query 1: Upsert user to SCIM group cache (PATCH)

INSERT INTO "scim_group_memberships" ("user_id", "scim_group_uid", "created_at", "updated_at") 
VALUES (114, '9baf5d35-e046-4059-9da8-e6b662a894e5', NOW(), NOW()) 
ON CONFLICT ("user_id", "scim_group_uid") DO NOTHING;

Query 2: Remove users from SCIM group cache (PATCH)

DELETE FROM "scim_group_memberships" 
WHERE "scim_group_memberships"."scim_group_uid" = '9baf5d35-e046-4059-9da8-e6b662a894e5' 
AND "scim_group_memberships"."user_id" IN (114, 115, 116, 117, 118);

Query 3: Replace all users in SCIM group cache (PUT)

-- First: Clear existing memberships
DELETE FROM "scim_group_memberships" 
WHERE "scim_group_memberships"."scim_group_uid" = '9baf5d35-e046-4059-9da8-e6b662a894e5';

-- Then: Insert new memberships
INSERT INTO "scim_group_memberships" ("user_id", "scim_group_uid", "created_at", "updated_at") 
VALUES (114, '9baf5d35-e046-4059-9da8-e6b662a894e5', NOW(), NOW());

NOTE: All queries use the existing unique_scim_group_memberships_user_id_and_scim_group_uid index. The functionality is for self-managed only and uses batching to handle large membership lists efficiently.

References

How to set up and validate locally

Given this MR only adds the foundation for !194470 (merged), proper test coverage should be enough validation. Happy to provider further context.

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.

Edited by Paulo Barros

Merge request reports

Loading