SAML Group Sync - Add/Remove Groups
Problem to solve
Once SAML groups have been mapped, we should check the groups section in a SAML assertion. If the SAML group is found then we should add the user to that GitLab group. If the SAML group isn't found then we should remove the user from that GitLab group.
Intended users
User experience goal
Proposal
- Sync process on user sign-in
- User signs in via Group SAML
- Sign-in kicks off a
SamlGroupSync
worker fromGitlab::Auth::GroupSaml::User#find_and_update!
. Parameters likely need to consist of at least:- User ID
- Top-level group ID
- Array of Group Names from IdP
- Worker will query for group links where:
-
group_id
is in the list of IDs contained within the top-level group. This can be obtained viaGroup#self_and_descendents
. -
group_name
is in the array of group names from the IdP
-
- Worker adds the user as a member of the groups at the respective access level.
NOTE: The last MR (if there are multiple MRs in this issue) should default enable the :saml_group_links
feature flag introduced in !45080 (merged). We can keep the feature flag around for a while in case we need to disable the feature for any reason.
During implementation we should consider how to make the worker and/or service classes reusable for other sync-on-sign-in solutions, such as for OAuth.
Everything built here can also be used for instance-level sync. The only difference needed, as an example, is to pass a nil
value for top-level group ID for the worker. In this case the worker can query for any group in the whole instance by name and add members accordingly. And instead of the worker being kicked off from Gitlab::Auth::GroupSaml::User
it is called from Gitlab::Auth::Saml::User
. We should keep this in mind during implementation, especially during the worker creation phase so the parameters and usage feels natural for either case.
The supported way to pass groups via SAML will be the same as is currently supported for self-managed admin and external groups: https://docs.gitlab.com/ee/integration/saml.html#requirements
<saml2:AttributeStatement>
<saml2:Attribute Name="Groups" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Everyone</saml2:AttributeValue>
<saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">DBlessing Test Group</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
In the initial implementation we should only support attribute statements with the name 'Groups'. Later we can make this configurable like it is for self-managed. For self-managed, the 'Groups' are obtained from the auth_hash (see Gitlab::Auth::Saml::AuthHash
).
Further details
This is an Ultimate level feature.
Permissions and Security
Documentation
Availability & Testing
A new end-to-end test would be need to cover this feature. Testcase issue: gitlab-org/quality/testcases#1072 (moved)