Prevent enterprise users from deleting their own account on GitLab.com

Related to https://gitlab.com/gitlab-org/gitlab/-/issues/7237 and the self-managed implementation in !117832 (merged)

What does this MR do and why?

  • Enterprise users on a GitLab Premium top-level group (with domain verification available) should not be able to delete their own accounts on GitLab.com (SaaS) when a group owner has disabled it.
  • Group owners can still delete enterprise users via the group enterprise users API.
  • This mirrors the existing self-managed, instance-level feature (which uses License.feature_available?(:disable_deleting_account_for_users) and Gitlab::CurrentSettings.allow_account_deletion?), but at the top-level group level for SaaS enterprise users. The two rules compose: account deletion is blocked if either the instance admin disabled it (self-managed) or the enterprise group owner disabled it (SaaS).
  • The setting is stored as a key inside a new enterprise_user_settings JSONB column on namespace_settings, following the established pattern for grouping related settings without widening the table with individual columns. It defaults to allow_enterprise_user_account_deletion: true, so there is no change in behaviour for groups that do not configure the setting.
  • Enforcement is applied at both the UI layer (EE::ProfilesHelper#prevent_delete_account?) and the API/controller layer (EE::RegistrationsController#allow_account_deletion?), and the account deletion section shows a clear message when the option is unavailable.

Gating

  • SaaS feature prevent_enterprise_user_account_deletion (GitLab.com only).
  • Licensed feature prevent_enterprise_user_account_deletion (Premium+, namespace-scoped).
  • Feature flag deleting_account_disabled_for_enterprise_users (development, default off)
  • Group setting allow_enterprise_user_account_deletion (default true).

Database Review

db:check-migrations

  • Adds one new JSONB column (enterprise_user_settings) to namespace_settings with DEFAULT '{}' and NOT NULL.
  • A CHECK constraint (jsonb_typeof(enterprise_user_settings) = 'object') ensures the column always stores an object.
  • No data backfill is required; existing rows use the default {} and the accessor defaults allow_enterprise_user_account_deletion to true.

Documentation Review

See !244182 (merged)

Screenshots or screen recordings

After

How to set up and validate locally

No API tests are needed since GitLab's API does not allow account self-deletion.

  1. Set up a SaaS environment with a Premium top-level group that has domain verification enabled.
  2. Create an ultimate top-level-group and add a user with the Owner role. (Make sure its not an admin, save the owner and group ids)
  3. Create a regular user (save its id)
  4. Open a terminal and run gdk rails console
  5. Create an enterprise user associated with that group.
    group = Group.find(:id)
    ent_user = User.find(:id)
    ent_user.user_detail.update!(enterprise_group_id: group.id)
  6. Enable the feature flag
    Feature.enable(:deleting_account_disabled_for_enterprise_users)
  7. As the group owner, go to Settings > General > Permissions for the group.
  8. In the Enterprise users section, uncheck Allow account self-deletion by enterprise users and save.
  9. Sign in as the enterprise user and go to User Settings > Account.
  10. Confirm the account deletion section is hidden/disabled with a clear message.
  11. Attempt to call the account deletion endpoint directly — confirm it redirects with the alert message.

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 Hakeem Abdul-Razak

Merge request reports

Loading