Duo Flows cannot be enabled by non-admin users when SAML group links exist and global SAML membership lock is enabled

When the following conditions are all true on a self-managed instance, non-admin users (including group/project Owners) cannot enable Duo Flows and receive the error "Could not enable flow not authorized to create member":

  1. Admin > Settings > General > Visibility and access controls > "Lock memberships to SAML Group Links synchronization" is enabled (lock_memberships_to_saml: true)
  2. The SAML group sync licensed feature is available (saml_group_sync_available)
  3. The root ancestor group has at least one SAML group link configured (saml_group_links_exists?)

https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/policies/ee/project_policy.rb?ref_type=heads#L264

The service account is created successfully but cannot be added to the project as a member. Only instance admins can enable flows in this configuration.

Root cause:

The policy rule in ee/app/policies/ee/project_policy.rb prevents admin_project_member for all non-admins when the above conditions are met:

rule { memberships_locked_to_saml & saml_group_sync_available & saml_group_links_exists & ~admin }.policy do prevent :admin_project_member end

The fix in !224066 (merged) (18.10) bypasses invite_project_members for composite identity service accounts but still falls through to super in Members::Projects::CreatorService#can_create_new_member?, which checks admin_project_member. This permission is prevented by the SAML lock rule, causing the member creation to fail.

Steps to reproduce:

  1. Configure instance-level SAML SSO
  2. Enable "Lock memberships to SAML Group Links synchronization" in Admin settings
  3. Add at least one SAML group link to a top-level group
  4. As a group/project Owner (non-admin), attempt to enable a Duo Flow on a project in that group

Expected: Flow is enabled successfully; composite identity service accounts should bypass the SAML membership lock the same way they bypass membership_lock and disable_invite_members

Tested via:

policy = ProjectPolicy.new(user, project)
policy.debug(:admin_project_member)
# + [15] prevent when all?(memberships_locked_to_saml, saml_group_sync_available, saml_group_links_exists, ~admin)

Related: #577607 (closed), !224066 (merged), !223735 (merged)

Version: GitLab 18.10.1 self-managed

Workaround

Admin can enable duo flow for the user

Edited by 🤖 GitLab Bot 🤖