Add read-only groups attribute to instance SCIM User resource
What does this MR do and why?
The instance SCIM API can tell you who is in a SCIM group but not what groups a user belongs to. GET /Users and GET /Users/:id return no entitlement information at all, so an IdP connector that reconciles per user (such as SailPoint) has no way to verify the associations it created. RFC 7643 section 4.1.2 defines a read-only groups attribute on the User resource for this.
This MR adds it to both GET endpoints and each entry looks like:
{ "value": "<scim_group_uid>", "display": "<saml_group_name>", "type": "direct" }valueis the SCIM group's ID: it's the sameidthe Groups endpoints return, so a connector can round-trip between the two resourcesdisplayis the SAML group link's name, matchingdisplayNameon the Group resourcetypeis the membership type, which is alwaysdirect(see !249043 (comment 3658852666))
This is the reverse of !243439 (merged) which populated members on the Groups side.
Implementation note
The lookup runs two bounded queries rather than a join because there's no association to join through: scim_group_memberships and saml_group_links are connected by a matching scim_group_uid, not a foreign key. Both queries run once per page, so the serializer issues no queries of its own. There's a QueryRecorder spec to cover it.
References
How to set up and validate locally
-
Set up Self-managed mode:
export GITLAB_SIMULATE_SAAS=0 -
Run
gdk reconfigure -
Configure SAML: edit
config/gitlab.yml, replacingdevelopment.omniauth.providerswith the followingClick to expand
development: <<: *base omniauth: providers: - { name: 'saml', label: 'SAML', args: { assertion_consumer_service_url: 'http://gdk.test:3000/users/auth/saml/callback', idp_cert_fingerprint: 'AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD', idp_sso_target_url: 'https://example.com/sso', issuer: 'http://gdk.test:3000', name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent' } } -
Start gdk:
gdk start -
Ensure your gdk instance has an active Premium or Ultimate tier license
-
In the rails console, seed a SCIM group and membership
group = Group.first user = group.members.last.user link = SamlGroupLink.create!( group: group, saml_group_name: 'Developers', access_level: ::Gitlab::Access::GUEST, scim_group_uid: SecureRandom.uuid ) ScimIdentity.create!(user: user, extern_uid: 'test_uid', group: nil, active: true) Authn::ScimGroupMembership.create!(user: user, scim_group_uid: link.scim_group_uid) link.scim_group_uid # note this for reference in step 8.3 -
Generate a SCIM token and note the token and URL
-
Using the token and URL from the previous step, verify the
groupsattribute is returned:-
GET /Users/:id :
curl -s "$BASE/Users/test_uid" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/scim+json" -
GET /Users:
curl -s "$BASE/Users" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/scim+json" -
Each user resource includes a
groupsarray. For a user that belongs to a SCIM group it contains one entry per group:"groups": [ { "value": "<scim_group_uid from step 6>", "display": "Developers", "type": "direct" } ]
-
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.
Closes #604760 (closed)